summaryrefslogtreecommitdiffstats
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/ARCMigrate/ARCMT.h131
-rw-r--r--include/clang/ARCMigrate/ARCMTActions.h76
-rw-r--r--include/clang/ARCMigrate/FileRemapper.h77
-rw-r--r--include/clang/AST/APValue.h452
-rw-r--r--include/clang/AST/AST.h28
-rw-r--r--include/clang/AST/ASTConsumer.h159
-rw-r--r--include/clang/AST/ASTContext.h2672
-rw-r--r--include/clang/AST/ASTDiagnostic.h47
-rw-r--r--include/clang/AST/ASTFwd.h33
-rw-r--r--include/clang/AST/ASTImporter.h295
-rw-r--r--include/clang/AST/ASTLambda.h80
-rw-r--r--include/clang/AST/ASTMutationListener.h127
-rw-r--r--include/clang/AST/ASTTypeTraits.h509
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h110
-rw-r--r--include/clang/AST/ASTVector.h405
-rw-r--r--include/clang/AST/Attr.h169
-rw-r--r--include/clang/AST/AttrIterator.h142
-rw-r--r--include/clang/AST/BaseSubobject.h87
-rw-r--r--include/clang/AST/BuiltinTypes.def261
-rw-r--r--include/clang/AST/CMakeLists.txt52
-rw-r--r--include/clang/AST/CXXInheritance.h365
-rw-r--r--include/clang/AST/CanonicalType.h665
-rw-r--r--include/clang/AST/CharUnits.h240
-rw-r--r--include/clang/AST/Comment.h1142
-rw-r--r--include/clang/AST/CommentBriefParser.h55
-rw-r--r--include/clang/AST/CommentCommandTraits.h189
-rw-r--r--include/clang/AST/CommentCommands.td241
-rw-r--r--include/clang/AST/CommentDiagnostic.h29
-rw-r--r--include/clang/AST/CommentHTMLNamedCharacterReferences.td177
-rw-r--r--include/clang/AST/CommentHTMLTags.td67
-rw-r--r--include/clang/AST/CommentLexer.h362
-rw-r--r--include/clang/AST/CommentParser.h123
-rw-r--r--include/clang/AST/CommentSema.h254
-rw-r--r--include/clang/AST/CommentVisitor.h70
-rw-r--r--include/clang/AST/Decl.h3801
-rw-r--r--include/clang/AST/DeclAccessPair.h72
-rw-r--r--include/clang/AST/DeclBase.h1904
-rw-r--r--include/clang/AST/DeclCXX.h3249
-rw-r--r--include/clang/AST/DeclContextInternals.h264
-rw-r--r--include/clang/AST/DeclFriend.h243
-rw-r--r--include/clang/AST/DeclGroup.h154
-rw-r--r--include/clang/AST/DeclLookups.h115
-rw-r--r--include/clang/AST/DeclObjC.h2742
-rw-r--r--include/clang/AST/DeclOpenMP.h91
-rw-r--r--include/clang/AST/DeclTemplate.h2927
-rw-r--r--include/clang/AST/DeclVisitor.h79
-rw-r--r--include/clang/AST/DeclarationName.h598
-rw-r--r--include/clang/AST/DependentDiagnostic.h189
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h129
-rw-r--r--include/clang/AST/Expr.h4941
-rw-r--r--include/clang/AST/ExprCXX.h4179
-rw-r--r--include/clang/AST/ExprObjC.h1568
-rw-r--r--include/clang/AST/ExprOpenMP.h129
-rw-r--r--include/clang/AST/ExternalASTSource.h578
-rw-r--r--include/clang/AST/GlobalDecl.h125
-rw-r--r--include/clang/AST/LambdaCapture.h128
-rw-r--r--include/clang/AST/Makefile79
-rw-r--r--include/clang/AST/Mangle.h243
-rw-r--r--include/clang/AST/MangleNumberingContext.h60
-rw-r--r--include/clang/AST/NSAPI.h262
-rw-r--r--include/clang/AST/NestedNameSpecifier.h516
-rw-r--r--include/clang/AST/OpenMPClause.h3198
-rw-r--r--include/clang/AST/OperationKinds.h356
-rw-r--r--include/clang/AST/ParentMap.h67
-rw-r--r--include/clang/AST/PrettyPrinter.h175
-rw-r--r--include/clang/AST/RawCommentList.h203
-rw-r--r--include/clang/AST/RecordLayout.h315
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h2805
-rw-r--r--include/clang/AST/Redeclarable.h285
-rw-r--r--include/clang/AST/SelectorLocationsKind.h83
-rw-r--r--include/clang/AST/Stmt.h2196
-rw-r--r--include/clang/AST/StmtCXX.h417
-rw-r--r--include/clang/AST/StmtGraphTraits.h83
-rw-r--r--include/clang/AST/StmtIterator.h144
-rw-r--r--include/clang/AST/StmtObjC.h375
-rw-r--r--include/clang/AST/StmtOpenMP.h2422
-rw-r--r--include/clang/AST/StmtVisitor.h227
-rw-r--r--include/clang/AST/TemplateBase.h661
-rw-r--r--include/clang/AST/TemplateName.h533
-rw-r--r--include/clang/AST/Type.h5683
-rw-r--r--include/clang/AST/TypeLoc.h2039
-rw-r--r--include/clang/AST/TypeLocNodes.def41
-rw-r--r--include/clang/AST/TypeLocVisitor.h62
-rw-r--r--include/clang/AST/TypeNodes.def129
-rw-r--r--include/clang/AST/TypeOrdering.h79
-rw-r--r--include/clang/AST/TypeVisitor.h95
-rw-r--r--include/clang/AST/UnresolvedSet.h140
-rw-r--r--include/clang/AST/VTTBuilder.h162
-rw-r--r--include/clang/AST/VTableBuilder.h566
-rw-r--r--include/clang/ASTMatchers/ASTMatchFinder.h294
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h4671
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h1591
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h404
-rw-r--r--include/clang/ASTMatchers/Dynamic/Diagnostics.h185
-rw-r--r--include/clang/ASTMatchers/Dynamic/Parser.h257
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h133
-rw-r--r--include/clang/ASTMatchers/Dynamic/VariantValue.h326
-rw-r--r--include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h49
-rw-r--r--include/clang/Analysis/Analyses/Consumed.h269
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h210
-rw-r--r--include/clang/Analysis/Analyses/FormatString.h679
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h117
-rw-r--r--include/clang/Analysis/Analyses/PostOrderCFGView.h115
-rw-r--r--include/clang/Analysis/Analyses/PseudoConstantAnalysis.h45
-rw-r--r--include/clang/Analysis/Analyses/ReachableCode.h69
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafety.h226
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyCommon.h505
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyLogical.h108
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyOps.def57
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTIL.h1918
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTraverse.h902
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyUtil.h358
-rw-r--r--include/clang/Analysis/Analyses/UninitializedValues.h126
-rw-r--r--include/clang/Analysis/AnalysisContext.h480
-rw-r--r--include/clang/Analysis/AnalysisDiagnostic.h28
-rw-r--r--include/clang/Analysis/CFG.h1113
-rw-r--r--include/clang/Analysis/CFGStmtMap.h52
-rw-r--r--include/clang/Analysis/CallGraph.h253
-rw-r--r--include/clang/Analysis/CodeInjector.h46
-rw-r--r--include/clang/Analysis/DomainSpecific/CocoaConventions.h42
-rw-r--r--include/clang/Analysis/DomainSpecific/ObjCNoReturn.h46
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowValues.h172
-rw-r--r--include/clang/Analysis/ProgramPoint.h704
-rw-r--r--include/clang/Analysis/Support/BumpVector.h250
-rw-r--r--include/clang/Basic/ABI.h211
-rw-r--r--include/clang/Basic/AddressSpaces.h51
-rw-r--r--include/clang/Basic/AllDiagnostics.h40
-rw-r--r--include/clang/Basic/Attr.td2172
-rw-r--r--include/clang/Basic/AttrDocs.td1861
-rw-r--r--include/clang/Basic/AttrKinds.h34
-rw-r--r--include/clang/Basic/Attributes.h39
-rw-r--r--include/clang/Basic/Builtins.def1257
-rw-r--r--include/clang/Basic/Builtins.h220
-rw-r--r--include/clang/Basic/BuiltinsAArch64.def65
-rw-r--r--include/clang/Basic/BuiltinsAMDGPU.def36
-rw-r--r--include/clang/Basic/BuiltinsARM.def114
-rw-r--r--include/clang/Basic/BuiltinsHexagon.def878
-rw-r--r--include/clang/Basic/BuiltinsLe64.def19
-rw-r--r--include/clang/Basic/BuiltinsMips.def900
-rw-r--r--include/clang/Basic/BuiltinsNEON.def21
-rw-r--r--include/clang/Basic/BuiltinsNVPTX.def569
-rw-r--r--include/clang/Basic/BuiltinsPPC.def379
-rw-r--r--include/clang/Basic/BuiltinsSystemZ.def252
-rw-r--r--include/clang/Basic/BuiltinsWebAssembly.def24
-rw-r--r--include/clang/Basic/BuiltinsX86.def1577
-rw-r--r--include/clang/Basic/BuiltinsXCore.def22
-rw-r--r--include/clang/Basic/CMakeLists.txt41
-rw-r--r--include/clang/Basic/CapturedStmt.h24
-rw-r--r--include/clang/Basic/CharInfo.h198
-rw-r--r--include/clang/Basic/CommentNodes.td27
-rw-r--r--include/clang/Basic/CommentOptions.h39
-rw-r--r--include/clang/Basic/DeclNodes.td88
-rw-r--r--include/clang/Basic/Diagnostic.h1414
-rw-r--r--include/clang/Basic/Diagnostic.td127
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td266
-rw-r--r--include/clang/Basic/DiagnosticAnalysisKinds.td12
-rw-r--r--include/clang/Basic/DiagnosticCategories.h26
-rw-r--r--include/clang/Basic/DiagnosticCategories.td11
-rw-r--r--include/clang/Basic/DiagnosticCommentKinds.td172
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td217
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td226
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td219
-rw-r--r--include/clang/Basic/DiagnosticGroups.td848
-rw-r--r--include/clang/Basic/DiagnosticIDs.h287
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td673
-rw-r--r--include/clang/Basic/DiagnosticOptions.def99
-rw-r--r--include/clang/Basic/DiagnosticOptions.h118
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td985
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td8221
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td124
-rw-r--r--include/clang/Basic/ExceptionSpecificationType.h60
-rw-r--r--include/clang/Basic/ExpressionTraits.h26
-rw-r--r--include/clang/Basic/FileManager.h288
-rw-r--r--include/clang/Basic/FileSystemOptions.h32
-rw-r--r--include/clang/Basic/FileSystemStatCache.h131
-rw-r--r--include/clang/Basic/IdentifierTable.h876
-rw-r--r--include/clang/Basic/LLVM.h83
-rw-r--r--include/clang/Basic/Lambda.h43
-rw-r--r--include/clang/Basic/LangOptions.def246
-rw-r--r--include/clang/Basic/LangOptions.h190
-rw-r--r--include/clang/Basic/Linkage.h110
-rw-r--r--include/clang/Basic/MacroBuilder.h48
-rw-r--r--include/clang/Basic/Makefile70
-rw-r--r--include/clang/Basic/Module.h569
-rw-r--r--include/clang/Basic/ObjCRuntime.h333
-rw-r--r--include/clang/Basic/OpenCLExtensions.def35
-rw-r--r--include/clang/Basic/OpenMPKinds.def451
-rw-r--r--include/clang/Basic/OpenMPKinds.h175
-rw-r--r--include/clang/Basic/OperatorKinds.def107
-rw-r--r--include/clang/Basic/OperatorKinds.h36
-rw-r--r--include/clang/Basic/OperatorPrecedence.h52
-rw-r--r--include/clang/Basic/PartialDiagnostic.h410
-rw-r--r--include/clang/Basic/PlistSupport.h119
-rw-r--r--include/clang/Basic/PrettyStackTrace.h38
-rw-r--r--include/clang/Basic/SanitizerBlacklist.h46
-rw-r--r--include/clang/Basic/Sanitizers.def122
-rw-r--r--include/clang/Basic/Sanitizers.h86
-rw-r--r--include/clang/Basic/SourceLocation.h438
-rw-r--r--include/clang/Basic/SourceManager.h1711
-rw-r--r--include/clang/Basic/SourceManagerInternals.h128
-rw-r--r--include/clang/Basic/Specifiers.h283
-rw-r--r--include/clang/Basic/StmtNodes.td224
-rw-r--r--include/clang/Basic/TargetBuiltins.h201
-rw-r--r--include/clang/Basic/TargetCXXABI.h354
-rw-r--r--include/clang/Basic/TargetInfo.h953
-rw-r--r--include/clang/Basic/TargetOptions.h54
-rw-r--r--include/clang/Basic/TemplateKinds.h44
-rw-r--r--include/clang/Basic/TokenKinds.def781
-rw-r--r--include/clang/Basic/TokenKinds.h106
-rw-r--r--include/clang/Basic/TypeTraits.h100
-rw-r--r--include/clang/Basic/Version.h82
-rw-r--r--include/clang/Basic/Version.inc.in6
-rw-r--r--include/clang/Basic/VersionTuple.h163
-rw-r--r--include/clang/Basic/VirtualFileSystem.h341
-rw-r--r--include/clang/Basic/Visibility.h141
-rw-r--r--include/clang/Basic/arm_neon.td1657
-rw-r--r--include/clang/CMakeLists.txt6
-rw-r--r--include/clang/CodeGen/BackendUtil.h44
-rw-r--r--include/clang/CodeGen/CGFunctionInfo.h538
-rw-r--r--include/clang/CodeGen/CodeGenABITypes.h91
-rw-r--r--include/clang/CodeGen/CodeGenAction.h107
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h54
-rw-r--r--include/clang/CodeGen/ObjectFilePCHContainerOperations.h43
-rw-r--r--include/clang/Config/config.h.cmake38
-rw-r--r--include/clang/Config/config.h.in40
-rw-r--r--include/clang/Driver/Action.h317
-rw-r--r--include/clang/Driver/CC1Options.td718
-rw-r--r--include/clang/Driver/CLCompatOptions.td342
-rw-r--r--include/clang/Driver/CMakeLists.txt3
-rw-r--r--include/clang/Driver/Compilation.h202
-rw-r--r--include/clang/Driver/Driver.h468
-rw-r--r--include/clang/Driver/DriverDiagnostic.h28
-rw-r--r--include/clang/Driver/Job.h174
-rw-r--r--include/clang/Driver/Makefile10
-rw-r--r--include/clang/Driver/Multilib.h175
-rw-r--r--include/clang/Driver/Options.h51
-rw-r--r--include/clang/Driver/Options.td2133
-rw-r--r--include/clang/Driver/Phases.h37
-rw-r--r--include/clang/Driver/SanitizerArgs.h73
-rw-r--r--include/clang/Driver/Tool.h137
-rw-r--r--include/clang/Driver/ToolChain.h418
-rw-r--r--include/clang/Driver/Types.def96
-rw-r--r--include/clang/Driver/Types.h97
-rw-r--r--include/clang/Driver/Util.h32
-rw-r--r--include/clang/Edit/Commit.h143
-rw-r--r--include/clang/Edit/EditedSource.h97
-rw-r--r--include/clang/Edit/EditsReceiver.h35
-rw-r--r--include/clang/Edit/FileOffset.h61
-rw-r--r--include/clang/Edit/Rewriters.h41
-rw-r--r--include/clang/Format/Format.h792
-rw-r--r--include/clang/Frontend/ASTConsumers.h58
-rw-r--r--include/clang/Frontend/ASTUnit.h924
-rw-r--r--include/clang/Frontend/ChainedDiagnosticConsumer.h72
-rw-r--r--include/clang/Frontend/CodeGenOptions.def212
-rw-r--r--include/clang/Frontend/CodeGenOptions.h245
-rw-r--r--include/clang/Frontend/CommandLineSourceLoc.h87
-rw-r--r--include/clang/Frontend/CompilerInstance.h785
-rw-r--r--include/clang/Frontend/CompilerInvocation.h219
-rw-r--r--include/clang/Frontend/DependencyOutputOptions.h73
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h178
-rw-r--r--include/clang/Frontend/FrontendAction.h298
-rw-r--r--include/clang/Frontend/FrontendActions.h241
-rw-r--r--include/clang/Frontend/FrontendDiagnostic.h28
-rw-r--r--include/clang/Frontend/FrontendOptions.h292
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h26
-rw-r--r--include/clang/Frontend/LangStandard.h100
-rw-r--r--include/clang/Frontend/LangStandards.def153
-rw-r--r--include/clang/Frontend/LayoutOverrideSource.h63
-rw-r--r--include/clang/Frontend/LogDiagnosticPrinter.h85
-rw-r--r--include/clang/Frontend/MigratorOptions.h31
-rw-r--r--include/clang/Frontend/MultiplexConsumer.h69
-rw-r--r--include/clang/Frontend/PCHContainerOperations.h118
-rw-r--r--include/clang/Frontend/PreprocessorOutputOptions.h41
-rw-r--r--include/clang/Frontend/SerializedDiagnosticPrinter.h43
-rw-r--r--include/clang/Frontend/SerializedDiagnosticReader.h131
-rw-r--r--include/clang/Frontend/SerializedDiagnostics.h59
-rw-r--r--include/clang/Frontend/TextDiagnostic.h122
-rw-r--r--include/clang/Frontend/TextDiagnosticBuffer.h55
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h58
-rw-r--r--include/clang/Frontend/Utils.h220
-rw-r--r--include/clang/Frontend/VerifyDiagnosticConsumer.h278
-rw-r--r--include/clang/FrontendTool/Utils.h30
-rw-r--r--include/clang/Index/CommentToXML.h52
-rw-r--r--include/clang/Index/USRGeneration.h62
-rw-r--r--include/clang/Lex/CodeCompletionHandler.h71
-rw-r--r--include/clang/Lex/DirectoryLookup.h196
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h48
-rw-r--r--include/clang/Lex/HeaderMap.h76
-rw-r--r--include/clang/Lex/HeaderSearch.h688
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h206
-rw-r--r--include/clang/Lex/LexDiagnostic.h28
-rw-r--r--include/clang/Lex/Lexer.h665
-rw-r--r--include/clang/Lex/LiteralSupport.h260
-rw-r--r--include/clang/Lex/MacroArgs.h127
-rw-r--r--include/clang/Lex/MacroInfo.h609
-rw-r--r--include/clang/Lex/ModuleLoader.h129
-rw-r--r--include/clang/Lex/ModuleMap.h514
-rw-r--r--include/clang/Lex/MultipleIncludeOpt.h181
-rw-r--r--include/clang/Lex/PPCallbacks.h509
-rw-r--r--include/clang/Lex/PPConditionalDirectiveRecord.h103
-rw-r--r--include/clang/Lex/PTHLexer.h104
-rw-r--r--include/clang/Lex/PTHManager.h150
-rw-r--r--include/clang/Lex/Pragma.h126
-rw-r--r--include/clang/Lex/PreprocessingRecord.h536
-rw-r--r--include/clang/Lex/Preprocessor.h1911
-rw-r--r--include/clang/Lex/PreprocessorLexer.h183
-rw-r--r--include/clang/Lex/PreprocessorOptions.h185
-rw-r--r--include/clang/Lex/ScratchBuffer.h45
-rw-r--r--include/clang/Lex/Token.h328
-rw-r--r--include/clang/Lex/TokenConcatenation.h72
-rw-r--r--include/clang/Lex/TokenLexer.h205
-rw-r--r--include/clang/Makefile44
-rw-r--r--include/clang/Parse/CMakeLists.txt4
-rw-r--r--include/clang/Parse/Makefile13
-rw-r--r--include/clang/Parse/ParseAST.h49
-rw-r--r--include/clang/Parse/ParseDiagnostic.h28
-rw-r--r--include/clang/Parse/Parser.h2593
-rw-r--r--include/clang/Rewrite/Core/DeltaTree.h50
-rw-r--r--include/clang/Rewrite/Core/HTMLRewrite.h81
-rw-r--r--include/clang/Rewrite/Core/RewriteBuffer.h117
-rw-r--r--include/clang/Rewrite/Core/RewriteRope.h214
-rw-r--r--include/clang/Rewrite/Core/Rewriter.h195
-rw-r--r--include/clang/Rewrite/Core/TokenRewriter.h79
-rw-r--r--include/clang/Rewrite/Frontend/ASTConsumers.h48
-rw-r--r--include/clang/Rewrite/Frontend/FixItRewriter.h132
-rw-r--r--include/clang/Rewrite/Frontend/FrontendActions.h83
-rw-r--r--include/clang/Rewrite/Frontend/Rewriters.h35
-rw-r--r--include/clang/Sema/AnalysisBasedWarnings.h103
-rw-r--r--include/clang/Sema/AttributeList.h863
-rw-r--r--include/clang/Sema/CMakeLists.txt24
-rw-r--r--include/clang/Sema/CXXFieldCollector.h80
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h976
-rw-r--r--include/clang/Sema/CodeCompleteOptions.h41
-rw-r--r--include/clang/Sema/DeclSpec.h2313
-rw-r--r--include/clang/Sema/DelayedDiagnostic.h305
-rw-r--r--include/clang/Sema/Designator.h210
-rw-r--r--include/clang/Sema/ExternalSemaSource.h229
-rw-r--r--include/clang/Sema/IdentifierResolver.h213
-rw-r--r--include/clang/Sema/Initialization.h1145
-rw-r--r--include/clang/Sema/LocInfoType.h62
-rw-r--r--include/clang/Sema/Lookup.h760
-rw-r--r--include/clang/Sema/LoopHint.h45
-rw-r--r--include/clang/Sema/Makefile39
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h353
-rw-r--r--include/clang/Sema/ObjCMethodList.h58
-rw-r--r--include/clang/Sema/Overload.h799
-rw-r--r--include/clang/Sema/Ownership.h287
-rw-r--r--include/clang/Sema/ParsedTemplate.h214
-rw-r--r--include/clang/Sema/PrettyDeclStackTrace.h47
-rw-r--r--include/clang/Sema/Scope.h484
-rw-r--r--include/clang/Sema/ScopeInfo.h858
-rw-r--r--include/clang/Sema/Sema.h9265
-rw-r--r--include/clang/Sema/SemaConsumer.h48
-rw-r--r--include/clang/Sema/SemaDiagnostic.h28
-rw-r--r--include/clang/Sema/SemaFixItUtils.h91
-rw-r--r--include/clang/Sema/SemaInternal.h346
-rw-r--r--include/clang/Sema/SemaLambda.h36
-rw-r--r--include/clang/Sema/Template.h519
-rw-r--r--include/clang/Sema/TemplateDeduction.h315
-rw-r--r--include/clang/Sema/TypoCorrection.h366
-rw-r--r--include/clang/Sema/Weak.h46
-rw-r--r--include/clang/Serialization/ASTBitCodes.h1605
-rw-r--r--include/clang/Serialization/ASTDeserializationListener.h58
-rw-r--r--include/clang/Serialization/ASTReader.h2141
-rw-r--r--include/clang/Serialization/ASTWriter.h920
-rw-r--r--include/clang/Serialization/CMakeLists.txt9
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h139
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h207
-rw-r--r--include/clang/Serialization/Makefile19
-rw-r--r--include/clang/Serialization/Module.h475
-rw-r--r--include/clang/Serialization/ModuleFileExtension.h149
-rw-r--r--include/clang/Serialization/ModuleManager.h289
-rw-r--r--include/clang/Serialization/SerializationDiagnostic.h28
-rw-r--r--include/clang/StaticAnalyzer/Checkers/CheckerBase.td39
-rw-r--r--include/clang/StaticAnalyzer/Checkers/ClangCheckers.h22
-rw-r--r--include/clang/StaticAnalyzer/Checkers/LocalCheckers.h28
-rw-r--r--include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h234
-rw-r--r--include/clang/StaticAnalyzer/Core/Analyses.def57
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h567
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h561
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h366
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h81
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h25
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h848
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h554
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h632
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerOptInfo.h44
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerRegistry.h140
-rw-r--r--include/clang/StaticAnalyzer/Core/IssueHash.h51
-rw-r--r--include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h40
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h109
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h135
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h200
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h60
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h1091
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h349
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h49
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h188
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h547
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h52
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h57
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h127
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h497
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h646
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h140
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h36
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h1370
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h854
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h245
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h43
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h333
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h574
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h288
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h51
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h162
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h61
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h681
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h46
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h27
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h100
-rw-r--r--include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h49
-rw-r--r--include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h33
-rw-r--r--include/clang/StaticAnalyzer/Frontend/FrontendActions.h60
-rw-r--r--include/clang/StaticAnalyzer/Frontend/ModelConsumer.h44
-rw-r--r--include/clang/Tooling/ArgumentsAdjusters.h69
-rw-r--r--include/clang/Tooling/CommonOptionsParser.h117
-rw-r--r--include/clang/Tooling/CompilationDatabase.h222
-rw-r--r--include/clang/Tooling/CompilationDatabasePluginRegistry.h27
-rw-r--r--include/clang/Tooling/Core/Lookup.h48
-rw-r--r--include/clang/Tooling/Core/Replacement.h241
-rw-r--r--include/clang/Tooling/FileMatchTrie.h89
-rw-r--r--include/clang/Tooling/JSONCompilationDatabase.h133
-rw-r--r--include/clang/Tooling/Refactoring.h74
-rw-r--r--include/clang/Tooling/RefactoringCallbacks.h90
-rw-r--r--include/clang/Tooling/ReplacementsYaml.h76
-rw-r--r--include/clang/Tooling/Tooling.h455
-rw-r--r--include/clang/module.modulemap134
437 files changed, 0 insertions, 185493 deletions
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
deleted file mode 100644
index 7408186..0000000
--- a/include/clang/ARCMigrate/ARCMT.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- 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_ARCMIGRATE_ARCMT_H
-#define LLVM_CLANG_ARCMIGRATE_ARCMT_H
-
-#include "clang/ARCMigrate/FileRemapper.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Frontend/CompilerInvocation.h"
-
-namespace clang {
- class ASTContext;
- class DiagnosticConsumer;
- class PCHContainerOperations;
-
-namespace arcmt {
- class MigrationPass;
-
-/// \brief 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
-///
-/// It then checks the AST and produces errors/warning for ARC migration issues
-/// that the user needs to handle manually.
-///
-/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
-/// even if the migrator can fix them, but the function will still return false
-/// if all ARC errors can be fixed.
-///
-/// \param plistOut if non-empty, it is the file path to store the plist with
-/// the pre-migration ARC diagnostics.
-///
-/// \returns false if no error is produced, true otherwise.
-bool
-checkForManualIssues(CompilerInvocation &CI, const FrontendInputFile &Input,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- DiagnosticConsumer *DiagClient,
- bool emitPremigrationARCErrors = false,
- StringRef plistOut = StringRef());
-
-/// \brief 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.
-bool
-applyTransformations(CompilerInvocation &origCI,
- const FrontendInputFile &Input,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- DiagnosticConsumer *DiagClient);
-
-/// \brief Applies automatic modifications and produces temporary files
-/// and metadata into the \p outputDir path.
-///
-/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
-/// even if the migrator can fix them, but the function will still return false
-/// if all ARC errors can be fixed.
-///
-/// \param plistOut if non-empty, it is the file path to store the plist with
-/// the pre-migration ARC diagnostics.
-///
-/// \returns false if no error is produced, true otherwise.
-bool migrateWithTemporaryFiles(
- CompilerInvocation &origCI, const FrontendInputFile &Input,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- DiagnosticConsumer *DiagClient, StringRef outputDir,
- bool emitPremigrationARCErrors, StringRef plistOut);
-
-/// \brief Get the set of file remappings from the \p outputDir path that
-/// migrateWithTemporaryFiles produced.
-///
-/// \returns false if no error is produced, true otherwise.
-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
-/// info.
-///
-/// \returns false if no error is produced, true otherwise.
-bool getFileRemappingsFromFileList(
- std::vector<std::pair<std::string,std::string> > &remap,
- ArrayRef<StringRef> remapFiles,
- DiagnosticConsumer *DiagClient);
-
-typedef void (*TransformFn)(MigrationPass &pass);
-
-std::vector<TransformFn> getAllTransformations(LangOptions::GCMode OrigGCMode,
- bool NoFinalizeRemoval);
-
-class MigrationProcess {
- CompilerInvocation OrigCI;
- std::shared_ptr<PCHContainerOperations> PCHContainerOps;
- DiagnosticConsumer *DiagClient;
- FileRemapper Remapper;
-
-public:
- bool HadARCErrors;
-
- MigrationProcess(const CompilerInvocation &CI,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- DiagnosticConsumer *diagClient,
- StringRef outputDir = StringRef());
-
- class RewriteListener {
- public:
- virtual ~RewriteListener();
-
- virtual void start(ASTContext &Ctx) { }
- virtual void finish() { }
-
- virtual void insert(SourceLocation loc, StringRef text) { }
- virtual void remove(CharSourceRange range) { }
- };
-
- bool applyTransform(TransformFn trans, RewriteListener *listener = nullptr);
-
- FileRemapper &getRemapper() { return Remapper; }
-};
-
-} // end namespace arcmt
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
deleted file mode 100644
index c830aa3..0000000
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ARCMIGRATE_ARCMTACTIONS_H
-#define LLVM_CLANG_ARCMIGRATE_ARCMTACTIONS_H
-
-#include "clang/ARCMigrate/FileRemapper.h"
-#include "clang/Frontend/FrontendAction.h"
-#include <memory>
-
-namespace clang {
-namespace arcmt {
-
-class CheckAction : public WrapperFrontendAction {
-protected:
- bool BeginInvocation(CompilerInstance &CI) override;
-
-public:
- CheckAction(FrontendAction *WrappedAction);
-};
-
-class ModifyAction : public WrapperFrontendAction {
-protected:
- bool BeginInvocation(CompilerInstance &CI) override;
-
-public:
- ModifyAction(FrontendAction *WrappedAction);
-};
-
-class MigrateSourceAction : public ASTFrontendAction {
- FileRemapper Remapper;
-protected:
- bool BeginInvocation(CompilerInstance &CI) override;
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-class MigrateAction : public WrapperFrontendAction {
- std::string MigrateDir;
- std::string PlistOut;
- bool EmitPremigrationARCErros;
-protected:
- bool BeginInvocation(CompilerInstance &CI) override;
-
-public:
- MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
- StringRef plistOut,
- bool emitPremigrationARCErrors);
-};
-
-/// \brief Migrates to modern ObjC syntax.
-class ObjCMigrateAction : public WrapperFrontendAction {
- std::string MigrateDir;
- unsigned ObjCMigAction;
- FileRemapper Remapper;
- CompilerInstance *CompInst;
-public:
- ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
- unsigned migrateAction);
-
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
- bool BeginInvocation(CompilerInstance &CI) override;
-};
-
-}
-}
-
-#endif
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
deleted file mode 100644
index 53b88e9..0000000
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- FileRemapper.h - File Remapping Helper ------------------*- 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_ARCMIGRATE_FILEREMAPPER_H
-#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/StringRef.h"
-#include <memory>
-
-namespace llvm {
- class MemoryBuffer;
-}
-
-namespace clang {
- class FileManager;
- class FileEntry;
- class DiagnosticsEngine;
- class PreprocessorOptions;
-
-namespace arcmt {
-
-class FileRemapper {
- // FIXME: Reuse the same FileManager for multiple ASTContexts.
- std::unique_ptr<FileManager> FileMgr;
-
- typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target;
- typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy;
- MappingsTy FromToMappings;
-
- llvm::DenseMap<const FileEntry *, const FileEntry *> ToFromMappings;
-
-public:
- FileRemapper();
- ~FileRemapper();
-
- bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag,
- bool ignoreIfFilesChanged);
- bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag,
- bool ignoreIfFilesChanged);
- bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag);
- bool flushToFile(StringRef outputPath, DiagnosticsEngine &Diag);
-
- bool overwriteOriginal(DiagnosticsEngine &Diag,
- StringRef outputDir = StringRef());
-
- void remap(StringRef filePath, std::unique_ptr<llvm::MemoryBuffer> memBuf);
-
- void applyMappings(PreprocessorOptions &PPOpts) const;
-
- void clear(StringRef outputDir = StringRef());
-
-private:
- void remap(const FileEntry *file, std::unique_ptr<llvm::MemoryBuffer> memBuf);
- void remap(const FileEntry *file, const FileEntry *newfile);
-
- const FileEntry *getOriginalFile(StringRef filePath);
- void resetTarget(Target &targ);
-
- bool report(const Twine &err, DiagnosticsEngine &Diag);
-
- std::string getRemapInfoFile(StringRef outputDir);
-};
-
-} // end namespace arcmt
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
deleted file mode 100644
index e58c219..0000000
--- a/include/clang/AST/APValue.h
+++ /dev/null
@@ -1,452 +0,0 @@
-//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- 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 APValue class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_APVALUE_H
-#define LLVM_CLANG_AST_APVALUE_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-
-namespace clang {
- class AddrLabelExpr;
- class ASTContext;
- class CharUnits;
- class DiagnosticBuilder;
- class Expr;
- class FieldDecl;
- class Decl;
- class ValueDecl;
- class CXXRecordDecl;
- class QualType;
-
-/// APValue - This class implements a discriminated union of [uninitialized]
-/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
-/// [Vector: N * APValue], [Array: N * APValue]
-class APValue {
- typedef llvm::APSInt APSInt;
- typedef llvm::APFloat APFloat;
-public:
- enum ValueKind {
- Uninitialized,
- Int,
- Float,
- ComplexInt,
- ComplexFloat,
- LValue,
- Vector,
- Array,
- Struct,
- Union,
- MemberPointer,
- AddrLabelDiff
- };
- typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
- typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
- union LValuePathEntry {
- /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
- /// in the path. An opaque value of type BaseOrMemberType.
- void *BaseOrMember;
- /// ArrayIndex - The array index of the next item in the path.
- uint64_t ArrayIndex;
- };
- struct NoLValuePath {};
- struct UninitArray {};
- struct UninitStruct {};
-private:
- ValueKind Kind;
-
- struct ComplexAPSInt {
- APSInt Real, Imag;
- ComplexAPSInt() : Real(1), Imag(1) {}
- };
- struct ComplexAPFloat {
- APFloat Real, Imag;
- ComplexAPFloat() : Real(0.0), Imag(0.0) {}
- };
- struct LV;
- struct Vec {
- APValue *Elts;
- unsigned NumElts;
- Vec() : Elts(nullptr), NumElts(0) {}
- ~Vec() { delete[] Elts; }
- };
- struct Arr {
- APValue *Elts;
- unsigned NumElts, ArrSize;
- Arr(unsigned NumElts, unsigned ArrSize);
- ~Arr();
- };
- struct StructData {
- APValue *Elts;
- unsigned NumBases;
- unsigned NumFields;
- StructData(unsigned NumBases, unsigned NumFields);
- ~StructData();
- };
- struct UnionData {
- const FieldDecl *Field;
- APValue *Value;
- UnionData();
- ~UnionData();
- };
- struct AddrLabelDiffData {
- const AddrLabelExpr* LHSExpr;
- const AddrLabelExpr* RHSExpr;
- };
- struct MemberPointerData;
-
- // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
- typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
- ComplexAPFloat, Vec, Arr, StructData,
- UnionData, AddrLabelDiffData> DataType;
- static const size_t DataSize = sizeof(DataType);
-
- DataType Data;
-
-public:
- APValue() : Kind(Uninitialized) {}
- explicit APValue(APSInt I) : Kind(Uninitialized) {
- MakeInt(); setInt(std::move(I));
- }
- explicit APValue(APFloat F) : Kind(Uninitialized) {
- MakeFloat(); setFloat(std::move(F));
- }
- explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
- MakeVector(); setVector(E, N);
- }
- APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
- MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
- }
- APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
- MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
- }
- APValue(const APValue &RHS);
- APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
- APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
- : Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O, N, CallIndex);
- }
- APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
- bool OnePastTheEnd, unsigned CallIndex)
- : Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
- }
- APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
- MakeArray(InitElts, Size);
- }
- APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
- MakeStruct(B, M);
- }
- explicit APValue(const FieldDecl *D, const APValue &V = APValue())
- : Kind(Uninitialized) {
- MakeUnion(); setUnion(D, V);
- }
- APValue(const ValueDecl *Member, bool IsDerivedMember,
- ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
- MakeMemberPointer(Member, IsDerivedMember, Path);
- }
- APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
- : Kind(Uninitialized) {
- MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
- }
-
- ~APValue() {
- MakeUninit();
- }
-
- /// \brief 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.
- void swap(APValue &RHS);
-
- ValueKind getKind() const { return Kind; }
- bool isUninit() const { return Kind == Uninitialized; }
- bool isInt() const { return Kind == Int; }
- bool isFloat() const { return Kind == Float; }
- bool isComplexInt() const { return Kind == ComplexInt; }
- bool isComplexFloat() const { return Kind == ComplexFloat; }
- bool isLValue() const { return Kind == LValue; }
- bool isVector() const { return Kind == Vector; }
- bool isArray() const { return Kind == Array; }
- bool isStruct() const { return Kind == Struct; }
- bool isUnion() const { return Kind == Union; }
- bool isMemberPointer() const { return Kind == MemberPointer; }
- bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
-
- void dump() const;
- void dump(raw_ostream &OS) const;
-
- void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
- std::string getAsString(ASTContext &Ctx, QualType Ty) const;
-
- APSInt &getInt() {
- assert(isInt() && "Invalid accessor");
- return *(APSInt*)(char*)Data.buffer;
- }
- const APSInt &getInt() const {
- return const_cast<APValue*>(this)->getInt();
- }
-
- APFloat &getFloat() {
- assert(isFloat() && "Invalid accessor");
- return *(APFloat*)(char*)Data.buffer;
- }
- const APFloat &getFloat() const {
- return const_cast<APValue*>(this)->getFloat();
- }
-
- APSInt &getComplexIntReal() {
- assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
- }
- const APSInt &getComplexIntReal() const {
- return const_cast<APValue*>(this)->getComplexIntReal();
- }
-
- APSInt &getComplexIntImag() {
- assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
- }
- const APSInt &getComplexIntImag() const {
- return const_cast<APValue*>(this)->getComplexIntImag();
- }
-
- APFloat &getComplexFloatReal() {
- assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
- }
- const APFloat &getComplexFloatReal() const {
- return const_cast<APValue*>(this)->getComplexFloatReal();
- }
-
- APFloat &getComplexFloatImag() {
- assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
- }
- const APFloat &getComplexFloatImag() const {
- return const_cast<APValue*>(this)->getComplexFloatImag();
- }
-
- const LValueBase getLValueBase() const;
- CharUnits &getLValueOffset();
- const CharUnits &getLValueOffset() const {
- return const_cast<APValue*>(this)->getLValueOffset();
- }
- bool isLValueOnePastTheEnd() const;
- bool hasLValuePath() const;
- ArrayRef<LValuePathEntry> getLValuePath() const;
- unsigned getLValueCallIndex() const;
-
- APValue &getVectorElt(unsigned I) {
- assert(isVector() && "Invalid accessor");
- assert(I < getVectorLength() && "Index out of range");
- return ((Vec*)(char*)Data.buffer)->Elts[I];
- }
- const APValue &getVectorElt(unsigned I) const {
- return const_cast<APValue*>(this)->getVectorElt(I);
- }
- unsigned getVectorLength() const {
- assert(isVector() && "Invalid accessor");
- return ((const Vec*)(const void *)Data.buffer)->NumElts;
- }
-
- APValue &getArrayInitializedElt(unsigned I) {
- assert(isArray() && "Invalid accessor");
- assert(I < getArrayInitializedElts() && "Index out of range");
- return ((Arr*)(char*)Data.buffer)->Elts[I];
- }
- const APValue &getArrayInitializedElt(unsigned I) const {
- return const_cast<APValue*>(this)->getArrayInitializedElt(I);
- }
- bool hasArrayFiller() const {
- return getArrayInitializedElts() != getArraySize();
- }
- APValue &getArrayFiller() {
- assert(isArray() && "Invalid accessor");
- assert(hasArrayFiller() && "No array filler");
- return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
- }
- const APValue &getArrayFiller() const {
- return const_cast<APValue*>(this)->getArrayFiller();
- }
- unsigned getArrayInitializedElts() const {
- assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data.buffer)->NumElts;
- }
- unsigned getArraySize() const {
- assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data.buffer)->ArrSize;
- }
-
- unsigned getStructNumBases() const {
- assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data.buffer)->NumBases;
- }
- unsigned getStructNumFields() const {
- assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data.buffer)->NumFields;
- }
- APValue &getStructBase(unsigned i) {
- assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data.buffer)->Elts[i];
- }
- APValue &getStructField(unsigned i) {
- assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
- }
- const APValue &getStructBase(unsigned i) const {
- return const_cast<APValue*>(this)->getStructBase(i);
- }
- const APValue &getStructField(unsigned i) const {
- return const_cast<APValue*>(this)->getStructField(i);
- }
-
- const FieldDecl *getUnionField() const {
- assert(isUnion() && "Invalid accessor");
- return ((const UnionData*)(const char*)Data.buffer)->Field;
- }
- APValue &getUnionValue() {
- assert(isUnion() && "Invalid accessor");
- return *((UnionData*)(char*)Data.buffer)->Value;
- }
- const APValue &getUnionValue() const {
- return const_cast<APValue*>(this)->getUnionValue();
- }
-
- const ValueDecl *getMemberPointerDecl() const;
- bool isMemberPointerToDerivedMember() const;
- ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
-
- const AddrLabelExpr* getAddrLabelDiffLHS() const {
- assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
- }
- const AddrLabelExpr* getAddrLabelDiffRHS() const {
- assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
- }
-
- void setInt(APSInt I) {
- assert(isInt() && "Invalid accessor");
- *(APSInt *)(char *)Data.buffer = std::move(I);
- }
- void setFloat(APFloat F) {
- assert(isFloat() && "Invalid accessor");
- *(APFloat *)(char *)Data.buffer = std::move(F);
- }
- void setVector(const APValue *E, unsigned N) {
- assert(isVector() && "Invalid accessor");
- ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
- ((Vec*)(char*)Data.buffer)->NumElts = N;
- for (unsigned i = 0; i != N; ++i)
- ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
- }
- void setComplexInt(APSInt R, APSInt I) {
- assert(R.getBitWidth() == I.getBitWidth() &&
- "Invalid complex int (type mismatch).");
- assert(isComplexInt() && "Invalid accessor");
- ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
- ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
- }
- void setComplexFloat(APFloat R, APFloat I) {
- assert(&R.getSemantics() == &I.getSemantics() &&
- "Invalid complex float (type mismatch).");
- assert(isComplexFloat() && "Invalid accessor");
- ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
- ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
- }
- void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
- unsigned CallIndex);
- void setLValue(LValueBase B, const CharUnits &O,
- ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
- unsigned CallIndex);
- void setUnion(const FieldDecl *Field, const APValue &Value) {
- assert(isUnion() && "Invalid accessor");
- ((UnionData*)(char*)Data.buffer)->Field = Field;
- *((UnionData*)(char*)Data.buffer)->Value = Value;
- }
- void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
- const AddrLabelExpr* RHSExpr) {
- ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
- ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
- }
-
- /// Assign by swapping from a copy of the RHS.
- APValue &operator=(APValue RHS) {
- swap(RHS);
- return *this;
- }
-
-private:
- void DestroyDataAndMakeUninit();
- void MakeUninit() {
- if (Kind != Uninitialized)
- DestroyDataAndMakeUninit();
- }
- void MakeInt() {
- assert(isUninit() && "Bad state change");
- new ((void*)Data.buffer) APSInt(1);
- Kind = Int;
- }
- void MakeFloat() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) APFloat(0.0);
- Kind = Float;
- }
- void MakeVector() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) Vec();
- Kind = Vector;
- }
- void MakeComplexInt() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) ComplexAPSInt();
- Kind = ComplexInt;
- }
- void MakeComplexFloat() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) ComplexAPFloat();
- Kind = ComplexFloat;
- }
- void MakeLValue();
- void MakeArray(unsigned InitElts, unsigned Size);
- void MakeStruct(unsigned B, unsigned M) {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) StructData(B, M);
- Kind = Struct;
- }
- void MakeUnion() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) UnionData();
- Kind = Union;
- }
- void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
- ArrayRef<const CXXRecordDecl*> Path);
- void MakeAddrLabelDiff() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) AddrLabelDiffData();
- Kind = AddrLabelDiff;
- }
-};
-
-} // end namespace clang.
-
-#endif
diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h
deleted file mode 100644
index 6db351d..0000000
--- a/include/clang/AST/AST.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- AST.h - "Umbrella" header for AST library --------------*- 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 interface to the AST classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_AST_H
-#define LLVM_CLANG_AST_AST_H
-
-// This header exports all AST interfaces.
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/Type.h"
-
-#endif
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
deleted file mode 100644
index b2730e4..0000000
--- a/include/clang/AST/ASTConsumer.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ASTConsumer class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
-#define LLVM_CLANG_AST_ASTCONSUMER_H
-
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
- class ASTContext;
- class CXXMethodDecl;
- class CXXRecordDecl;
- class Decl;
- class DeclGroupRef;
- class ASTMutationListener;
- class ASTDeserializationListener; // layering violation because void* is ugly
- class SemaConsumer; // layering violation required for safe SemaConsumer
- class TagDecl;
- class VarDecl;
- class FunctionDecl;
- class ImportDecl;
-
-/// ASTConsumer - This is an abstract interface that should be implemented by
-/// 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
- /// semantic analysis.
- bool SemaConsumer;
-
- friend class SemaConsumer;
-
-public:
- ASTConsumer() : SemaConsumer(false) { }
-
- virtual ~ASTConsumer() {}
-
- /// Initialize - This is called to initialize the consumer, providing the
- /// ASTContext.
- virtual void Initialize(ASTContext &Context) {}
-
- /// HandleTopLevelDecl - Handle the specified top-level declaration. This is
- /// called by the parser to process every top-level Decl*.
- ///
- /// \returns true to continue parsing, or false to abort parsing.
- virtual bool HandleTopLevelDecl(DeclGroupRef D);
-
- /// \brief This callback is invoked each time an inline method definition is
- /// completed.
- virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {}
-
- /// HandleInterestingDecl - Handle the specified interesting declaration. This
- /// is called by the AST reader when deserializing things that might interest
- /// the consumer. The default implementation forwards to HandleTopLevelDecl.
- virtual void HandleInterestingDecl(DeclGroupRef D);
-
- /// HandleTranslationUnit - This method is called when the ASTs for entire
- /// translation unit have been parsed.
- virtual void HandleTranslationUnit(ASTContext &Ctx) {}
-
- /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
- /// (e.g. struct, union, enum, class) is completed. This allows the client to
- /// hack on the type, which can occur at any point in the file (because these
- /// can be defined in declspecs).
- virtual void HandleTagDeclDefinition(TagDecl *D) {}
-
- /// \brief 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.
- /// 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
- /// and ObjC container.
- /// The default implementation ignored them.
- virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
-
- /// \brief Handle an ImportDecl that was implicitly created due to an
- /// inclusion directive.
- /// The default implementation passes it to HandleTopLevelDecl.
- virtual void HandleImplicitImportDecl(ImportDecl *D);
-
- /// \brief Handle a pragma that appends to Linker Options. Currently this
- /// only exists to support Microsoft's #pragma comment(linker, "/foo").
- virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {}
-
- /// \brief Handle a pragma that emits a mismatch identifier and value to the
- /// object file for the linker to work with. Currently, this only exists to
- /// support Microsoft's #pragma detect_mismatch.
- virtual void HandleDetectMismatch(llvm::StringRef Name,
- llvm::StringRef Value) {}
-
- /// \brief Handle a dependent library created by a pragma in the source.
- /// Currently this only exists to support Microsoft's
- /// #pragma comment(lib, "/foo").
- virtual void HandleDependentLibrary(llvm::StringRef Lib) {}
-
- /// CompleteTentativeDefinition - Callback invoked at the end of a translation
- /// unit to notify the consumer that the given tentative definition should be
- /// completed.
- ///
- /// The variable declaration itself will be a tentative
- /// definition. If it had an incomplete array type, its type will
- /// have already been changed to an array of size 1. However, the
- /// declaration remains a tentative definition and has not been
- /// modified by the introduction of an implicit zero initializer.
- virtual void CompleteTentativeDefinition(VarDecl *D) {}
-
- /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
- // variable has been instantiated.
- virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
-
- /// \brief 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
- /// 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
- /// AST files, it should return a pointer to a ASTDeserializationListener here
- virtual ASTDeserializationListener *GetASTDeserializationListener() {
- return nullptr;
- }
-
- /// PrintStats - If desired, print any statistics.
- virtual void PrintStats() {}
-
- /// \brief 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
- /// body may be parsed anyway if it is needed (for instance, if it contains
- /// the code completion point or is constexpr).
- virtual bool shouldSkipFunctionBody(Decl *D) { return true; }
-};
-
-} // end namespace clang.
-
-#endif
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
deleted file mode 100644
index b66009e..0000000
--- a/include/clang/AST/ASTContext.h
+++ /dev/null
@@ -1,2672 +0,0 @@
-//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- 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::ASTContext interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
-#define LLVM_CLANG_AST_ASTCONTEXT_H
-
-#include "clang/AST/ASTTypeTraits.h"
-#include "clang/AST/CanonicalType.h"
-#include "clang/AST/CommentCommandTraits.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/RawCommentList.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/OperatorKinds.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/SanitizerBlacklist.h"
-#include "clang/Basic/VersionTuple.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Support/Allocator.h"
-#include <memory>
-#include <vector>
-
-namespace llvm {
- struct fltSemantics;
-}
-
-namespace clang {
- class FileManager;
- class AtomicExpr;
- class ASTRecordLayout;
- class BlockExpr;
- class CharUnits;
- class DiagnosticsEngine;
- class Expr;
- class ASTMutationListener;
- class IdentifierTable;
- class MaterializeTemporaryExpr;
- class SelectorTable;
- class TargetInfo;
- class CXXABI;
- class MangleNumberingContext;
- // Decls
- class MangleContext;
- class ObjCIvarDecl;
- class ObjCPropertyDecl;
- class UnresolvedSetIterator;
- class UsingDecl;
- class UsingShadowDecl;
- class VTableContextBase;
-
- namespace Builtin { class Context; }
- enum BuiltinTemplateKind : int;
-
- namespace comments {
- class FullComment;
- }
-
- struct TypeInfo {
- uint64_t Width;
- unsigned Align;
- bool AlignIsRequired : 1;
- TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
- TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
- : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
- };
-
-/// \brief 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> {
- ASTContext &this_() { return *this; }
-
- mutable SmallVector<Type *, 0> Types;
- mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
- mutable llvm::FoldingSet<ComplexType> ComplexTypes;
- mutable llvm::FoldingSet<PointerType> PointerTypes;
- mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
- mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
- mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
- mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
- mutable llvm::FoldingSet<MemberPointerType> MemberPointerTypes;
- mutable llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
- mutable llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
- mutable std::vector<VariableArrayType*> VariableArrayTypes;
- mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
- mutable llvm::FoldingSet<DependentSizedExtVectorType>
- DependentSizedExtVectorTypes;
- mutable llvm::FoldingSet<VectorType> VectorTypes;
- mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
- mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
- FunctionProtoTypes;
- mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
- mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
- mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
- mutable llvm::FoldingSet<SubstTemplateTypeParmType>
- SubstTemplateTypeParmTypes;
- mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
- SubstTemplateTypeParmPackTypes;
- mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
- TemplateSpecializationTypes;
- mutable llvm::FoldingSet<ParenType> ParenTypes;
- mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
- mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
- mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
- ASTContext&>
- DependentTemplateSpecializationTypes;
- llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
- mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
- mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
- mutable llvm::FoldingSet<AutoType> AutoTypes;
- mutable llvm::FoldingSet<AtomicType> AtomicTypes;
- llvm::FoldingSet<AttributedType> AttributedTypes;
-
- mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
- mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
- mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
- SubstTemplateTemplateParms;
- mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
- ASTContext&>
- SubstTemplateTemplateParmPacks;
-
- /// \brief The set of nested name specifiers.
- ///
- /// This set is managed by the NestedNameSpecifier class.
- mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
- mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
- friend class NestedNameSpecifier;
-
- /// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
- ///
- /// This is lazily created. This is intentionally not serialized.
- mutable llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>
- ASTRecordLayouts;
- mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
- ObjCLayouts;
-
- /// \brief A cache from types to size and alignment information.
- typedef llvm::DenseMap<const Type *, struct TypeInfo> TypeInfoMap;
- mutable TypeInfoMap MemoizedTypeInfo;
-
- /// \brief A cache mapping from CXXRecordDecls to key functions.
- llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;
-
- /// \brief Mapping from ObjCContainers to their ObjCImplementations.
- llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
-
- /// \brief 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.
- llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
-
- /// \brief 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
- /// 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
- /// is used in canonical template names.
- class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
- TemplateTemplateParmDecl *Parm;
-
- public:
- CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
- : Parm(Parm) { }
-
- TemplateTemplateParmDecl *getParam() const { return Parm; }
-
- void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- TemplateTemplateParmDecl *Parm);
- };
- mutable llvm::FoldingSet<CanonicalTemplateTemplateParm>
- CanonTemplateTemplateParms;
-
- TemplateTemplateParmDecl *
- getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
-
- /// \brief The typedef for the __int128_t type.
- mutable TypedefDecl *Int128Decl;
-
- /// \brief The typedef for the __uint128_t type.
- mutable TypedefDecl *UInt128Decl;
-
- /// \brief The typedef for the __float128 stub type.
- mutable TypeDecl *Float128StubDecl;
-
- /// \brief The typedef for the target specific predefined
- /// __builtin_va_list type.
- mutable TypedefDecl *BuiltinVaListDecl;
-
- /// The typedef for the predefined \c __builtin_ms_va_list type.
- mutable TypedefDecl *BuiltinMSVaListDecl;
-
- /// \brief The typedef for the predefined \c id type.
- mutable TypedefDecl *ObjCIdDecl;
-
- /// \brief The typedef for the predefined \c SEL type.
- mutable TypedefDecl *ObjCSelDecl;
-
- /// \brief The typedef for the predefined \c Class type.
- mutable TypedefDecl *ObjCClassDecl;
-
- /// \brief The typedef for the predefined \c Protocol class in Objective-C.
- mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
-
- /// \brief The typedef for the predefined 'BOOL' type.
- mutable TypedefDecl *BOOLDecl;
-
- // Typedefs which may be provided defining the structure of Objective-C
- // pseudo-builtins
- QualType ObjCIdRedefinitionType;
- QualType ObjCClassRedefinitionType;
- QualType ObjCSelRedefinitionType;
-
- /// The identifier 'NSObject'.
- IdentifierInfo *NSObjectName = nullptr;
-
- /// The identifier 'NSCopying'.
- IdentifierInfo *NSCopyingName = nullptr;
-
- /// The identifier '__make_integer_seq'.
- mutable IdentifierInfo *MakeIntegerSeqName = nullptr;
-
- QualType ObjCConstantStringType;
- mutable RecordDecl *CFConstantStringTypeDecl;
-
- mutable QualType ObjCSuperType;
-
- QualType ObjCNSStringType;
-
- /// \brief The typedef declaration for the Objective-C "instancetype" type.
- TypedefDecl *ObjCInstanceTypeDecl;
-
- /// \brief The type for the C FILE type.
- TypeDecl *FILEDecl;
-
- /// \brief The type for the C jmp_buf type.
- TypeDecl *jmp_bufDecl;
-
- /// \brief The type for the C sigjmp_buf type.
- TypeDecl *sigjmp_bufDecl;
-
- /// \brief The type for the C ucontext_t type.
- TypeDecl *ucontext_tDecl;
-
- /// \brief 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;
-
- /// \brief 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;
-
- /// \brief Declaration for the CUDA cudaConfigureCall function.
- FunctionDecl *cudaConfigureCallDecl;
-
- /// \brief 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
- /// 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
- /// than the owning module of the declaration) that contain merged
- /// definitions of that entity.
- llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules;
-
-public:
- /// \brief A type synonym for the TemplateOrInstantiation mapping.
- typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
- TemplateOrSpecializationInfo;
-
-private:
-
- /// \brief A mapping to contain the template or declaration that
- /// a variable declaration describes or was instantiated from,
- /// respectively.
- ///
- /// For non-templates, this value will be NULL. For variable
- /// declarations that describe a variable template, this will be a
- /// pointer to a VarTemplateDecl. For static data members
- /// of class template specializations, this will be the
- /// MemberSpecializationInfo referring to the member variable that was
- /// instantiated or specialized. Thus, the mapping will keep track of
- /// the static data member templates from which static data members of
- /// class template specializations were instantiated.
- ///
- /// Given the following example:
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// static T value;
- /// };
- ///
- /// template<typename T>
- /// T X<T>::value = T(17);
- ///
- /// int *x = &X<int>::value;
- /// \endcode
- ///
- /// This mapping will contain an entry that maps from the VarDecl for
- /// X<int>::value to the corresponding VarDecl for X<T>::value (within the
- /// class template X) and will be marked TSK_ImplicitInstantiation.
- llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
- TemplateOrInstantiation;
-
- /// \brief Keeps track of the declaration from which a UsingDecl was
- /// created during instantiation.
- ///
- /// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl,
- /// or an UnresolvedUsingTypenameDecl.
- ///
- /// For example:
- /// \code
- /// template<typename T>
- /// struct A {
- /// void f();
- /// };
- ///
- /// template<typename T>
- /// struct B : A<T> {
- /// using A<T>::f;
- /// };
- ///
- /// template struct B<int>;
- /// \endcode
- ///
- /// This mapping will contain an entry that maps from the UsingDecl in
- /// B<int> to the UnresolvedUsingDecl in B<T>.
- llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl;
-
- llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
- InstantiatedFromUsingShadowDecl;
-
- llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
-
- /// \brief Mapping that stores the methods overridden by a given C++
- /// member function.
- ///
- /// Since most C++ member functions aren't virtual and therefore
- /// don't override anything, we store the overridden functions in
- /// this map on the side rather than within the CXXMethodDecl structure.
- typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
- llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
-
- /// \brief 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 *, MangleNumberingContext *>
- MangleNumberingContexts;
-
- /// \brief Side-table of mangling numbers for declarations which rarely
- /// need them (like static local vars).
- llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
- llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers;
-
- /// \brief Mapping that stores parameterIndex values for ParmVarDecls when
- /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
- typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable;
- ParameterIndexTable ParamIndices;
-
- ImportDecl *FirstLocalImport;
- ImportDecl *LastLocalImport;
-
- TranslationUnitDecl *TUDecl;
- mutable ExternCContextDecl *ExternCContext;
- mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
-
- /// \brief The associated SourceManager object.a
- SourceManager &SourceMgr;
-
- /// \brief 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
- /// entities should not be instrumented.
- std::unique_ptr<SanitizerBlacklist> SanitizerBL;
-
- /// \brief 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.
- PartialDiagnostic::StorageAllocator DiagAllocator;
-
- /// \brief The current C++ ABI.
- std::unique_ptr<CXXABI> ABI;
- CXXABI *createCXXABI(const TargetInfo &T);
-
- /// \brief The logical -> physical address space map.
- const LangAS::Map *AddrSpaceMap;
-
- /// \brief Address space map mangling must be used with language specific
- /// address spaces (e.g. OpenCL/CUDA)
- bool AddrSpaceMapMangling;
-
- friend class ASTDeclReader;
- friend class ASTReader;
- friend class ASTWriter;
- friend class CXXRecordDecl;
-
- const TargetInfo *Target;
- const TargetInfo *AuxTarget;
- clang::PrintingPolicy PrintingPolicy;
-
-public:
- IdentifierTable &Idents;
- SelectorTable &Selectors;
- Builtin::Context &BuiltinInfo;
- mutable DeclarationNameTable DeclarationNames;
- IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
- ASTMutationListener *Listener;
-
- /// \brief Contains parents of a node.
- typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector;
-
- /// \brief 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.
- typedef llvm::DenseMap<const void *,
- llvm::PointerUnion4<const Decl *, const Stmt *,
- ast_type_traits::DynTypedNode *,
- ParentVector *>> ParentMapPointers;
-
- /// Parent map for nodes without pointer identity. We store a full
- /// DynTypedNode for all keys.
- typedef llvm::DenseMap<
- ast_type_traits::DynTypedNode,
- llvm::PointerUnion4<const Decl *, const Stmt *,
- ast_type_traits::DynTypedNode *, ParentVector *>>
- ParentMapOtherNodes;
-
- /// Container for either a single DynTypedNode or for an ArrayRef to
- /// DynTypedNode. For use with ParentMap.
- class DynTypedNodeList {
- typedef ast_type_traits::DynTypedNode DynTypedNode;
- llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode,
- ArrayRef<DynTypedNode>> Storage;
- bool IsSingleNode;
-
- public:
- DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
- new (Storage.buffer) DynTypedNode(N);
- }
- DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
- new (Storage.buffer) ArrayRef<DynTypedNode>(A);
- }
-
- const ast_type_traits::DynTypedNode *begin() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
- ->begin();
- return reinterpret_cast<const DynTypedNode *>(Storage.buffer);
- }
-
- const ast_type_traits::DynTypedNode *end() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
- ->end();
- return reinterpret_cast<const DynTypedNode *>(Storage.buffer) + 1;
- }
-
- size_t size() const { return end() - begin(); }
- bool empty() const { return begin() == end(); }
- const DynTypedNode &operator[](size_t N) const {
- assert(N < size() && "Out of bounds!");
- return *(begin() + N);
- }
- };
-
- /// \brief 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)
- /// in the number of AST nodes.
- ///
- /// Caveats and FIXMEs:
- /// Calculating the parent map over all AST nodes will need to load the
- /// full AST. This can be undesirable in the case where the full AST is
- /// expensive to create (for example, when using precompiled header
- /// preambles). Thus, there are good opportunities for optimization here.
- /// One idea is to walk the given node downwards, looking for references
- /// to declaration contexts - once a declaration context is found, compute
- /// the parent map for the declaration context; if that can satisfy the
- /// request, loading the whole AST can be avoided. Note that this is made
- /// more complex by statements in templates having multiple parents - those
- /// problems can be solved by building closure over the templated parts of
- /// the AST, which also avoids touching large parts of the AST.
- /// Additionally, we will want to add an interface to already give a hint
- /// where to search for the parents, for example when looking at a statement
- /// inside a certain function.
- ///
- /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
- /// NestedNameSpecifier or NestedNameSpecifierLoc.
- template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node) {
- return getParents(ast_type_traits::DynTypedNode::create(Node));
- }
-
- DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node);
-
- const clang::PrintingPolicy &getPrintingPolicy() const {
- return PrintingPolicy;
- }
-
- void setPrintingPolicy(const clang::PrintingPolicy &Policy) {
- PrintingPolicy = Policy;
- }
-
- SourceManager& getSourceManager() { return SourceMgr; }
- const SourceManager& getSourceManager() const { return SourceMgr; }
-
- llvm::BumpPtrAllocator &getAllocator() const {
- return BumpAlloc;
- }
-
- void *Allocate(size_t Size, unsigned Align = 8) const {
- return BumpAlloc.Allocate(Size, Align);
- }
- template <typename T> T *Allocate(size_t Num = 1) const {
- return static_cast<T *>(Allocate(Num * sizeof(T), llvm::alignOf<T>()));
- }
- void Deallocate(void *Ptr) const { }
-
- /// Return the total amount of physical memory allocated for representing
- /// AST nodes and type information.
- size_t getASTAllocatedMemory() const {
- return BumpAlloc.getTotalMemory();
- }
- /// Return the total memory used for various side tables.
- size_t getSideTableAllocatedMemory() const;
-
- PartialDiagnostic::StorageAllocator &getDiagAllocator() {
- return DiagAllocator;
- }
-
- const TargetInfo &getTargetInfo() const { return *Target; }
- const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
-
- /// getIntTypeForBitwidth -
- /// sets integer QualTy according to specified details:
- /// bitwidth, signed/unsigned.
- /// Returns empty type if there is no appropriate target types.
- QualType getIntTypeForBitwidth(unsigned DestWidth,
- unsigned Signed) const;
- /// getRealTypeForBitwidth -
- /// sets floating point QualTy according to specified bitwidth.
- /// Returns empty type if there is no appropriate target types.
- QualType getRealTypeForBitwidth(unsigned DestWidth) const;
-
- bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
-
- const LangOptions& getLangOpts() const { return LangOpts; }
-
- const SanitizerBlacklist &getSanitizerBlacklist() const {
- return *SanitizerBL;
- }
-
- DiagnosticsEngine &getDiagnostics() const;
-
- FullSourceLoc getFullLoc(SourceLocation Loc) const {
- return FullSourceLoc(Loc,SourceMgr);
- }
-
- /// \brief All comments in this translation unit.
- RawCommentList Comments;
-
- /// \brief True if comments are already loaded from ExternalASTSource.
- mutable bool CommentsLoaded;
-
- class RawCommentAndCacheFlags {
- public:
- enum Kind {
- /// We searched for a comment attached to the particular declaration, but
- /// didn't find any.
- ///
- /// getRaw() == 0.
- NoCommentInDecl = 0,
-
- /// We have found a comment attached to this particular declaration.
- ///
- /// getRaw() != 0.
- FromDecl,
-
- /// This declaration does not have an attached comment, and we have
- /// searched the redeclaration chain.
- ///
- /// If getRaw() == 0, the whole redeclaration chain does not have any
- /// comments.
- ///
- /// If getRaw() != 0, it is a comment propagated from other
- /// redeclaration.
- FromRedecl
- };
-
- Kind getKind() const LLVM_READONLY {
- return Data.getInt();
- }
-
- void setKind(Kind K) {
- Data.setInt(K);
- }
-
- const RawComment *getRaw() const LLVM_READONLY {
- return Data.getPointer();
- }
-
- void setRaw(const RawComment *RC) {
- Data.setPointer(RC);
- }
-
- const Decl *getOriginalDecl() const LLVM_READONLY {
- return OriginalDecl;
- }
-
- void setOriginalDecl(const Decl *Orig) {
- OriginalDecl = Orig;
- }
-
- private:
- llvm::PointerIntPair<const RawComment *, 2, Kind> Data;
- const Decl *OriginalDecl;
- };
-
- /// \brief 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
- /// redeclaration.
- mutable llvm::DenseMap<const Decl *, comments::FullComment *> ParsedComments;
-
- /// \brief Return the documentation comment attached to a given declaration,
- /// without looking into cache.
- RawComment *getRawCommentForDeclNoCache(const Decl *D) const;
-
-public:
- RawCommentList &getRawCommentList() {
- return Comments;
- }
-
- void addComment(const RawComment &RC) {
- assert(LangOpts.RetainCommentsFromSystemHeaders ||
- !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin()));
- Comments.addComment(RC, BumpAlloc);
- }
-
- /// \brief Return the documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached.
- ///
- /// \param OriginalDecl if not NULL, is set to declaration AST node that had
- /// the comment, if the comment we found comes from a redeclaration.
- const RawComment *
- getRawCommentForAnyRedecl(const Decl *D,
- const Decl **OriginalDecl = nullptr) const;
-
- /// Return parsed documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached.
- ///
- /// \param PP the Preprocessor used with this TU. Could be NULL if
- /// preprocessor is not available.
- comments::FullComment *getCommentForDecl(const Decl *D,
- const Preprocessor *PP) const;
-
- /// Return parsed documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached. Does not look at any
- /// redeclarations of the declaration.
- comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;
-
- comments::FullComment *cloneFullComment(comments::FullComment *FC,
- const Decl *D) const;
-
-private:
- mutable comments::CommandTraits CommentCommandTraits;
-
- /// \brief Iterator that visits import declarations.
- class import_iterator {
- ImportDecl *Import;
-
- public:
- typedef ImportDecl *value_type;
- typedef ImportDecl *reference;
- typedef ImportDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- import_iterator() : Import() {}
- explicit import_iterator(ImportDecl *Import) : Import(Import) {}
-
- reference operator*() const { return Import; }
- pointer operator->() const { return Import; }
-
- import_iterator &operator++() {
- Import = ASTContext::getNextLocalImport(Import);
- return *this;
- }
-
- import_iterator operator++(int) {
- import_iterator Other(*this);
- ++(*this);
- return Other;
- }
-
- friend bool operator==(import_iterator X, import_iterator Y) {
- return X.Import == Y.Import;
- }
-
- friend bool operator!=(import_iterator X, import_iterator Y) {
- return X.Import != Y.Import;
- }
- };
-
-public:
- comments::CommandTraits &getCommentCommandTraits() const {
- return CommentCommandTraits;
- }
-
- /// \brief Retrieve the attributes for the given declaration.
- AttrVec& getDeclAttrs(const Decl *D);
-
- /// \brief 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
- /// class template specialization, returns the templated static data member
- /// from which it was instantiated.
- // FIXME: Remove ?
- MemberSpecializationInfo *getInstantiatedFromStaticDataMember(
- const VarDecl *Var);
-
- TemplateOrSpecializationInfo
- getTemplateOrSpecializationInfo(const VarDecl *Var);
-
- FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD);
-
- void setClassScopeSpecializationPattern(FunctionDecl *FD,
- FunctionDecl *Pattern);
-
- /// \brief 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,
- SourceLocation PointOfInstantiation = SourceLocation());
-
- void setTemplateOrSpecializationInfo(VarDecl *Inst,
- TemplateOrSpecializationInfo TSI);
-
- /// \brief If the given using decl \p Inst is an instantiation of a
- /// (possibly unresolved) using decl from a template instantiation,
- /// return it.
- NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
-
- /// \brief Remember that the using decl \p Inst is an instantiation
- /// of the using decl \p Pattern of a class template.
- void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern);
-
- void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
- UsingShadowDecl *Pattern);
- UsingShadowDecl *getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst);
-
- FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
-
- void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
-
- // Access to the set of methods overridden by the given C++ method.
- typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
- overridden_cxx_method_iterator
- overridden_methods_begin(const CXXMethodDecl *Method) const;
-
- overridden_cxx_method_iterator
- overridden_methods_end(const CXXMethodDecl *Method) const;
-
- unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
-
- /// \brief 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.
- ///
- /// An ObjC method is considered to override any method in the class's
- /// base classes, its protocols, or its categories' protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- void getOverriddenMethods(
- const NamedDecl *Method,
- SmallVectorImpl<const NamedDecl *> &Overridden) const;
-
- /// \brief Notify the AST context that a new import declaration has been
- /// parsed or implicitly created within this translation unit.
- void addedLocalImportDecl(ImportDecl *Import);
-
- static ImportDecl *getNextLocalImport(ImportDecl *Import) {
- return Import->NextLocalImport;
- }
-
- typedef llvm::iterator_range<import_iterator> import_range;
- import_range local_imports() const {
- return import_range(import_iterator(FirstLocalImport), import_iterator());
- }
-
- Decl *getPrimaryMergedDecl(Decl *D) {
- Decl *Result = MergedDecls.lookup(D);
- return Result ? Result : D;
- }
- void setPrimaryMergedDecl(Decl *D, Decl *Primary) {
- MergedDecls[D] = Primary;
- }
-
- /// \brief 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
- /// added duplicates into the list.
- void deduplicateMergedDefinitonsFor(NamedDecl *ND);
-
- /// \brief Get the additional modules in which the definition \p Def has
- /// been merged.
- ArrayRef<Module*> getModulesWithMergedDefinition(NamedDecl *Def) {
- auto MergedIt = MergedDefModules.find(Def);
- if (MergedIt == MergedDefModules.end())
- return None;
- return MergedIt->second;
- }
-
- TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
-
- ExternCContextDecl *getExternCContextDecl() const;
- BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
-
- // Builtin Types.
- CanQualType VoidTy;
- CanQualType BoolTy;
- CanQualType CharTy;
- 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 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;
- CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
- CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- CanQualType VoidPtrTy, NullPtrTy;
- CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
- CanQualType BuiltinFnTy;
- CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
- CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
- CanQualType ObjCBuiltinBoolTy;
- CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy;
- CanQualType OCLImage2dTy, OCLImage2dArrayTy, OCLImage2dDepthTy;
- CanQualType OCLImage2dArrayDepthTy, OCLImage2dMSAATy, OCLImage2dArrayMSAATy;
- CanQualType OCLImage2dMSAADepthTy, OCLImage2dArrayMSAADepthTy;
- CanQualType OCLImage3dTy;
- CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
- CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
- CanQualType OMPArraySectionTy;
-
- // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
- mutable QualType AutoDeductTy; // Deduction against 'auto'.
- mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'.
-
- // Decl used to help define __builtin_va_list for some targets.
- // The decl is built when constructing 'BuiltinVaListDecl'.
- mutable Decl *VaListTagDecl;
-
- ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
- SelectorTable &sels, Builtin::Context &builtins);
-
- ~ASTContext();
-
- /// \brief 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
- /// with this AST context, if any.
- ExternalASTSource *getExternalSource() const {
- return ExternalSource.get();
- }
-
- /// \brief 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
- /// created.
- void setASTMutationListener(ASTMutationListener *Listener) {
- this->Listener = Listener;
- }
-
- /// \brief Retrieve a pointer to the AST mutation listener associated
- /// with this AST context, if any.
- ASTMutationListener *getASTMutationListener() const { return Listener; }
-
- void PrintStats() const;
- const SmallVectorImpl<Type *>& getTypes() const { return Types; }
-
- BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
- const IdentifierInfo *II) const;
-
- /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl
- /// declaration.
- RecordDecl *buildImplicitRecord(StringRef Name,
- RecordDecl::TagKind TK = TTK_Struct) const;
-
- /// \brief Create a new implicit TU-level typedef declaration.
- TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;
-
- /// \brief Retrieve the declaration for the 128-bit signed integer type.
- TypedefDecl *getInt128Decl() const;
-
- /// \brief Retrieve the declaration for the 128-bit unsigned integer type.
- TypedefDecl *getUInt128Decl() const;
-
- /// \brief Retrieve the declaration for a 128-bit float stub type.
- TypeDecl *getFloat128StubType() const;
-
- //===--------------------------------------------------------------------===//
- // Type Constructors
- //===--------------------------------------------------------------------===//
-
-private:
- /// \brief Return a type with extended qualifiers.
- QualType getExtQualType(const Type *Base, Qualifiers Quals) const;
-
- QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
-
-public:
- /// \brief 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
- /// space. If T already has an address space specifier, it is silently
- /// replaced.
- QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
-
- /// \brief 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
- /// attribute.
- QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const;
-
- /// \brief 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
- /// \c restrict.
- QualType getRestrictType(QualType T) const {
- return T.withFastQualifiers(Qualifiers::Restrict);
- }
-
- /// \brief 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
- /// \c volatile.
- QualType getVolatileType(QualType T) const {
- return T.withFastQualifiers(Qualifiers::Volatile);
- }
-
- /// \brief 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.
- ///
- /// It can be reasonably expected that this will always be equivalent to
- /// calling T.withConst().
- QualType getConstType(QualType T) const { return T.withConst(); }
-
- /// \brief 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.
- void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
-
- /// \brief 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
- /// 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
- /// 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
- /// type to a new type.
- QualType getAdjustedType(QualType Orig, QualType New) const;
- CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const {
- return CanQualType::CreateUnsafe(
- getAdjustedType((QualType)Orig, (QualType)New));
- }
-
- /// \brief Return the uniqued reference to the decayed version of the given
- /// type. Can only be called on array and function types which decay to
- /// pointer types.
- QualType getDecayedType(QualType T) const;
- CanQualType getDecayedType(CanQualType T) const {
- return CanQualType::CreateUnsafe(getDecayedType((QualType) T));
- }
-
- /// \brief 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
- /// specified type.
- QualType getBlockPointerType(QualType T) const;
-
- /// Gets the struct used to keep track of the descriptor for pointer to
- /// blocks.
- QualType getBlockDescriptorType() const;
-
- /// Gets the struct used to keep track of the extended descriptor for
- /// pointer to blocks.
- QualType getBlockDescriptorExtendedType() const;
-
- void setcudaConfigureCallDecl(FunctionDecl *FD) {
- cudaConfigureCallDecl = FD;
- }
- FunctionDecl *getcudaConfigureCallDecl() {
- return cudaConfigureCallDecl;
- }
-
- /// 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.
- bool getByrefLifetime(QualType Ty,
- Qualifiers::ObjCLifetime &Lifetime,
- bool &HasByrefExtendedLayout) const;
-
- /// \brief 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
- /// to the specified type.
- QualType getRValueReferenceType(QualType T) const;
-
- /// \brief 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
- /// 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
- /// array of the specified element type.
- ///
- /// FIXME: We will need these to be uniqued, or at least comparable, at some
- /// point.
- QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
- unsigned IndexTypeQuals,
- SourceRange Brackets) const;
-
- /// \brief 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
- /// 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 [*].
- QualType getVariableArrayDecayedType(QualType Ty) const;
-
- /// \brief 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;
-
- /// \brief 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.
- QualType getExtVectorType(QualType VectorType, unsigned NumElts) const;
-
- /// \pre Return a non-unique reference to the type for a dependently-sized
- /// vector of the specified element type.
- ///
- /// FIXME: We will need these to be uniqued, or at least comparable, at some
- /// point.
- QualType getDependentSizedExtVectorType(QualType VectorType,
- Expr *SizeExpr,
- SourceLocation AttrLoc) const;
-
- /// \brief Return a K&R style C function type like 'int()'.
- QualType getFunctionNoProtoType(QualType ResultTy,
- const FunctionType::ExtInfo &Info) const;
-
- QualType getFunctionNoProtoType(QualType ResultTy) const {
- return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
- }
-
- /// \brief Return a normal function type with a typed argument list.
- QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
- const FunctionProtoType::ExtProtoInfo &EPI) const;
-
- /// \brief Return the unique reference to the type for the specified type
- /// declaration.
- QualType getTypeDeclType(const TypeDecl *Decl,
- const TypeDecl *PrevDecl = nullptr) const {
- assert(Decl && "Passed null for Decl param");
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
-
- if (PrevDecl) {
- assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
- Decl->TypeForDecl = PrevDecl->TypeForDecl;
- return QualType(PrevDecl->TypeForDecl, 0);
- }
-
- return getTypeDeclTypeSlow(Decl);
- }
-
- /// \brief Return the unique reference to the type for the specified
- /// typedef-name decl.
- QualType getTypedefType(const TypedefNameDecl *Decl,
- QualType Canon = QualType()) const;
-
- QualType getRecordType(const RecordDecl *Decl) const;
-
- QualType getEnumType(const EnumDecl *Decl) const;
-
- QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
-
- QualType getAttributedType(AttributedType::Kind attrKind,
- QualType modifiedType,
- QualType equivalentType);
-
- QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
- QualType Replacement) const;
- QualType getSubstTemplateTypeParmPackType(
- const TemplateTypeParmType *Replaced,
- const TemplateArgument &ArgPack);
-
- QualType
- getTemplateTypeParmType(unsigned Depth, unsigned Index,
- bool ParameterPack,
- TemplateTypeParmDecl *ParmDecl = nullptr) const;
-
- QualType getTemplateSpecializationType(TemplateName T,
- const TemplateArgument *Args,
- unsigned NumArgs,
- QualType Canon = QualType()) const;
-
- QualType getCanonicalTemplateSpecializationType(TemplateName T,
- const TemplateArgument *Args,
- unsigned NumArgs) const;
-
- QualType getTemplateSpecializationType(TemplateName T,
- const TemplateArgumentListInfo &Args,
- QualType Canon = QualType()) const;
-
- TypeSourceInfo *
- getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
- const TemplateArgumentListInfo &Args,
- QualType Canon = QualType()) const;
-
- QualType getParenType(QualType NamedType) const;
-
- QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- QualType NamedType) const;
- QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- QualType Canon = QualType()) const;
-
- QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- const TemplateArgumentListInfo &Args) const;
- QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- unsigned NumArgs,
- const TemplateArgument *Args) const;
-
- QualType getPackExpansionType(QualType Pattern,
- Optional<unsigned> NumExpansions);
-
- QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
- ObjCInterfaceDecl *PrevDecl = nullptr) const;
-
- /// Legacy interface: cannot provide type arguments or __kindof.
- QualType getObjCObjectType(QualType Base,
- ObjCProtocolDecl * const *Protocols,
- unsigned NumProtocols) const;
-
- QualType getObjCObjectType(QualType Base,
- ArrayRef<QualType> typeArgs,
- ArrayRef<ObjCProtocolDecl *> protocols,
- bool isKindOf) const;
-
- bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
- /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
- /// QT's qualified-id protocol list adopt all protocols in IDecl's list
- /// of protocols.
- bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
- ObjCInterfaceDecl *IDecl);
-
- /// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType.
- QualType getObjCObjectPointerType(QualType OIT) const;
-
- /// \brief GCC extension.
- QualType getTypeOfExprType(Expr *e) const;
- QualType getTypeOfType(QualType t) const;
-
- /// \brief C++11 decltype.
- QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
-
- /// \brief Unary type transforms
- QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
- UnaryTransformType::UTTKind UKind) const;
-
- /// \brief C++11 deduced auto type.
- QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
- bool IsDependent) const;
-
- /// \brief C++11 deduction pattern for 'auto' type.
- QualType getAutoDeductType() const;
-
- /// \brief C++11 deduction pattern for 'auto &&' type.
- QualType getAutoRRefDeductType() const;
-
- /// \brief 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
- /// <stddef.h>.
- ///
- /// The sizeof operator requires this (C99 6.5.3.4p4).
- CanQualType getSizeType() const;
-
- /// \brief 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
- /// <stdint.h>.
- CanQualType getUIntMaxType() const;
-
- /// \brief 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
- /// 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".
- ///
- /// Used when in C++, as a GCC extension.
- QualType getSignedWCharType() const;
-
- /// \brief 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
- /// 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),
- /// as defined by the target.
- QualType getIntPtrType() const;
-
- /// \brief 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
- /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
- QualType getPointerDiffType() const;
-
- /// \brief 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.
- QualType getCFConstantStringType() const;
-
- /// \brief Returns the C struct type for objc_super
- QualType getObjCSuperType() const;
- void setObjCSuperType(QualType ST) { ObjCSuperType = ST; }
-
- /// Get the structure type used to representation CFStrings, or NULL
- /// if it hasn't yet been built.
- QualType getRawCFConstantStringType() const {
- if (CFConstantStringTypeDecl)
- return getTagDeclType(CFConstantStringTypeDecl);
- return QualType();
- }
- void setCFConstantStringType(QualType T);
-
- // This setter/getter represents the ObjC type for an NSConstantString.
- void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
- QualType getObjCConstantStringInterface() const {
- return ObjCConstantStringType;
- }
-
- QualType getObjCNSStringType() const {
- return ObjCNSStringType;
- }
-
- void setObjCNSStringType(QualType T) {
- ObjCNSStringType = T;
- }
-
- /// \brief 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())
- return getObjCIdType();
- return ObjCIdRedefinitionType;
- }
-
- /// \brief 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
- /// different from the built-in \c Class if \c Class has been typedef'd.
- QualType getObjCClassRedefinitionType() const {
- if (ObjCClassRedefinitionType.isNull())
- return getObjCClassType();
- return ObjCClassRedefinitionType;
- }
-
- /// \brief 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
- /// different from the built-in 'SEL' if 'SEL' has been typedef'd.
- QualType getObjCSelRedefinitionType() const {
- if (ObjCSelRedefinitionType.isNull())
- return getObjCSelType();
- return ObjCSelRedefinitionType;
- }
-
-
- /// \brief Set the user-written type that redefines 'SEL'.
- void setObjCSelRedefinitionType(QualType RedefType) {
- ObjCSelRedefinitionType = RedefType;
- }
-
- /// Retrieve the identifier 'NSObject'.
- IdentifierInfo *getNSObjectName() {
- if (!NSObjectName) {
- NSObjectName = &Idents.get("NSObject");
- }
-
- return NSObjectName;
- }
-
- /// Retrieve the identifier 'NSCopying'.
- IdentifierInfo *getNSCopyingName() {
- if (!NSCopyingName) {
- NSCopyingName = &Idents.get("NSCopying");
- }
-
- return NSCopyingName;
- }
-
- IdentifierInfo *getMakeIntegerSeqName() const {
- if (!MakeIntegerSeqName)
- MakeIntegerSeqName = &Idents.get("__make_integer_seq");
- return MakeIntegerSeqName;
- }
-
- /// \brief 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
- /// "instancetype" type.
- TypedefDecl *getObjCInstanceTypeDecl();
-
- /// \brief Set the type for the C FILE type.
- void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
-
- /// \brief 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.
- void setjmp_bufDecl(TypeDecl *jmp_bufDecl) {
- this->jmp_bufDecl = jmp_bufDecl;
- }
-
- /// \brief 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.
- void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl) {
- this->sigjmp_bufDecl = sigjmp_bufDecl;
- }
-
- /// \brief 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.
- void setucontext_tDecl(TypeDecl *ucontext_tDecl) {
- this->ucontext_tDecl = ucontext_tDecl;
- }
-
- /// \brief 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.
- QualType getLogicalOperationType() const {
- return getLangOpts().CPlusPlus ? BoolTy : IntTy;
- }
-
- /// \brief 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.
- void getObjCEncodingForType(QualType T, std::string &S,
- const FieldDecl *Field=nullptr,
- QualType *NotEncodedT=nullptr) const;
-
- /// \brief Emit the Objective-C property type encoding for the given
- /// type \p T into \p S.
- void getObjCEncodingForPropertyType(QualType T, std::string &S) const;
-
- void getLegacyIntegralTypeEncoding(QualType &t) const;
-
- /// \brief 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.
- ///
- /// This is in the same format as Objective-C method encodings.
- ///
- /// \returns true if an error occurred (e.g., because one of the parameter
- /// types is incomplete), false otherwise.
- bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S);
-
- /// \brief Emit the encoded type for the method declaration \p Decl into
- /// \p S.
- ///
- /// \returns true if an error occurred (e.g., because one of the parameter
- /// types is incomplete), false otherwise.
- bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S,
- bool Extended = false)
- const;
-
- /// \brief Return the encoded type for this block declaration.
- std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
-
- /// getObjCEncodingForPropertyDecl - Return the encoded type for
- /// this method declaration. If non-NULL, Container must be either
- /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
- /// only be NULL when getting encodings for protocol properties.
- void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
- const Decl *Container,
- std::string &S) const;
-
- bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
- ObjCProtocolDecl *rProto) const;
-
- ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
- const ObjCPropertyDecl *PD,
- const Decl *Container) const;
-
- /// \brief Return the size of type \p T for Objective-C encoding purpose,
- /// in characters.
- CharUnits getObjCEncodingTypeSize(QualType T) const;
-
- /// \brief Retrieve the typedef corresponding to the predefined \c id type
- /// in Objective-C.
- TypedefDecl *getObjCIdDecl() const;
-
- /// \brief 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.
- QualType getObjCIdType() const {
- return getTypeDeclType(getObjCIdDecl());
- }
-
- /// \brief 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
- /// 'SEL' type.
- QualType getObjCSelType() const {
- return getTypeDeclType(getObjCSelDecl());
- }
-
- /// \brief Retrieve the typedef declaration corresponding to the predefined
- /// Objective-C 'Class' type.
- TypedefDecl *getObjCClassDecl() const;
-
- /// \brief 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.
- QualType getObjCClassType() const {
- return getTypeDeclType(getObjCClassDecl());
- }
-
- /// \brief Retrieve the Objective-C class declaration corresponding to
- /// the predefined \c Protocol class.
- ObjCInterfaceDecl *getObjCProtocolDecl() const;
-
- /// \brief Retrieve declaration of 'BOOL' typedef
- TypedefDecl *getBOOLDecl() const {
- return BOOLDecl;
- }
-
- /// \brief Save declaration of 'BOOL' typedef
- void setBOOLDecl(TypedefDecl *TD) {
- BOOLDecl = TD;
- }
-
- /// \brief type of 'BOOL' type.
- QualType getBOOLType() const {
- return getTypeDeclType(getBOOLDecl());
- }
-
- /// \brief 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
- /// \c __builtin_va_list type.
- TypedefDecl *getBuiltinVaListDecl() const;
-
- /// \brief 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
- /// \c __va_list_tag type used to help define the \c __builtin_va_list type
- /// for some targets.
- Decl *getVaListTagDecl() const;
-
- /// Retrieve the C type declaration corresponding to the predefined
- /// \c __builtin_ms_va_list type.
- TypedefDecl *getBuiltinMSVaListDecl() const;
-
- /// Retrieve the type of the \c __builtin_ms_va_list type.
- QualType getBuiltinMSVaListType() const {
- return getTypeDeclType(getBuiltinMSVaListDecl());
- }
-
- /// \brief 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.
- QualType getQualifiedType(SplitQualType split) const {
- return getQualifiedType(split.Ty, split.Quals);
- }
-
- /// \brief Return a type with additional qualifiers.
- QualType getQualifiedType(QualType T, Qualifiers Qs) const {
- if (!Qs.hasNonFastQualifiers())
- return T.withFastQualifiers(Qs.getFastQualifiers());
- QualifierCollector Qc(Qs);
- const Type *Ptr = Qc.strip(T);
- return getExtQualType(Ptr, Qc);
- }
-
- /// \brief 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.
- ///
- /// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None.
- QualType getLifetimeQualifiedType(QualType type,
- Qualifiers::ObjCLifetime lifetime) {
- assert(type.getObjCLifetime() == Qualifiers::OCL_None);
- assert(lifetime != Qualifiers::OCL_None);
-
- Qualifiers qs;
- qs.addObjCLifetime(lifetime);
- return getQualifiedType(type, qs);
- }
-
- /// getUnqualifiedObjCPointerType - Returns version of
- /// Objective-C pointer type with lifetime qualifier removed.
- QualType getUnqualifiedObjCPointerType(QualType type) const {
- if (!type.getTypePtr()->isObjCObjectPointerType() ||
- !type.getQualifiers().hasObjCLifetime())
- return type;
- Qualifiers Qs = type.getQualifiers();
- Qs.removeObjCLifetime();
- return getQualifiedType(type.getUnqualifiedType(), Qs);
- }
-
- DeclarationNameInfo getNameForTemplate(TemplateName Name,
- SourceLocation NameLoc) const;
-
- TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) const;
-
- TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
- bool TemplateKeyword,
- TemplateDecl *Template) const;
-
- TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
- const IdentifierInfo *Name) const;
- TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
- OverloadedOperatorKind Operator) const;
- TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
- TemplateName replacement) const;
- TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
- const TemplateArgument &ArgPack) const;
-
- enum GetBuiltinTypeError {
- GE_None, ///< No error
- GE_Missing_stdio, ///< Missing a type from <stdio.h>
- GE_Missing_setjmp, ///< Missing a type from <setjmp.h>
- GE_Missing_ucontext ///< Missing a type from <ucontext.h>
- };
-
- /// \brief 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
- /// expressions.
- QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
- unsigned *IntegerConstantArgs = nullptr) const;
-
-private:
- CanQualType getFromTargetType(unsigned Type) const;
- TypeInfo getTypeInfoImpl(const Type *T) const;
-
- //===--------------------------------------------------------------------===//
- // Type Predicates.
- //===--------------------------------------------------------------------===//
-
-public:
- /// \brief 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
- /// 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
- /// attribute set.
- static bool isObjCNSObjectType(QualType Ty) {
- return Ty->isObjCNSObjectType();
- }
-
- //===--------------------------------------------------------------------===//
- // Type Sizing and Analysis
- //===--------------------------------------------------------------------===//
-
- /// \brief 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.
- 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.
- unsigned getOpenMPDefaultSimdAlign(QualType T) const;
-
- /// \brief 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.
- uint64_t getCharWidth() const {
- return getTypeSize(CharTy);
- }
-
- /// \brief 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.
- int64_t toBits(CharUnits CharSize) const;
-
- /// \brief 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
- /// 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 (complete) type \p T, in
- /// characters.
- CharUnits getTypeAlignInChars(QualType T) const;
- CharUnits getTypeAlignInChars(const Type *T) const;
-
- // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
- // type is a record, its data size is returned.
- std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
-
- 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
- /// 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
- /// 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
- /// this target, to be used if no alignment value is specified.
- unsigned getTargetDefaultAlignForAttributeAligned(void) const;
-
- /// \brief 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
- /// global variable with type \p T.
- CharUnits getAlignOfGlobalVarInChars(QualType T) const;
-
- /// \brief 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
- /// alignment.
- ///
- /// If \p ForAlignof, references are treated like their underlying type
- /// and large arrays don't get any special treatment. If not \p ForAlignof
- /// it computes the value expected by CodeGen: references are treated like
- /// 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
- /// 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
- /// Objective-C interface.
- const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D)
- const;
-
- void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS,
- bool Simple = false) const;
-
- /// \brief 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
- /// given record decl, or NULL if there isn't one.
- ///
- /// The key function is, according to the Itanium C++ ABI section 5.2.3:
- /// ...the first non-pure virtual function that is not inline at the
- /// point of class definition.
- ///
- /// Other ABIs use the same idea. However, the ARM C++ ABI ignores
- /// virtual functions that are defined 'inline', which means that
- /// the result of this computation can change.
- const CXXMethodDecl *getCurrentKeyFunction(const CXXRecordDecl *RD);
-
- /// \brief 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.
- ///
- /// This is used in ABIs where out-of-line definitions marked
- /// inline are not considered to be key functions.
- ///
- /// \param method should be the declaration from the class definition
- void setNonKeyFunction(const CXXMethodDecl *method);
-
- /// Loading virtual member pointers using the virtual inheritance model
- /// always results in an adjustment using the vbtable even if the index is
- /// zero.
- ///
- /// This is usually OK because the first slot in the vbtable points
- /// backwards to the top of the MDC. However, the MDC might be reusing a
- /// vbptr from an nv-base. In this case, the first slot in the vbtable
- /// points to the start of the nv-base which introduced the vbptr and *not*
- /// the MDC. Modify the NonVirtualBaseAdjustment to account for this.
- CharUnits getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const;
-
- /// Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
- uint64_t getFieldOffset(const ValueDecl *FD) const;
-
- bool isNearlyEmpty(const CXXRecordDecl *RD) const;
-
- VTableContextBase *getVTableContext();
-
- MangleContext *createMangleContext();
-
- void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
- SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;
-
- unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const;
- void CollectInheritedProtocols(const Decl *CDecl,
- llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
-
- //===--------------------------------------------------------------------===//
- // Type Operators
- //===--------------------------------------------------------------------===//
-
- /// \brief 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
- /// types. Decorators can include typedefs, 'typeof' operators, etc. The
- /// returned type is guaranteed to be free of any of these, allowing two
- /// canonical types to be compared for exact equality with a simple pointer
- /// comparison.
- CanQualType getCanonicalType(QualType T) const {
- return CanQualType::CreateUnsafe(T.getCanonicalType());
- }
-
- const Type *getCanonicalType(const Type *T) const {
- return T->getCanonicalTypeInternal().getTypePtr();
- }
-
- /// \brief 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.
- bool hasSameType(QualType T1, QualType T2) const {
- return getCanonicalType(T1) == getCanonicalType(T2);
- }
-
- bool hasSameType(const Type *T1, const Type *T2) const {
- return getCanonicalType(T1) == getCanonicalType(T2);
- }
-
- /// \brief Return this type as a completely-unqualified array type,
- /// capturing the qualifiers in \p Quals.
- ///
- /// This will remove the minimal amount of sugaring from the types, similar
- /// to the behavior of QualType::getUnqualifiedType().
- ///
- /// \param T is the qualified type, which may be an ArrayType
- ///
- /// \param Quals will receive the full set of qualifiers that were
- /// applied to the array.
- ///
- /// \returns if this is an array type, the completely unqualified array type
- /// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
- QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals);
-
- /// \brief Determine whether the given types are equivalent after
- /// cvr-qualifiers have been removed.
- bool hasSameUnqualifiedType(QualType T1, QualType T2) const {
- return getCanonicalType(T1).getTypePtr() ==
- getCanonicalType(T2).getTypePtr();
- }
-
- bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT,
- bool IsParam) const {
- auto SubTnullability = SubT->getNullability(*this);
- auto SuperTnullability = SuperT->getNullability(*this);
- if (SubTnullability.hasValue() == SuperTnullability.hasValue()) {
- // Neither has nullability; return true
- if (!SubTnullability)
- return true;
- // Both have nullability qualifier.
- if (*SubTnullability == *SuperTnullability ||
- *SubTnullability == NullabilityKind::Unspecified ||
- *SuperTnullability == NullabilityKind::Unspecified)
- return true;
-
- if (IsParam) {
- // Ok for the superclass method parameter to be "nonnull" and the subclass
- // method parameter to be "nullable"
- return (*SuperTnullability == NullabilityKind::NonNull &&
- *SubTnullability == NullabilityKind::Nullable);
- }
- else {
- // For the return type, it's okay for the superclass method to specify
- // "nullable" and the subclass method specify "nonnull"
- return (*SuperTnullability == NullabilityKind::Nullable &&
- *SubTnullability == NullabilityKind::NonNull);
- }
- }
- return true;
- }
-
- bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
- const ObjCMethodDecl *MethodImp);
-
- bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
-
- /// \brief Retrieves the "canonical" nested name specifier for a
- /// given nested name specifier.
- ///
- /// The canonical nested name specifier is a nested name specifier
- /// that uniquely identifies a type or namespace within the type
- /// system. For example, given:
- ///
- /// \code
- /// namespace N {
- /// struct S {
- /// template<typename T> struct X { typename T* type; };
- /// };
- /// }
- ///
- /// template<typename T> struct Y {
- /// typename N::S::X<T>::type member;
- /// };
- /// \endcode
- ///
- /// Here, the nested-name-specifier for N::S::X<T>:: will be
- /// S::X<template-param-0-0>, since 'S' and 'X' are uniquely defined
- /// by declarations in the type system and the canonical type for
- /// the template type parameter 'T' is template-param-0-0.
- NestedNameSpecifier *
- getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
-
- /// \brief 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
- /// given template.
- ///
- /// The canonical template name is the simplest expression that can
- /// be used to refer to a given template. For most templates, this
- /// expression is just the template declaration itself. For example,
- /// the template std::vector can be referred to via a variety of
- /// names---std::vector, \::std::vector, vector (if vector is in
- /// scope), etc.---but all of these names map down to the same
- /// TemplateDecl, which is used to form the canonical template name.
- ///
- /// Dependent template names are more interesting. Here, the
- /// template name could be something like T::template apply or
- /// std::allocator<T>::template rebind, where the nested name
- /// specifier itself is dependent. In this case, the canonical
- /// template name uses the shortest form of the dependent
- /// nested-name-specifier, which itself contains all canonical
- /// types, values, and templates.
- TemplateName getCanonicalTemplateName(TemplateName Name) const;
-
- /// \brief Determine whether the given template names refer to the same
- /// template.
- bool hasSameTemplateName(TemplateName X, TemplateName Y);
-
- /// \brief Retrieve the "canonical" template argument.
- ///
- /// The canonical template argument is the simplest template argument
- /// (which may be a type, value, expression, or declaration) that
- /// expresses the value of the argument.
- TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg)
- const;
-
- /// Type Query functions. If the type is an instance of the specified class,
- /// return the Type pointer for the underlying maximally pretty type. This
- /// is a member of ASTContext because this may need to do some amount of
- /// canonicalization, e.g. to move type qualifiers into the element type.
- const ArrayType *getAsArrayType(QualType T) const;
- const ConstantArrayType *getAsConstantArrayType(QualType T) const {
- return dyn_cast_or_null<ConstantArrayType>(getAsArrayType(T));
- }
- const VariableArrayType *getAsVariableArrayType(QualType T) const {
- return dyn_cast_or_null<VariableArrayType>(getAsArrayType(T));
- }
- const IncompleteArrayType *getAsIncompleteArrayType(QualType T) const {
- return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T));
- }
- const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T)
- const {
- return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
- }
-
- /// \brief 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
- /// actually be an array type).
- QualType getBaseElementType(QualType QT) const;
-
- /// \brief Return number of constant array elements.
- uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
-
- /// \brief 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
- /// 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
- /// array type to a pointer.
- ///
- /// This operation is non-trivial when handling typedefs etc. The canonical
- /// type of \p T must be an array type, this returns a pointer to a properly
- /// qualified element of the array.
- ///
- /// 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
- /// 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
- /// retainable type and returns its ownership.
- Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const;
-
- /// \brief 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.
- ///
- /// 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,
- /// 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
- /// \p typeDomain/\p typeSize).
- ///
- /// \param typeDomain a real floating point or complex type.
- /// \param typeSize a real floating point or complex type.
- QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
- QualType typeDomain) const;
-
- unsigned getTargetAddressSpace(QualType T) const {
- return getTargetAddressSpace(T.getQualifiers());
- }
-
- unsigned getTargetAddressSpace(Qualifiers Q) const {
- return getTargetAddressSpace(Q.getAddressSpace());
- }
-
- unsigned getTargetAddressSpace(unsigned AS) const {
- if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
- return AS;
- else
- return (*AddrSpaceMap)[AS - LangAS::Offset];
- }
-
- bool addressSpaceMapManglingFor(unsigned AS) const {
- return AddrSpaceMapMangling ||
- AS < LangAS::Offset ||
- AS >= LangAS::Offset + LangAS::Count;
- }
-
-private:
- // Helper for integer ordering
- unsigned getIntegerRank(const Type *T) const;
-
-public:
-
- //===--------------------------------------------------------------------===//
- // Type Compatibility Predicates
- //===--------------------------------------------------------------------===//
-
- /// Compatibility predicates used to check assignment expressions.
- bool typesAreCompatible(QualType T1, QualType T2,
- bool CompareUnqualified = false); // C99 6.2.7p1
-
- bool propertyTypesAreCompatible(QualType, QualType);
- bool typesAreBlockPointerCompatible(QualType, QualType);
-
- bool isObjCIdType(QualType T) const {
- return T == getObjCIdType();
- }
- bool isObjCClassType(QualType T) const {
- return T == getObjCClassType();
- }
- bool isObjCSelType(QualType T) const {
- return T == getObjCSelType();
- }
- bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
- bool ForCompare);
-
- bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
-
- // Check the safety of assignment from LHS to RHS
- bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT);
- bool canAssignObjCInterfaces(const ObjCObjectType *LHS,
- const ObjCObjectType *RHS);
- bool canAssignObjCInterfacesInBlockPointer(
- const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT,
- bool BlockReturnType);
- bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
- QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT);
- bool canBindObjCObjectType(QualType To, QualType From);
-
- // Functions for calculating composite types
- QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false, bool BlockReturnType = false);
- QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false);
- QualType mergeFunctionParameterTypes(QualType, QualType,
- bool OfBlockPointer = false,
- bool Unqualified = false);
- QualType mergeTransparentUnionType(QualType, QualType,
- bool OfBlockPointer=false,
- bool Unqualified = false);
-
- QualType mergeObjCGCQualifiers(QualType, QualType);
-
- bool FunctionTypesMatchOnNSConsumedAttrs(
- const FunctionProtoType *FromFunctionType,
- const FunctionProtoType *ToFunctionType);
-
- void ResetObjCLayout(const ObjCContainerDecl *CD);
-
- //===--------------------------------------------------------------------===//
- // Integer Predicates
- //===--------------------------------------------------------------------===//
-
- // The width of an integer, as defined in C99 6.2.6.2. This is the number
- // of bits in an integer type excluding any padding bits.
- unsigned getIntWidth(QualType T) const;
-
- // 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.
- QualType getCorrespondingUnsignedType(QualType T) const;
-
- //===--------------------------------------------------------------------===//
- // Integer Values
- //===--------------------------------------------------------------------===//
-
- /// \brief 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 {
- llvm::APSInt Res(getIntWidth(Type),
- !Type->isSignedIntegerOrEnumerationType());
- Res = Value;
- return Res;
- }
-
- bool isSentinelNullExpr(const Expr *E);
-
- /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if
- /// none exists.
- ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
- /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if
- /// none exists.
- ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
-
- /// \brief Return true if there is at least one \@implementation in the TU.
- bool AnyObjCImplementation() {
- return !ObjCImpls.empty();
- }
-
- /// \brief Set the implementation of ObjCInterfaceDecl.
- void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
- ObjCImplementationDecl *ImplD);
- /// \brief Set the implementation of ObjCCategoryDecl.
- void setObjCImplementation(ObjCCategoryDecl *CatD,
- ObjCCategoryImplDecl *ImplD);
-
- /// \brief Get the duplicate declaration of a ObjCMethod in the same
- /// interface, or null if none exists.
- const ObjCMethodDecl *
- getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const;
-
- void setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
- const ObjCMethodDecl *Redecl);
-
- /// \brief 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.
- void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
- /// \brief Get the copy initialization expression of the VarDecl \p VD, or
- /// NULL if none exists.
- Expr *getBlockVarCopyInits(const VarDecl* VD);
-
- /// \brief Allocate an uninitialized TypeSourceInfo.
- ///
- /// The caller should initialize the memory held by TypeSourceInfo using
- /// the TypeLoc wrappers.
- ///
- /// \param T the type that will be the basis for type source info. This type
- /// should refer to how the declarator was written in source code, not to
- /// what type semantic analysis resolved the declarator to.
- ///
- /// \param Size the size of the type info to create, or 0 if the size
- /// should be calculated based on the type.
- TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0) const;
-
- /// \brief 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
- /// ASTContext is destroyed.
- ///
- /// \param Callback A callback function that will be invoked on destruction.
- ///
- /// \param Data Pointer data that will be provided to the callback function
- /// when it is called.
- void AddDeallocation(void (*Callback)(void*), void *Data);
-
- GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
- GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
-
- /// \brief 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.
- ///
- /// \returns true if the function/var must be CodeGen'ed/deserialized even if
- /// it is not used.
- bool DeclMustBeEmitted(const Decl *D);
-
- const CXXConstructorDecl *
- getCopyConstructorForExceptionObject(CXXRecordDecl *RD);
-
- void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
- CXXConstructorDecl *CD);
-
- void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
- unsigned ParmIdx, Expr *DAE);
-
- Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
- unsigned ParmIdx);
-
- void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND);
-
- TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD);
-
- void addDeclaratorForUnnamedTagDecl(TagDecl *TD, DeclaratorDecl *DD);
-
- DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD);
-
- void setManglingNumber(const NamedDecl *ND, unsigned Number);
- unsigned getManglingNumber(const NamedDecl *ND) const;
-
- void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
- unsigned getStaticLocalNumber(const VarDecl *VD) const;
-
- /// \brief Retrieve the context for computing mangling numbers in the given
- /// DeclContext.
- MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
-
- MangleNumberingContext *createMangleNumberingContext() const;
-
- /// \brief 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
- /// 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
- /// of static storage duration.
- APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
- bool MayCreate);
-
- //===--------------------------------------------------------------------===//
- // Statistics
- //===--------------------------------------------------------------------===//
-
- /// \brief The number of implicitly-declared default constructors.
- static unsigned NumImplicitDefaultConstructors;
-
- /// \brief The number of implicitly-declared default constructors for
- /// which declarations were built.
- static unsigned NumImplicitDefaultConstructorsDeclared;
-
- /// \brief The number of implicitly-declared copy constructors.
- static unsigned NumImplicitCopyConstructors;
-
- /// \brief The number of implicitly-declared copy constructors for
- /// which declarations were built.
- static unsigned NumImplicitCopyConstructorsDeclared;
-
- /// \brief The number of implicitly-declared move constructors.
- static unsigned NumImplicitMoveConstructors;
-
- /// \brief The number of implicitly-declared move constructors for
- /// which declarations were built.
- static unsigned NumImplicitMoveConstructorsDeclared;
-
- /// \brief The number of implicitly-declared copy assignment operators.
- static unsigned NumImplicitCopyAssignmentOperators;
-
- /// \brief 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.
- static unsigned NumImplicitMoveAssignmentOperators;
-
- /// \brief The number of implicitly-declared move assignment operators for
- /// which declarations were built.
- static unsigned NumImplicitMoveAssignmentOperatorsDeclared;
-
- /// \brief The number of implicitly-declared destructors.
- static unsigned NumImplicitDestructors;
-
- /// \brief The number of implicitly-declared destructors for which
- /// declarations were built.
- static unsigned NumImplicitDestructorsDeclared;
-
-private:
- ASTContext(const ASTContext &) = delete;
- void operator=(const ASTContext &) = delete;
-
-public:
- /// \brief Initialize built-in types.
- ///
- /// This routine may only be invoked once for a given ASTContext object.
- /// It is normally invoked after ASTContext construction.
- ///
- /// \param Target The target
- void InitBuiltinTypes(const TargetInfo &Target,
- const TargetInfo *AuxTarget = nullptr);
-
-private:
- void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
-
- // Return the Objective-C type encoding for a given type.
- void getObjCEncodingForTypeImpl(QualType t, std::string &S,
- bool ExpandPointedToStructures,
- bool ExpandStructures,
- const FieldDecl *Field,
- bool OutermostType = false,
- bool EncodingProperty = false,
- bool StructField = false,
- bool EncodeBlockParameters = false,
- bool EncodeClassNames = false,
- bool EncodePointerToObjCTypedef = false,
- QualType *NotEncodedT=nullptr) const;
-
- // Adds the encoding of the structure's members.
- void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
- const FieldDecl *Field,
- bool includeVBases = true,
- QualType *NotEncodedT=nullptr) const;
-public:
- // Adds the encoding of a method parameter or return type.
- void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
- QualType T, std::string& S,
- bool Extended) const;
-
- /// \brief Returns true if this is an inline-initialized static data member
- /// which is treated as a definition for MSVC compatibility.
- bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
-
-private:
- const ASTRecordLayout &
- getObjCLayout(const ObjCInterfaceDecl *D,
- const ObjCImplementationDecl *Impl) const;
-
- /// \brief 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
- // within the AST. In some places we thread the AST bump pointer allocator
- // into the datastructures which avoids this mess during deallocation but is
- // wasteful of memory, and here we require a lot of error prone book keeping
- // in order to track and run destructors while we're tearing things down.
- typedef llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>
- DeallocationFunctionsAndArguments;
- DeallocationFunctionsAndArguments Deallocations;
-
- // FIXME: This currently contains the set of StoredDeclMaps used
- // by DeclContext objects. This probably should not be in ASTContext,
- // but we include it here so that ASTContext can quickly deallocate them.
- llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
-
- friend class DeclContext;
- friend class DeclarationNameTable;
- void ReleaseDeclContextMaps();
- void ReleaseParentMapEntries();
-
- std::unique_ptr<ParentMapPointers> PointerParents;
- std::unique_ptr<ParentMapOtherNodes> OtherParents;
-
- std::unique_ptr<VTableContextBase> VTContext;
-
-public:
- enum PragmaSectionFlag : unsigned {
- PSF_None = 0,
- PSF_Read = 0x1,
- PSF_Write = 0x2,
- PSF_Execute = 0x4,
- PSF_Implicit = 0x8,
- PSF_Invalid = 0x80000000U,
- };
-
- struct SectionInfo {
- DeclaratorDecl *Decl;
- SourceLocation PragmaSectionLocation;
- int SectionFlags;
- SectionInfo() {}
- SectionInfo(DeclaratorDecl *Decl,
- SourceLocation PragmaSectionLocation,
- int SectionFlags)
- : Decl(Decl),
- PragmaSectionLocation(PragmaSectionLocation),
- SectionFlags(SectionFlags) {}
- };
-
- llvm::StringMap<SectionInfo> SectionInfos;
-};
-
-/// \brief Utility function for constructing a nullary selector.
-static 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.
-static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
- IdentifierInfo* II = &Ctx.Idents.get(name);
- return Ctx.Selectors.getSelector(1, &II);
-}
-
-} // end namespace clang
-
-// operator new and delete aren't allowed inside namespaces.
-
-/// @brief Placement new for using the ASTContext's allocator.
-///
-/// This placement form of operator new uses the ASTContext's allocator for
-/// obtaining memory.
-///
-/// IMPORTANT: These are also declared in clang/AST/AttrIterator.h! Any changes
-/// here need to also be made there.
-///
-/// We intentionally avoid using a nothrow specification here so that the calls
-/// to this operator will not perform a null check on the result -- the
-/// underlying allocator never returns null pointers.
-///
-/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
-/// @code
-/// // Default alignment (8)
-/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
-/// // Specific alignment
-/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments);
-/// @endcode
-/// Memory allocated through this placement new operator does not need to be
-/// explicitly freed, as ASTContext will free all of this memory when it gets
-/// destroyed. Please note that you cannot use delete on the pointer.
-///
-/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
-/// @param C The ASTContext that provides the allocator.
-/// @param Alignment The alignment of the allocated memory (if the underlying
-/// allocator supports it).
-/// @return The allocated memory. Could be NULL.
-inline void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment) {
- return C.Allocate(Bytes, Alignment);
-}
-/// @brief 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
-/// is called implicitly by the compiler if a placement new expression using
-/// the ASTContext throws in the object constructor.
-inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
- C.Deallocate(Ptr);
-}
-
-/// This placement form of operator new[] uses the ASTContext's allocator for
-/// obtaining memory.
-///
-/// We intentionally avoid using a nothrow specification here so that the calls
-/// to this operator will not perform a null check on the result -- the
-/// underlying allocator never returns null pointers.
-///
-/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
-/// @code
-/// // Default alignment (8)
-/// char *data = new (Context) char[10];
-/// // Specific alignment
-/// char *data = new (Context, 4) char[10];
-/// @endcode
-/// Memory allocated through this placement new[] operator does not need to be
-/// explicitly freed, as ASTContext will free all of this memory when it gets
-/// destroyed. Please note that you cannot use delete on the pointer.
-///
-/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
-/// @param C The ASTContext that provides the allocator.
-/// @param Alignment The alignment of the allocated memory (if the underlying
-/// allocator supports it).
-/// @return The allocated memory. Could be NULL.
-inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
- size_t Alignment = 8) {
- return C.Allocate(Bytes, Alignment);
-}
-
-/// @brief 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
-/// is called implicitly by the compiler if a placement new[] expression using
-/// the ASTContext throws in the object constructor.
-inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) {
- C.Deallocate(Ptr);
-}
-
-/// \brief Create the representation of a LazyGenerationalUpdatePtr.
-template <typename Owner, typename T,
- void (clang::ExternalASTSource::*Update)(Owner)>
-typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
- clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue(
- const clang::ASTContext &Ctx, T Value) {
- // Note, this is implemented here so that ExternalASTSource.h doesn't need to
- // include ASTContext.h. We explicitly instantiate it for all relevant types
- // in ASTContext.cpp.
- if (auto *Source = Ctx.getExternalSource())
- return new (Ctx) LazyData(Source, Value);
- return Value;
-}
-
-#endif
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
deleted file mode 100644
index 27c85e6..0000000
--- a/include/clang/AST/ASTDiagnostic.h
+++ /dev/null
@@ -1,47 +0,0 @@
-//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- 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_AST_ASTDIAGNOSTIC_H
-#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define ASTSTART
-#include "clang/Basic/DiagnosticASTKinds.inc"
-#undef DIAG
- NUM_BUILTIN_AST_DIAGNOSTICS
- };
- } // end namespace diag
-
- /// \brief DiagnosticsEngine argument formatting function for diagnostics that
- /// involve AST nodes.
- ///
- /// This function formats diagnostic arguments for various AST nodes,
- /// including types, declaration names, nested name specifiers, and
- /// declaration contexts, into strings that can be printed as part of
- /// diagnostics. It is meant to be used as the argument to
- /// \c DiagnosticsEngine::SetArgToStringFn(), where the cookie is an \c
- /// ASTContext pointer.
- void FormatASTNodeDiagnosticArgument(
- DiagnosticsEngine::ArgumentKind Kind,
- intptr_t Val,
- StringRef Modifier,
- StringRef Argument,
- ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
- SmallVectorImpl<char> &Output,
- void *Cookie,
- ArrayRef<intptr_t> QualTypeVals);
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
deleted file mode 100644
index 003d489..0000000
--- a/include/clang/AST/ASTFwd.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===--- ASTFwd.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--------------------------------------------------------------===//
-///
-/// \file
-/// \brief Forward declaration of all AST node types.
-///
-//===-------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTFWD_H
-#define LLVM_CLANG_AST_ASTFWD_H
-
-namespace clang {
-
-class Decl;
-#define DECL(DERIVED, BASE) class DERIVED##Decl;
-#include "clang/AST/DeclNodes.inc"
-class Stmt;
-#define STMT(DERIVED, BASE) class DERIVED;
-#include "clang/AST/StmtNodes.inc"
-class Type;
-#define TYPE(DERIVED, BASE) class DERIVED##Type;
-#include "clang/AST/TypeNodes.def"
-class CXXCtorInitializer;
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
deleted file mode 100644
index ee48955..0000000
--- a/include/clang/AST/ASTImporter.h
+++ /dev/null
@@ -1,295 +0,0 @@
-//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- 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 ASTImporter class which imports AST nodes from one
-// context into another context.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
-#define LLVM_CLANG_AST_ASTIMPORTER_H
-
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- class ASTContext;
- 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,
- /// merging AST nodes where appropriate.
- class ASTImporter {
- public:
- typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
-
- private:
- /// \brief The contexts we're importing to and from.
- ASTContext &ToContext, &FromContext;
-
- /// \brief The file managers we're importing to and from.
- FileManager &ToFileManager, &FromFileManager;
-
- /// \brief Whether to perform a minimal import.
- bool Minimal;
-
- /// \brief Whether the last diagnostic came from the "from" context.
- bool LastDiagFromFrom;
-
- /// \brief 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"
- /// context to the corresponding declarations in the "to" context.
- llvm::DenseMap<Decl *, Decl *> ImportedDecls;
-
- /// \brief 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
- /// manager to the corresponding FileIDs in the "to" source manager.
- llvm::DenseMap<FileID, FileID> ImportedFileIDs;
-
- /// \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
- /// (which we have already complained about).
- NonEquivalentDeclSet NonEquivalentDecls;
-
- public:
- /// \brief Create a new AST importer.
- ///
- /// \param ToContext The context we'll be importing into.
- ///
- /// \param ToFileManager The file manager we'll be importing into.
- ///
- /// \param FromContext The context we'll be importing from.
- ///
- /// \param FromFileManager The file manager we'll be importing into.
- ///
- /// \param MinimalImport If true, the importer will attempt to import
- /// as little as it can, e.g., by importing declarations as forward
- /// declarations that can be completed at a later point.
- ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
- ASTContext &FromContext, FileManager &FromFileManager,
- bool MinimalImport);
-
- virtual ~ASTImporter();
-
- /// \brief 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"
- /// 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
- /// "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
- /// "to" context.
- ///
- /// \returns the equivalent declaration in the "to" context, or a NULL type
- /// if an error occurred.
- Decl *Import(Decl *FromD);
-
- /// \brief 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"
- /// 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
- /// "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
- /// "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"
- /// 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"
- /// 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
- /// "to" context.
- TemplateName Import(TemplateName From);
-
- /// \brief 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
- /// 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"
- /// 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
- /// 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"
- /// 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
- /// "to" context.
- ///
- /// \returns the equivalent file ID in the source manager of the "to"
- /// context.
- FileID Import(FileID);
-
- /// \brief 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
- /// given context.
- ///
- /// This routine is invoked whenever there is a name conflict while
- /// importing a declaration. The returned name will become the name of the
- /// imported declaration. By default, the returned name is the same as the
- /// original name, leaving the conflict unresolve such that name lookup
- /// for this name is likely to find an ambiguity later.
- ///
- /// Subclasses may override this routine to resolve the conflict, e.g., by
- /// renaming the declaration being imported.
- ///
- /// \param Name the name of the declaration being imported, which conflicts
- /// with other declarations.
- ///
- /// \param DC the declaration context (in the "to" AST context) in which
- /// the name is being imported.
- ///
- /// \param IDNS the identifier namespace in which the name will be found.
- ///
- /// \param Decls the set of declarations with the same name as the
- /// declaration being imported.
- ///
- /// \param NumDecls the number of conflicting declarations in \p Decls.
- ///
- /// \returns the name that the newly-imported declaration should have.
- virtual DeclarationName HandleNameConflict(DeclarationName Name,
- DeclContext *DC,
- unsigned IDNS,
- NamedDecl **Decls,
- unsigned NumDecls);
-
- /// \brief 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.
- ASTContext &getFromContext() const { return FromContext; }
-
- /// \brief 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.
- FileManager &getFromFileManager() const { return FromFileManager; }
-
- /// \brief Report a diagnostic in the "to" context.
- DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
-
- /// \brief 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.
- NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
-
- /// \brief 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
- /// 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
- /// RecordDecl can be found, we can complete it without the need for
- /// importation, eliminating this loop.
- virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
-
- /// \brief Determine whether the given types are structurally
- /// equivalent.
- bool IsStructurallyEquivalent(QualType From, QualType To,
- bool Complain = true);
- };
-}
-
-#endif // LLVM_CLANG_AST_ASTIMPORTER_H
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
deleted file mode 100644
index 69df2d8..0000000
--- a/include/clang/AST/ASTLambda.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file provides some common utility functions for processing
-/// Lambda related AST Constructs.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTLAMBDA_H
-#define LLVM_CLANG_AST_ASTLAMBDA_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
-
-namespace clang {
-inline StringRef getLambdaStaticInvokerName() {
- return "__invoke";
-}
-// This function returns true if M is a specialization, a template,
-// or a non-generic lambda call operator.
-inline bool isLambdaCallOperator(const CXXMethodDecl *MD) {
- const CXXRecordDecl *LambdaClass = MD->getParent();
- if (!LambdaClass || !LambdaClass->isLambda()) return false;
- return MD->getOverloadedOperator() == OO_Call;
-}
-
-inline bool isLambdaCallOperator(const DeclContext *DC) {
- if (!DC || !isa<CXXMethodDecl>(DC)) return false;
- return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
-}
-
-inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
- if (!MD) return false;
- const CXXRecordDecl *LambdaClass = MD->getParent();
- if (LambdaClass && LambdaClass->isGenericLambda())
- return isLambdaCallOperator(MD) &&
- MD->isFunctionTemplateSpecialization();
- return false;
-}
-
-inline bool isLambdaConversionOperator(CXXConversionDecl *C) {
- return C ? C->getParent()->isLambda() : false;
-}
-
-inline bool isLambdaConversionOperator(Decl *D) {
- if (!D) return false;
- if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D))
- return isLambdaConversionOperator(Conv);
- if (FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(D))
- if (CXXConversionDecl *Conv =
- dyn_cast_or_null<CXXConversionDecl>(F->getTemplatedDecl()))
- return isLambdaConversionOperator(Conv);
- return false;
-}
-
-inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
- return isGenericLambdaCallOperatorSpecialization(
- dyn_cast<CXXMethodDecl>(DC));
-}
-
-
-// This returns the parent DeclContext ensuring that the correct
-// parent DeclContext is returned for Lambdas
-inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
- if (isLambdaCallOperator(DC))
- return DC->getParent()->getParent();
- else
- return DC->getParent();
-}
-
-} // clang
-
-#endif
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
deleted file mode 100644
index 3ff392d..0000000
--- a/include/clang/AST/ASTMutationListener.h
+++ /dev/null
@@ -1,127 +0,0 @@
-//===--- ASTMutationListener.h - AST Mutation Interface --------*- 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 ASTMutationListener interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
-#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
-
-namespace clang {
- class Attr;
- class ClassTemplateDecl;
- class ClassTemplateSpecializationDecl;
- class CXXDestructorDecl;
- class CXXRecordDecl;
- class Decl;
- class DeclContext;
- class FunctionDecl;
- class FunctionTemplateDecl;
- class Module;
- class NamedDecl;
- class ObjCCategoryDecl;
- class ObjCContainerDecl;
- class ObjCInterfaceDecl;
- class ObjCPropertyDecl;
- class QualType;
- class RecordDecl;
- class TagDecl;
- class VarDecl;
- class VarTemplateDecl;
- class VarTemplateSpecializationDecl;
-
-/// \brief 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.
- virtual void CompletedTagDefinition(const TagDecl *D) { }
-
- /// \brief 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.
- virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {}
-
- /// \brief 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
- /// template declaration.
- virtual void
- AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
- const VarTemplateSpecializationDecl *D) {}
-
- /// \brief 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
- /// instantiated.
- virtual void ResolvedExceptionSpec(const FunctionDecl *FD) {}
-
- /// \brief 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.
- virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
- const FunctionDecl *Delete) {}
-
- /// \brief An implicit member got a definition.
- virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
-
- /// \brief A static data member was implicitly instantiated.
- virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
-
- /// \brief A function template's definition was instantiated.
- virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
-
- /// \brief A new objc category class was added for an interface.
- virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
- const ObjCInterfaceDecl *IFD) {}
-
- /// \brief 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
- /// previously marked as threadprivate.
- ///
- /// \param D the declaration marked OpenMP threadprivate.
- virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}
-
- /// \brief 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
- ///
- /// \param Attr The attribute that was added to the Record
- ///
- /// \param Record The RecordDecl that got a new attribute
- virtual void AddedAttributeToRecord(const Attr *Attr,
- const RecordDecl *Record) {}
-
- // NOTE: If new methods are added they should also be added to
- // MultiplexASTMutationListener.
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
deleted file mode 100644
index dcaac80..0000000
--- a/include/clang/AST/ASTTypeTraits.h
+++ /dev/null
@@ -1,509 +0,0 @@
-//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Provides a dynamic type identifier and a dynamically typed node container
-// that can be used to store an AST base node at runtime in the same storage in
-// a type safe way.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
-#define LLVM_CLANG_AST_ASTTYPETRAITS_H
-
-#include "clang/AST/ASTFwd.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/Support/AlignOf.h"
-
-namespace llvm {
-
-class raw_ostream;
-
-}
-
-namespace clang {
-
-struct PrintingPolicy;
-
-namespace ast_type_traits {
-
-/// \brief 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.
- ASTNodeKind() : KindId(NKI_None) {}
-
- /// \brief 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
- 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.
- bool isSame(ASTNodeKind Other) const;
-
- /// \brief 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.
- /// \param Distance If non-null, used to return the distance between \c this
- /// and \c Other in the class hierarchy.
- bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
-
- /// \brief String representation of the kind.
- StringRef asStringRef() const;
-
- /// \brief Strict weak ordering for ASTNodeKind.
- bool operator<(const ASTNodeKind &Other) const {
- return KindId < Other.KindId;
- }
-
- /// \brief 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 ASTNodeKind() if they are not related.
- static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
- ASTNodeKind Kind2);
-
- /// \brief 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(); }
- // NKI_NumberOfKinds is not a valid value, so it is good for a
- // tombstone key.
- static inline ASTNodeKind getTombstoneKey() {
- return ASTNodeKind(NKI_NumberOfKinds);
- }
- static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
- static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
- return LHS.KindId == RHS.KindId;
- }
- };
-
- /// Check if the given ASTNodeKind identifies a type that offers pointer
- /// identity. This is useful for the fast path in DynTypedNode.
- bool hasPointerIdentity() const {
- return KindId > NKI_LastKindWithoutPointerIdentity;
- }
-
-private:
- /// \brief Kind ids.
- ///
- /// Includes all possible base and derived kinds.
- enum NodeKindId {
- NKI_None,
- NKI_TemplateArgument,
- NKI_NestedNameSpecifierLoc,
- NKI_QualType,
- NKI_TypeLoc,
- NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
- NKI_CXXCtorInitializer,
- NKI_NestedNameSpecifier,
- NKI_Decl,
-#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
-#include "clang/AST/DeclNodes.inc"
- NKI_Stmt,
-#define STMT(DERIVED, BASE) NKI_##DERIVED,
-#include "clang/AST/StmtNodes.inc"
- NKI_Type,
-#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
-#include "clang/AST/TypeNodes.def"
- NKI_NumberOfKinds
- };
-
- /// \brief 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
- /// 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.
- ///
- /// This struct is specialized below for all known kinds.
- template <class T> struct KindToKindId {
- static const NodeKindId Id = NKI_None;
- };
- template <class T>
- struct KindToKindId<const T> : KindToKindId<T> {};
-
- /// \brief Per kind info.
- struct KindInfo {
- /// \brief The id of the parent kind, or None if it has no parent.
- NodeKindId ParentId;
- /// \brief Name of the kind.
- const char *Name;
- };
- static const KindInfo AllKindInfo[NKI_NumberOfKinds];
-
- NodeKindId KindId;
-};
-
-#define KIND_TO_KIND_ID(Class) \
- template <> struct ASTNodeKind::KindToKindId<Class> { \
- static const NodeKindId Id = NKI_##Class; \
- };
-KIND_TO_KIND_ID(CXXCtorInitializer)
-KIND_TO_KIND_ID(TemplateArgument)
-KIND_TO_KIND_ID(NestedNameSpecifier)
-KIND_TO_KIND_ID(NestedNameSpecifierLoc)
-KIND_TO_KIND_ID(QualType)
-KIND_TO_KIND_ID(TypeLoc)
-KIND_TO_KIND_ID(Decl)
-KIND_TO_KIND_ID(Stmt)
-KIND_TO_KIND_ID(Type)
-#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
-#include "clang/AST/DeclNodes.inc"
-#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
-#include "clang/AST/StmtNodes.inc"
-#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
-#include "clang/AST/TypeNodes.def"
-#undef KIND_TO_KIND_ID
-
-inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
- OS << K.asStringRef();
- return OS;
-}
-
-/// \brief A dynamically typed AST node container.
-///
-/// Stores an AST node in a type safe way. This allows writing code that
-/// works with different kinds of AST nodes, despite the fact that they don't
-/// have a common base class.
-///
-/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
-/// and \c get<T>() to retrieve the node as type T if the types match.
-///
-/// See \c ASTNodeKind for which node base types are currently supported;
-/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
-/// the supported base types.
-class DynTypedNode {
-public:
- /// \brief 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.
- ///
- /// Returns NULL if the stored node does not have a type that is
- /// convertible to \c T.
- ///
- /// For types that have identity via their pointer in the AST
- /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
- /// pointer points to the referenced AST node.
- /// For other types (like \c QualType) the value is stored directly
- /// in the \c DynTypedNode, and the returned pointer points at
- /// the storage inside DynTypedNode. For those nodes, do not
- /// use the pointer outside the scope of the DynTypedNode.
- template <typename T>
- const T *get() const {
- return BaseConverter<T>::get(NodeKind, Storage.buffer);
- }
-
- /// \brief 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>
- const T &getUnchecked() const {
- return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
- }
-
- ASTNodeKind getNodeKind() const { return NodeKind; }
-
- /// \brief 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
- /// method returns NULL.
- const void *getMemoizationData() const {
- return NodeKind.hasPointerIdentity()
- ? *reinterpret_cast<void *const *>(Storage.buffer)
- : nullptr;
- }
-
- /// \brief 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.
- void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
-
- /// \brief 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.
- ///
- /// Supports comparison of nodes that support memoization.
- /// FIXME: Implement comparsion 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))
- return NodeKind < Other.NodeKind;
-
- if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
- return getUnchecked<QualType>().getAsOpaquePtr() <
- Other.getUnchecked<QualType>().getAsOpaquePtr();
-
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) {
- auto TLA = getUnchecked<TypeLoc>();
- auto TLB = Other.getUnchecked<TypeLoc>();
- return std::make_pair(TLA.getType().getAsOpaquePtr(),
- TLA.getOpaqueData()) <
- std::make_pair(TLB.getType().getAsOpaquePtr(),
- TLB.getOpaqueData());
- }
-
- if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
- NodeKind)) {
- auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
- auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
- return std::make_pair(NNSLA.getNestedNameSpecifier(),
- NNSLA.getOpaqueData()) <
- std::make_pair(NNSLB.getNestedNameSpecifier(),
- NNSLB.getOpaqueData());
- }
-
- assert(getMemoizationData() && Other.getMemoizationData());
- return getMemoizationData() < Other.getMemoizationData();
- }
- bool operator==(const DynTypedNode &Other) const {
- // DynTypedNode::create() stores the exact kind of the node in NodeKind.
- // If they contain the same node, their NodeKind must be the same.
- if (!NodeKind.isSame(Other.NodeKind))
- return false;
-
- // FIXME: Implement for other types.
- if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
- return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
-
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind))
- return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
-
- if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
- return getUnchecked<NestedNameSpecifierLoc>() ==
- Other.getUnchecked<NestedNameSpecifierLoc>();
-
- assert(getMemoizationData() && Other.getMemoizationData());
- return getMemoizationData() == Other.getMemoizationData();
- }
- bool operator!=(const DynTypedNode &Other) const {
- return !operator==(Other);
- }
- /// @}
-
- /// \brief Hooks for using DynTypedNode as a key in a DenseMap.
- struct DenseMapInfo {
- static inline DynTypedNode getEmptyKey() {
- DynTypedNode Node;
- Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey();
- return Node;
- }
- static inline DynTypedNode getTombstoneKey() {
- DynTypedNode Node;
- Node.NodeKind = ASTNodeKind::DenseMapInfo::getTombstoneKey();
- return Node;
- }
- static unsigned getHashValue(const DynTypedNode &Val) {
- // FIXME: Add hashing support for the remaining types.
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(Val.NodeKind)) {
- auto TL = Val.getUnchecked<TypeLoc>();
- return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
- TL.getOpaqueData());
- }
-
- if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
- Val.NodeKind)) {
- auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
- return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
- NNSL.getOpaqueData());
- }
-
- assert(Val.getMemoizationData());
- return llvm::hash_value(Val.getMemoizationData());
- }
- static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
- auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey();
- auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey();
- return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
- ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) ||
- (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
- ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
- LHS == RHS;
- }
- };
-
-private:
- /// \brief 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*.
- template <typename T, typename BaseT> struct DynCastPtrConverter {
- static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
- if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
- return &getUnchecked(NodeKind, Storage);
- return nullptr;
- }
- static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
- assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
- return *cast<T>(static_cast<const BaseT *>(
- *reinterpret_cast<const void *const *>(Storage)));
- }
- static DynTypedNode create(const BaseT &Node) {
- DynTypedNode Result;
- Result.NodeKind = ASTNodeKind::getFromNode(Node);
- new (Result.Storage.buffer) const void *(&Node);
- return Result;
- }
- };
-
- /// \brief 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))
- return &getUnchecked(NodeKind, Storage);
- return nullptr;
- }
- static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
- assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
- return *static_cast<const T *>(
- *reinterpret_cast<const void *const *>(Storage));
- }
- static DynTypedNode create(const T &Node) {
- DynTypedNode Result;
- Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
- new (Result.Storage.buffer) const void *(&Node);
- return Result;
- }
- };
-
- /// \brief 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))
- return reinterpret_cast<const T *>(Storage);
- return nullptr;
- }
- static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
- assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
- return *reinterpret_cast<const T *>(Storage);
- }
- static DynTypedNode create(const T &Node) {
- DynTypedNode Result;
- Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
- new (Result.Storage.buffer) T(Node);
- return Result;
- }
- };
-
- ASTNodeKind NodeKind;
-
- /// \brief 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
- /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
- /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and
- /// \c TemplateArguments on the other hand do not have storage or unique
- /// pointers and thus need to be stored by value.
- llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
- NestedNameSpecifierLoc, QualType,
- TypeLoc> Storage;
-};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
- : public DynCastPtrConverter<T, Decl> {};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
- : public DynCastPtrConverter<T, Stmt> {};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
- : public DynCastPtrConverter<T, Type> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- NestedNameSpecifierLoc,
- void> : public ValueConverter<NestedNameSpecifierLoc> {};
-
-template <>
-struct DynTypedNode::BaseConverter<QualType,
- void> : public ValueConverter<QualType> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- TypeLoc, void> : public ValueConverter<TypeLoc> {};
-
-// The only operation we allow on unsupported types is \c get.
-// This allows to conveniently use \c DynTypedNode when having an arbitrary
-// AST node that is not supported, but prevents misuse - a user cannot create
-// a DynTypedNode from arbitrary types.
-template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
- static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
- return NULL;
- }
-};
-
-} // end namespace ast_type_traits
-} // end namespace clang
-
-namespace llvm {
-
-template <>
-struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind>
- : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {};
-
-template <>
-struct DenseMapInfo<clang::ast_type_traits::DynTypedNode>
- : clang::ast_type_traits::DynTypedNode::DenseMapInfo {};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
deleted file mode 100644
index 9078a0e..0000000
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===-- ASTUnresolvedSet.h - Unresolved sets of declarations ---*- 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 an UnresolvedSet-like class, whose contents are
-// allocated using the allocator associated with an ASTContext.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
-#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
-
-#include "clang/AST/ASTVector.h"
-#include "clang/AST/UnresolvedSet.h"
-
-namespace clang {
-
-/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
-class ASTUnresolvedSet {
- struct DeclsTy : ASTVector<DeclAccessPair> {
- DeclsTy() {}
- DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}
-
- bool isLazy() const { return getTag(); }
- void setLazy(bool Lazy) { setTag(Lazy); }
- };
-
- DeclsTy Decls;
-
- friend class LazyASTUnresolvedSet;
-
-public:
- ASTUnresolvedSet() {}
- ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
-
- typedef UnresolvedSetIterator iterator;
- typedef UnresolvedSetIterator const_iterator;
-
- iterator begin() { return iterator(Decls.begin()); }
- iterator end() { return iterator(Decls.end()); }
-
- const_iterator begin() const { return const_iterator(Decls.begin()); }
- const_iterator end() const { return const_iterator(Decls.end()); }
-
- void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) {
- Decls.push_back(DeclAccessPair::make(D, AS), C);
- }
-
- /// Replaces the given declaration with the new one, once.
- ///
- /// \return true if the set changed
- bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) {
- for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
- if (I->getDecl() == Old) {
- I->set(New, AS);
- return true;
- }
- }
- return false;
- }
-
- void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }
-
- void clear() { Decls.clear(); }
-
- bool empty() const { return Decls.empty(); }
- unsigned size() const { return Decls.size(); }
-
- void reserve(ASTContext &C, unsigned N) {
- Decls.reserve(C, N);
- }
-
- void append(ASTContext &C, iterator I, iterator E) {
- Decls.append(C, I.I, E.I);
- }
-
- DeclAccessPair &operator[](unsigned I) { return Decls[I]; }
- const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
-};
-
-/// \brief An UnresolvedSet-like class that might not have been loaded from the
-/// external AST source yet.
-class LazyASTUnresolvedSet {
- mutable ASTUnresolvedSet Impl;
-
- void getFromExternalSource(ASTContext &C) const;
-
-public:
- ASTUnresolvedSet &get(ASTContext &C) const {
- if (Impl.Decls.isLazy())
- getFromExternalSource(C);
- return Impl;
- }
-
- void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
- void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
- assert(Impl.empty() || Impl.Decls.isLazy());
- Impl.Decls.setLazy(true);
- Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS);
- }
-};
-
-} // namespace clang
-
-#endif
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
deleted file mode 100644
index 79453bf..0000000
--- a/include/clang/AST/ASTVector.h
+++ /dev/null
@@ -1,405 +0,0 @@
-//===- ASTVector.h - Vector that uses ASTContext for allocation --*- 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 ASTVector, a vector ADT whose contents are
-// allocated using the allocator associated with an ASTContext..
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h.
-// We can refactor this core logic into something common.
-
-#ifndef LLVM_CLANG_AST_ASTVECTOR_H
-#define LLVM_CLANG_AST_ASTVECTOR_H
-
-#include "clang/AST/AttrIterator.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/type_traits.h"
-#include <algorithm>
-#include <cstring>
-#include <memory>
-
-namespace clang {
- class ASTContext;
-
-template<typename T>
-class ASTVector {
-private:
- T *Begin, *End;
- llvm::PointerIntPair<T*, 1, bool> Capacity;
-
- void setEnd(T *P) { this->End = P; }
-
-protected:
- // Make a tag bit available to users of this class.
- // FIXME: This is a horrible hack.
- bool getTag() const { return Capacity.getInt(); }
- void setTag(bool B) { Capacity.setInt(B); }
-
-public:
- // Default ctor - Initialize to empty.
- ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
-
- ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
- O.Begin = O.End = nullptr;
- O.Capacity.setPointer(nullptr);
- O.Capacity.setInt(false);
- }
-
- ASTVector(const ASTContext &C, unsigned N)
- : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
- reserve(C, N);
- }
-
- ASTVector &operator=(ASTVector &&RHS) {
- ASTVector O(std::move(RHS));
- using std::swap;
- swap(Begin, O.Begin);
- swap(End, O.End);
- swap(Capacity, O.Capacity);
- return *this;
- }
-
- ~ASTVector() {
- if (std::is_class<T>::value) {
- // Destroy the constructed elements in the vector.
- destroy_range(Begin, End);
- }
- }
-
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T value_type;
- typedef T* iterator;
- typedef const T* const_iterator;
-
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
-
- // forward iterator creation methods.
- iterator begin() { return Begin; }
- const_iterator begin() const { return Begin; }
- iterator end() { return End; }
- const_iterator end() const { return End; }
-
- // reverse iterator creation methods.
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
-
- bool empty() const { return Begin == End; }
- size_type size() const { return End-Begin; }
-
- reference operator[](unsigned idx) {
- assert(Begin + idx < End);
- return Begin[idx];
- }
- const_reference operator[](unsigned idx) const {
- assert(Begin + idx < End);
- return Begin[idx];
- }
-
- reference front() {
- return begin()[0];
- }
- const_reference front() const {
- return begin()[0];
- }
-
- reference back() {
- return end()[-1];
- }
- const_reference back() const {
- return end()[-1];
- }
-
- void pop_back() {
- --End;
- End->~T();
- }
-
- T pop_back_val() {
- T Result = back();
- pop_back();
- return Result;
- }
-
- void clear() {
- if (std::is_class<T>::value) {
- destroy_range(Begin, End);
- }
- End = Begin;
- }
-
- /// data - Return a pointer to the vector's buffer, even if empty().
- pointer data() {
- return pointer(Begin);
- }
-
- /// data - Return a pointer to the vector's buffer, even if empty().
- const_pointer data() const {
- return const_pointer(Begin);
- }
-
- void push_back(const_reference Elt, const ASTContext &C) {
- if (End < this->capacity_ptr()) {
- Retry:
- new (End) T(Elt);
- ++End;
- return;
- }
- grow(C);
- goto Retry;
- }
-
- void reserve(const ASTContext &C, unsigned N) {
- if (unsigned(this->capacity_ptr()-Begin) < N)
- grow(C, N);
- }
-
- /// capacity - Return the total number of elements in the currently allocated
- /// buffer.
- size_t capacity() const { return this->capacity_ptr() - Begin; }
-
- /// append - Add the specified range to the end of the SmallVector.
- ///
- template<typename in_iter>
- void append(const ASTContext &C, in_iter in_start, in_iter in_end) {
- size_type NumInputs = std::distance(in_start, in_end);
-
- if (NumInputs == 0)
- return;
-
- // Grow allocated space if needed.
- if (NumInputs > size_type(this->capacity_ptr()-this->end()))
- this->grow(C, this->size()+NumInputs);
-
- // Copy the new elements over.
- // TODO: NEED To compile time dispatch on whether in_iter is a random access
- // iterator to use the fast uninitialized_copy.
- std::uninitialized_copy(in_start, in_end, this->end());
- this->setEnd(this->end() + NumInputs);
- }
-
- /// append - Add the specified range to the end of the SmallVector.
- ///
- void append(const ASTContext &C, size_type NumInputs, const T &Elt) {
- // Grow allocated space if needed.
- if (NumInputs > size_type(this->capacity_ptr()-this->end()))
- this->grow(C, this->size()+NumInputs);
-
- // Copy the new elements over.
- std::uninitialized_fill_n(this->end(), NumInputs, Elt);
- this->setEnd(this->end() + NumInputs);
- }
-
- /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
- /// starting with "Dest", constructing elements into it as needed.
- template<typename It1, typename It2>
- static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
- std::uninitialized_copy(I, E, Dest);
- }
-
- iterator insert(const ASTContext &C, iterator I, const T &Elt) {
- if (I == this->end()) { // Important special case for empty vector.
- push_back(Elt, C);
- return this->end()-1;
- }
-
- if (this->End < this->capacity_ptr()) {
- Retry:
- new (this->end()) T(this->back());
- this->setEnd(this->end()+1);
- // Push everything else over.
- std::copy_backward(I, this->end()-1, this->end());
- *I = Elt;
- return I;
- }
- size_t EltNo = I-this->begin();
- this->grow(C);
- I = this->begin()+EltNo;
- goto Retry;
- }
-
- iterator insert(const ASTContext &C, iterator I, size_type NumToInsert,
- const T &Elt) {
- // Convert iterator to elt# to avoid invalidating iterator when we reserve()
- size_t InsertElt = I - this->begin();
-
- if (I == this->end()) { // Important special case for empty vector.
- append(C, NumToInsert, Elt);
- return this->begin() + InsertElt;
- }
-
- // Ensure there is enough space.
- reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
-
- // Uninvalidate the iterator.
- I = this->begin()+InsertElt;
-
- // If there are more elements between the insertion point and the end of the
- // range than there are being inserted, we can use a simple approach to
- // insertion. Since we already reserved space, we know that this won't
- // reallocate the vector.
- if (size_t(this->end()-I) >= NumToInsert) {
- T *OldEnd = this->end();
- append(C, this->end()-NumToInsert, this->end());
-
- // Copy the existing elements that get replaced.
- std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
-
- std::fill_n(I, NumToInsert, Elt);
- return I;
- }
-
- // Otherwise, we're inserting more elements than exist already, and we're
- // not inserting at the end.
-
- // Copy over the elements that we're about to overwrite.
- T *OldEnd = this->end();
- this->setEnd(this->end() + NumToInsert);
- size_t NumOverwritten = OldEnd-I;
- this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
-
- // Replace the overwritten part.
- std::fill_n(I, NumOverwritten, Elt);
-
- // Insert the non-overwritten middle part.
- std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
- return I;
- }
-
- template<typename ItTy>
- iterator insert(const ASTContext &C, iterator I, ItTy From, ItTy To) {
- // Convert iterator to elt# to avoid invalidating iterator when we reserve()
- size_t InsertElt = I - this->begin();
-
- if (I == this->end()) { // Important special case for empty vector.
- append(C, From, To);
- return this->begin() + InsertElt;
- }
-
- size_t NumToInsert = std::distance(From, To);
-
- // Ensure there is enough space.
- reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
-
- // Uninvalidate the iterator.
- I = this->begin()+InsertElt;
-
- // If there are more elements between the insertion point and the end of the
- // range than there are being inserted, we can use a simple approach to
- // insertion. Since we already reserved space, we know that this won't
- // reallocate the vector.
- if (size_t(this->end()-I) >= NumToInsert) {
- T *OldEnd = this->end();
- append(C, this->end()-NumToInsert, this->end());
-
- // Copy the existing elements that get replaced.
- std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
-
- std::copy(From, To, I);
- return I;
- }
-
- // Otherwise, we're inserting more elements than exist already, and we're
- // not inserting at the end.
-
- // Copy over the elements that we're about to overwrite.
- T *OldEnd = this->end();
- this->setEnd(this->end() + NumToInsert);
- size_t NumOverwritten = OldEnd-I;
- this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
-
- // Replace the overwritten part.
- for (; NumOverwritten > 0; --NumOverwritten) {
- *I = *From;
- ++I; ++From;
- }
-
- // Insert the non-overwritten middle part.
- this->uninitialized_copy(From, To, OldEnd);
- return I;
- }
-
- void resize(const ASTContext &C, unsigned N, const T &NV) {
- if (N < this->size()) {
- this->destroy_range(this->begin()+N, this->end());
- this->setEnd(this->begin()+N);
- } else if (N > this->size()) {
- if (this->capacity() < N)
- this->grow(C, N);
- construct_range(this->end(), this->begin()+N, NV);
- this->setEnd(this->begin()+N);
- }
- }
-
-private:
- /// grow - double the size of the allocated memory, guaranteeing space for at
- /// least one more element or MinSize if specified.
- void grow(const ASTContext &C, size_type MinSize = 1);
-
- void construct_range(T *S, T *E, const T &Elt) {
- for (; S != E; ++S)
- new (S) T(Elt);
- }
-
- void destroy_range(T *S, T *E) {
- while (S != E) {
- --E;
- E->~T();
- }
- }
-
-protected:
- const_iterator capacity_ptr() const {
- return (iterator) Capacity.getPointer();
- }
- iterator capacity_ptr() { return (iterator)Capacity.getPointer(); }
-};
-
-// Define this out-of-line to dissuade the C++ compiler from inlining it.
-template <typename T>
-void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
- size_t CurCapacity = this->capacity();
- size_t CurSize = size();
- size_t NewCapacity = 2*CurCapacity;
- if (NewCapacity < MinSize)
- NewCapacity = MinSize;
-
- // Allocate the memory from the ASTContext.
- T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
-
- // Copy the elements over.
- if (Begin != End) {
- if (std::is_class<T>::value) {
- std::uninitialized_copy(Begin, End, NewElts);
- // Destroy the original elements.
- destroy_range(Begin, End);
- } else {
- // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
- memcpy(NewElts, Begin, CurSize * sizeof(T));
- }
- }
-
- // ASTContext never frees any memory.
- Begin = NewElts;
- End = NewElts+CurSize;
- Capacity.setPointer(Begin+NewCapacity);
-}
-
-} // end: clang namespace
-#endif
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
deleted file mode 100644
index 8b80e9f..0000000
--- a/include/clang/AST/Attr.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Attr interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ATTR_H
-#define LLVM_CLANG_AST_ATTR_H
-
-#include "clang/AST/AttrIterator.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/AttrKinds.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Sanitizers.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/VersionTuple.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-
-namespace clang {
- class ASTContext;
- class IdentifierInfo;
- class ObjCInterfaceDecl;
- class Expr;
- class QualType;
- class FunctionDecl;
- class TypeSourceInfo;
-
-/// Attr - This represents one attribute.
-class Attr {
-private:
- SourceRange Range;
- unsigned AttrKind : 16;
-
-protected:
- /// An index into the spelling list of an
- /// attribute defined in Attr.td file.
- unsigned SpellingListIndex : 4;
- bool Inherited : 1;
- bool IsPackExpansion : 1;
- bool Implicit : 1;
- bool IsLateParsed : 1;
- bool DuplicatesAllowed : 1;
-
- void *operator new(size_t bytes) LLVM_NOEXCEPT {
- llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
- }
- void operator delete(void *data) LLVM_NOEXCEPT {
- llvm_unreachable("Attrs cannot be released with regular 'delete'.");
- }
-
-public:
- // Forward so that the regular new and delete do not hide global ones.
- void *operator new(size_t Bytes, ASTContext &C,
- size_t Alignment = 8) LLVM_NOEXCEPT {
- return ::operator new(Bytes, C, Alignment);
- }
- void operator delete(void *Ptr, ASTContext &C,
- size_t Alignment) LLVM_NOEXCEPT {
- return ::operator delete(Ptr, C, Alignment);
- }
-
-protected:
- Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
- : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
- Inherited(false), IsPackExpansion(false), Implicit(false),
- IsLateParsed(IsLateParsed), DuplicatesAllowed(DuplicatesAllowed) {}
-
-public:
-
- attr::Kind getKind() const {
- return static_cast<attr::Kind>(AttrKind);
- }
-
- unsigned getSpellingListIndex() const { return SpellingListIndex; }
- const char *getSpelling() const;
-
- SourceLocation getLocation() const { return Range.getBegin(); }
- SourceRange getRange() const { return Range; }
- void setRange(SourceRange R) { Range = R; }
-
- bool isInherited() const { return Inherited; }
-
- /// \brief Returns true if the attribute has been implicitly created instead
- /// of explicitly written by the user.
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I) { Implicit = I; }
-
- void setPackExpansion(bool PE) { IsPackExpansion = PE; }
- bool isPackExpansion() const { return IsPackExpansion; }
-
- // Clone this attribute.
- Attr *clone(ASTContext &C) const;
-
- bool isLateParsed() const { return IsLateParsed; }
-
- // 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 InheritableAttr : public Attr {
-protected:
- InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
- : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
-
-public:
- void setInherited(bool I) { Inherited = I; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() <= attr::LAST_INHERITABLE;
- }
-};
-
-class InheritableParamAttr : public InheritableAttr {
-protected:
- InheritableParamAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
- : InheritableAttr(AK, R, SpellingListIndex, IsLateParsed,
- DuplicatesAllowed) {}
-
-public:
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- // Relies on relative order of enum emission with respect to MS inheritance
- // attrs.
- return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
- }
-};
-
-#include "clang/AST/Attrs.inc"
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const Attr *At) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
- DiagnosticsEngine::ak_attr);
- return DB;
-}
-
-inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const Attr *At) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
- DiagnosticsEngine::ak_attr);
- return PD;
-}
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
deleted file mode 100644
index a0c8030..0000000
--- a/include/clang/AST/AttrIterator.h
+++ /dev/null
@@ -1,142 +0,0 @@
-//===--- AttrIterator.h - Classes for attribute iteration -------*- 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 Attr vector and specific_attr_iterator interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ATTRITERATOR_H
-#define LLVM_CLANG_AST_ATTRITERATOR_H
-
-#include "clang/Basic/LLVM.h"
-#include <iterator>
-
-namespace clang {
- class ASTContext;
- class Attr;
-}
-
-// Defined in ASTContext.h
-void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment = 8);
-// FIXME: Being forced to not have a default argument here due to redeclaration
-// rules on default arguments sucks
-void *operator new[](size_t Bytes, const clang::ASTContext &C,
- size_t Alignment);
-
-// It is good practice to pair new/delete operators. Also, MSVC gives many
-// warnings if a matching delete overload is not declared, even though the
-// throw() spec guarantees it will not be implicitly called.
-void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
-void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
-
-namespace clang {
-
-/// AttrVec - A vector of Attr, which is how they are stored on the AST.
-typedef SmallVector<Attr*, 2> AttrVec;
-typedef SmallVector<const Attr*, 2> ConstAttrVec;
-
-/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
-/// providing attributes that are of a specific type.
-template <typename SpecificAttr, typename Container = AttrVec>
-class specific_attr_iterator {
- typedef typename Container::const_iterator Iterator;
-
- /// Current - The current, underlying iterator.
- /// In order to ensure we don't dereference an invalid iterator unless
- /// specifically requested, we don't necessarily advance this all the
- /// way. Instead, we advance it when an operation is requested; if the
- /// operation is acting on what should be a past-the-end iterator,
- /// then we offer no guarantees, but this way we do not dereference a
- /// past-the-end iterator when we move to a past-the-end position.
- mutable Iterator Current;
-
- void AdvanceToNext() const {
- while (!isa<SpecificAttr>(*Current))
- ++Current;
- }
-
- void AdvanceToNext(Iterator I) const {
- while (Current != I && !isa<SpecificAttr>(*Current))
- ++Current;
- }
-
-public:
- typedef SpecificAttr* value_type;
- typedef SpecificAttr* reference;
- typedef SpecificAttr* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- specific_attr_iterator() : Current() { }
- explicit specific_attr_iterator(Iterator i) : Current(i) { }
-
- reference operator*() const {
- AdvanceToNext();
- return cast<SpecificAttr>(*Current);
- }
- pointer operator->() const {
- AdvanceToNext();
- return cast<SpecificAttr>(*Current);
- }
-
- specific_attr_iterator& operator++() {
- ++Current;
- return *this;
- }
- specific_attr_iterator operator++(int) {
- specific_attr_iterator Tmp(*this);
- ++(*this);
- return Tmp;
- }
-
- friend bool operator==(specific_attr_iterator Left,
- specific_attr_iterator Right) {
- assert((Left.Current == nullptr) == (Right.Current == nullptr));
- if (Left.Current < Right.Current)
- Left.AdvanceToNext(Right.Current);
- else
- Right.AdvanceToNext(Left.Current);
- return Left.Current == Right.Current;
- }
- friend bool operator!=(specific_attr_iterator Left,
- specific_attr_iterator Right) {
- return !(Left == Right);
- }
-};
-
-template <typename SpecificAttr, typename Container>
-inline specific_attr_iterator<SpecificAttr, Container>
- specific_attr_begin(const Container& container) {
- return specific_attr_iterator<SpecificAttr, Container>(container.begin());
-}
-template <typename SpecificAttr, typename Container>
-inline specific_attr_iterator<SpecificAttr, Container>
- specific_attr_end(const Container& container) {
- return specific_attr_iterator<SpecificAttr, Container>(container.end());
-}
-
-template <typename SpecificAttr, typename Container>
-inline bool hasSpecificAttr(const Container& container) {
- return specific_attr_begin<SpecificAttr>(container) !=
- specific_attr_end<SpecificAttr>(container);
-}
-template <typename SpecificAttr, typename Container>
-inline SpecificAttr *getSpecificAttr(const Container& container) {
- specific_attr_iterator<SpecificAttr, Container> i =
- specific_attr_begin<SpecificAttr>(container);
- if (i != specific_attr_end<SpecificAttr>(container))
- return *i;
- else
- return nullptr;
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
deleted file mode 100644
index da538e3..0000000
--- a/include/clang/AST/BaseSubobject.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides a definition of the BaseSubobject class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_BASESUBOBJECT_H
-#define LLVM_CLANG_AST_BASESUBOBJECT_H
-
-#include "clang/AST/CharUnits.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/type_traits.h"
-
-namespace clang {
- class CXXRecordDecl;
-
-// BaseSubobject - Uniquely identifies a direct or indirect base class.
-// Stores both the base class decl and the offset from the most derived class to
-// the base class. Used for vtable and VTT generation.
-class BaseSubobject {
- /// Base - The base class declaration.
- const CXXRecordDecl *Base;
-
- /// BaseOffset - The offset from the most derived class to the base class.
- CharUnits BaseOffset;
-
-public:
- BaseSubobject() { }
- BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
- : Base(Base), BaseOffset(BaseOffset) { }
-
- /// getBase - Returns the base class declaration.
- const CXXRecordDecl *getBase() const { return Base; }
-
- /// getBaseOffset - Returns the base class offset.
- CharUnits getBaseOffset() const { return BaseOffset; }
-
- friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
- return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
- }
-};
-
-} // end namespace clang
-
-namespace llvm {
-
-template<> struct DenseMapInfo<clang::BaseSubobject> {
- static clang::BaseSubobject getEmptyKey() {
- return clang::BaseSubobject(
- DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
- clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
- }
-
- static clang::BaseSubobject getTombstoneKey() {
- return clang::BaseSubobject(
- DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
- clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey()));
- }
-
- static unsigned getHashValue(const clang::BaseSubobject &Base) {
- typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
- return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
- Base.getBaseOffset()));
- }
-
- static bool isEqual(const clang::BaseSubobject &LHS,
- const clang::BaseSubobject &RHS) {
- return LHS == RHS;
- }
-};
-
-// It's OK to treat BaseSubobject as a POD type.
-template <> struct isPodLike<clang::BaseSubobject> {
- static const bool value = true;
-};
-
-}
-
-#endif
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
deleted file mode 100644
index 85e237a..0000000
--- a/include/clang/AST/BuiltinTypes.def
+++ /dev/null
@@ -1,261 +0,0 @@
-//===-- BuiltinTypeNodes.def - Metadata about BuiltinTypes ------*- 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 database about various builtin singleton types.
-//
-// BuiltinType::Id is the enumerator defining the type.
-//
-// Context.SingletonId is the global singleton of this type. Some global
-// singletons are shared by multiple types.
-//
-// BUILTIN_TYPE(Id, SingletonId) - A builtin type that has not been
-// covered by any other #define. Defining this macro covers all
-// the builtins.
-//
-// SIGNED_TYPE(Id, SingletonId) - A signed integral type.
-//
-// UNSIGNED_TYPE(Id, SingletonId) - An unsigned integral type.
-//
-// FLOATING_TYPE(Id, SingletonId) - A floating-point type.
-//
-// PLACEHOLDER_TYPE(Id, SingletonId) - A placeholder type. Placeholder
-// types are used to perform context-sensitive checking of specific
-// forms of expression.
-//
-// SHARED_SINGLETON_TYPE(Expansion) - The given expansion corresponds
-// to a builtin which uses a shared singleton type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SIGNED_TYPE
-#define SIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef UNSIGNED_TYPE
-#define UNSIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef FLOATING_TYPE
-#define FLOATING_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef PLACEHOLDER_TYPE
-#define PLACEHOLDER_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef SHARED_SINGLETON_TYPE
-#define SHARED_SINGLETON_TYPE(Expansion) Expansion
-#endif
-
-//===- Builtin Types ------------------------------------------------------===//
-
-// void
-BUILTIN_TYPE(Void, VoidTy)
-
-//===- Unsigned Types -----------------------------------------------------===//
-
-// 'bool' in C++, '_Bool' in C99
-UNSIGNED_TYPE(Bool, BoolTy)
-
-// 'char' for targets where it's unsigned
-SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(Char_U, CharTy))
-
-// 'unsigned char', explicitly qualified
-UNSIGNED_TYPE(UChar, UnsignedCharTy)
-
-// 'wchar_t' for targets where it's unsigned
-SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
-
-// 'char16_t' in C++
-UNSIGNED_TYPE(Char16, Char16Ty)
-
-// 'char32_t' in C++
-UNSIGNED_TYPE(Char32, Char32Ty)
-
-// 'unsigned short'
-UNSIGNED_TYPE(UShort, UnsignedShortTy)
-
-// 'unsigned int'
-UNSIGNED_TYPE(UInt, UnsignedIntTy)
-
-// 'unsigned long'
-UNSIGNED_TYPE(ULong, UnsignedLongTy)
-
-// 'unsigned long long'
-UNSIGNED_TYPE(ULongLong, UnsignedLongLongTy)
-
-// '__uint128_t'
-UNSIGNED_TYPE(UInt128, UnsignedInt128Ty)
-
-//===- Signed Types -------------------------------------------------------===//
-
-// 'char' for targets where it's signed
-SHARED_SINGLETON_TYPE(SIGNED_TYPE(Char_S, CharTy))
-
-// 'signed char', explicitly qualified
-SIGNED_TYPE(SChar, SignedCharTy)
-
-// 'wchar_t' for targets where it's signed
-SHARED_SINGLETON_TYPE(SIGNED_TYPE(WChar_S, WCharTy))
-
-// 'short' or 'signed short'
-SIGNED_TYPE(Short, ShortTy)
-
-// 'int' or 'signed int'
-SIGNED_TYPE(Int, IntTy)
-
-// 'long' or 'signed long'
-SIGNED_TYPE(Long, LongTy)
-
-// 'long long' or 'signed long long'
-SIGNED_TYPE(LongLong, LongLongTy)
-
-// '__int128_t'
-SIGNED_TYPE(Int128, Int128Ty)
-
-//===- Floating point types -----------------------------------------------===//
-
-// 'half' in OpenCL, '__fp16' in ARM NEON.
-FLOATING_TYPE(Half, HalfTy)
-
-// 'float'
-FLOATING_TYPE(Float, FloatTy)
-
-// 'double'
-FLOATING_TYPE(Double, DoubleTy)
-
-// 'long double'
-FLOATING_TYPE(LongDouble, LongDoubleTy)
-
-//===- Language-specific types --------------------------------------------===//
-
-// This is the type of C++0x 'nullptr'.
-BUILTIN_TYPE(NullPtr, NullPtrTy)
-
-// The primitive Objective C 'id' type. The user-visible 'id'
-// type is a typedef of an ObjCObjectPointerType to an
-// ObjCObjectType with this as its base. In fact, this only ever
-// shows up in an AST as the base type of an ObjCObjectType.
-BUILTIN_TYPE(ObjCId, ObjCBuiltinIdTy)
-
-// The primitive Objective C 'Class' type. The user-visible
-// 'Class' type is a typedef of an ObjCObjectPointerType to an
-// ObjCObjectType with this as its base. In fact, this only ever
-// shows up in an AST as the base type of an ObjCObjectType.
-BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy)
-
-// The primitive Objective C 'SEL' type. The user-visible 'SEL'
-// type is a typedef of a PointerType to this.
-BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy)
-
-// OpenCL image types.
-BUILTIN_TYPE(OCLImage1d, OCLImage1dTy)
-BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy)
-BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy)
-BUILTIN_TYPE(OCLImage2d, OCLImage2dTy)
-BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy)
-BUILTIN_TYPE(OCLImage2dDepth, OCLImage2dDepthTy)
-BUILTIN_TYPE(OCLImage2dArrayDepth, OCLImage2dArrayDepthTy)
-BUILTIN_TYPE(OCLImage2dMSAA, OCLImage2dMSAATy)
-BUILTIN_TYPE(OCLImage2dArrayMSAA, OCLImage2dArrayMSAATy)
-BUILTIN_TYPE(OCLImage2dMSAADepth, OCLImage2dMSAADepthTy)
-BUILTIN_TYPE(OCLImage2dArrayMSAADepth, OCLImage2dArrayMSAADepthTy)
-BUILTIN_TYPE(OCLImage3d, OCLImage3dTy)
-
-// OpenCL sampler_t.
-BUILTIN_TYPE(OCLSampler, OCLSamplerTy)
-
-// OpenCL event_t.
-BUILTIN_TYPE(OCLEvent, OCLEventTy)
-
-// OpenCL clk_event_t.
-BUILTIN_TYPE(OCLClkEvent, OCLClkEventTy)
-
-// OpenCL queue_t.
-BUILTIN_TYPE(OCLQueue, OCLQueueTy)
-
-// OpenCL ndrange_t.
-BUILTIN_TYPE(OCLNDRange, OCLNDRangeTy)
-
-// OpenCL reserve_id_t.
-BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy)
-
-// This represents the type of an expression whose type is
-// totally unknown, e.g. 'T::foo'. It is permitted for this to
-// appear in situations where the structure of the type is
-// theoretically deducible.
-BUILTIN_TYPE(Dependent, DependentTy)
-
-// The type of an unresolved overload set. A placeholder type.
-// Expressions with this type have one of the following basic
-// forms, with parentheses generally permitted:
-// foo # possibly qualified, not if an implicit access
-// foo # possibly qualified, not if an implicit access
-// &foo # possibly qualified, not if an implicit access
-// x->foo # only if might be a static member function
-// &x->foo # only if might be a static member function
-// &Class::foo # when a pointer-to-member; sub-expr also has this type
-// OverloadExpr::find can be used to analyze the expression.
-//
-// Overload should be the first placeholder type, or else change
-// BuiltinType::isNonOverloadPlaceholderType()
-PLACEHOLDER_TYPE(Overload, OverloadTy)
-
-// The type of a bound C++ non-static member function.
-// A placeholder type. Expressions with this type have one of the
-// following basic forms:
-// foo # if an implicit access
-// x->foo # if only contains non-static members
-PLACEHOLDER_TYPE(BoundMember, BoundMemberTy)
-
-// The type of an expression which refers to a pseudo-object,
-// such as those introduced by Objective C's @property or
-// VS.NET's __property declarations. A placeholder type. The
-// pseudo-object is actually accessed by emitting a call to
-// some sort of function or method; typically there is a pair
-// of a setter and a getter, with the setter used if the
-// pseudo-object reference is used syntactically as the
-// left-hand-side of an assignment operator.
-//
-// A pseudo-object reference naming an Objective-C @property is
-// always a dot access with a base of object-pointer type,
-// e.g. 'x.foo'.
-//
-// In VS.NET, a __property declaration creates an implicit
-// member with an associated name, which can then be named
-// in any of the normal ways an ordinary member could be.
-PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy)
-
-// __builtin_any_type. A placeholder type. Useful for clients
-// like debuggers that don't know what type to give something.
-// Only a small number of operations are valid on expressions of
-// unknown type, most notably explicit casts.
-PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy)
-
-PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy)
-
-// The type of a cast which, in ARC, would normally require a
-// __bridge, but which might be okay depending on the immediate
-// context.
-PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
-
-// A placeholder type for OpenMP array sections.
-PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy)
-
-#ifdef LAST_BUILTIN_TYPE
-LAST_BUILTIN_TYPE(OMPArraySection)
-#undef LAST_BUILTIN_TYPE
-#endif
-
-#undef SHARED_SINGLETON_TYPE
-#undef PLACEHOLDER_TYPE
-#undef FLOATING_TYPE
-#undef SIGNED_TYPE
-#undef UNSIGNED_TYPE
-#undef BUILTIN_TYPE
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
deleted file mode 100644
index 260734f..0000000
--- a/include/clang/AST/CMakeLists.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-clang_tablegen(Attrs.inc -gen-clang-attr-classes
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrClasses)
-
-clang_tablegen(AttrImpl.inc -gen-clang-attr-impl
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrImpl)
-
-clang_tablegen(AttrDump.inc -gen-clang-attr-dump
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrDump)
-
-clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrVisitor)
-
-clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes
- SOURCE ../Basic/StmtNodes.td
- TARGET ClangStmtNodes)
-
-clang_tablegen(DeclNodes.inc -gen-clang-decl-nodes
- SOURCE ../Basic/DeclNodes.td
- TARGET ClangDeclNodes)
-
-clang_tablegen(CommentNodes.inc -gen-clang-comment-nodes
- SOURCE ../Basic/CommentNodes.td
- TARGET ClangCommentNodes)
-
-clang_tablegen(CommentHTMLTags.inc -gen-clang-comment-html-tags
- SOURCE CommentHTMLTags.td
- TARGET ClangCommentHTMLTags)
-
-clang_tablegen(CommentHTMLTagsProperties.inc -gen-clang-comment-html-tags-properties
- SOURCE CommentHTMLTags.td
- TARGET ClangCommentHTMLTagsProperties)
-
-clang_tablegen(CommentHTMLNamedCharacterReferences.inc -gen-clang-comment-html-named-character-references
- SOURCE CommentHTMLNamedCharacterReferences.td
- TARGET ClangCommentHTMLNamedCharacterReferences)
-
-clang_tablegen(CommentCommandInfo.inc -gen-clang-comment-command-info
- SOURCE CommentCommands.td
- TARGET ClangCommentCommandInfo)
-
-clang_tablegen(CommentCommandList.inc -gen-clang-comment-command-list
- SOURCE CommentCommands.td
- TARGET ClangCommentCommandList)
-
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
deleted file mode 100644
index 8587260..0000000
--- a/include/clang/AST/CXXInheritance.h
+++ /dev/null
@@ -1,365 +0,0 @@
-//===------ CXXInheritance.h - C++ Inheritance ------------------*- 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 routines that help analyzing C++ inheritance hierarchies.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_CXXINHERITANCE_H
-#define LLVM_CLANG_AST_CXXINHERITANCE_H
-
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeOrdering.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-#include <list>
-#include <map>
-
-namespace clang {
-
-class CXXBaseSpecifier;
-class CXXMethodDecl;
-class CXXRecordDecl;
-class NamedDecl;
-
-/// \brief Represents an element in a path from a derived class to a
-/// base class.
-///
-/// Each step in the path references the link from a
-/// derived class to one of its direct base classes, along with a
-/// 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
- /// 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.
- const CXXRecordDecl *Class;
-
- /// \brief 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
- /// is no base numbering for the zero or one virtual bases of a
- /// given type.
- int SubobjectNumber;
-};
-
-/// \brief 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.
-///
-/// Individual elements in the path are described by the \c CXXBasePathElement
-/// structure, which captures both the link from a derived class to one of its
-/// direct bases and identification describing which base class
-/// subobject is being used.
-class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
-public:
- CXXBasePath() : Access(AS_public) {}
-
- /// \brief 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;
-
- /// \brief The set of declarations found inside this base class
- /// subobject.
- DeclContext::lookup_result Decls;
-
- void clear() {
- SmallVectorImpl<CXXBasePathElement>::clear();
- Access = AS_public;
- }
-};
-
-/// BasePaths - Represents the set of paths from a derived class to
-/// one of its (direct or indirect) bases. For example, given the
-/// following class hierarchy:
-///
-/// @code
-/// class A { };
-/// class B : public A { };
-/// class C : public A { };
-/// class D : public B, public C{ };
-/// @endcode
-///
-/// There are two potential BasePaths to represent paths from D to a
-/// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0)
-/// and another is (D,0)->(C,0)->(A,1). These two paths actually
-/// refer to two different base class subobjects of the same type,
-/// so the BasePaths object refers to an ambiguous path. On the
-/// other hand, consider the following class hierarchy:
-///
-/// @code
-/// class A { };
-/// class B : public virtual A { };
-/// class C : public virtual A { };
-/// class D : public B, public C{ };
-/// @endcode
-///
-/// Here, there are two potential BasePaths again, (D, 0) -> (B, 0)
-/// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them
-/// refer to the same base class subobject of type A (the virtual
-/// one), there is no ambiguity.
-class CXXBasePaths {
- /// \brief The type from which this search originated.
- CXXRecordDecl *Origin;
-
- /// 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
- /// whether we found a path to a virtual base for that class type,
- /// while the element 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;
-
- /// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
- /// ambiguous paths while it is looking for a path from a derived
- /// type to a base type.
- bool FindAmbiguities;
-
- /// RecordPaths - Whether Sema::IsDerivedFrom should record paths
- /// while it is determining whether there are paths from a derived
- /// type to a base type.
- bool RecordPaths;
-
- /// DetectVirtual - Whether Sema::IsDerivedFrom should abort the search
- /// 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;
-
- /// \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;
-
- friend class CXXRecordDecl;
-
- void ComputeDeclsFound();
-
- bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
- CXXRecordDecl::BaseMatchesCallback BaseMatches);
-
-public:
- typedef std::list<CXXBasePath>::iterator paths_iterator;
- typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
- typedef NamedDecl **decl_iterator;
-
- /// BasePaths - Construct a new BasePaths structure to record the
- /// paths for a derived-to-base search.
- explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
- bool DetectVirtual = true)
- : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
- DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
- NumDeclsFound(0) {}
-
- paths_iterator begin() { return Paths.begin(); }
- paths_iterator end() { return Paths.end(); }
- const_paths_iterator begin() const { return Paths.begin(); }
- const_paths_iterator end() const { return Paths.end(); }
-
- CXXBasePath& front() { return Paths.front(); }
- const CXXBasePath& front() const { return Paths.front(); }
-
- typedef llvm::iterator_range<decl_iterator> decl_range;
- decl_range found_decls();
-
- /// \brief Determine whether the path from the most-derived type to the
- /// given base type is ambiguous (i.e., it refers to multiple subobjects of
- /// the same base type).
- bool isAmbiguous(CanQualType BaseType);
-
- /// \brief Whether we are finding multiple paths to detect ambiguities.
- bool isFindingAmbiguities() const { return FindAmbiguities; }
-
- /// \brief Whether we are recording paths.
- bool isRecordingPaths() const { return RecordPaths; }
-
- /// \brief Specify whether we should be recording paths or not.
- void setRecordingPaths(bool RP) { RecordPaths = RP; }
-
- /// \brief Whether we are detecting virtual bases.
- bool isDetectingVirtual() const { return DetectVirtual; }
-
- /// \brief 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
- /// began
- CXXRecordDecl *getOrigin() const { return Origin; }
- void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; }
-
- /// \brief Clear the base-paths results.
- void clear();
-
- /// \brief Swap this data structure's contents with another CXXBasePaths
- /// object.
- void swap(CXXBasePaths &Other);
-};
-
-/// \brief Uniquely identifies a virtual method within a class
-/// hierarchy by the method itself and a class subobject number.
-struct UniqueVirtualMethod {
- UniqueVirtualMethod()
- : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
-
- UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
- const CXXRecordDecl *InVirtualSubobject)
- : Method(Method), Subobject(Subobject),
- InVirtualSubobject(InVirtualSubobject) { }
-
- /// \brief The overriding virtual method.
- CXXMethodDecl *Method;
-
- /// \brief The subobject in which the overriding virtual method
- /// resides.
- unsigned Subobject;
-
- /// \brief 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;
-
- friend bool operator==(const UniqueVirtualMethod &X,
- const UniqueVirtualMethod &Y) {
- return X.Method == Y.Method && X.Subobject == Y.Subobject &&
- X.InVirtualSubobject == Y.InVirtualSubobject;
- }
-
- friend bool operator!=(const UniqueVirtualMethod &X,
- const UniqueVirtualMethod &Y) {
- return !(X == Y);
- }
-};
-
-/// \brief 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
-/// overridden virtual function occurs, while the second part of the
-/// pair is the virtual method that overrides it (including the
-/// subobject in which that virtual function occurs).
-class OverridingMethods {
- typedef SmallVector<UniqueVirtualMethod, 4> ValuesT;
- typedef llvm::MapVector<unsigned, ValuesT> MapType;
- MapType Overrides;
-
-public:
- // Iterate over the set of subobjects that have overriding methods.
- typedef MapType::iterator iterator;
- typedef MapType::const_iterator const_iterator;
- iterator begin() { return Overrides.begin(); }
- const_iterator begin() const { return Overrides.begin(); }
- iterator end() { return Overrides.end(); }
- const_iterator end() const { return Overrides.end(); }
- unsigned size() const { return Overrides.size(); }
-
- // Iterate over the set of overriding virtual methods in a given
- // subobject.
- typedef SmallVectorImpl<UniqueVirtualMethod>::iterator
- overriding_iterator;
- typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator
- overriding_const_iterator;
-
- // Add a new overriding method for a particular subobject.
- void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
-
- // Add all of the overriding methods from "other" into overrides for
- // this method. Used when merging the overrides from multiple base
- // class subobjects.
- void add(const OverridingMethods &Other);
-
- // Replace all overriding virtual methods in all subobjects with the
- // given virtual method.
- void replaceAll(UniqueVirtualMethod Overriding);
-};
-
-/// \brief A mapping from each virtual member function to its set of
-/// final overriders.
-///
-/// Within a class hierarchy for a given derived class, each virtual
-/// member function in that hierarchy has one or more "final
-/// overriders" (C++ [class.virtual]p2). A final overrider for a
-/// virtual function "f" is the virtual function that will actually be
-/// invoked when dispatching a call to "f" through the
-/// vtable. Well-formed classes have a single final overrider for each
-/// virtual function; in abstract classes, the final overrider for at
-/// least one virtual function is a pure virtual function. Due to
-/// multiple, virtual inheritance, it is possible for a class to have
-/// more than one final overrider. Athough this is an error (per C++
-/// [class.virtual]p2), it is not considered an error here: the final
-/// overrider map can represent multiple final overriders for a
-/// method, and it is up to the client to determine whether they are
-/// problem. For example, the following class \c D has two final
-/// overriders for the virtual function \c A::f(), one in \c C and one
-/// in \c D:
-///
-/// \code
-/// struct A { virtual void f(); };
-/// struct B : virtual A { virtual void f(); };
-/// struct C : virtual A { virtual void f(); };
-/// struct D : B, C { };
-/// \endcode
-///
-/// This data structure contains a mapping from every virtual
-/// function *that does not override an existing virtual function* and
-/// in every subobject where that virtual function occurs to the set
-/// of virtual functions that override it. Thus, the same virtual
-/// function \c A::f can actually occur in multiple subobjects of type
-/// \c A due to multiple inheritance, and may be overridden by
-/// different virtual functions in each, as in the following example:
-///
-/// \code
-/// struct A { virtual void f(); };
-/// struct B : A { virtual void f(); };
-/// struct C : A { virtual void f(); };
-/// struct D : B, C { };
-/// \endcode
-///
-/// Unlike in the previous example, where the virtual functions \c
-/// B::f and \c C::f both overrode \c A::f in the same subobject of
-/// type \c A, in this example the two virtual functions both override
-/// \c A::f but in *different* subobjects of type A. This is
-/// represented by numbering the subobjects in which the overridden
-/// and the overriding virtual member functions are located. Subobject
-/// 0 represents the virtual base class subobject of that type, while
-/// subobject numbers greater than 0 refer to non-virtual base class
-/// subobjects of that type.
-class CXXFinalOverriderMap
- : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { };
-
-/// \brief A set of all the primary bases for a class.
-class CXXIndirectPrimaryBaseSet
- : public llvm::SmallSet<const CXXRecordDecl*, 32> { };
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
deleted file mode 100644
index b25800b..0000000
--- a/include/clang/AST/CanonicalType.h
+++ /dev/null
@@ -1,665 +0,0 @@
-//===-- CanonicalType.h - C Language Family Type Representation -*- 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 CanQual class template, which provides access to
-// canonical types.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_CANONICALTYPE_H
-#define LLVM_CLANG_AST_CANONICALTYPE_H
-
-#include "clang/AST/Type.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Support/Casting.h"
-
-namespace clang {
-
-template<typename T> class CanProxy;
-template<typename T> struct CanProxyAdaptor;
-
-//----------------------------------------------------------------------------//
-// Canonical, qualified type template
-//----------------------------------------------------------------------------//
-
-/// \brief 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
-/// syntactic sugar has been eliminated. A CanQualType may also have various
-/// qualifiers (const, volatile, restrict) attached to it.
-///
-/// The template type parameter @p T is one of the Type classes (PointerType,
-/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
-/// type (or some subclass of that type). The typedef @c CanQualType is just
-/// a shorthand for @c CanQual<Type>.
-///
-/// An instance of @c CanQual<T> can be implicitly converted to a
-/// @c CanQual<U> when T is derived from U, which essentially provides an
-/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
-/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
-/// be implicitly converted to a QualType, but the reverse operation requires
-/// a call to ASTContext::getCanonicalType().
-///
-///
-template<typename T = Type>
-class CanQual {
- /// \brief The actual, canonical type.
- QualType Stored;
-
-public:
- /// \brief Constructs a NULL canonical type.
- CanQual() : Stored() { }
-
- /// \brief 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
- /// canonical type.
- ///
- /// The underlying pointer must not be NULL.
- const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
-
- /// \brief Retrieve the underlying type pointer, which refers to a
- /// canonical type, or NULL.
- ///
- const T *getTypePtrOrNull() const {
- return cast_or_null<T>(Stored.getTypePtrOrNull());
- }
-
- /// \brief Implicit conversion to a qualified type.
- operator QualType() const { return Stored; }
-
- /// \brief Implicit conversion to bool.
- explicit operator bool() const { return !isNull(); }
-
- bool isNull() const {
- return Stored.isNull();
- }
-
- SplitQualType split() const { return Stored.split(); }
-
- /// \brief 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
- /// more specific (canonical) type in the type system. For example:
- ///
- /// @code
- /// void f(CanQual<Type> T) {
- /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
- /// // look at Ptr's pointee type
- /// }
- /// }
- /// @endcode
- ///
- /// \returns A proxy pointer to the same type, but with the specified
- /// static type (@p U). If the dynamic type is not the specified static type
- /// or a derived class thereof, a NULL canonical type.
- template<typename U> CanProxy<U> getAs() const;
-
- template<typename U> CanProxy<U> castAs() const;
-
- /// \brief Overloaded arrow operator that produces a canonical type
- /// proxy.
- CanProxy<T> operator->() const;
-
- /// \brief Retrieve all qualifiers.
- Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
-
- /// \brief Retrieve the const/volatile/restrict qualifiers.
- unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
-
- /// \brief Determines whether this type has any qualifiers
- bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
-
- bool isConstQualified() const {
- return Stored.isLocalConstQualified();
- }
- bool isVolatileQualified() const {
- return Stored.isLocalVolatileQualified();
- }
- bool isRestrictQualified() const {
- return Stored.isLocalRestrictQualified();
- }
-
- /// \brief 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.
- CanQual<T> getUnqualifiedType() const;
-
- /// \brief 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
- /// 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
- /// 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
- /// it refers to; otherwise, returns the type itself.
- CanQual<Type> getNonReferenceType() const;
-
- /// \brief Retrieve the internal representation of this canonical type.
- void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
-
- /// \brief Construct a canonical type from its internal representation.
- static CanQual<T> getFromOpaquePtr(void *Ptr);
-
- /// \brief 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
- // (dynamic) type.
- static CanQual<T> CreateUnsafe(QualType Other);
-
- void dump() const { Stored.dump(); }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddPointer(getAsOpaquePtr());
- }
-};
-
-template<typename T, typename U>
-inline bool operator==(CanQual<T> x, CanQual<U> y) {
- return x.getAsOpaquePtr() == y.getAsOpaquePtr();
-}
-
-template<typename T, typename U>
-inline bool operator!=(CanQual<T> x, CanQual<U> y) {
- return x.getAsOpaquePtr() != y.getAsOpaquePtr();
-}
-
-/// \brief Represents a canonical, potentially-qualified type.
-typedef CanQual<Type> CanQualType;
-
-inline CanQualType Type::getCanonicalTypeUnqualified() const {
- return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- CanQualType T) {
- DB << static_cast<QualType>(T);
- return DB;
-}
-
-//----------------------------------------------------------------------------//
-// Internal proxy classes used by canonical types
-//----------------------------------------------------------------------------//
-
-#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor) \
-CanQualType Accessor() const { \
-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
-/// storing the underlying canonical type and providing basic conversions.
-template<typename T>
-class CanProxyBase {
-protected:
- CanQual<T> Stored;
-
-public:
- /// \brief Retrieve the pointer to the underlying Type
- const T *getTypePtr() const { return Stored.getTypePtr(); }
-
- /// \brief Implicit conversion to the underlying pointer.
- ///
- /// Also provides the ability to use canonical type proxies in a Boolean
- // context,e.g.,
- /// @code
- /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
- /// @endcode
- operator const T*() const { return this->Stored.getTypePtrOrNull(); }
-
- /// \brief 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>();
- }
-
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
-
- // Type predicates
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
-
- /// \brief 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
- /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
- /// by the arrow operator in the primary CanProxyAdaptor template.
- const CanProxyAdaptor<T> *operator->() const {
- return static_cast<const CanProxyAdaptor<T> *>(this);
- }
-};
-
-/// \brief Replacable 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
-/// as part of each canonical proxy type. The primary template merely provides
-/// redirection to the underlying type (T), e.g., @c PointerType. One can
-/// provide specializations of this class template for each underlying type
-/// that provide accessors returning canonical types (@c CanQualType) rather
-/// than the more typical @c QualType, to propagate the notion of "canonical"
-/// through the system.
-template<typename T>
-struct CanProxyAdaptor : CanProxyBase<T> { };
-
-/// \brief Canonical proxy type returned when retrieving the members of a
-/// canonical type or as the result of the @c CanQual<T>::getAs member
-/// function.
-///
-/// The CanProxy type mainly exists as a proxy through which operator-> will
-/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
-/// type that provides canonical-type access to the fields of the type.
-template<typename T>
-class CanProxy : public CanProxyAdaptor<T> {
-public:
- /// \brief Build a NULL proxy.
- CanProxy() { }
-
- /// \brief Build a proxy to the given canonical type.
- CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
-
- /// \brief Implicit conversion to the stored canonical type.
- operator CanQual<T>() const { return this->Stored; }
-};
-
-} // end namespace clang
-
-namespace llvm {
-
-/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
-/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
-/// to return smart pointer (proxies?).
-template<typename T>
-struct simplify_type< ::clang::CanQual<T> > {
- typedef const T *SimpleType;
- static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
- return Val.getTypePtr();
- }
-};
-
-// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
-template<typename T>
-class PointerLikeTypeTraits<clang::CanQual<T> > {
-public:
- static inline void *getAsVoidPointer(clang::CanQual<T> P) {
- return P.getAsOpaquePtr();
- }
- static inline clang::CanQual<T> getFromVoidPointer(void *P) {
- return clang::CanQual<T>::getFromOpaquePtr(P);
- }
- // qualifier information is encoded in the low bits.
- enum { NumLowBitsAvailable = 0 };
-};
-
-} // end namespace llvm
-
-namespace clang {
-
-//----------------------------------------------------------------------------//
-// Canonical proxy adaptors for canonical type nodes.
-//----------------------------------------------------------------------------//
-
-/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
-/// into an iterator over CanQualTypes.
-template <typename InputIterator>
-struct CanTypeIterator
- : llvm::iterator_adaptor_base<
- CanTypeIterator<InputIterator>, InputIterator,
- typename std::iterator_traits<InputIterator>::iterator_category,
- CanQualType,
- typename std::iterator_traits<InputIterator>::difference_type,
- CanProxy<Type>, CanQualType> {
- CanTypeIterator() {}
- explicit CanTypeIterator(InputIterator Iter)
- : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
-
- CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); }
- CanProxy<Type> operator->() const;
-};
-
-template<>
-struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
-};
-
-template<>
-struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<BlockPointerType>
- : public CanProxyBase<BlockPointerType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<LValueReferenceType>
- : public CanProxyBase<LValueReferenceType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<RValueReferenceType>
- : public CanProxyBase<RValueReferenceType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<MemberPointerType>
- : public CanProxyBase<MemberPointerType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
-};
-
-// CanProxyAdaptors for arrays are intentionally unimplemented because
-// they are not safe.
-template<> struct CanProxyAdaptor<ArrayType>;
-template<> struct CanProxyAdaptor<ConstantArrayType>;
-template<> struct CanProxyAdaptor<IncompleteArrayType>;
-template<> struct CanProxyAdaptor<VariableArrayType>;
-template<> struct CanProxyAdaptor<DependentSizedArrayType>;
-
-template<>
-struct CanProxyAdaptor<DependentSizedExtVectorType>
- : public CanProxyBase<DependentSizedExtVectorType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
-};
-
-template<>
-struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
-};
-
-template<>
-struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
-};
-
-template<>
-struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
-};
-
-template<>
-struct CanProxyAdaptor<FunctionNoProtoType>
- : public CanProxyBase<FunctionNoProtoType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
-};
-
-template<>
-struct CanProxyAdaptor<FunctionProtoType>
- : public CanProxyBase<FunctionProtoType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
- CanQualType getParamType(unsigned i) const {
- return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
- }
-
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
-
- typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
- param_type_iterator;
-
- param_type_iterator param_type_begin() const {
- return param_type_iterator(this->getTypePtr()->param_type_begin());
- }
-
- param_type_iterator param_type_end() const {
- return param_type_iterator(this->getTypePtr()->param_type_end());
- }
-
- // Note: canonical function types never have exception specifications
-};
-
-template<>
-struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
-};
-
-template<>
-struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
-};
-
-template <>
-struct CanProxyAdaptor<UnaryTransformType>
- : public CanProxyBase<UnaryTransformType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
-};
-
-template<>
-struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
-};
-
-template<>
-struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
-};
-
-template<>
-struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
-};
-
-template<>
-struct CanProxyAdaptor<TemplateTypeParmType>
- : public CanProxyBase<TemplateTypeParmType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
-};
-
-template<>
-struct CanProxyAdaptor<ObjCObjectType>
- : public CanProxyBase<ObjCObjectType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
- getInterface)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
-
- typedef ObjCObjectPointerType::qual_iterator qual_iterator;
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
-};
-
-template<>
-struct CanProxyAdaptor<ObjCObjectPointerType>
- : public CanProxyBase<ObjCObjectPointerType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
- getInterfaceType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
-
- typedef ObjCObjectPointerType::qual_iterator qual_iterator;
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
-};
-
-//----------------------------------------------------------------------------//
-// Method and function definitions
-//----------------------------------------------------------------------------//
-template<typename T>
-inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
- return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
-}
-
-template<typename T>
-inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
- if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
- return RefType->getPointeeType();
- else
- return *this;
-}
-
-template<typename T>
-CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
- CanQual<T> Result;
- Result.Stored = QualType::getFromOpaquePtr(Ptr);
- assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
- Result.Stored.isCanonical()) && "Type is not canonical!");
- return Result;
-}
-
-template<typename T>
-CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
- assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
- assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
- "Dynamic type does not meet the static type's requires");
- CanQual<T> Result;
- Result.Stored = Other;
- return Result;
-}
-
-template<typename T>
-template<typename U>
-CanProxy<U> CanQual<T>::getAs() const {
- ArrayType_cannot_be_used_with_getAs<U> at;
- (void)at;
-
- if (Stored.isNull())
- return CanProxy<U>();
-
- if (isa<U>(Stored.getTypePtr()))
- return CanQual<U>::CreateUnsafe(Stored);
-
- return CanProxy<U>();
-}
-
-template<typename T>
-template<typename U>
-CanProxy<U> CanQual<T>::castAs() const {
- ArrayType_cannot_be_used_with_getAs<U> at;
- (void)at;
-
- assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
- return CanQual<U>::CreateUnsafe(Stored);
-}
-
-template<typename T>
-CanProxy<T> CanQual<T>::operator->() const {
- return CanProxy<T>(*this);
-}
-
-template <typename InputIterator>
-CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const {
- return CanProxy<Type>(*this);
-}
-
-}
-
-
-#endif
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
deleted file mode 100644
index 1d22bcc..0000000
--- a/include/clang/AST/CharUnits.h
+++ /dev/null
@@ -1,240 +0,0 @@
-//===--- CharUnits.h - Character units for sizes and offsets ----*- 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 CharUnits class
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_CHARUNITS_H
-#define LLVM_CLANG_AST_CHARUNITS_H
-
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/MathExtras.h"
-
-namespace clang {
-
- /// CharUnits - This is an opaque type for sizes expressed in character units.
- /// Instances of this type represent a quantity as a multiple of the size
- /// of the standard C type, char, on the target architecture. As an opaque
- /// type, CharUnits protects you from accidentally combining operations on
- /// quantities in bit units and character units.
- ///
- /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
- /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
- /// the same quantity of storage. However, we use the term 'character unit'
- /// rather than 'byte' to avoid an implication that a character unit is
- /// exactly 8 bits.
- ///
- /// For portability, never assume that a target character is 8 bits wide. Use
- /// CharUnit values wherever you calculate sizes, offsets, or alignments
- /// in character units.
- class CharUnits {
- public:
- typedef int64_t QuantityType;
-
- private:
- QuantityType Quantity;
-
- explicit CharUnits(QuantityType C) : Quantity(C) {}
-
- public:
-
- /// CharUnits - A default constructor.
- CharUnits() : Quantity(0) {}
-
- /// Zero - Construct a CharUnits quantity of zero.
- static CharUnits Zero() {
- return CharUnits(0);
- }
-
- /// One - Construct a CharUnits quantity of one.
- static CharUnits One() {
- return CharUnits(1);
- }
-
- /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
- static CharUnits fromQuantity(QuantityType Quantity) {
- return CharUnits(Quantity);
- }
-
- // Compound assignment.
- CharUnits& operator+= (const CharUnits &Other) {
- Quantity += Other.Quantity;
- return *this;
- }
- CharUnits& operator++ () {
- ++Quantity;
- return *this;
- }
- CharUnits operator++ (int) {
- return CharUnits(Quantity++);
- }
- CharUnits& operator-= (const CharUnits &Other) {
- Quantity -= Other.Quantity;
- return *this;
- }
- CharUnits& operator-- () {
- --Quantity;
- return *this;
- }
- CharUnits operator-- (int) {
- return CharUnits(Quantity--);
- }
-
- // Comparison operators.
- bool operator== (const CharUnits &Other) const {
- return Quantity == Other.Quantity;
- }
- bool operator!= (const CharUnits &Other) const {
- return Quantity != Other.Quantity;
- }
-
- // Relational operators.
- bool operator< (const CharUnits &Other) const {
- return Quantity < Other.Quantity;
- }
- bool operator<= (const CharUnits &Other) const {
- return Quantity <= Other.Quantity;
- }
- bool operator> (const CharUnits &Other) const {
- return Quantity > Other.Quantity;
- }
- bool operator>= (const CharUnits &Other) const {
- return Quantity >= Other.Quantity;
- }
-
- // Other predicates.
-
- /// isZero - Test whether the quantity equals zero.
- bool isZero() const { return Quantity == 0; }
-
- /// isOne - Test whether the quantity equals one.
- bool isOne() const { return Quantity == 1; }
-
- /// isPositive - Test whether the quantity is greater than zero.
- bool isPositive() const { return Quantity > 0; }
-
- /// isNegative - Test whether the quantity is less than zero.
- bool isNegative() const { return Quantity < 0; }
-
- /// isPowerOfTwo - Test whether the quantity is a power of two.
- /// Zero is not a power of two.
- bool isPowerOfTwo() const {
- return (Quantity & -Quantity) == Quantity;
- }
-
- /// Test whether this is a multiple of the other value.
- ///
- /// Among other things, this promises that
- /// self.RoundUpToAlignment(N) will just return self.
- bool isMultipleOf(CharUnits N) const {
- return (*this % N) == 0;
- }
-
- // Arithmetic operators.
- CharUnits operator* (QuantityType N) const {
- return CharUnits(Quantity * N);
- }
- CharUnits operator/ (QuantityType N) const {
- return CharUnits(Quantity / N);
- }
- QuantityType operator/ (const CharUnits &Other) const {
- return Quantity / Other.Quantity;
- }
- CharUnits operator% (QuantityType N) const {
- return CharUnits(Quantity % N);
- }
- QuantityType operator% (const CharUnits &Other) const {
- return Quantity % Other.Quantity;
- }
- CharUnits operator+ (const CharUnits &Other) const {
- return CharUnits(Quantity + Other.Quantity);
- }
- CharUnits operator- (const CharUnits &Other) const {
- return CharUnits(Quantity - Other.Quantity);
- }
- CharUnits operator- () const {
- return CharUnits(-Quantity);
- }
-
-
- // Conversions.
-
- /// getQuantity - Get the raw integer representation of this quantity.
- QuantityType getQuantity() const { return Quantity; }
-
- /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
- /// greater than or equal to this quantity and is a multiple of \p Align.
- /// Align must be non-zero.
- CharUnits RoundUpToAlignment(const CharUnits &Align) const {
- return CharUnits(llvm::RoundUpToAlignment(Quantity,
- Align.Quantity));
- }
-
- /// Given that this is a non-zero alignment value, what is the
- /// alignment at the given offset?
- CharUnits alignmentAtOffset(CharUnits offset) const {
- assert(Quantity != 0 && "offsetting from unknown alignment?");
- return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
- }
-
- /// Given that this is the alignment of the first element of an
- /// array, return the minimum alignment of any element in the array.
- CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
- // Since we don't track offsetted alignments, the alignment of
- // the second element (or any odd element) will be minimally
- // aligned.
- return alignmentAtOffset(elementSize);
- }
-
-
- }; // class CharUnit
-} // namespace clang
-
-inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
- const clang::CharUnits &CU) {
- return CU * Scale;
-}
-
-namespace llvm {
-
-template<> struct DenseMapInfo<clang::CharUnits> {
- static clang::CharUnits getEmptyKey() {
- clang::CharUnits::QuantityType Quantity =
- DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
-
- return clang::CharUnits::fromQuantity(Quantity);
- }
-
- static clang::CharUnits getTombstoneKey() {
- clang::CharUnits::QuantityType Quantity =
- DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
-
- return clang::CharUnits::fromQuantity(Quantity);
- }
-
- static unsigned getHashValue(const clang::CharUnits &CU) {
- clang::CharUnits::QuantityType Quantity = CU.getQuantity();
- return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
- }
-
- static bool isEqual(const clang::CharUnits &LHS,
- const clang::CharUnits &RHS) {
- return LHS == RHS;
- }
-};
-
-template <> struct isPodLike<clang::CharUnits> {
- static const bool value = true;
-};
-
-} // end namespace llvm
-
-#endif // LLVM_CLANG_AST_CHARUNITS_H
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
deleted file mode 100644
index 94470cb..0000000
--- a/include/clang/AST/Comment.h
+++ /dev/null
@@ -1,1142 +0,0 @@
-//===--- Comment.h - Comment AST nodes --------------------------*- 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 comment AST nodes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENT_H
-#define LLVM_CLANG_AST_COMMENT_H
-
-#include "clang/AST/CommentCommandTraits.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-class Decl;
-class ParmVarDecl;
-class TemplateParameterList;
-
-namespace comments {
-class FullComment;
-
-/// Describes the syntax that was used in a documentation command.
-///
-/// Exact values of this enumeration are important because they used to select
-/// parts of diagnostic messages. Audit diagnostics before changing or adding
-/// a new value.
-enum CommandMarkerKind {
- /// Command started with a backslash character:
- /// \code
- /// \foo
- /// \endcode
- CMK_Backslash = 0,
-
- /// Command started with an 'at' character:
- /// \code
- /// @foo
- /// \endcode
- CMK_At = 1
-};
-
-/// Any part of the comment.
-/// Abstract class.
-class Comment {
-protected:
- /// Preferred location to show caret.
- SourceLocation Loc;
-
- /// Source range of this AST node.
- SourceRange Range;
-
- class CommentBitfields {
- friend class Comment;
-
- /// Type of this AST node.
- unsigned Kind : 8;
- };
- enum { NumCommentBits = 8 };
-
- class InlineContentCommentBitfields {
- friend class InlineContentComment;
-
- unsigned : NumCommentBits;
-
- /// True if there is a newline after this inline content node.
- /// (There is no separate AST node for a newline.)
- unsigned HasTrailingNewline : 1;
- };
- enum { NumInlineContentCommentBits = NumCommentBits + 1 };
-
- class TextCommentBitfields {
- friend class TextComment;
-
- unsigned : NumInlineContentCommentBits;
-
- /// True if \c IsWhitespace field contains a valid value.
- mutable unsigned IsWhitespaceValid : 1;
-
- /// True if this comment AST node contains only whitespace.
- mutable unsigned IsWhitespace : 1;
- };
- enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
-
- class InlineCommandCommentBitfields {
- friend class InlineCommandComment;
-
- unsigned : NumInlineContentCommentBits;
-
- unsigned RenderKind : 2;
- unsigned CommandID : CommandInfo::NumCommandIDBits;
- };
- enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 2 +
- CommandInfo::NumCommandIDBits };
-
- class HTMLTagCommentBitfields {
- friend class HTMLTagComment;
-
- unsigned : NumInlineContentCommentBits;
-
- /// True if we found that this tag is malformed in some way.
- unsigned IsMalformed : 1;
- };
- enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
-
- class HTMLStartTagCommentBitfields {
- friend class HTMLStartTagComment;
-
- unsigned : NumHTMLTagCommentBits;
-
- /// True if this tag is self-closing (e. g., <br />). This is based on tag
- /// spelling in comment (plain <br> would not set this flag).
- unsigned IsSelfClosing : 1;
- };
- enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
-
- class ParagraphCommentBitfields {
- friend class ParagraphComment;
-
- unsigned : NumCommentBits;
-
- /// True if \c IsWhitespace field contains a valid value.
- mutable unsigned IsWhitespaceValid : 1;
-
- /// True if this comment AST node contains only whitespace.
- mutable unsigned IsWhitespace : 1;
- };
- enum { NumParagraphCommentBits = NumCommentBits + 2 };
-
- class BlockCommandCommentBitfields {
- friend class BlockCommandComment;
-
- unsigned : NumCommentBits;
-
- unsigned CommandID : CommandInfo::NumCommandIDBits;
-
- /// Describes the syntax that was used in a documentation command.
- /// Contains values from CommandMarkerKind enum.
- unsigned CommandMarker : 1;
- };
- enum { NumBlockCommandCommentBits = NumCommentBits +
- CommandInfo::NumCommandIDBits + 1 };
-
- class ParamCommandCommentBitfields {
- friend class ParamCommandComment;
-
- unsigned : NumBlockCommandCommentBits;
-
- /// Parameter passing direction, see ParamCommandComment::PassDirection.
- unsigned Direction : 2;
-
- /// True if direction was specified explicitly in the comment.
- unsigned IsDirectionExplicit : 1;
- };
- enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
-
- union {
- CommentBitfields CommentBits;
- InlineContentCommentBitfields InlineContentCommentBits;
- TextCommentBitfields TextCommentBits;
- InlineCommandCommentBitfields InlineCommandCommentBits;
- HTMLTagCommentBitfields HTMLTagCommentBits;
- HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
- ParagraphCommentBitfields ParagraphCommentBits;
- BlockCommandCommentBitfields BlockCommandCommentBits;
- ParamCommandCommentBitfields ParamCommandCommentBits;
- };
-
- void setSourceRange(SourceRange SR) {
- Range = SR;
- }
-
- void setLocation(SourceLocation L) {
- Loc = L;
- }
-
-public:
- enum CommentKind {
- NoCommentKind = 0,
-#define COMMENT(CLASS, PARENT) CLASS##Kind,
-#define COMMENT_RANGE(BASE, FIRST, LAST) \
- First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind,
-#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
- First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind
-#define ABSTRACT_COMMENT(COMMENT)
-#include "clang/AST/CommentNodes.inc"
- };
-
- Comment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd) :
- Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
- CommentBits.Kind = K;
- }
-
- CommentKind getCommentKind() const {
- return static_cast<CommentKind>(CommentBits.Kind);
- }
-
- const char *getCommentKindName() const;
-
- void dump() const;
- void dumpColor() const;
- void dump(const ASTContext &Context) const;
- void dump(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM) const;
-
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return Range.getBegin();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- return Range.getEnd();
- }
-
- SourceLocation getLocation() const LLVM_READONLY { return Loc; }
-
- typedef Comment * const *child_iterator;
-
- child_iterator child_begin() const;
- child_iterator child_end() const;
-
- // TODO: const child iterator
-
- unsigned child_count() const {
- return child_end() - child_begin();
- }
-};
-
-/// Inline content (contained within a block).
-/// Abstract class.
-class InlineContentComment : public Comment {
-protected:
- InlineContentComment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd) :
- Comment(K, LocBegin, LocEnd) {
- InlineContentCommentBits.HasTrailingNewline = 0;
- }
-
-public:
- static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstInlineContentCommentConstant &&
- C->getCommentKind() <= LastInlineContentCommentConstant;
- }
-
- void addTrailingNewline() {
- InlineContentCommentBits.HasTrailingNewline = 1;
- }
-
- bool hasTrailingNewline() const {
- return InlineContentCommentBits.HasTrailingNewline;
- }
-};
-
-/// Plain text.
-class TextComment : public InlineContentComment {
- StringRef Text;
-
-public:
- TextComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef Text) :
- InlineContentComment(TextCommentKind, LocBegin, LocEnd),
- Text(Text) {
- TextCommentBits.IsWhitespaceValid = false;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == TextCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- StringRef getText() const LLVM_READONLY { return Text; }
-
- bool isWhitespace() const {
- if (TextCommentBits.IsWhitespaceValid)
- return TextCommentBits.IsWhitespace;
-
- TextCommentBits.IsWhitespace = isWhitespaceNoCache();
- TextCommentBits.IsWhitespaceValid = true;
- return TextCommentBits.IsWhitespace;
- }
-
-private:
- bool isWhitespaceNoCache() const;
-};
-
-/// A command with word-like arguments that is considered inline content.
-class InlineCommandComment : public InlineContentComment {
-public:
- struct Argument {
- SourceRange Range;
- StringRef Text;
-
- Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
- };
-
- /// The most appropriate rendering mode for this command, chosen on command
- /// semantics in Doxygen.
- enum RenderKind {
- RenderNormal,
- RenderBold,
- RenderMonospaced,
- RenderEmphasized
- };
-
-protected:
- /// Command arguments.
- ArrayRef<Argument> Args;
-
-public:
- InlineCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- RenderKind RK,
- ArrayRef<Argument> Args) :
- InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
- Args(Args) {
- InlineCommandCommentBits.RenderKind = RK;
- InlineCommandCommentBits.CommandID = CommandID;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == InlineCommandCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- unsigned getCommandID() const {
- return InlineCommandCommentBits.CommandID;
- }
-
- StringRef getCommandName(const CommandTraits &Traits) const {
- return Traits.getCommandInfo(getCommandID())->Name;
- }
-
- SourceRange getCommandNameRange() const {
- return SourceRange(getLocStart().getLocWithOffset(-1),
- getLocEnd());
- }
-
- RenderKind getRenderKind() const {
- return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
- }
-
- unsigned getNumArgs() const {
- return Args.size();
- }
-
- StringRef getArgText(unsigned Idx) const {
- return Args[Idx].Text;
- }
-
- SourceRange getArgRange(unsigned Idx) const {
- return Args[Idx].Range;
- }
-};
-
-/// Abstract class for opening and closing HTML tags. HTML tags are always
-/// treated as inline content (regardless HTML semantics).
-class HTMLTagComment : public InlineContentComment {
-protected:
- StringRef TagName;
- SourceRange TagNameRange;
-
- HTMLTagComment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef TagName,
- SourceLocation TagNameBegin,
- SourceLocation TagNameEnd) :
- InlineContentComment(K, LocBegin, LocEnd),
- TagName(TagName),
- TagNameRange(TagNameBegin, TagNameEnd) {
- setLocation(TagNameBegin);
- HTMLTagCommentBits.IsMalformed = 0;
- }
-
-public:
- static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
- C->getCommentKind() <= LastHTMLTagCommentConstant;
- }
-
- StringRef getTagName() const LLVM_READONLY { return TagName; }
-
- SourceRange getTagNameSourceRange() const LLVM_READONLY {
- SourceLocation L = getLocation();
- return SourceRange(L.getLocWithOffset(1),
- L.getLocWithOffset(1 + TagName.size()));
- }
-
- bool isMalformed() const {
- return HTMLTagCommentBits.IsMalformed;
- }
-
- void setIsMalformed() {
- HTMLTagCommentBits.IsMalformed = 1;
- }
-};
-
-/// An opening HTML tag with attributes.
-class HTMLStartTagComment : public HTMLTagComment {
-public:
- class Attribute {
- public:
- SourceLocation NameLocBegin;
- StringRef Name;
-
- SourceLocation EqualsLoc;
-
- SourceRange ValueRange;
- StringRef Value;
-
- Attribute() { }
-
- Attribute(SourceLocation NameLocBegin, StringRef Name) :
- NameLocBegin(NameLocBegin), Name(Name),
- EqualsLoc(SourceLocation()),
- ValueRange(SourceRange()), Value(StringRef())
- { }
-
- Attribute(SourceLocation NameLocBegin, StringRef Name,
- SourceLocation EqualsLoc,
- SourceRange ValueRange, StringRef Value) :
- NameLocBegin(NameLocBegin), Name(Name),
- EqualsLoc(EqualsLoc),
- ValueRange(ValueRange), Value(Value)
- { }
-
- SourceLocation getNameLocEnd() const {
- return NameLocBegin.getLocWithOffset(Name.size());
- }
-
- SourceRange getNameRange() const {
- return SourceRange(NameLocBegin, getNameLocEnd());
- }
- };
-
-private:
- ArrayRef<Attribute> Attributes;
-
-public:
- HTMLStartTagComment(SourceLocation LocBegin,
- StringRef TagName) :
- HTMLTagComment(HTMLStartTagCommentKind,
- LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
- TagName,
- LocBegin.getLocWithOffset(1),
- LocBegin.getLocWithOffset(1 + TagName.size())) {
- HTMLStartTagCommentBits.IsSelfClosing = false;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == HTMLStartTagCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- unsigned getNumAttrs() const {
- return Attributes.size();
- }
-
- const Attribute &getAttr(unsigned Idx) const {
- return Attributes[Idx];
- }
-
- void setAttrs(ArrayRef<Attribute> Attrs) {
- Attributes = Attrs;
- if (!Attrs.empty()) {
- const Attribute &Attr = Attrs.back();
- SourceLocation L = Attr.ValueRange.getEnd();
- if (L.isValid())
- Range.setEnd(L);
- else {
- Range.setEnd(Attr.getNameLocEnd());
- }
- }
- }
-
- void setGreaterLoc(SourceLocation GreaterLoc) {
- Range.setEnd(GreaterLoc);
- }
-
- bool isSelfClosing() const {
- return HTMLStartTagCommentBits.IsSelfClosing;
- }
-
- void setSelfClosing() {
- HTMLStartTagCommentBits.IsSelfClosing = true;
- }
-};
-
-/// A closing HTML tag.
-class HTMLEndTagComment : public HTMLTagComment {
-public:
- HTMLEndTagComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef TagName) :
- HTMLTagComment(HTMLEndTagCommentKind,
- LocBegin, LocEnd,
- TagName,
- LocBegin.getLocWithOffset(2),
- LocBegin.getLocWithOffset(2 + TagName.size()))
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == HTMLEndTagCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-};
-
-/// Block content (contains inline content).
-/// Abstract class.
-class BlockContentComment : public Comment {
-protected:
- BlockContentComment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd) :
- Comment(K, LocBegin, LocEnd)
- { }
-
-public:
- static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstBlockContentCommentConstant &&
- C->getCommentKind() <= LastBlockContentCommentConstant;
- }
-};
-
-/// A single paragraph that contains inline content.
-class ParagraphComment : public BlockContentComment {
- ArrayRef<InlineContentComment *> Content;
-
-public:
- ParagraphComment(ArrayRef<InlineContentComment *> Content) :
- BlockContentComment(ParagraphCommentKind,
- SourceLocation(),
- SourceLocation()),
- Content(Content) {
- if (Content.empty()) {
- ParagraphCommentBits.IsWhitespace = true;
- ParagraphCommentBits.IsWhitespaceValid = true;
- return;
- }
-
- ParagraphCommentBits.IsWhitespaceValid = false;
-
- setSourceRange(SourceRange(Content.front()->getLocStart(),
- Content.back()->getLocEnd()));
- setLocation(Content.front()->getLocStart());
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == ParagraphCommentKind;
- }
-
- child_iterator child_begin() const {
- return reinterpret_cast<child_iterator>(Content.begin());
- }
-
- child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(Content.end());
- }
-
- bool isWhitespace() const {
- if (ParagraphCommentBits.IsWhitespaceValid)
- return ParagraphCommentBits.IsWhitespace;
-
- ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
- ParagraphCommentBits.IsWhitespaceValid = true;
- return ParagraphCommentBits.IsWhitespace;
- }
-
-private:
- bool isWhitespaceNoCache() const;
-};
-
-/// A command that has zero or more word-like arguments (number of word-like
-/// arguments depends on command name) and a paragraph as an argument
-/// (e. g., \\brief).
-class BlockCommandComment : public BlockContentComment {
-public:
- struct Argument {
- SourceRange Range;
- StringRef Text;
-
- Argument() { }
- Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
- };
-
-protected:
- /// Word-like arguments.
- ArrayRef<Argument> Args;
-
- /// Paragraph argument.
- ParagraphComment *Paragraph;
-
- BlockCommandComment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockContentComment(K, LocBegin, LocEnd),
- Paragraph(nullptr) {
- setLocation(getCommandNameBeginLoc());
- BlockCommandCommentBits.CommandID = CommandID;
- BlockCommandCommentBits.CommandMarker = CommandMarker;
- }
-
-public:
- BlockCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
- Paragraph(nullptr) {
- setLocation(getCommandNameBeginLoc());
- BlockCommandCommentBits.CommandID = CommandID;
- BlockCommandCommentBits.CommandMarker = CommandMarker;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
- C->getCommentKind() <= LastBlockCommandCommentConstant;
- }
-
- child_iterator child_begin() const {
- return reinterpret_cast<child_iterator>(&Paragraph);
- }
-
- child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(&Paragraph + 1);
- }
-
- unsigned getCommandID() const {
- return BlockCommandCommentBits.CommandID;
- }
-
- StringRef getCommandName(const CommandTraits &Traits) const {
- return Traits.getCommandInfo(getCommandID())->Name;
- }
-
- SourceLocation getCommandNameBeginLoc() const {
- return getLocStart().getLocWithOffset(1);
- }
-
- SourceRange getCommandNameRange(const CommandTraits &Traits) const {
- StringRef Name = getCommandName(Traits);
- return SourceRange(getCommandNameBeginLoc(),
- getLocStart().getLocWithOffset(1 + Name.size()));
- }
-
- unsigned getNumArgs() const {
- return Args.size();
- }
-
- StringRef getArgText(unsigned Idx) const {
- return Args[Idx].Text;
- }
-
- SourceRange getArgRange(unsigned Idx) const {
- return Args[Idx].Range;
- }
-
- void setArgs(ArrayRef<Argument> A) {
- Args = A;
- if (Args.size() > 0) {
- SourceLocation NewLocEnd = Args.back().Range.getEnd();
- if (NewLocEnd.isValid())
- setSourceRange(SourceRange(getLocStart(), NewLocEnd));
- }
- }
-
- ParagraphComment *getParagraph() const LLVM_READONLY {
- return Paragraph;
- }
-
- bool hasNonWhitespaceParagraph() const {
- return Paragraph && !Paragraph->isWhitespace();
- }
-
- void setParagraph(ParagraphComment *PC) {
- Paragraph = PC;
- SourceLocation NewLocEnd = PC->getLocEnd();
- if (NewLocEnd.isValid())
- setSourceRange(SourceRange(getLocStart(), NewLocEnd));
- }
-
- CommandMarkerKind getCommandMarker() const LLVM_READONLY {
- return static_cast<CommandMarkerKind>(
- BlockCommandCommentBits.CommandMarker);
- }
-};
-
-/// Doxygen \\param command.
-class ParamCommandComment : public BlockCommandComment {
-private:
- /// Parameter index in the function declaration.
- unsigned ParamIndex;
-
-public:
- enum : unsigned {
- InvalidParamIndex = ~0U,
- VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
- };
-
- ParamCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
- CommandID, CommandMarker),
- ParamIndex(InvalidParamIndex) {
- ParamCommandCommentBits.Direction = In;
- ParamCommandCommentBits.IsDirectionExplicit = false;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == ParamCommandCommentKind;
- }
-
- enum PassDirection {
- In,
- Out,
- InOut
- };
-
- static const char *getDirectionAsString(PassDirection D);
-
- PassDirection getDirection() const LLVM_READONLY {
- return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
- }
-
- bool isDirectionExplicit() const LLVM_READONLY {
- return ParamCommandCommentBits.IsDirectionExplicit;
- }
-
- void setDirection(PassDirection Direction, bool Explicit) {
- ParamCommandCommentBits.Direction = Direction;
- ParamCommandCommentBits.IsDirectionExplicit = Explicit;
- }
-
- bool hasParamName() const {
- return getNumArgs() > 0;
- }
-
- StringRef getParamName(const FullComment *FC) const;
-
- StringRef getParamNameAsWritten() const {
- return Args[0].Text;
- }
-
- SourceRange getParamNameRange() const {
- return Args[0].Range;
- }
-
- bool isParamIndexValid() const LLVM_READONLY {
- return ParamIndex != InvalidParamIndex;
- }
-
- bool isVarArgParam() const LLVM_READONLY {
- return ParamIndex == VarArgParamIndex;
- }
-
- void setIsVarArgParam() {
- ParamIndex = VarArgParamIndex;
- assert(isParamIndexValid());
- }
-
- unsigned getParamIndex() const LLVM_READONLY {
- assert(isParamIndexValid());
- assert(!isVarArgParam());
- return ParamIndex;
- }
-
- void setParamIndex(unsigned Index) {
- ParamIndex = Index;
- assert(isParamIndexValid());
- assert(!isVarArgParam());
- }
-};
-
-/// Doxygen \\tparam command, describes a template parameter.
-class TParamCommandComment : public BlockCommandComment {
-private:
- /// If this template parameter name was resolved (found in template parameter
- /// list), then this stores a list of position indexes in all template
- /// parameter lists.
- ///
- /// For example:
- /// \verbatim
- /// template<typename C, template<typename T> class TT>
- /// void test(TT<int> aaa);
- /// \endverbatim
- /// For C: Position = { 0 }
- /// For TT: Position = { 1 }
- /// For T: Position = { 1, 0 }
- ArrayRef<unsigned> Position;
-
-public:
- TParamCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID,
- CommandMarker)
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == TParamCommandCommentKind;
- }
-
- bool hasParamName() const {
- return getNumArgs() > 0;
- }
-
- StringRef getParamName(const FullComment *FC) const;
-
- StringRef getParamNameAsWritten() const {
- return Args[0].Text;
- }
-
- SourceRange getParamNameRange() const {
- return Args[0].Range;
- }
-
- bool isPositionValid() const LLVM_READONLY {
- return !Position.empty();
- }
-
- unsigned getDepth() const {
- assert(isPositionValid());
- return Position.size();
- }
-
- unsigned getIndex(unsigned Depth) const {
- assert(isPositionValid());
- return Position[Depth];
- }
-
- void setPosition(ArrayRef<unsigned> NewPosition) {
- Position = NewPosition;
- assert(isPositionValid());
- }
-};
-
-/// A line of text contained in a verbatim block.
-class VerbatimBlockLineComment : public Comment {
- StringRef Text;
-
-public:
- VerbatimBlockLineComment(SourceLocation LocBegin,
- StringRef Text) :
- Comment(VerbatimBlockLineCommentKind,
- LocBegin,
- LocBegin.getLocWithOffset(Text.size())),
- Text(Text)
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimBlockLineCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- StringRef getText() const LLVM_READONLY {
- return Text;
- }
-};
-
-/// A verbatim block command (e. g., preformatted code). Verbatim block has an
-/// opening and a closing command and contains multiple lines of text
-/// (VerbatimBlockLineComment nodes).
-class VerbatimBlockComment : public BlockCommandComment {
-protected:
- StringRef CloseName;
- SourceLocation CloseNameLocBegin;
- ArrayRef<VerbatimBlockLineComment *> Lines;
-
-public:
- VerbatimBlockComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID) :
- BlockCommandComment(VerbatimBlockCommentKind,
- LocBegin, LocEnd, CommandID,
- CMK_At) // FIXME: improve source fidelity.
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimBlockCommentKind;
- }
-
- child_iterator child_begin() const {
- return reinterpret_cast<child_iterator>(Lines.begin());
- }
-
- child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(Lines.end());
- }
-
- void setCloseName(StringRef Name, SourceLocation LocBegin) {
- CloseName = Name;
- CloseNameLocBegin = LocBegin;
- }
-
- void setLines(ArrayRef<VerbatimBlockLineComment *> L) {
- Lines = L;
- }
-
- StringRef getCloseName() const {
- return CloseName;
- }
-
- unsigned getNumLines() const {
- return Lines.size();
- }
-
- StringRef getText(unsigned LineIdx) const {
- return Lines[LineIdx]->getText();
- }
-};
-
-/// A verbatim line command. Verbatim line has an opening command, a single
-/// line of text (up to the newline after the opening command) and has no
-/// closing command.
-class VerbatimLineComment : public BlockCommandComment {
-protected:
- StringRef Text;
- SourceLocation TextBegin;
-
-public:
- VerbatimLineComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- SourceLocation TextBegin,
- StringRef Text) :
- BlockCommandComment(VerbatimLineCommentKind,
- LocBegin, LocEnd,
- CommandID,
- CMK_At), // FIXME: improve source fidelity.
- Text(Text),
- TextBegin(TextBegin)
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimLineCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- StringRef getText() const {
- return Text;
- }
-
- SourceRange getTextRange() const {
- return SourceRange(TextBegin, getLocEnd());
- }
-};
-
-/// Information about the declaration, useful to clients of FullComment.
-struct DeclInfo {
- /// Declaration the comment is actually attached to (in the source).
- /// Should not be NULL.
- const Decl *CommentDecl;
-
- /// CurrentDecl is the declaration with which the FullComment is associated.
- ///
- /// It can be different from \c CommentDecl. It happens when we 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).
- ///
- /// The information in the DeclInfo corresponds to CurrentDecl.
- const Decl *CurrentDecl;
-
- /// Parameters that can be referenced by \\param if \c CommentDecl is something
- /// that we consider a "function".
- ArrayRef<const ParmVarDecl *> ParamVars;
-
- /// Function return type if \c CommentDecl is something that we consider
- /// a "function".
- QualType ReturnType;
-
- /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
- /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
- /// true).
- const TemplateParameterList *TemplateParameters;
-
- /// A simplified description of \c CommentDecl kind that should be good enough
- /// for documentation rendering purposes.
- enum DeclKind {
- /// Everything else not explicitly mentioned below.
- OtherKind,
-
- /// Something that we consider a "function":
- /// \li function,
- /// \li function template,
- /// \li function template specialization,
- /// \li member function,
- /// \li member function template,
- /// \li member function template specialization,
- /// \li ObjC method,
- /// \li a typedef for a function pointer, member function pointer,
- /// ObjC block.
- FunctionKind,
-
- /// Something that we consider a "class":
- /// \li class/struct,
- /// \li class template,
- /// \li class template (partial) specialization.
- ClassKind,
-
- /// Something that we consider a "variable":
- /// \li namespace scope variables;
- /// \li static and non-static class data members;
- /// \li enumerators.
- VariableKind,
-
- /// A C++ namespace.
- NamespaceKind,
-
- /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
- /// see \c TypedefNameDecl.
- TypedefKind,
-
- /// An enumeration or scoped enumeration.
- EnumKind
- };
-
- /// What kind of template specialization \c CommentDecl is.
- enum TemplateDeclKind {
- NotTemplate,
- Template,
- TemplateSpecialization,
- TemplatePartialSpecialization
- };
-
- /// If false, only \c CommentDecl is valid.
- unsigned IsFilled : 1;
-
- /// Simplified kind of \c CommentDecl, see \c DeclKind enum.
- unsigned Kind : 3;
-
- /// Is \c CommentDecl a template declaration.
- unsigned TemplateKind : 2;
-
- /// Is \c CommentDecl an ObjCMethodDecl.
- unsigned IsObjCMethod : 1;
-
- /// Is \c CommentDecl a non-static member function of C++ class or
- /// instance method of ObjC class.
- /// Can be true only if \c IsFunctionDecl is true.
- unsigned IsInstanceMethod : 1;
-
- /// Is \c CommentDecl a static member function of C++ class or
- /// class method of ObjC class.
- /// Can be true only if \c IsFunctionDecl is true.
- unsigned IsClassMethod : 1;
-
- void fill();
-
- DeclKind getKind() const LLVM_READONLY {
- return static_cast<DeclKind>(Kind);
- }
-
- TemplateDeclKind getTemplateKind() const LLVM_READONLY {
- return static_cast<TemplateDeclKind>(TemplateKind);
- }
-};
-
-/// A full comment attached to a declaration, contains block content.
-class FullComment : public Comment {
- ArrayRef<BlockContentComment *> Blocks;
- DeclInfo *ThisDeclInfo;
-
-public:
- FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
- Comment(FullCommentKind, SourceLocation(), SourceLocation()),
- Blocks(Blocks), ThisDeclInfo(D) {
- if (Blocks.empty())
- return;
-
- setSourceRange(SourceRange(Blocks.front()->getLocStart(),
- Blocks.back()->getLocEnd()));
- setLocation(Blocks.front()->getLocStart());
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == FullCommentKind;
- }
-
- child_iterator child_begin() const {
- return reinterpret_cast<child_iterator>(Blocks.begin());
- }
-
- child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(Blocks.end());
- }
-
- const Decl *getDecl() const LLVM_READONLY {
- return ThisDeclInfo->CommentDecl;
- }
-
- const DeclInfo *getDeclInfo() const LLVM_READONLY {
- if (!ThisDeclInfo->IsFilled)
- ThisDeclInfo->fill();
- return ThisDeclInfo;
- }
-
- ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
-
-};
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
deleted file mode 100644
index be5b8ee..0000000
--- a/include/clang/AST/CommentBriefParser.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===--- CommentBriefParser.h - Dumb comment parser -------------*- 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 very simple Doxygen comment parser.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_AST_COMMENTBRIEFPARSER_H
-#define LLVM_CLANG_AST_COMMENTBRIEFPARSER_H
-
-#include "clang/AST/CommentLexer.h"
-
-namespace clang {
-namespace comments {
-
-/// A very simple comment parser that extracts "a brief description".
-///
-/// 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 the first paragraph,
-/// \li a \\result or \\return or \\returns paragraph.
-class BriefParser {
- Lexer &L;
-
- const CommandTraits &Traits;
-
- /// Current lookahead token.
- Token Tok;
-
- SourceLocation ConsumeToken() {
- SourceLocation Loc = Tok.getLocation();
- L.lex(Tok);
- return Loc;
- }
-
-public:
- BriefParser(Lexer &L, const CommandTraits &Traits);
-
- /// Return the best "brief description" we can find.
- std::string Parse();
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
deleted file mode 100644
index 289f2fd..0000000
--- a/include/clang/AST/CommentCommandTraits.h
+++ /dev/null
@@ -1,189 +0,0 @@
-//===--- CommentCommandTraits.h - Comment command properties ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the class that provides information about comment
-// commands.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_AST_COMMENTCOMMANDTRAITS_H
-#define LLVM_CLANG_AST_COMMENTCOMMANDTRAITS_H
-
-#include "clang/Basic/CommentOptions.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-namespace comments {
-
-/// \brief Information about a single command.
-///
-/// When reordering, adding or removing members please update the corresponding
-/// TableGen backend.
-struct CommandInfo {
- unsigned getID() const {
- return ID;
- }
-
- const char *Name;
-
- /// Name of the command that ends the verbatim block.
- const char *EndCommandName;
-
- /// DRY definition of the number of bits used for a command ID.
- enum { NumCommandIDBits = 20 };
-
- /// The ID of the command.
- unsigned ID : NumCommandIDBits;
-
- /// Number of word-like arguments for a given block command, except for
- /// \\param and \\tparam commands -- these have special argument parsers.
- unsigned NumArgs : 4;
-
- /// True if this command is a inline command (of any kind).
- unsigned IsInlineCommand : 1;
-
- /// True if this command is a block command (of any kind).
- unsigned IsBlockCommand : 1;
-
- /// True if this command is introducing a brief documentation
- /// paragraph (\\brief or an alias).
- unsigned IsBriefCommand : 1;
-
- /// True if this command is \\returns or an alias.
- unsigned IsReturnsCommand : 1;
-
- /// True if this command is introducing documentation for a function
- /// parameter (\\param or an alias).
- unsigned IsParamCommand : 1;
-
- /// True if this command is introducing documentation for
- /// a template parameter (\\tparam or an alias).
- unsigned IsTParamCommand : 1;
-
- /// True if this command is \\throws or an alias.
- unsigned IsThrowsCommand : 1;
-
- /// True if this command is \\deprecated or an alias.
- unsigned IsDeprecatedCommand : 1;
-
- /// \brief 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.
- ///
- /// 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.
- unsigned IsVerbatimBlockEndCommand : 1;
-
- /// \brief 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
- /// documented.
- ///
- /// For example:
- /// \code
- /// \fn void f(int a);
- /// \endcode
- unsigned IsDeclarationCommand : 1;
-
- /// \brief 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
- /// as \@coclass, \@classdesign, etc.
- unsigned IsRecordLikeDetailCommand : 1;
-
- /// \brief 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
- /// created during parsing.
- unsigned IsUnknownCommand : 1;
-};
-
-/// This class provides information about commands that can be used
-/// in comments.
-class CommandTraits {
-public:
- enum KnownCommandIDs {
-#define COMMENT_COMMAND(NAME) KCI_##NAME,
-#include "clang/AST/CommentCommandList.inc"
-#undef COMMENT_COMMAND
- KCI_Last
- };
-
- CommandTraits(llvm::BumpPtrAllocator &Allocator,
- const CommentOptions &CommentOptions);
-
- void registerCommentOptions(const CommentOptions &CommentOptions);
-
- /// \returns a CommandInfo object for a given command name or
- /// NULL if no CommandInfo object exists for this command.
- const CommandInfo *getCommandInfoOrNULL(StringRef Name) const;
-
- const CommandInfo *getCommandInfo(StringRef Name) const {
- if (const CommandInfo *Info = getCommandInfoOrNULL(Name))
- return Info;
- llvm_unreachable("the command should be known");
- }
-
- const CommandInfo *getTypoCorrectCommandInfo(StringRef Typo) const;
-
- const CommandInfo *getCommandInfo(unsigned CommandID) const;
-
- const CommandInfo *registerUnknownCommand(StringRef CommandName);
-
- const CommandInfo *registerBlockCommand(StringRef CommandName);
-
- /// \returns a CommandInfo object for a given command name or
- /// NULL if \c Name is not a builtin command.
- static const CommandInfo *getBuiltinCommandInfo(StringRef Name);
-
- /// \returns a CommandInfo object for a given command ID or
- /// NULL if \c CommandID is not a builtin command.
- static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID);
-
-private:
- CommandTraits(const CommandTraits &) = delete;
- void operator=(const CommandTraits &) = delete;
-
- const CommandInfo *getRegisteredCommandInfo(StringRef Name) const;
- const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const;
-
- CommandInfo *createCommandInfoWithName(StringRef CommandName);
-
- unsigned NextID;
-
- /// Allocator for CommandInfo objects.
- llvm::BumpPtrAllocator &Allocator;
-
- SmallVector<CommandInfo *, 4> RegisteredCommands;
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
deleted file mode 100644
index 958ee03..0000000
--- a/include/clang/AST/CommentCommands.td
+++ /dev/null
@@ -1,241 +0,0 @@
-//===----------------------------------------------------------------------===//
-// Define command classes.
-//===----------------------------------------------------------------------===//
-
-class Command<string name> {
- string Name = name;
- string EndCommandName = "";
-
- int NumArgs = 0;
-
- bit IsInlineCommand = 0;
-
- bit IsBlockCommand = 0;
- bit IsBriefCommand = 0;
- bit IsReturnsCommand = 0;
- bit IsParamCommand = 0;
- bit IsTParamCommand = 0;
- bit IsThrowsCommand = 0;
- bit IsDeprecatedCommand = 0;
- bit IsHeaderfileCommand = 0;
-
- bit IsEmptyParagraphAllowed = 0;
-
- bit IsVerbatimBlockCommand = 0;
- bit IsVerbatimBlockEndCommand = 0;
- bit IsVerbatimLineCommand = 0;
- bit IsDeclarationCommand = 0;
- bit IsFunctionDeclarationCommand = 0;
- bit IsRecordLikeDetailCommand = 0;
- bit IsRecordLikeDeclarationCommand = 0;
-}
-
-class InlineCommand<string name> : Command<name> {
- let IsInlineCommand = 1;
-}
-
-class BlockCommand<string name> : Command<name> {
- let IsBlockCommand = 1;
-}
-
-class RecordLikeDetailCommand<string name> : BlockCommand<name> {
- let IsRecordLikeDetailCommand = 1;
-}
-
-class VerbatimBlockCommand<string name> : Command<name> {
- let EndCommandName = name;
- let IsVerbatimBlockCommand = 1;
-}
-
-multiclass VerbatimBlockCommand<string name, string endCommandName> {
- def Begin : Command<name> {
- let EndCommandName = endCommandName;
- let IsVerbatimBlockCommand = 1;
- }
-
- def End : Command<endCommandName> {
- let IsVerbatimBlockEndCommand = 1;
- }
-}
-
-class VerbatimLineCommand<string name> : Command<name> {
- let IsVerbatimLineCommand = 1;
-}
-
-class DeclarationVerbatimLineCommand<string name> :
- VerbatimLineCommand<name> {
- let IsDeclarationCommand = 1;
-}
-
-class FunctionDeclarationVerbatimLineCommand<string name> :
- DeclarationVerbatimLineCommand<name> {
- let IsFunctionDeclarationCommand = 1;
-}
-
-class RecordLikeDeclarationVerbatimLineCommand<string name> :
- DeclarationVerbatimLineCommand<name> {
- let IsRecordLikeDeclarationCommand = 1;
-}
-
-//===----------------------------------------------------------------------===//
-// InlineCommand
-//===----------------------------------------------------------------------===//
-
-def B : InlineCommand<"b">;
-def C : InlineCommand<"c">;
-def P : InlineCommand<"p">;
-def A : InlineCommand<"a">;
-def E : InlineCommand<"e">;
-def Em : InlineCommand<"em">;
-
-//===----------------------------------------------------------------------===//
-// BlockCommand
-//===----------------------------------------------------------------------===//
-
-def Brief : BlockCommand<"brief"> { let IsBriefCommand = 1; }
-def Short : BlockCommand<"short"> { let IsBriefCommand = 1; }
-
-// Opposite of \brief, it is the default in our implementation.
-def Details : BlockCommand<"details">;
-
-def Returns : BlockCommand<"returns"> { let IsReturnsCommand = 1; }
-def Return : BlockCommand<"return"> { let IsReturnsCommand = 1; }
-def Result : BlockCommand<"result"> { let IsReturnsCommand = 1; }
-
-def Param : BlockCommand<"param"> { let IsParamCommand = 1; }
-
-// Doxygen command for template parameter documentation.
-def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; }
-
-// HeaderDoc command for template parameter documentation.
-def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
-
-def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; }
-def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; }
-def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; }
-
-def Deprecated : BlockCommand<"deprecated"> {
- let IsEmptyParagraphAllowed = 1;
- let IsDeprecatedCommand = 1;
-}
-
-def Headerfile : BlockCommand<"headerfile"> { let IsHeaderfileCommand = 1; }
-
-// We don't do any additional semantic analysis for the following
-// BlockCommands. It might be a good idea to do something extra for them, but
-// for now we model them as plain BlockCommands.
-def Arg : BlockCommand<"arg">;
-def Attention : BlockCommand<"attention">;
-def Author : BlockCommand<"author">;
-def Authors : BlockCommand<"authors">;
-def Bug : BlockCommand<"bug">;
-def Copyright : BlockCommand<"copyright">;
-def Date : BlockCommand<"date">;
-def Invariant : BlockCommand<"invariant">;
-def Li : BlockCommand<"li">;
-def Note : BlockCommand<"note">;
-def Par : BlockCommand<"par">;
-def Post : BlockCommand<"post">;
-def Pre : BlockCommand<"pre">;
-def Remark : BlockCommand<"remark">;
-def Remarks : BlockCommand<"remarks">;
-def Sa : BlockCommand<"sa">;
-def See : BlockCommand<"see">;
-def Since : BlockCommand<"since">;
-def Todo : BlockCommand<"todo">;
-def Version : BlockCommand<"version">;
-def Warning : BlockCommand<"warning">;
-// HeaderDoc commands
-def Abstract : BlockCommand<"abstract"> { let IsBriefCommand = 1; }
-def ClassDesign : RecordLikeDetailCommand<"classdesign">;
-def CoClass : RecordLikeDetailCommand<"coclass">;
-def Dependency : RecordLikeDetailCommand<"dependency">;
-def Discussion : BlockCommand<"discussion">;
-def Helper : RecordLikeDetailCommand<"helper">;
-def HelperClass : RecordLikeDetailCommand<"helperclass">;
-def Helps : RecordLikeDetailCommand<"helps">;
-def InstanceSize : RecordLikeDetailCommand<"instancesize">;
-def Ownership : RecordLikeDetailCommand<"ownership">;
-def Performance : RecordLikeDetailCommand<"performance">;
-def Security : RecordLikeDetailCommand<"security">;
-def SeeAlso : BlockCommand<"seealso">;
-def SuperClass : RecordLikeDetailCommand<"superclass">;
-
-//===----------------------------------------------------------------------===//
-// VerbatimBlockCommand
-//===----------------------------------------------------------------------===//
-
-defm Code : VerbatimBlockCommand<"code", "endcode">;
-defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">;
-defm Htmlonly : VerbatimBlockCommand<"htmlonly", "endhtmlonly">;
-defm Latexonly : VerbatimBlockCommand<"latexonly", "endlatexonly">;
-defm Xmlonly : VerbatimBlockCommand<"xmlonly", "endxmlonly">;
-defm Manonly : VerbatimBlockCommand<"manonly", "endmanonly">;
-defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">;
-
-defm Dot : VerbatimBlockCommand<"dot", "enddot">;
-defm Msc : VerbatimBlockCommand<"msc", "endmsc">;
-
-// These three commands have special support in CommentLexer to recognize their
-// names.
-def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula
-defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula
-defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment
-
-// HeaderDoc commands
-defm Textblock : VerbatimBlockCommand<"textblock", "/textblock">;
-defm Link : VerbatimBlockCommand<"link", "/link">;
-
-//===----------------------------------------------------------------------===//
-// VerbatimLineCommand
-//===----------------------------------------------------------------------===//
-
-def Defgroup : VerbatimLineCommand<"defgroup">;
-def Ingroup : VerbatimLineCommand<"ingroup">;
-def Addtogroup : VerbatimLineCommand<"addtogroup">;
-def Weakgroup : VerbatimLineCommand<"weakgroup">;
-def Name : VerbatimLineCommand<"name">;
-
-def Section : VerbatimLineCommand<"section">;
-def Subsection : VerbatimLineCommand<"subsection">;
-def Subsubsection : VerbatimLineCommand<"subsubsection">;
-def Paragraph : VerbatimLineCommand<"paragraph">;
-
-def Mainpage : VerbatimLineCommand<"mainpage">;
-def Subpage : VerbatimLineCommand<"subpage">;
-def Ref : VerbatimLineCommand<"ref">;
-
-def Relates : VerbatimLineCommand<"relates">;
-def Related : VerbatimLineCommand<"related">;
-def RelatesAlso : VerbatimLineCommand<"relatesalso">;
-def RelatedAlso : VerbatimLineCommand<"relatedalso">;
-
-//===----------------------------------------------------------------------===//
-// DeclarationVerbatimLineCommand
-//===----------------------------------------------------------------------===//
-
-// Doxygen commands.
-def Def : DeclarationVerbatimLineCommand<"def">;
-def Fn : DeclarationVerbatimLineCommand<"fn">;
-def Namespace : DeclarationVerbatimLineCommand<"namespace">;
-def Overload : DeclarationVerbatimLineCommand<"overload">;
-def Property : DeclarationVerbatimLineCommand<"property">;
-def Typedef : DeclarationVerbatimLineCommand<"typedef">;
-def Var : DeclarationVerbatimLineCommand<"var">;
-
-// HeaderDoc commands.
-def Class : RecordLikeDeclarationVerbatimLineCommand<"class">;
-def Interface : RecordLikeDeclarationVerbatimLineCommand<"interface">;
-def Protocol : RecordLikeDeclarationVerbatimLineCommand<"protocol">;
-def Struct : RecordLikeDeclarationVerbatimLineCommand<"struct">;
-def Union : RecordLikeDeclarationVerbatimLineCommand<"union">;
-def Category : DeclarationVerbatimLineCommand<"category">;
-def Template : DeclarationVerbatimLineCommand<"template">;
-def Function : FunctionDeclarationVerbatimLineCommand<"function">;
-def FunctionGroup : FunctionDeclarationVerbatimLineCommand<"functiongroup">;
-def Method : FunctionDeclarationVerbatimLineCommand<"method">;
-def MethodGroup : FunctionDeclarationVerbatimLineCommand<"methodgroup">;
-def Callback : FunctionDeclarationVerbatimLineCommand<"callback">;
-def Const : DeclarationVerbatimLineCommand<"const">;
-def Constant : DeclarationVerbatimLineCommand<"constant">;
-def Enum : DeclarationVerbatimLineCommand<"enum">;
diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h
deleted file mode 100644
index f3a209b..0000000
--- a/include/clang/AST/CommentDiagnostic.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===--- CommentDiagnostic.h - Diagnostics for the AST library --*- 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_AST_COMMENTDIAGNOSTIC_H
-#define LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define COMMENTSTART
-#include "clang/Basic/DiagnosticCommentKinds.inc"
-#undef DIAG
- NUM_BUILTIN_COMMENT_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentHTMLNamedCharacterReferences.td b/include/clang/AST/CommentHTMLNamedCharacterReferences.td
deleted file mode 100644
index 4493108..0000000
--- a/include/clang/AST/CommentHTMLNamedCharacterReferences.td
+++ /dev/null
@@ -1,177 +0,0 @@
-// HTML Named Character Reference
-class NCR<string spelling, int codePoint> {
- string Spelling = spelling;
- int CodePoint = codePoint;
-}
-
-// The list below includes named character references supported by Doxygen:
-// http://www.stack.nl/~dimitri/doxygen/manual/htmlcmds.html
-//
-// It does not include all HTML 5 named character references.
-//
-// Corresponding code point values can be found here:
-// http://www.w3.org/TR/2011/WD-html5-20110113/named-character-references.html
-
-def : NCR<"copy", 0x000A9>;
-def : NCR<"COPY", 0x000A9>;
-def : NCR<"trade", 0x02122>;
-def : NCR<"TRADE", 0x02122>;
-def : NCR<"reg", 0x000AE>;
-def : NCR<"REG", 0x000AE>;
-def : NCR<"lt", 0x0003C>;
-def : NCR<"Lt", 0x0003C>;
-def : NCR<"LT", 0x0003C>;
-def : NCR<"gt", 0x0003E>;
-def : NCR<"Gt", 0x0003E>;
-def : NCR<"GT", 0x0003E>;
-def : NCR<"amp", 0x00026>;
-def : NCR<"AMP", 0x00026>;
-def : NCR<"apos", 0x00027>;
-def : NCR<"quot", 0x00022>;
-def : NCR<"QUOT", 0x00022>;
-def : NCR<"lsquo", 0x02018>;
-def : NCR<"rsquo", 0x02019>;
-def : NCR<"ldquo", 0x0201C>;
-def : NCR<"rdquo", 0x0201D>;
-def : NCR<"ndash", 0x02013>;
-def : NCR<"mdash", 0x02014>;
-
-def : NCR<"Auml", 0x000C4>;
-def : NCR<"Euml", 0x000CB>;
-def : NCR<"Iuml", 0x000CF>;
-def : NCR<"Ouml", 0x000D6>;
-def : NCR<"Uuml", 0x000DC>;
-def : NCR<"Yuml", 0x00178>;
-def : NCR<"auml", 0x000E4>;
-def : NCR<"euml", 0x000EB>;
-def : NCR<"iuml", 0x000EF>;
-def : NCR<"ouml", 0x000F6>;
-def : NCR<"uuml", 0x000FC>;
-def : NCR<"yuml", 0x000FF>;
-
-def : NCR<"Aacute", 0x000C1>;
-def : NCR<"Eacute", 0x000C9>;
-def : NCR<"Iacute", 0x000CD>;
-def : NCR<"Oacute", 0x000D3>;
-def : NCR<"Uacute", 0x000DA>;
-def : NCR<"Yacute", 0x000DD>;
-def : NCR<"aacute", 0x000E1>;
-def : NCR<"eacute", 0x000E9>;
-def : NCR<"iacute", 0x000ED>;
-def : NCR<"oacute", 0x000F3>;
-def : NCR<"uacute", 0x000FA>;
-def : NCR<"yacute", 0x000FD>;
-
-def : NCR<"Agrave", 0x000C0>;
-def : NCR<"Egrave", 0x000C8>;
-def : NCR<"Igrave", 0x000CC>;
-def : NCR<"Ograve", 0x000D2>;
-def : NCR<"Ugrave", 0x000D9>;
-// def : NCR<"Ygrave", 0x01EF2>; // Defined neither in Doxygen, nor in HTML5.
-def : NCR<"agrave", 0x000E0>;
-def : NCR<"egrave", 0x000E8>;
-def : NCR<"igrave", 0x000EC>;
-def : NCR<"ograve", 0x000F2>;
-def : NCR<"ugrave", 0x000F9>;
-def : NCR<"ygrave", 0x01EF3>; // Defined in Doxygen, not defined in HTML5.
-
-def : NCR<"Acirc", 0x000C2>;
-def : NCR<"Ecirc", 0x000CA>;
-def : NCR<"Icirc", 0x000CE>;
-def : NCR<"Ocirc", 0x000D4>;
-def : NCR<"Ucirc", 0x000DB>;
-def : NCR<"Ycirc", 0x00176>; // Not defined in Doxygen, defined in HTML5.
-def : NCR<"acirc", 0x000E2>;
-def : NCR<"ecirc", 0x000EA>;
-def : NCR<"icirc", 0x000EE>;
-def : NCR<"ocirc", 0x000F4>;
-def : NCR<"ucirc", 0x000FB>;
-def : NCR<"ycirc", 0x00177>;
-
-def : NCR<"Atilde", 0x000C3>;
-def : NCR<"Ntilde", 0x000D1>;
-def : NCR<"Otilde", 0x000D5>;
-def : NCR<"atilde", 0x000E3>;
-def : NCR<"ntilde", 0x000F1>;
-def : NCR<"otilde", 0x000F5>;
-
-def : NCR<"szlig", 0x000DF>;
-
-def : NCR<"ccedil", 0x000E7>;
-def : NCR<"Ccedil", 0x000C7>;
-
-def : NCR<"aring", 0x000E5>;
-def : NCR<"Aring", 0x000C5>;
-
-def : NCR<"nbsp", 0x000A0>;
-
-def : NCR<"Gamma", 0x00393>;
-def : NCR<"Delta", 0x00394>;
-def : NCR<"Theta", 0x00398>;
-def : NCR<"Lambda", 0x0039B>;
-def : NCR<"Xi", 0x0039E>;
-def : NCR<"Pi", 0x003A0>;
-def : NCR<"Sigma", 0x003A3>;
-def : NCR<"Upsilon", 0x003A5>;
-def : NCR<"Phi", 0x003A6>;
-def : NCR<"Psi", 0x003A8>;
-def : NCR<"Omega", 0x003A9>;
-
-def : NCR<"alpha", 0x003B1>;
-def : NCR<"beta", 0x003B2>;
-def : NCR<"gamma", 0x003B3>;
-def : NCR<"delta", 0x003B4>;
-def : NCR<"epsilon", 0x003B5>;
-def : NCR<"zeta", 0x003B6>;
-def : NCR<"eta", 0x003B7>;
-def : NCR<"theta", 0x003B8>;
-def : NCR<"iota", 0x003B9>;
-def : NCR<"kappa", 0x003BA>;
-def : NCR<"lambda", 0x003BB>;
-def : NCR<"mu", 0x003BC>;
-def : NCR<"nu", 0x003BD>;
-def : NCR<"xi", 0x003BE>;
-def : NCR<"pi", 0x003C0>;
-def : NCR<"rho", 0x003C1>;
-def : NCR<"sigma", 0x003C3>;
-def : NCR<"tau", 0x003C4>;
-def : NCR<"upsilon", 0x003C5>;
-def : NCR<"phi", 0x003C6>;
-def : NCR<"chi", 0x003C7>;
-def : NCR<"psi", 0x003C8>;
-def : NCR<"omega", 0x003C9>;
-def : NCR<"sigmaf", 0x003C2>;
-
-def : NCR<"sect", 0x000A7>;
-def : NCR<"deg", 0x000B0>;
-def : NCR<"prime", 0x02032>;
-def : NCR<"Prime", 0x02033>;
-def : NCR<"infin", 0x0221E>;
-def : NCR<"empty", 0x02205>;
-def : NCR<"plusmn", 0x000B1>;
-def : NCR<"times", 0x000D7>;
-def : NCR<"minus", 0x02212>;
-def : NCR<"sdot", 0x022C5>;
-def : NCR<"part", 0x02202>;
-def : NCR<"nabla", 0x02207>;
-def : NCR<"radic", 0x0221A>;
-def : NCR<"perp", 0x022A5>;
-def : NCR<"sum", 0x02211>;
-def : NCR<"int", 0x0222B>;
-def : NCR<"prod", 0x0220F>;
-def : NCR<"sim", 0x0223C>;
-def : NCR<"asymp", 0x02248>;
-def : NCR<"ne", 0x02260>;
-def : NCR<"equiv", 0x02261>;
-def : NCR<"prop", 0x0221D>;
-def : NCR<"le", 0x02264>;
-def : NCR<"ge", 0x02265>;
-def : NCR<"larr", 0x02190>;
-def : NCR<"rarr", 0x02192>;
-def : NCR<"isin", 0x02208>;
-def : NCR<"notin", 0x02209>;
-def : NCR<"lceil", 0x02308>;
-def : NCR<"rceil", 0x02309>;
-def : NCR<"lfloor", 0x0230A>;
-def : NCR<"rfloor", 0x0230B>;
-
diff --git a/include/clang/AST/CommentHTMLTags.td b/include/clang/AST/CommentHTMLTags.td
deleted file mode 100644
index 2514900..0000000
--- a/include/clang/AST/CommentHTMLTags.td
+++ /dev/null
@@ -1,67 +0,0 @@
-class Tag<string spelling> {
- string Spelling = spelling;
- bit EndTagOptional = 0;
- bit EndTagForbidden = 0;
-}
-
-def Em : Tag<"em">;
-def Strong : Tag<"strong">;
-def Tt : Tag<"tt">;
-def I : Tag<"i">;
-def B : Tag<"b">;
-def Big : Tag<"big">;
-def Small : Tag<"small">;
-def Strike : Tag<"strike">;
-def S : Tag<"s">;
-def U : Tag<"u">;
-def Font : Tag<"font">;
-def A : Tag<"a">;
-def Hr : Tag<"hr"> { let EndTagForbidden = 1; }
-def Div : Tag<"div">;
-def Span : Tag<"span">;
-def H1 : Tag<"h1">;
-def H2 : Tag<"h2">;
-def H3 : Tag<"h3">;
-def H4 : Tag<"h4">;
-def H5 : Tag<"h5">;
-def H6 : Tag<"h6">;
-def Code : Tag<"code">;
-def Blockquote : Tag<"blockquote">;
-def Sub : Tag<"sub">;
-def Sup : Tag<"sup">;
-def Img : Tag<"img"> { let EndTagForbidden = 1; }
-def P : Tag<"p"> { let EndTagOptional = 1; }
-def Br : Tag<"br"> { let EndTagForbidden = 1; }
-def Pre : Tag<"pre">;
-def Ins : Tag<"ins">;
-def Del : Tag<"del">;
-def Ul : Tag<"ul">;
-def Ol : Tag<"ol">;
-def Li : Tag<"li"> { let EndTagOptional = 1; }
-def Dl : Tag<"dl">;
-def Dt : Tag<"dt"> { let EndTagOptional = 1; }
-def Dd : Tag<"dd"> { let EndTagOptional = 1; }
-def Table : Tag<"table">;
-def Caption : Tag<"caption">;
-def Thead : Tag<"thead"> { let EndTagOptional = 1; }
-def Tfoot : Tag<"tfoot"> { let EndTagOptional = 1; }
-def Tbody : Tag<"tbody"> { let EndTagOptional = 1; }
-def Colgroup : Tag<"colgroup"> { let EndTagOptional = 1; }
-def Col : Tag<"col"> { let EndTagForbidden = 1; }
-def Tr : Tag<"tr"> { let EndTagOptional = 1; }
-def Th : Tag<"th"> { let EndTagOptional = 1; }
-def Td : Tag<"td"> { let EndTagOptional = 1; }
-
-// Define a blacklist of attributes that are not safe to pass through to HTML
-// output if the input is untrusted.
-//
-// FIXME: this should be a whitelist. When changing this to a whitelist, don't
-// forget to change the default in the TableGen backend.
-class Attribute<string spelling> {
- string Spelling = spelling;
- bit IsSafeToPassThrough = 1;
-}
-class EventHandlerContentAttribute<string spelling> : Attribute<spelling> {
- let IsSafeToPassThrough = 0;
-}
-
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
deleted file mode 100644
index f190b93..0000000
--- a/include/clang/AST/CommentLexer.h
+++ /dev/null
@@ -1,362 +0,0 @@
-//===--- CommentLexer.h - Lexer for structured comments ---------*- 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 lexer for structured comments and supporting token class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENTLEXER_H
-#define LLVM_CLANG_AST_COMMENTLEXER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-namespace comments {
-
-class Lexer;
-class TextTokenRetokenizer;
-struct CommandInfo;
-class CommandTraits;
-
-namespace tok {
-enum TokenKind {
- eof,
- newline,
- text,
- unknown_command, // Command that does not have an ID.
- backslash_command, // Command with an ID, that used backslash marker.
- at_command, // Command with an ID, that used 'at' marker.
- verbatim_block_begin,
- verbatim_block_line,
- verbatim_block_end,
- verbatim_line_name,
- verbatim_line_text,
- html_start_tag, // <tag
- html_ident, // attr
- html_equals, // =
- html_quoted_string, // "blah\"blah" or 'blah\'blah'
- html_greater, // >
- html_slash_greater, // />
- html_end_tag // </tag
-};
-} // end namespace tok
-
-/// \brief Comment token.
-class Token {
- friend class Lexer;
- friend class TextTokenRetokenizer;
-
- /// The location of the token.
- SourceLocation Loc;
-
- /// The actual kind of the token.
- tok::TokenKind Kind;
-
- /// Length of the token spelling in comment. Can be 0 for synthenized
- /// tokens.
- unsigned Length;
-
- /// Contains text value associated with a token.
- const char *TextPtr;
-
- /// Integer value associated with a token.
- ///
- /// If the token is a konwn 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;
-
-public:
- SourceLocation getLocation() const LLVM_READONLY { return Loc; }
- void setLocation(SourceLocation SL) { Loc = SL; }
-
- SourceLocation getEndLocation() const LLVM_READONLY {
- if (Length == 0 || Length == 1)
- return Loc;
- return Loc.getLocWithOffset(Length - 1);
- }
-
- tok::TokenKind getKind() const LLVM_READONLY { return Kind; }
- void setKind(tok::TokenKind K) { Kind = K; }
-
- bool is(tok::TokenKind K) const LLVM_READONLY { return Kind == K; }
- bool isNot(tok::TokenKind K) const LLVM_READONLY { return Kind != K; }
-
- unsigned getLength() const LLVM_READONLY { return Length; }
- void setLength(unsigned L) { Length = L; }
-
- StringRef getText() const LLVM_READONLY {
- assert(is(tok::text));
- return StringRef(TextPtr, IntVal);
- }
-
- void setText(StringRef Text) {
- assert(is(tok::text));
- TextPtr = Text.data();
- IntVal = Text.size();
- }
-
- StringRef getUnknownCommandName() const LLVM_READONLY {
- assert(is(tok::unknown_command));
- return StringRef(TextPtr, IntVal);
- }
-
- void setUnknownCommandName(StringRef Name) {
- assert(is(tok::unknown_command));
- TextPtr = Name.data();
- IntVal = Name.size();
- }
-
- unsigned getCommandID() const LLVM_READONLY {
- assert(is(tok::backslash_command) || is(tok::at_command));
- return IntVal;
- }
-
- void setCommandID(unsigned ID) {
- assert(is(tok::backslash_command) || is(tok::at_command));
- IntVal = ID;
- }
-
- unsigned getVerbatimBlockID() const LLVM_READONLY {
- assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
- return IntVal;
- }
-
- void setVerbatimBlockID(unsigned ID) {
- assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
- IntVal = ID;
- }
-
- StringRef getVerbatimBlockText() const LLVM_READONLY {
- assert(is(tok::verbatim_block_line));
- return StringRef(TextPtr, IntVal);
- }
-
- void setVerbatimBlockText(StringRef Text) {
- assert(is(tok::verbatim_block_line));
- TextPtr = Text.data();
- IntVal = Text.size();
- }
-
- unsigned getVerbatimLineID() const LLVM_READONLY {
- assert(is(tok::verbatim_line_name));
- return IntVal;
- }
-
- void setVerbatimLineID(unsigned ID) {
- assert(is(tok::verbatim_line_name));
- IntVal = ID;
- }
-
- StringRef getVerbatimLineText() const LLVM_READONLY {
- assert(is(tok::verbatim_line_text));
- return StringRef(TextPtr, IntVal);
- }
-
- void setVerbatimLineText(StringRef Text) {
- assert(is(tok::verbatim_line_text));
- TextPtr = Text.data();
- IntVal = Text.size();
- }
-
- StringRef getHTMLTagStartName() const LLVM_READONLY {
- assert(is(tok::html_start_tag));
- return StringRef(TextPtr, IntVal);
- }
-
- void setHTMLTagStartName(StringRef Name) {
- assert(is(tok::html_start_tag));
- TextPtr = Name.data();
- IntVal = Name.size();
- }
-
- StringRef getHTMLIdent() const LLVM_READONLY {
- assert(is(tok::html_ident));
- return StringRef(TextPtr, IntVal);
- }
-
- void setHTMLIdent(StringRef Name) {
- assert(is(tok::html_ident));
- TextPtr = Name.data();
- IntVal = Name.size();
- }
-
- StringRef getHTMLQuotedString() const LLVM_READONLY {
- assert(is(tok::html_quoted_string));
- return StringRef(TextPtr, IntVal);
- }
-
- void setHTMLQuotedString(StringRef Str) {
- assert(is(tok::html_quoted_string));
- TextPtr = Str.data();
- IntVal = Str.size();
- }
-
- StringRef getHTMLTagEndName() const LLVM_READONLY {
- assert(is(tok::html_end_tag));
- return StringRef(TextPtr, IntVal);
- }
-
- void setHTMLTagEndName(StringRef Name) {
- assert(is(tok::html_end_tag));
- TextPtr = Name.data();
- IntVal = Name.size();
- }
-
- void dump(const Lexer &L, const SourceManager &SM) const;
-};
-
-/// \brief Comment lexer.
-class Lexer {
-private:
- Lexer(const Lexer &) = delete;
- void operator=(const Lexer &) = delete;
-
- /// Allocator for strings that are semantic values of tokens and have to be
- /// computed (for example, resolved decimal character references).
- llvm::BumpPtrAllocator &Allocator;
-
- DiagnosticsEngine &Diags;
-
- const CommandTraits &Traits;
-
- const char *const BufferStart;
- const char *const BufferEnd;
- SourceLocation FileLoc;
-
- const char *BufferPtr;
-
- /// One past end pointer for the current comment. For BCPL comments points
- /// to newline or BufferEnd, for C comments points to star in '*/'.
- const char *CommentEnd;
-
- enum LexerCommentState {
- LCS_BeforeComment,
- LCS_InsideBCPLComment,
- LCS_InsideCComment,
- LCS_BetweenComments
- };
-
- /// Low-level lexer state, track if we are inside or outside of comment.
- LexerCommentState CommentState;
-
- enum LexerState {
- /// Lexing normal comment text
- LS_Normal,
-
- /// Finished lexing verbatim block beginning command, will lex first body
- /// line.
- LS_VerbatimBlockFirstLine,
-
- /// Lexing verbatim block body line-by-line, skipping line-starting
- /// decorations.
- LS_VerbatimBlockBody,
-
- /// Finished lexing verbatim line beginning command, will lex text (one
- /// line).
- LS_VerbatimLineText,
-
- /// Finished lexing \verbatim <TAG \endverbatim part, lexing tag attributes.
- LS_HTMLStartTag,
-
- /// Finished lexing \verbatim </TAG \endverbatim part, lexing '>'.
- LS_HTMLEndTag
- };
-
- /// Current lexing mode.
- LexerState State;
-
- /// If State is LS_VerbatimBlock, contains the name of verbatim end
- /// command, including command marker.
- SmallString<16> VerbatimBlockEndCommandName;
-
- /// Given a character reference name (e.g., "lt"), return the character that
- /// it stands for (e.g., "<").
- StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;
-
- /// Given a Unicode codepoint as base-10 integer, return the character.
- StringRef resolveHTMLDecimalCharacterReference(StringRef Name) const;
-
- /// Given a Unicode codepoint as base-16 integer, return the character.
- StringRef resolveHTMLHexCharacterReference(StringRef Name) const;
-
- void formTokenWithChars(Token &Result, const char *TokEnd,
- tok::TokenKind Kind);
-
- void formTextToken(Token &Result, const char *TokEnd) {
- StringRef Text(BufferPtr, TokEnd - BufferPtr);
- formTokenWithChars(Result, TokEnd, tok::text);
- Result.setText(Text);
- }
-
- SourceLocation getSourceLocation(const char *Loc) const {
- assert(Loc >= BufferStart && Loc <= BufferEnd &&
- "Location out of range for this buffer!");
-
- const unsigned CharNo = Loc - BufferStart;
- return FileLoc.getLocWithOffset(CharNo);
- }
-
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
- return Diags.Report(Loc, DiagID);
- }
-
- /// Eat string matching regexp \code \s*\* \endcode.
- void skipLineStartingDecorations();
-
- /// Lex stuff inside comments. CommentEnd should be set correctly.
- void lexCommentText(Token &T);
-
- void setupAndLexVerbatimBlock(Token &T,
- const char *TextBegin,
- char Marker, const CommandInfo *Info);
-
- void lexVerbatimBlockFirstLine(Token &T);
-
- void lexVerbatimBlockBody(Token &T);
-
- void setupAndLexVerbatimLine(Token &T, const char *TextBegin,
- const CommandInfo *Info);
-
- void lexVerbatimLineText(Token &T);
-
- void lexHTMLCharacterReference(Token &T);
-
- void setupAndLexHTMLStartTag(Token &T);
-
- void lexHTMLStartTag(Token &T);
-
- void setupAndLexHTMLEndTag(Token &T);
-
- void lexHTMLEndTag(Token &T);
-
-public:
- Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags,
- const CommandTraits &Traits,
- SourceLocation FileLoc,
- const char *BufferStart, const char *BufferEnd);
-
- void lex(Token &T);
-
- StringRef getSpelling(const Token &Tok,
- const SourceManager &SourceMgr,
- bool *Invalid = nullptr) const;
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
deleted file mode 100644
index fa88628..0000000
--- a/include/clang/AST/CommentParser.h
+++ /dev/null
@@ -1,123 +0,0 @@
-//===--- CommentParser.h - Doxygen comment parser ---------------*- 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 Doxygen comment parser.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENTPARSER_H
-#define LLVM_CLANG_AST_COMMENTPARSER_H
-
-#include "clang/AST/Comment.h"
-#include "clang/AST/CommentLexer.h"
-#include "clang/AST/CommentSema.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/Support/Allocator.h"
-
-namespace clang {
-class SourceManager;
-
-namespace comments {
-class CommandTraits;
-
-/// Doxygen comment parser.
-class Parser {
- Parser(const Parser &) = delete;
- void operator=(const Parser &) = delete;
-
- friend class TextTokenRetokenizer;
-
- Lexer &L;
-
- Sema &S;
-
- /// Allocator for anything that goes into AST nodes.
- llvm::BumpPtrAllocator &Allocator;
-
- /// Source manager for the comment being parsed.
- const SourceManager &SourceMgr;
-
- DiagnosticsEngine &Diags;
-
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
- return Diags.Report(Loc, DiagID);
- }
-
- const CommandTraits &Traits;
-
- /// Current lookahead token. We can safely assume that all tokens are from
- /// a single source file.
- Token Tok;
-
- /// A stack of additional lookahead tokens.
- SmallVector<Token, 8> MoreLATokens;
-
- void consumeToken() {
- if (MoreLATokens.empty())
- L.lex(Tok);
- else
- Tok = MoreLATokens.pop_back_val();
- }
-
- void putBack(const Token &OldTok) {
- MoreLATokens.push_back(Tok);
- Tok = OldTok;
- }
-
- void putBack(ArrayRef<Token> Toks) {
- if (Toks.empty())
- return;
-
- MoreLATokens.push_back(Tok);
- MoreLATokens.append(Toks.rbegin(), std::prev(Toks.rend()));
-
- Tok = Toks[0];
- }
-
- bool isTokBlockCommand() {
- return (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) &&
- Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand;
- }
-
-public:
- Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
- const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
- const CommandTraits &Traits);
-
- /// Parse arguments for \\param command.
- void parseParamCommandArgs(ParamCommandComment *PC,
- TextTokenRetokenizer &Retokenizer);
-
- /// Parse arguments for \\tparam command.
- void parseTParamCommandArgs(TParamCommandComment *TPC,
- TextTokenRetokenizer &Retokenizer);
-
- void parseBlockCommandArgs(BlockCommandComment *BC,
- TextTokenRetokenizer &Retokenizer,
- unsigned NumArgs);
-
- BlockCommandComment *parseBlockCommand();
- InlineCommandComment *parseInlineCommand();
-
- HTMLStartTagComment *parseHTMLStartTag();
- HTMLEndTagComment *parseHTMLEndTag();
-
- BlockContentComment *parseParagraphOrBlockCommand();
-
- VerbatimBlockComment *parseVerbatimBlock();
- VerbatimLineComment *parseVerbatimLine();
- BlockContentComment *parseBlockContent();
- FullComment *parseFullComment();
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
deleted file mode 100644
index 6a80383..0000000
--- a/include/clang/AST/CommentSema.h
+++ /dev/null
@@ -1,254 +0,0 @@
-//===--- CommentSema.h - Doxygen comment semantic analysis ------*- 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 semantic analysis class for Doxygen comments.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENTSEMA_H
-#define LLVM_CLANG_AST_COMMENTSEMA_H
-
-#include "clang/AST/Comment.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-
-namespace clang {
-class Decl;
-class SourceMgr;
-class Preprocessor;
-
-namespace comments {
-class CommandTraits;
-
-class Sema {
- Sema(const Sema &) = delete;
- void operator=(const Sema &) = delete;
-
- /// Allocator for AST nodes.
- llvm::BumpPtrAllocator &Allocator;
-
- /// Source manager for the comment being parsed.
- const SourceManager &SourceMgr;
-
- DiagnosticsEngine &Diags;
-
- CommandTraits &Traits;
-
- const Preprocessor *PP;
-
- /// Information about the declaration this comment is attached to.
- DeclInfo *ThisDeclInfo;
-
- /// Comment AST nodes that correspond to parameter names in
- /// \c TemplateParameters.
- ///
- /// Contains a valid value if \c DeclInfo->IsFilled is true.
- llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
-
- /// AST node for the \\brief command and its aliases.
- const BlockCommandComment *BriefCommand;
-
- /// AST node for the \\headerfile command.
- const BlockCommandComment *HeaderfileCommand;
-
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
- return Diags.Report(Loc, DiagID);
- }
-
- /// A stack of HTML tags that are currently open (not matched with closing
- /// tags).
- SmallVector<HTMLStartTagComment *, 8> HTMLOpenTags;
-
-public:
- Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
- DiagnosticsEngine &Diags, CommandTraits &Traits,
- const Preprocessor *PP);
-
- void setDecl(const Decl *D);
-
- /// Returns a copy of array, owned by Sema's allocator.
- template<typename T>
- ArrayRef<T> copyArray(ArrayRef<T> Source) {
- if (!Source.empty())
- return Source.copy(Allocator);
- return None;
- }
-
- ParagraphComment *actOnParagraphComment(
- ArrayRef<InlineContentComment *> Content);
-
- BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker);
-
- void actOnBlockCommandArgs(BlockCommandComment *Command,
- ArrayRef<BlockCommandComment::Argument> Args);
-
- void actOnBlockCommandFinish(BlockCommandComment *Command,
- ParagraphComment *Paragraph);
-
- ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker);
-
- void actOnParamCommandDirectionArg(ParamCommandComment *Command,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
-
- void actOnParamCommandParamNameArg(ParamCommandComment *Command,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
-
- void actOnParamCommandFinish(ParamCommandComment *Command,
- ParagraphComment *Paragraph);
-
- TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker);
-
- void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
-
- void actOnTParamCommandFinish(TParamCommandComment *Command,
- ParagraphComment *Paragraph);
-
- InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
- SourceLocation CommandLocEnd,
- unsigned CommandID);
-
- InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
- SourceLocation CommandLocEnd,
- unsigned CommandID,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
-
- InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef CommandName);
-
- InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID);
-
- TextComment *actOnText(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef Text);
-
- VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
- unsigned CommandID);
-
- VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
- StringRef Text);
-
- void actOnVerbatimBlockFinish(VerbatimBlockComment *Block,
- SourceLocation CloseNameLocBegin,
- StringRef CloseName,
- ArrayRef<VerbatimBlockLineComment *> Lines);
-
- VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
- unsigned CommandID,
- SourceLocation TextBegin,
- StringRef Text);
-
- HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin,
- StringRef TagName);
-
- void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag,
- ArrayRef<HTMLStartTagComment::Attribute> Attrs,
- SourceLocation GreaterLoc,
- bool IsSelfClosing);
-
- HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef TagName);
-
- FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
-
- void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
-
- void checkReturnsCommand(const BlockCommandComment *Command);
-
- /// Emit diagnostics about duplicate block commands that should be
- /// used only once per comment, e.g., \\brief and \\returns.
- void checkBlockCommandDuplicate(const BlockCommandComment *Command);
-
- void checkDeprecatedCommand(const BlockCommandComment *Comment);
-
- void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment);
-
- void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment);
-
- void checkContainerDecl(const BlockCommandComment *Comment);
-
- /// Resolve parameter names to parameter indexes in function declaration.
- /// Emit diagnostics about unknown parametrs.
- void resolveParamCommandIndexes(const FullComment *FC);
-
- bool isFunctionDecl();
- bool isAnyFunctionDecl();
-
- /// \returns \c true if declaration that this comment is attached to declares
- /// a function pointer.
- bool isFunctionPointerVarDecl();
- bool isFunctionOrMethodVariadic();
- bool isObjCMethodDecl();
- bool isObjCPropertyDecl();
- bool isTemplateOrSpecialization();
- bool isRecordLikeDecl();
- bool isClassOrStructDecl();
- bool isUnionDecl();
- bool isObjCInterfaceDecl();
- bool isObjCProtocolDecl();
- bool isClassTemplateDecl();
- bool isFunctionTemplateDecl();
-
- ArrayRef<const ParmVarDecl *> getParamVars();
-
- /// Extract all important semantic information from
- /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
- void inspectThisDecl();
-
- /// Returns index of a function parameter with a given name.
- unsigned resolveParmVarReference(StringRef Name,
- ArrayRef<const ParmVarDecl *> ParamVars);
-
- /// Returns index of a function parameter with the name closest to a given
- /// typo.
- unsigned correctTypoInParmVarReference(StringRef Typo,
- ArrayRef<const ParmVarDecl *> ParamVars);
-
- bool resolveTParamReference(StringRef Name,
- const TemplateParameterList *TemplateParameters,
- SmallVectorImpl<unsigned> *Position);
-
- StringRef correctTypoInTParamReference(
- StringRef Typo,
- const TemplateParameterList *TemplateParameters);
-
- InlineCommandComment::RenderKind
- getInlineCommandRenderKind(StringRef Name) const;
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h
deleted file mode 100644
index 21641bf..0000000
--- a/include/clang/AST/CommentVisitor.h
+++ /dev/null
@@ -1,70 +0,0 @@
-//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- 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_AST_COMMENTVISITOR_H
-#define LLVM_CLANG_AST_COMMENTVISITOR_H
-
-#include "clang/AST/Comment.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-namespace comments {
-
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
-
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
-class CommentVisitorBase {
-public:
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->visit ## NAME(static_cast<PTR(CLASS)>(C))
-
- RetTy visit(PTR(Comment) C) {
- if (!C)
- return RetTy();
-
- switch (C->getCommentKind()) {
- default: llvm_unreachable("Unknown comment kind!");
-#define ABSTRACT_COMMENT(COMMENT)
-#define COMMENT(CLASS, PARENT) \
- case Comment::CLASS##Kind: DISPATCH(CLASS, CLASS);
-#include "clang/AST/CommentNodes.inc"
-#undef ABSTRACT_COMMENT
-#undef COMMENT
- }
- }
-
- // If the derived class does not implement a certain Visit* method, fall back
- // on Visit* method for the superclass.
-#define ABSTRACT_COMMENT(COMMENT) COMMENT
-#define COMMENT(CLASS, PARENT) \
- RetTy visit ## CLASS(PTR(CLASS) C) { DISPATCH(PARENT, PARENT); }
-#include "clang/AST/CommentNodes.inc"
-#undef ABSTRACT_COMMENT
-#undef COMMENT
-
- RetTy visitComment(PTR(Comment) C) { return RetTy(); }
-
-#undef PTR
-#undef DISPATCH
-};
-
-template<typename ImplClass, typename RetTy=void>
-class CommentVisitor :
- public CommentVisitorBase<make_ptr, ImplClass, RetTy> {};
-
-template<typename ImplClass, typename RetTy=void>
-class ConstCommentVisitor :
- public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
deleted file mode 100644
index 046ce70..0000000
--- a/include/clang/AST/Decl.h
+++ /dev/null
@@ -1,3801 +0,0 @@
-//===--- Decl.h - Classes for representing declarations ---------*- 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 Decl subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECL_H
-#define LLVM_CLANG_AST_DECL_H
-
-#include "clang/AST/APValue.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/Redeclarable.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/Linkage.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/OperatorKinds.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/TrailingObjects.h"
-
-namespace clang {
-struct ASTTemplateArgumentListInfo;
-class CXXTemporary;
-class CompoundStmt;
-class DependentFunctionTemplateSpecializationInfo;
-class Expr;
-class FunctionTemplateDecl;
-class FunctionTemplateSpecializationInfo;
-class LabelStmt;
-class MemberSpecializationInfo;
-class NestedNameSpecifier;
-class ParmVarDecl;
-class Stmt;
-class StringLiteral;
-class TemplateArgumentList;
-class TemplateParameterList;
-class TypeAliasTemplateDecl;
-class TypeLoc;
-class UnresolvedSetImpl;
-class VarTemplateDecl;
-
-/// \brief 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 {
- QualType Ty;
- // Contains a memory block after the class, used for type source information,
- // allocated by ASTContext.
- friend class ASTContext;
- TypeSourceInfo(QualType ty) : Ty(ty) { }
-public:
- /// \brief Return the type wrapped by this type source info.
- QualType getType() const { return Ty; }
-
- /// \brief 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!
- void overrideType(QualType T) { Ty = T; }
-};
-
-/// TranslationUnitDecl - The top declaration context.
-class TranslationUnitDecl : public Decl, public DeclContext {
- virtual void anchor();
- ASTContext &Ctx;
-
- /// The (most recently entered) anonymous namespace for this
- /// translation unit, if one has been created.
- NamespaceDecl *AnonymousNamespace;
-
- explicit TranslationUnitDecl(ASTContext &ctx);
-public:
- ASTContext &getASTContext() const { return Ctx; }
-
- NamespaceDecl *getAnonymousNamespace() const { return AnonymousNamespace; }
- void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; }
-
- static TranslationUnitDecl *Create(ASTContext &C);
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TranslationUnit; }
- static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
- return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
- }
- static TranslationUnitDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<TranslationUnitDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief 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:
-///
-/// \code
-/// namespace N { extern "C" void f(); } // #1
-/// void N::f() {} // #2
-/// namespace M { extern "C" void f(); } // #3
-/// \endcode
-///
-/// The semantic context of #1 is namespace N and its lexical context is the
-/// LinkageSpecDecl; the semantic context of #2 is namespace N and its lexical
-/// context is the TU. However, both declarations are also visible in the
-/// extern "C" context.
-///
-/// The declaration at #3 finds it is a redeclaration of \c N::f through
-/// lookup in the extern "C" context.
-class ExternCContextDecl : public Decl, public DeclContext {
- virtual void anchor();
-
- explicit ExternCContextDecl(TranslationUnitDecl *TU)
- : Decl(ExternCContext, TU, SourceLocation()),
- DeclContext(ExternCContext) {}
-public:
- static ExternCContextDecl *Create(const ASTContext &C,
- TranslationUnitDecl *TU);
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ExternCContext; }
- static DeclContext *castToDeclContext(const ExternCContextDecl *D) {
- return static_cast<DeclContext *>(const_cast<ExternCContextDecl*>(D));
- }
- static ExternCContextDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<ExternCContextDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// NamedDecl - This represents a decl with a name. Many decls have names such
-/// as ObjCMethodDecl, but not \@class, etc.
-class NamedDecl : public Decl {
- virtual void anchor();
- /// Name - 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;
-
-private:
- NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY;
-
-protected:
- NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
- : 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.).
- IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
-
- /// getName - 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 {
- assert(Name.isIdentifier() && "Name is not a simple identifier");
- 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.
- //
- // FIXME: This function should be renamed to indicate that it is not just an
- // alternate form of getName(), and clients should move as appropriate.
- //
- // FIXME: Deprecated, move clients to getName().
- std::string getNameAsString() const { return Name.getAsString(); }
-
- void printName(raw_ostream &os) const { os << Name; }
-
- /// getDeclName - 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.
- 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().
- /// Creating this name is expensive, so it should be called only when
- /// performance doesn't matter.
- void printQualifiedName(raw_ostream &OS) const;
- void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
-
- // FIXME: Remove string version.
- std::string getQualifiedNameAsString() const;
-
- /// getNameForDiagnostic - Appends a human-readable name for this
- /// declaration into the given stream.
- ///
- /// This is the method invoked by Sema when displaying a NamedDecl
- /// in a diagnostic. It does not necessarily produce the same
- /// result as printName(); for example, class template
- /// specializations are printed with their template arguments.
- virtual void getNameForDiagnostic(raw_ostream &OS,
- 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.
- ///
- /// \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.
- bool hasLinkage() const;
-
- using Decl::isModulePrivate;
- using Decl::setModulePrivate;
-
- /// \brief Determine whether this declaration is hidden from name lookup.
- bool isHidden() const { return Hidden; }
-
- /// \brief Set whether this declaration is hidden from name lookup.
- void setHidden(bool Hide) {
- assert((!Hide || isFromASTFile() || hasLocalOwningModuleStorage()) &&
- "declaration with no owning module can't be hidden");
- Hidden = Hide;
- }
-
- /// \brief Determine whether this declaration is a C++ class member.
- bool isCXXClassMember() const {
- const DeclContext *DC = getDeclContext();
-
- // C++0x [class.mem]p1:
- // The enumerators of an unscoped enumeration defined in
- // the class are members of the class.
- if (isa<EnumDecl>(DC))
- DC = DC->getRedeclContext();
-
- return DC->isRecord();
- }
-
- /// \brief 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.
- /// 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
- /// anonymous namespaces are external (in c++98).
- Linkage getFormalLinkage() const {
- return clang::getFormalLinkage(getLinkageInternal());
- }
-
- /// \brief True if this decl has external linkage.
- bool hasExternalFormalLinkage() const {
- return isExternalFormalLinkage(getLinkageInternal());
- }
-
- bool isExternallyVisible() const {
- return clang::isExternallyVisible(getLinkageInternal());
- }
-
- /// \brief Determines the visibility of this entity.
- Visibility getVisibility() const {
- return getLinkageAndVisibility().getVisibility();
- }
-
- /// \brief Determines the linkage and visibility of this entity.
- LinkageInfo getLinkageAndVisibility() const;
-
- /// Kinds of explicit visibility.
- enum ExplicitVisibilityKind {
- VisibilityForType,
- VisibilityForValue
- };
-
- /// \brief 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
- /// checking. Should always return true.
- bool isLinkageValid() const;
-
- /// \brief True if something has required us to compute the linkage
- /// of this declaration.
- ///
- /// Language features which can retroactively change linkage (like a
- /// typedef name for linkage purposes) may need to consider this,
- /// but hopefully only in transitory ways during parsing.
- bool hasLinkageBeenComputed() const {
- return hasCachedLinkage();
- }
-
- /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
- /// the underlying named decl.
- NamedDecl *getUnderlyingDecl() {
- // Fast-path the common case.
- if (this->getKind() != UsingShadow &&
- this->getKind() != ObjCCompatibleAlias &&
- this->getKind() != NamespaceAlias)
- return this;
-
- return getUnderlyingDeclImpl();
- }
- const NamedDecl *getUnderlyingDecl() const {
- return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
- }
-
- NamedDecl *getMostRecentDecl() {
- return cast<NamedDecl>(static_cast<Decl *>(this)->getMostRecentDecl());
- }
- const NamedDecl *getMostRecentDecl() const {
- return const_cast<NamedDecl*>(this)->getMostRecentDecl();
- }
-
- ObjCStringFormatFamily getObjCFStringFormattingFamily() const;
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
- ND.printName(OS);
- return OS;
-}
-
-/// LabelDecl - 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
-/// location is where the __label__ is.
-class LabelDecl : public NamedDecl {
- void anchor() override;
- LabelStmt *TheStmt;
- StringRef MSAsmName;
- bool MSAsmNameResolved;
- /// LocStart - 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;
-
- LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
- LabelStmt *S, SourceLocation StartL)
- : NamedDecl(Label, DC, IdentL, II),
- TheStmt(S),
- MSAsmNameResolved(false),
- LocStart(StartL) {}
-
-public:
- static LabelDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation IdentL, IdentifierInfo *II);
- static LabelDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation IdentL, IdentifierInfo *II,
- SourceLocation GnuLabelL);
- static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- LabelStmt *getStmt() const { return TheStmt; }
- void setStmt(LabelStmt *T) { TheStmt = T; }
-
- bool isGnuLocal() const { return LocStart != getLocation(); }
- void setLocStart(SourceLocation L) { LocStart = L; }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(LocStart, getLocation());
- }
-
- bool isMSAsmLabel() const { return MSAsmName.size() != 0; }
- bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; }
- void setMSAsmLabel(StringRef Name);
- StringRef getMSAsmLabel() const { return MSAsmName; }
- void setMSAsmLabelResolved() { MSAsmNameResolved = true; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Label; }
-};
-
-/// NamespaceDecl - Represent a C++ namespace.
-class NamespaceDecl : public NamedDecl, public DeclContext,
- public Redeclarable<NamespaceDecl>
-{
- /// LocStart - 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.
- SourceLocation RBraceLoc;
-
- /// \brief 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.
- llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
-
- NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, NamespaceDecl *PrevDecl);
-
- typedef Redeclarable<NamespaceDecl> redeclarable_base;
- NamespaceDecl *getNextRedeclarationImpl() override;
- NamespaceDecl *getPreviousDeclImpl() override;
- NamespaceDecl *getMostRecentDeclImpl() override;
-
-public:
- static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
- bool Inline, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- NamespaceDecl *PrevDecl);
-
- static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- /// \brief Returns true if this is an anonymous namespace declaration.
- ///
- /// For example:
- /// \code
- /// namespace {
- /// ...
- /// };
- /// \endcode
- /// q.v. C++ [namespace.unnamed]
- bool isAnonymousNamespace() const {
- return !getIdentifier();
- }
-
- /// \brief Returns true if this is an inline namespace declaration.
- bool isInline() const {
- return AnonOrFirstNamespaceAndInline.getInt();
- }
-
- /// \brief Set whether this is an inline namespace declaration.
- void setInline(bool Inline) {
- AnonOrFirstNamespaceAndInline.setInt(Inline);
- }
-
- /// \brief Get the original (first) namespace declaration.
- NamespaceDecl *getOriginalNamespace();
-
- /// \brief Get the original (first) namespace declaration.
- const NamespaceDecl *getOriginalNamespace() const;
-
- /// \brief 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,
- /// if any.
- NamespaceDecl *getAnonymousNamespace() const {
- return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer();
- }
-
- void setAnonymousNamespace(NamespaceDecl *D) {
- getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D);
- }
-
- /// Retrieves the canonical declaration of this namespace.
- NamespaceDecl *getCanonicalDecl() override {
- return getOriginalNamespace();
- }
- const NamespaceDecl *getCanonicalDecl() const {
- return getOriginalNamespace();
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(LocStart, RBraceLoc);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
- SourceLocation getRBraceLoc() const { return RBraceLoc; }
- void setLocStart(SourceLocation L) { LocStart = L; }
- void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Namespace; }
- static DeclContext *castToDeclContext(const NamespaceDecl *D) {
- return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
- }
- static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// ValueDecl - 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 {
- void anchor() override;
- QualType DeclType;
-
-protected:
- ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T)
- : NamedDecl(DK, DC, L, N), DeclType(T) {}
-public:
- QualType getType() const { return DeclType; }
- void setType(QualType newType) { DeclType = newType; }
-
- /// \brief Determine whether this symbol is weakly-imported,
- /// or declared with the weak or weak-ref attr.
- bool isWeak() const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
-};
-
-/// QualifierInfo - 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 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;
-
- /// TemplParamLists - 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
- /// case of an explicit specialization) a final "template <>".
- TemplateParameterList** TemplParamLists;
-
- /// Default constructor.
- QualifierInfo()
- : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {}
-
- /// setTemplateParameterListsInfo - Sets info about "outer" template
- /// parameter lists.
- void setTemplateParameterListsInfo(ASTContext &Context,
- ArrayRef<TemplateParameterList *> TPLists);
-
-private:
- // Copy constructor and copy assignment are disabled.
- QualifierInfo(const QualifierInfo&) = delete;
- QualifierInfo& operator=(const QualifierInfo&) = delete;
-};
-
-/// \brief 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,
- // to be used for the (uncommon) case of out-of-line declarations.
- struct ExtInfo : public QualifierInfo {
- TypeSourceInfo *TInfo;
- };
-
- llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
-
- /// InnerLocStart - The start of the source range for this declaration,
- /// ignoring outer template declarations.
- SourceLocation InnerLocStart;
-
- bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); }
- ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); }
- const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); }
-
-protected:
- DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- SourceLocation StartL)
- : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {
- }
-
-public:
- TypeSourceInfo *getTypeSourceInfo() const {
- return hasExtInfo()
- ? getExtInfo()->TInfo
- : DeclInfo.get<TypeSourceInfo*>();
- }
- void setTypeSourceInfo(TypeSourceInfo *TI) {
- if (hasExtInfo())
- getExtInfo()->TInfo = TI;
- else
- DeclInfo = TI;
- }
-
- /// getInnerLocStart - Return SourceLocation representing 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.
- SourceLocation getOuterLocStart() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
- SourceLocation getLocStart() const LLVM_READONLY {
- return getOuterLocStart();
- }
-
- /// \brief 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
- /// information) that qualifies the name of this declaration, if it was
- /// present in the source.
- NestedNameSpecifierLoc getQualifierLoc() const {
- return hasExtInfo() ? getExtInfo()->QualifierLoc
- : NestedNameSpecifierLoc();
- }
-
- void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
-
- unsigned getNumTemplateParameterLists() const {
- return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
- }
- TemplateParameterList *getTemplateParameterList(unsigned index) const {
- assert(index < getNumTemplateParameterLists());
- return getExtInfo()->TemplParamLists[index];
- }
- void setTemplateParameterListsInfo(ASTContext &Context,
- ArrayRef<TemplateParameterList *> TPLists);
-
- SourceLocation getTypeSpecStartLoc() const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstDeclarator && K <= lastDeclarator;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief 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 {
- EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
- CheckingICE(false), IsICE(false) { }
-
- /// \brief Whether this statement was already evaluated.
- bool WasEvaluated : 1;
-
- /// \brief Whether this statement is being evaluated.
- bool IsEvaluating : 1;
-
- /// \brief 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
- /// integral constant expression.
- bool CheckingICE : 1;
-
- /// \brief 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;
-
- Stmt *Value;
- APValue Evaluated;
-};
-
-/// VarDecl - An instance of this class is created to represent a variable
-/// declaration or definition.
-class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
-public:
- /// getStorageClassSpecifierString - 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);
-
- /// \brief Initialization styles.
- enum InitializationStyle {
- CInit, ///< C-style initialization with assignment
- CallInit, ///< Call-style initialization (C++98)
- ListInit ///< Direct list-initialization (C++11)
- };
-
- /// \brief Kinds of thread-local storage.
- enum TLSKind {
- TLS_None, ///< Not a TLS variable.
- TLS_Static, ///< TLS with a known-constant initializer.
- TLS_Dynamic ///< TLS with a dynamic initializer.
- };
-
-protected:
- // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we
- // have allocated the auxilliary struct of information there.
- //
- // TODO: It is a bit unfortunate to use a PointerUnion inside the VarDecl for
- // this as *many* VarDecls are ParmVarDecls that don't have default
- // arguments. We could save some space by moving this pointer union to be
- // allocated in trailing space when necessary.
- typedef llvm::PointerUnion<Stmt *, EvaluatedStmt *> InitType;
-
- /// \brief The initializer for this variable or, for a ParmVarDecl, the
- /// C++ default argument.
- mutable InitType Init;
-
-private:
- class VarDeclBitfields {
- friend class VarDecl;
- friend class ASTDeclReader;
-
- unsigned SClass : 3;
- unsigned TSCSpec : 2;
- unsigned InitStyle : 2;
- };
- enum { NumVarDeclBits = 7 };
-
- friend class ASTDeclReader;
- friend class StmtIteratorBase;
- friend class ASTNodeImporter;
-
-protected:
- enum { NumParameterIndexBits = 8 };
-
- enum DefaultArgKind {
- DAK_None,
- DAK_Unparsed,
- DAK_Uninstantiated,
- DAK_Normal
- };
-
- class ParmVarDeclBitfields {
- friend class ParmVarDecl;
- friend class ASTDeclReader;
-
- unsigned : NumVarDeclBits;
-
- /// Whether this parameter inherits a default argument from a
- /// prior declaration.
- unsigned HasInheritedDefaultArg : 1;
-
- /// Describes the kind of default argument for this parameter. By default
- /// this is none. If this is normal, then the default argument is stored in
- /// the \c VarDecl initalizer expression unless we were unble to parse
- /// (even an invalid) expression for the default argument.
- unsigned DefaultArgKind : 2;
-
- /// Whether this parameter undergoes K&R argument promotion.
- unsigned IsKNRPromoted : 1;
-
- /// Whether this parameter is an ObjC method parameter or not.
- unsigned IsObjCMethodParam : 1;
-
- /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
- /// Otherwise, the number of function parameter scopes enclosing
- /// the function parameter scope in which this parameter was
- /// declared.
- unsigned ScopeDepthOrObjCQuals : 7;
-
- /// The number of parameters preceding this parameter in the
- /// function parameter scope in which it was declared.
- unsigned ParameterIndex : NumParameterIndexBits;
- };
-
- class NonParmVarDeclBitfields {
- friend class VarDecl;
- friend class ASTDeclReader;
-
- unsigned : NumVarDeclBits;
-
- /// \brief 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
- /// 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
- /// for-range statement.
- unsigned CXXForRangeDecl : 1;
-
- /// \brief Whether this variable is an ARC pseudo-__strong
- /// variable; see isARCPseudoStrong() for details.
- unsigned ARCPseudoStrong : 1;
-
- /// \brief Whether this variable is (C++0x) constexpr.
- unsigned IsConstexpr : 1;
-
- /// \brief Whether this variable is a (C++ Concepts TS) concept.
- unsigned IsConcept : 1;
-
- /// \brief 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
- /// declared in the same block scope. This controls whether we should merge
- /// the type of this declaration with its previous declaration.
- unsigned PreviousDeclInSameBlockScope : 1;
- };
-
- union {
- unsigned AllBits;
- VarDeclBitfields VarDeclBits;
- ParmVarDeclBitfields ParmVarDeclBits;
- NonParmVarDeclBitfields NonParmVarDeclBits;
- };
-
- VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC);
-
- typedef Redeclarable<VarDecl> redeclarable_base;
- VarDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- VarDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- VarDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- static VarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S);
-
- static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// \brief Returns the storage class as written in the source. For the
- /// computed linkage of symbol, see getLinkage.
- StorageClass getStorageClass() const {
- return (StorageClass) VarDeclBits.SClass;
- }
- void setStorageClass(StorageClass SC);
-
- void setTSCSpec(ThreadStorageClassSpecifier TSC) {
- VarDeclBits.TSCSpec = TSC;
- assert(VarDeclBits.TSCSpec == TSC && "truncation");
- }
- ThreadStorageClassSpecifier getTSCSpec() const {
- return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec);
- }
- TLSKind getTLSKind() const;
-
- /// hasLocalStorage - Returns true if a variable with function scope
- /// is a non-static local variable.
- bool hasLocalStorage() const {
- if (getStorageClass() == SC_None)
- // Second check is for C++11 [dcl.stc]p4.
- return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
-
- // Global Named Register (GNU extension)
- if (getStorageClass() == SC_Register && !isLocalVarDeclOrParm())
- return false;
-
- // Return true for: Auto, Register.
- // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
-
- return getStorageClass() >= SC_Auto;
- }
-
- /// isStaticLocal - 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
- (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local))
- && !isFileVarDecl();
- }
-
- /// \brief 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.
- ///
- /// 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].
- StorageDuration getStorageDuration() const {
- return hasLocalStorage() ? SD_Automatic :
- getTSCSpec() ? SD_Thread : SD_Static;
- }
-
- /// \brief Compute the language linkage.
- LanguageLinkage getLanguageLinkage() const;
-
- /// \brief 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,
- /// a C++ extern "C" linkage spec.
- bool isInExternCContext() const;
-
- /// \brief 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.
- ///
- /// void foo() { int x; static int y; extern int z; }
- ///
- bool isLocalVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- if (const DeclContext *DC = getLexicalDeclContext())
- return DC->getRedeclContext()->isFunctionOrMethod();
- return false;
- }
-
- /// \brief 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.
- bool isFunctionOrMethodVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();
- return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
- }
-
- /// \brief Determines whether this is a static data member.
- ///
- /// This will only be true in C++, and applies to, e.g., the
- /// variable 'x' in:
- /// \code
- /// struct S {
- /// static int x;
- /// };
- /// \endcode
- bool isStaticDataMember() const {
- // If it wasn't static, it would be a FieldDecl.
- return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
- }
-
- VarDecl *getCanonicalDecl() override;
- const VarDecl *getCanonicalDecl() const {
- return const_cast<VarDecl*>(this)->getCanonicalDecl();
- }
-
- enum DefinitionKind {
- DeclarationOnly, ///< This declaration is only a declaration.
- TentativeDefinition, ///< This declaration is a tentative definition.
- Definition ///< This declaration is definitely a definition.
- };
-
- /// \brief 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;
- DefinitionKind isThisDeclarationADefinition() const {
- return isThisDeclarationADefinition(getASTContext());
- }
-
- /// \brief 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.
- VarDecl *getActingDefinition();
- const VarDecl *getActingDefinition() const {
- return const_cast<VarDecl*>(this)->getActingDefinition();
- }
-
- /// \brief 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);
- }
- VarDecl *getDefinition() {
- return getDefinition(getASTContext());
- }
- const VarDecl *getDefinition() const {
- return const_cast<VarDecl*>(this)->getDefinition();
- }
-
- /// \brief Determine whether this is or was instantiated from an out-of-line
- /// definition of a static data member.
- bool isOutOfLine() const override;
-
- /// \brief If this is a static data member, find its out-of-line definition.
- VarDecl *getOutOfLineDefinition();
-
- /// isFileVarDecl - Returns true for file scoped variable declaration.
- bool isFileVarDecl() const {
- Kind K = getKind();
- if (K == ParmVar || K == ImplicitParam)
- return false;
-
- if (getLexicalDeclContext()->getRedeclContext()->isFileContext())
- return true;
-
- if (isStaticDataMember())
- return true;
-
- return false;
- }
-
- /// getAnyInitializer - 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
- /// declaration it is attached to. Also get that declaration.
- const Expr *getAnyInitializer(const VarDecl *&D) const;
-
- bool hasInit() const;
- const Expr *getInit() const {
- return const_cast<VarDecl *>(this)->getInit();
- }
- Expr *getInit();
-
- /// \brief 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
- /// 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.
- bool isUsableInConstantExpressions(ASTContext &C) const;
-
- EvaluatedStmt *ensureEvaluatedStmt() const;
-
- /// \brief 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
- /// 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
- /// initializer is an integral constant expression or not.
- bool isInitKnownICE() const;
-
- /// \brief 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
- /// declaration is an integral constant expression.
- bool checkInitIsICE() const;
-
- void setInitStyle(InitializationStyle Style) {
- VarDeclBits.InitStyle = Style;
- }
-
- /// \brief 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
- /// the expression inside the parens or a "ClassType(a,b,c)" class constructor
- /// expression for class types. List-style initialization is C++11 syntax,
- /// e.g. "int x{1};". Clients can distinguish between different forms of
- /// initialization by checking this value. In particular, "int x = {1};" is
- /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the
- /// Init expression in all three cases is an InitListExpr.
- InitializationStyle getInitStyle() const {
- return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
- }
-
- /// \brief Whether the initializer is a direct-initializer (list or call).
- bool isDirectInit() const {
- return getInitStyle() != CInit;
- }
-
- /// \brief 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;
- }
- void setExceptionVariable(bool EV) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.ExceptionVar = EV;
- }
-
- /// \brief 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
- /// non-volatile local variables of class type as NRVO objects. These
- /// locals can be allocated within the return slot of their containing
- /// function, in which case there is no need to copy the object to the
- /// return slot when returning from the function. Within the function body,
- /// each return that returns the NRVO object will have this variable as its
- /// NRVO candidate.
- bool isNRVOVariable() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOVariable;
- }
- void setNRVOVariable(bool NRVO) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.NRVOVariable = NRVO;
- }
-
- /// \brief 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;
- }
- void setCXXForRangeDecl(bool FRD) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.CXXForRangeDecl = FRD;
- }
-
- /// \brief 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.
- bool isARCPseudoStrong() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ARCPseudoStrong;
- }
- void setARCPseudoStrong(bool ps) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.ARCPseudoStrong = ps;
- }
-
- /// Whether this variable is (C++11) constexpr.
- bool isConstexpr() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConstexpr;
- }
- void setConstexpr(bool IC) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.IsConstexpr = IC;
- }
-
- /// Whether this variable is (C++ Concepts TS) concept.
- bool isConcept() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConcept;
- }
- void setConcept(bool IC) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.IsConcept = IC;
- }
-
- /// Whether this variable is the implicit variable for a lambda init-capture.
- bool isInitCapture() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture;
- }
- void setInitCapture(bool IC) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.IsInitCapture = IC;
- }
-
- /// Whether this local extern variable declaration's previous declaration
- /// was declared in the same block scope. Only correct in C++.
- bool isPreviousDeclInSameBlockScope() const {
- return isa<ParmVarDecl>(this)
- ? false
- : NonParmVarDeclBits.PreviousDeclInSameBlockScope;
- }
- void setPreviousDeclInSameBlockScope(bool Same) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
- }
-
- /// \brief 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
- /// 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
- /// 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
- /// class template specialization, retrieves the member specialization
- /// information.
- MemberSpecializationInfo *getMemberSpecializationInfo() const;
-
- /// \brief 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
- /// static data member VD.
- void setInstantiationOfStaticDataMember(VarDecl *VD,
- TemplateSpecializationKind TSK);
-
- /// \brief Retrieves the variable template that is described by this
- /// variable declaration.
- ///
- /// Every variable template is represented as a VarTemplateDecl and a
- /// VarDecl. The former contains template properties (such as
- /// the template parameter lists) while the latter contains the
- /// actual description of the template's
- /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the
- /// VarDecl that from a VarTemplateDecl, while
- /// getDescribedVarTemplate() retrieves the VarTemplateDecl from
- /// a VarDecl.
- VarTemplateDecl *getDescribedVarTemplate() const;
-
- void setDescribedVarTemplate(VarTemplateDecl *Template);
-
- // 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; }
-};
-
-class ImplicitParamDecl : public VarDecl {
- void anchor() override;
-public:
- static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T);
-
- static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType Type)
- : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
- /*tinfo*/ nullptr, SC_None) {
- setImplicit();
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ImplicitParam; }
-};
-
-/// ParmVarDecl - Represents a parameter to a function.
-class ParmVarDecl : public VarDecl {
-public:
- enum { MaxFunctionScopeDepth = 255 };
- enum { MaxFunctionScopeIndex = 255 };
-
-protected:
- ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
- : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
- assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
- assert(ParmVarDeclBits.DefaultArgKind == DAK_None);
- assert(ParmVarDeclBits.IsKNRPromoted == false);
- assert(ParmVarDeclBits.IsObjCMethodParam == false);
- setDefaultArg(DefArg);
- }
-
-public:
- static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg);
-
- static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- void setObjCMethodScopeInfo(unsigned parameterIndex) {
- ParmVarDeclBits.IsObjCMethodParam = true;
- setParameterIndex(parameterIndex);
- }
-
- void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) {
- assert(!ParmVarDeclBits.IsObjCMethodParam);
-
- ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth;
- assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth
- && "truncation!");
-
- setParameterIndex(parameterIndex);
- }
-
- bool isObjCMethodParameter() const {
- return ParmVarDeclBits.IsObjCMethodParam;
- }
-
- unsigned getFunctionScopeDepth() const {
- if (ParmVarDeclBits.IsObjCMethodParam) return 0;
- return ParmVarDeclBits.ScopeDepthOrObjCQuals;
- }
-
- /// Returns the index of this parameter in its prototype or method scope.
- unsigned getFunctionScopeIndex() const {
- return getParameterIndex();
- }
-
- ObjCDeclQualifier getObjCDeclQualifier() const {
- if (!ParmVarDeclBits.IsObjCMethodParam) return OBJC_TQ_None;
- return ObjCDeclQualifier(ParmVarDeclBits.ScopeDepthOrObjCQuals);
- }
- void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
- assert(ParmVarDeclBits.IsObjCMethodParam);
- ParmVarDeclBits.ScopeDepthOrObjCQuals = QTVal;
- }
-
- /// True if the value passed to this parameter must undergo
- /// K&R-style default argument promotion:
- ///
- /// C99 6.5.2.2.
- /// If the expression that denotes the called function has a type
- /// that does not include a prototype, the integer promotions are
- /// performed on each argument, and arguments that have type float
- /// are promoted to double.
- bool isKNRPromoted() const {
- return ParmVarDeclBits.IsKNRPromoted;
- }
- void setKNRPromoted(bool promoted) {
- ParmVarDeclBits.IsKNRPromoted = promoted;
- }
-
- Expr *getDefaultArg();
- const Expr *getDefaultArg() const {
- return const_cast<ParmVarDecl *>(this)->getDefaultArg();
- }
-
- void setDefaultArg(Expr *defarg);
-
- /// \brief Retrieve the source range that covers the entire default
- /// argument.
- SourceRange getDefaultArgRange() const;
- void setUninstantiatedDefaultArg(Expr *arg);
- Expr *getUninstantiatedDefaultArg();
- const Expr *getUninstantiatedDefaultArg() const {
- return const_cast<ParmVarDecl *>(this)->getUninstantiatedDefaultArg();
- }
-
- /// hasDefaultArg - 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.,
- /// @code
- /// class X {
- /// public:
- /// void f(int x = 17); // x has an unparsed default argument now
- /// }; // x has a regular default argument now
- /// @endcode
- bool hasUnparsedDefaultArg() const {
- return ParmVarDeclBits.DefaultArgKind == DAK_Unparsed;
- }
-
- bool hasUninstantiatedDefaultArg() const {
- 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.
- void setUnparsedDefaultArg() {
- ParmVarDeclBits.DefaultArgKind = DAK_Unparsed;
- }
-
- bool hasInheritedDefaultArg() const {
- return ParmVarDeclBits.HasInheritedDefaultArg;
- }
-
- void setHasInheritedDefaultArg(bool I = true) {
- ParmVarDeclBits.HasInheritedDefaultArg = I;
- }
-
- QualType getOriginalType() const;
-
- /// \brief Determine whether this parameter is actually a function
- /// parameter pack.
- bool isParameterPack() const;
-
- /// setOwningFunction - 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.
- void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ParmVar; }
-
-private:
- enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 };
-
- void setParameterIndex(unsigned parameterIndex) {
- if (parameterIndex >= ParameterIndexSentinel) {
- setParameterIndexLarge(parameterIndex);
- return;
- }
-
- ParmVarDeclBits.ParameterIndex = parameterIndex;
- assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
- }
- unsigned getParameterIndex() const {
- unsigned d = ParmVarDeclBits.ParameterIndex;
- return d == ParameterIndexSentinel ? getParameterIndexLarge() : d;
- }
-
- void setParameterIndexLarge(unsigned parameterIndex);
- unsigned getParameterIndexLarge() const;
-};
-
-/// FunctionDecl - An instance of this class is created to represent 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
-/// function. Only one of those FunctionDecls will be found when
-/// traversing the list of declarations in the context of the
-/// FunctionDecl (e.g., the translation unit); this FunctionDecl
-/// contains all of the information known about the function. Other,
-/// previous declarations of the function are available via the
-/// getPreviousDecl() chain.
-class FunctionDecl : public DeclaratorDecl, public DeclContext,
- public Redeclarable<FunctionDecl> {
-public:
- /// \brief The kind of templated function a FunctionDecl can be.
- enum TemplatedKind {
- TK_NonTemplate,
- TK_FunctionTemplate,
- TK_MemberSpecialization,
- TK_FunctionTemplateSpecialization,
- TK_DependentFunctionTemplateSpecialization
- };
-
-private:
- /// ParamInfo - 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;
-
- /// DeclsInPrototypeScope - Array of pointers to NamedDecls for
- /// decls defined in the function prototype that are not parameters. E.g.
- /// 'enum Y' in 'void f(enum Y {AA} x) {}'.
- ArrayRef<NamedDecl *> DeclsInPrototypeScope;
-
- LazyDeclStmtPtr Body;
-
- // FIXME: This can be packed into the bitfields in DeclContext.
- // NOTE: VC++ packs bitfields poorly if the types differ.
- unsigned SClass : 2;
- unsigned IsInline : 1;
- unsigned IsInlineSpecified : 1;
- unsigned IsVirtualAsWritten : 1;
- unsigned IsPure : 1;
- unsigned HasInheritedPrototype : 1;
- unsigned HasWrittenPrototype : 1;
- unsigned IsDeleted : 1;
- unsigned IsTrivial : 1; // sunk from CXXMethodDecl
- unsigned IsDefaulted : 1; // sunk from CXXMethoDecl
- unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl
- unsigned HasImplicitReturnZero : 1;
- unsigned IsLateTemplateParsed : 1;
- unsigned IsConstexpr : 1;
-
- /// \brief Indicates if the function uses __try.
- unsigned UsesSEHTry : 1;
-
- /// \brief Indicates if the function was a definition but its body was
- /// skipped.
- unsigned HasSkippedBody : 1;
-
- /// \brief 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,
- /// we can only compute the full range once the function body has been
- /// de-serialized, so it's far better to have the (sometimes-redundant)
- /// EndRangeLoc.
- SourceLocation EndRangeLoc;
-
- /// \brief The template or declaration that this declaration
- /// describes or was instantiated from, respectively.
- ///
- /// For non-templates, this value will be NULL. For function
- /// declarations that describe a function template, this will be a
- /// pointer to a FunctionTemplateDecl. For member functions
- /// of class template specializations, this will be a MemberSpecializationInfo
- /// pointer containing information about the specialization.
- /// For function template specializations, this will be a
- /// FunctionTemplateSpecializationInfo, which contains information about
- /// the template being specialized and the template arguments involved in
- /// that specialization.
- llvm::PointerUnion4<FunctionTemplateDecl *,
- MemberSpecializationInfo *,
- FunctionTemplateSpecializationInfo *,
- DependentFunctionTemplateSpecializationInfo *>
- TemplateOrSpecialization;
-
- /// DNLoc - Provides source/type location info for the
- /// declaration name embedded in the DeclaratorDecl base class.
- DeclarationNameLoc DNLoc;
-
- /// \brief Specify that this function declaration is actually a function
- /// template specialization.
- ///
- /// \param C the ASTContext.
- ///
- /// \param Template the function template that this function template
- /// specialization specializes.
- ///
- /// \param TemplateArgs the template arguments that produced this
- /// function template specialization from the template.
- ///
- /// \param InsertPos If non-NULL, the position in the function template
- /// specialization set where the function template specialization data will
- /// be inserted.
- ///
- /// \param TSK the kind of template specialization this is.
- ///
- /// \param TemplateArgsAsWritten location info of template arguments.
- ///
- /// \param PointOfInstantiation point at which the function template
- /// specialization was first instantiated.
- void setFunctionTemplateSpecialization(ASTContext &C,
- FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation PointOfInstantiation);
-
- /// \brief Specify that this record is an instantiation of the
- /// member function FD.
- void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
- TemplateSpecializationKind TSK);
-
- void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
-
-protected:
- FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, bool isInlineSpecified,
- bool isConstexprSpecified)
- : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
- StartLoc),
- DeclContext(DK),
- redeclarable_base(C),
- ParamInfo(nullptr), Body(),
- SClass(S),
- IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
- IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
- HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
- IsDefaulted(false), IsExplicitlyDefaulted(false),
- HasImplicitReturnZero(false), IsLateTemplateParsed(false),
- IsConstexpr(isConstexprSpecified), UsesSEHTry(false),
- HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()),
- TemplateOrSpecialization(),
- DNLoc(NameInfo.getInfo()) {}
-
- typedef Redeclarable<FunctionDecl> redeclarable_base;
- FunctionDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- FunctionDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- FunctionDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation NLoc,
- DeclarationName N, QualType T,
- TypeSourceInfo *TInfo,
- StorageClass SC,
- bool isInlineSpecified = false,
- bool hasWrittenPrototype = true,
- bool isConstexprSpecified = false) {
- DeclarationNameInfo NameInfo(N, NLoc);
- return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo,
- SC,
- isInlineSpecified, hasWrittenPrototype,
- isConstexprSpecified);
- }
-
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass SC,
- bool isInlineSpecified,
- bool hasWrittenPrototype,
- bool isConstexprSpecified = false);
-
- static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
- }
-
- void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
- bool Qualified) const override;
-
- void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
-
- 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).
- bool hasBody(const FunctionDecl *&Definition) const;
-
- bool hasBody() const override {
- const FunctionDecl* Definition;
- return hasBody(Definition);
- }
-
- /// hasTrivialBody - Returns whether the function has a trivial body that does
- /// not require any specific codegen.
- bool hasTrivialBody() const;
-
- /// isDefined - 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.
- bool isDefined(const FunctionDecl *&Definition) const;
-
- virtual bool isDefined() const {
- const FunctionDecl* Definition;
- return isDefined(Definition);
- }
-
- /// getBody - Retrieve the body (definition) of the function. 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).
- /// NOTE: For checking if there is a body, use hasBody() instead, to avoid
- /// unnecessary AST de-serialization of the body.
- Stmt *getBody(const FunctionDecl *&Definition) const;
-
- Stmt *getBody() const override {
- const FunctionDecl* Definition;
- return getBody(Definition);
- }
-
- /// isThisDeclarationADefinition - Returns whether this specific
- /// declaration of the function is also a definition. This does not
- /// determine whether the function has been defined (e.g., in a
- /// previous definition); for that information, use isDefined. Note
- /// that this returns false for a defaulted function unless that function
- /// has been implicitly defined (possibly as deleted).
- bool isThisDeclarationADefinition() const {
- return IsDeleted || Body || IsLateTemplateParsed;
- }
-
- /// doesThisDeclarationHaveABody - Returns whether this specific
- /// declaration of the function has a body - that is, if it is a non-
- /// deleted definition.
- bool doesThisDeclarationHaveABody() const {
- return Body || IsLateTemplateParsed;
- }
-
- void setBody(Stmt *B);
- void setLazyBody(uint64_t Offset) { Body = Offset; }
-
- /// Whether this function is variadic.
- bool isVariadic() const;
-
- /// Whether this function is marked as virtual explicitly.
- bool isVirtualAsWritten() const { return IsVirtualAsWritten; }
- void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; }
-
- /// Whether this virtual function is pure, i.e. makes the containing class
- /// abstract.
- bool isPure() const { return IsPure; }
- void setPure(bool P = true);
-
- /// Whether this templated function will be late parsed.
- bool isLateTemplateParsed() const { return IsLateTemplateParsed; }
- void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; }
-
- /// Whether this function is "trivial" in some specialized C++ senses.
- /// Can only be true for default constructors, copy constructors,
- /// copy assignment operators, and destructors. Not meaningful until
- /// the class has been fully built by Sema.
- bool isTrivial() const { return IsTrivial; }
- void setTrivial(bool IT) { IsTrivial = IT; }
-
- /// Whether this function is defaulted per C++0x. Only valid for
- /// special member functions.
- bool isDefaulted() const { return IsDefaulted; }
- void setDefaulted(bool D = true) { IsDefaulted = D; }
-
- /// Whether this function is explicitly defaulted per C++0x. Only valid
- /// for special member functions.
- bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; }
- void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; }
-
- /// Whether falling off this function implicitly returns null/zero.
- /// If a more specific implicit return value is required, front-ends
- /// should synthesize the appropriate return statements.
- bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
- void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
-
- /// \brief 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.
- bool hasPrototype() const {
- return HasWrittenPrototype || HasInheritedPrototype;
- }
-
- bool hasWrittenPrototype() const { return HasWrittenPrototype; }
-
- /// \brief Whether this function inherited its prototype from a
- /// previous declaration.
- bool hasInheritedPrototype() const { return HasInheritedPrototype; }
- void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; }
-
- /// Whether this is a (C++11) constexpr function or constexpr constructor.
- bool isConstexpr() const { return IsConstexpr; }
- void setConstexpr(bool IC) { IsConstexpr = IC; }
-
- /// \brief Indicates the function uses __try.
- bool usesSEHTry() const { return UsesSEHTry; }
- void setUsesSEHTry(bool UST) { UsesSEHTry = UST; }
-
- /// \brief 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
- /// called or have its address taken. Deleted functions are
- /// typically used in C++ overload resolution to attract arguments
- /// whose type or lvalue/rvalue-ness would permit the use of a
- /// different overload that would behave incorrectly. For example,
- /// one might use deleted functions to ban implicit conversion from
- /// a floating-point number to an Integer type:
- ///
- /// @code
- /// struct Integer {
- /// Integer(long); // construct from a long
- /// Integer(double) = delete; // no construction from float or double
- /// Integer(long double) = delete; // no construction from long double
- /// };
- /// @endcode
- // If a function is deleted, its first declaration must be.
- bool isDeleted() const { return getCanonicalDecl()->IsDeleted; }
- bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; }
- void setDeletedAsWritten(bool D = true) { IsDeleted = D; }
-
- /// \brief 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
- /// point.
- bool isMSVCRTEntryPoint() const;
-
- /// \brief 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 *);
- /// void operator delete(void *, void *);
- /// void operator delete[](void *, void *);
- /// These functions have special behavior under [new.delete.placement]:
- /// These functions are reserved, a C++ program may not define
- /// functions that displace the versions in the Standard C++ library.
- /// The provisions of [basic.stc.dynamic] do not apply to these
- /// reserved placement forms of operator new and operator delete.
- ///
- /// This function must be an allocation or deallocation function.
- bool isReservedGlobalPlacementOperator() const;
-
- /// \brief 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;
- /// void *operator new[](size_t);
- /// void *operator new[](size_t, const std::nothrow_t &) noexcept;
- /// void operator delete(void *) noexcept;
- /// void operator delete(void *, std::size_t) noexcept; [C++1y]
- /// void operator delete(void *, const std::nothrow_t &) noexcept;
- /// void operator delete[](void *) noexcept;
- /// void operator delete[](void *, std::size_t) noexcept; [C++1y]
- /// void operator delete[](void *, const std::nothrow_t &) noexcept;
- /// These functions have special behavior under C++1y [expr.new]:
- /// An implementation is allowed to omit a call to a replaceable global
- /// allocation function. [...]
- bool isReplaceableGlobalAllocationFunction() const;
-
- /// Compute the language linkage.
- LanguageLinkage getLanguageLinkage() const;
-
- /// \brief 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,
- /// a C++ extern "C" linkage spec.
- bool isInExternCContext() const;
-
- /// \brief 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.
- bool isGlobal() const;
-
- /// \brief 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.
- bool hasSkippedBody() const { return HasSkippedBody; }
- void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
-
- void setPreviousDeclaration(FunctionDecl * PrevDecl);
-
- FunctionDecl *getCanonicalDecl() override;
- const FunctionDecl *getCanonicalDecl() const {
- return const_cast<FunctionDecl*>(this)->getCanonicalDecl();
- }
-
- unsigned getBuiltinID() const;
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return getNumParams(); }
- typedef ParmVarDecl **param_iterator;
- typedef ParmVarDecl * const *param_const_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
- typedef llvm::iterator_range<param_const_iterator> param_const_range;
-
- param_iterator param_begin() { return param_iterator(ParamInfo); }
- param_iterator param_end() {
- return param_iterator(ParamInfo + param_size());
- }
- param_range params() { return param_range(param_begin(), param_end()); }
-
- param_const_iterator param_begin() const {
- return param_const_iterator(ParamInfo);
- }
- param_const_iterator param_end() const {
- return param_const_iterator(ParamInfo + param_size());
- }
- param_const_range params() const {
- return param_const_range(param_begin(), param_end());
- }
-
- /// getNumParams - Return the number of parameters this function must have
- /// based on its FunctionType. This is the length of the ParamInfo array
- /// after it has been created.
- unsigned getNumParams() const;
-
- const ParmVarDecl *getParamDecl(unsigned i) const {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- ParmVarDecl *getParamDecl(unsigned i) {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- void setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
- setParams(getASTContext(), NewParamInfo);
- }
-
- // ArrayRef iterface to parameters.
- // FIXME: Should one day replace iterator interface.
- ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(ParamInfo, getNumParams());
- }
-
- ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
- return DeclsInPrototypeScope;
- }
- void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
-
- /// getMinRequiredArguments - Returns the minimum number of arguments
- /// needed to call this function. This may be fewer than the number of
- /// function parameters, if some of the parameters have default
- /// arguments (in C++).
- unsigned getMinRequiredArguments() const;
-
- QualType getReturnType() const {
- return getType()->getAs<FunctionType>()->getReturnType();
- }
-
- /// \brief Attempt to compute an informative source range covering the
- /// function return type. This may omit qualifiers and other information with
- /// limited representation in the AST.
- SourceRange getReturnTypeSourceRange() const;
-
- /// \brief Determine the type of an expression that calls this function.
- QualType getCallResultType() const {
- return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
- }
-
- /// \brief Returns true if this function or its return type has the
- /// warn_unused_result attribute. If the return type has the attribute and
- /// this function is a method of the return type's class, then false will be
- /// returned to avoid spurious warnings on member methods such as assignment
- /// operators.
- bool hasUnusedResultAttr() const;
-
- /// \brief 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
- /// function.
- bool isInlineSpecified() const { return IsInlineSpecified; }
-
- /// Set whether the "inline" keyword was specified for this function.
- void setInlineSpecified(bool I) {
- IsInlineSpecified = I;
- IsInline = I;
- }
-
- /// Flag that this function is implicitly inline.
- void setImplicitlyInline() {
- IsInline = true;
- }
-
- /// \brief 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; }
-
- bool isInlineDefinitionExternallyVisible() const;
-
- bool isMSExternInline() const;
-
- bool doesDeclarationForceExternallyVisibleDefinition() const;
-
- /// isOverloadedOperator - Whether this function declaration
- /// represents an C++ overloaded operator, e.g., "operator+".
- bool isOverloadedOperator() const {
- return getOverloadedOperator() != OO_None;
- }
-
- OverloadedOperatorKind getOverloadedOperator() const;
-
- const IdentifierInfo *getLiteralIdentifier() const;
-
- /// \brief If this function is an instantiation of a member function
- /// of a class template specialization, retrieves the function from
- /// which it was instantiated.
- ///
- /// This routine will return non-NULL for (non-templated) member
- /// functions of class templates and for instantiations of function
- /// templates. For example, given:
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// void f(T);
- /// };
- /// \endcode
- ///
- /// The declaration for X<int>::f is a (non-templated) FunctionDecl
- /// whose parent is the class template specialization X<int>. For
- /// this declaration, getInstantiatedFromFunction() will return
- /// the FunctionDecl X<T>::A. When a complete definition of
- /// X<int>::A is required, it will be instantiated from the
- /// declaration returned by getInstantiatedFromMemberFunction().
- FunctionDecl *getInstantiatedFromMemberFunction() const;
-
- /// \brief What kind of templated function this is.
- TemplatedKind getTemplatedKind() const;
-
- /// \brief 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
- /// member function FD.
- void setInstantiationOfMemberFunction(FunctionDecl *FD,
- TemplateSpecializationKind TSK) {
- setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
- }
-
- /// \brief Retrieves the function template that is described by this
- /// function declaration.
- ///
- /// Every function template is represented as a FunctionTemplateDecl
- /// and a FunctionDecl (or something derived from FunctionDecl). The
- /// former contains template properties (such as the template
- /// parameter lists) while the latter contains the actual
- /// description of the template's
- /// contents. FunctionTemplateDecl::getTemplatedDecl() retrieves the
- /// FunctionDecl that describes the function template,
- /// getDescribedFunctionTemplate() retrieves the
- /// FunctionTemplateDecl from a FunctionDecl.
- FunctionTemplateDecl *getDescribedFunctionTemplate() const;
-
- void setDescribedFunctionTemplate(FunctionTemplateDecl *Template);
-
- /// \brief 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
- /// template specialization is instantiated from.
- FunctionDecl *getClassScopeSpecializationPattern() const;
-
- /// \brief 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
- /// 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
- /// function template.
- bool isTemplateInstantiation() const;
-
- /// \brief 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
- /// 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
- /// 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,
- /// if any.
- ///
- /// If this function declaration is not a function template specialization
- /// or if it had no explicit template argument list, returns NULL.
- /// Note that it an explicit template argument list may be written empty,
- /// e.g., template<> void foo<>(char* s);
- const ASTTemplateArgumentListInfo*
- getTemplateSpecializationArgsAsWritten() const;
-
- /// \brief Specify that this function declaration is actually a function
- /// template specialization.
- ///
- /// \param Template the function template that this function template
- /// specialization specializes.
- ///
- /// \param TemplateArgs the template arguments that produced this
- /// function template specialization from the template.
- ///
- /// \param InsertPos If non-NULL, the position in the function template
- /// specialization set where the function template specialization data will
- /// be inserted.
- ///
- /// \param TSK the kind of template specialization this is.
- ///
- /// \param TemplateArgsAsWritten location info of template arguments.
- ///
- /// \param PointOfInstantiation point at which the function template
- /// specialization was first instantiated.
- void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
- const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr,
- SourceLocation PointOfInstantiation = SourceLocation()) {
- setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
- InsertPos, TSK, TemplateArgsAsWritten,
- PointOfInstantiation);
- }
-
- /// \brief Specifies that this function declaration is actually a
- /// dependent function template specialization.
- void setDependentTemplateSpecialization(ASTContext &Context,
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
-
- DependentFunctionTemplateSpecializationInfo *
- getDependentSpecializationInfo() const;
-
- /// \brief Determine what kind of template instantiation this function
- /// represents.
- TemplateSpecializationKind getTemplateSpecializationKind() const;
-
- /// \brief 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
- /// specialization or a member of a class template specialization.
- ///
- /// \returns the first point of instantiation, if this function was
- /// instantiated from a template; otherwise, returns an invalid source
- /// location.
- SourceLocation getPointOfInstantiation() const;
-
- /// \brief 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.
- /// 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;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstFunction && K <= lastFunction;
- }
- static DeclContext *castToDeclContext(const FunctionDecl *D) {
- return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
- }
- static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-
-/// FieldDecl - An instance of this class is created by Sema::ActOnField to
-/// represent a member of a struct/union/class.
-class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
- // FIXME: This can be packed into the bitfields in Decl.
- bool Mutable : 1;
- mutable unsigned CachedFieldIndex : 31;
-
- /// The kinds of value we can store in InitializerOrBitWidth.
- ///
- /// Note that this is compatible with InClassInitStyle except for
- /// ISK_CapturedVLAType.
- enum InitStorageKind {
- /// If the pointer is null, there's nothing special. Otherwise,
- /// this is a bitfield and the pointer is the Expr* storing the
- /// bit-width.
- ISK_BitWidthOrNothing = (unsigned) ICIS_NoInit,
-
- /// The pointer is an (optional due to delayed parsing) Expr*
- /// holding the copy-initializer.
- ISK_InClassCopyInit = (unsigned) ICIS_CopyInit,
-
- /// The pointer is an (optional due to delayed parsing) Expr*
- /// holding the list-initializer.
- ISK_InClassListInit = (unsigned) ICIS_ListInit,
-
- /// The pointer is a VariableArrayType* that's been captured;
- /// the enclosing context is a lambda or captured statement.
- ISK_CapturedVLAType,
- };
-
- /// \brief Storage for either the bit-width, the in-class
- /// initializer, or the captured variable length array bound.
- ///
- /// We can safely combine these because in-class initializers are
- /// not permitted for bit-fields, and both are exclusive with VLA
- /// captures.
- ///
- /// If the storage kind is ISK_InClassCopyInit or
- /// ISK_InClassListInit, but the initializer is null, then this
- /// field has an in-class initializer which has not yet been parsed
- /// and attached.
- llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage;
-protected:
- FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
- InClassInitStyle InitStyle)
- : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
- Mutable(Mutable), CachedFieldIndex(0),
- InitStorage(BW, (InitStorageKind) InitStyle) {
- assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield");
- }
-
-public:
- static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
- InClassInitStyle InitStyle);
-
- static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// getFieldIndex - 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).
- bool isMutable() const { return Mutable; }
-
- /// \brief Determines whether this field is a bitfield.
- bool isBitField() const {
- return InitStorage.getInt() == ISK_BitWidthOrNothing &&
- InitStorage.getPointer() != nullptr;
- }
-
- /// @brief Determines whether this is an unnamed bitfield.
- bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
-
- /// isAnonymousStructOrUnion - 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.
- bool isAnonymousStructOrUnion() const;
-
- Expr *getBitWidth() const {
- return isBitField()
- ? static_cast<Expr *>(InitStorage.getPointer())
- : nullptr;
- }
- unsigned getBitWidthValue(const ASTContext &Ctx) const;
-
- /// setBitWidth - Set the bit-field width for this member.
- // Note: used by some clients (i.e., do not remove it).
- void setBitWidth(Expr *Width) {
- assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
- InitStorage.getPointer() == nullptr &&
- "bit width, initializer or captured type already set");
- InitStorage.setPointerAndInt(Width, ISK_BitWidthOrNothing);
- }
-
- /// removeBitWidth - 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");
- InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
- }
-
- /// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
- /// this field has.
- InClassInitStyle getInClassInitStyle() const {
- InitStorageKind storageKind = InitStorage.getInt();
- return (storageKind == ISK_CapturedVLAType
- ? ICIS_NoInit : (InClassInitStyle) storageKind);
- }
-
- /// hasInClassInitializer - Determine whether this member has a C++11 in-class
- /// initializer.
- bool hasInClassInitializer() const {
- return getInClassInitStyle() != ICIS_NoInit;
- }
-
- /// getInClassInitializer - Get the C++11 in-class initializer for this
- /// member, or null if one has not been set. If a valid declaration has an
- /// in-class initializer, but this returns null, then we have not parsed and
- /// attached it yet.
- Expr *getInClassInitializer() const {
- return hasInClassInitializer()
- ? static_cast<Expr *>(InitStorage.getPointer())
- : nullptr;
- }
-
- /// setInClassInitializer - Set the C++11 in-class initializer for this
- /// member.
- void setInClassInitializer(Expr *Init) {
- assert(hasInClassInitializer() &&
- InitStorage.getPointer() == nullptr &&
- "bit width, initializer or captured type already set");
- InitStorage.setPointer(Init);
- }
-
- /// removeInClassInitializer - Remove the C++11 in-class initializer from this
- /// member.
- void removeInClassInitializer() {
- assert(hasInClassInitializer() && "no initializer to remove");
- InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
- }
-
- /// \brief 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.
- const VariableArrayType *getCapturedVLAType() const {
- return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
- InitStorage.getPointer())
- : nullptr;
- }
- /// \brief Set the captured variable length array type for this field.
- void setCapturedVLAType(const VariableArrayType *VLAType);
-
- /// getParent - Returns the parent of this field declaration, which
- /// is the struct in which this method is defined.
- const RecordDecl *getParent() const {
- return cast<RecordDecl>(getDeclContext());
- }
-
- RecordDecl *getParent() {
- return cast<RecordDecl>(getDeclContext());
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Retrieves the canonical declaration of this field.
- FieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// EnumConstantDecl - 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.
-class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
- Stmt *Init; // an integer constant expression
- llvm::APSInt Val; // The value.
-protected:
- EnumConstantDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, Expr *E,
- const llvm::APSInt &V)
- : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
-
-public:
-
- static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *E,
- const llvm::APSInt &V);
- static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- const Expr *getInitExpr() const { return (const Expr*) Init; }
- Expr *getInitExpr() { return (Expr*) Init; }
- const llvm::APSInt &getInitVal() const { return Val; }
-
- void setInitExpr(Expr *E) { Init = (Stmt*) E; }
- void setInitVal(const llvm::APSInt &V) { Val = V; }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Retrieves the canonical declaration of this enumerator.
- EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == EnumConstant; }
-
- friend class StmtIteratorBase;
-};
-
-/// 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.
-class IndirectFieldDecl : public ValueDecl,
- public Mergeable<IndirectFieldDecl> {
- void anchor() override;
- NamedDecl **Chaining;
- unsigned ChainingSize;
-
- IndirectFieldDecl(DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T,
- NamedDecl **CH, unsigned CHS)
- : ValueDecl(IndirectField, DC, L, N, T), Chaining(CH), ChainingSize(CHS) {}
-
-public:
- static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, NamedDecl **CH, unsigned CHS);
-
- static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- typedef NamedDecl * const *chain_iterator;
- typedef llvm::iterator_range<chain_iterator> chain_range;
-
- chain_range chain() const { return chain_range(chain_begin(), chain_end()); }
- chain_iterator chain_begin() const { return chain_iterator(Chaining); }
- chain_iterator chain_end() const {
- return chain_iterator(Chaining + ChainingSize);
- }
-
- unsigned getChainingSize() const { return ChainingSize; }
-
- FieldDecl *getAnonField() const {
- assert(ChainingSize >= 2);
- return cast<FieldDecl>(Chaining[ChainingSize - 1]);
- }
-
- VarDecl *getVarDecl() const {
- assert(ChainingSize >= 2);
- return dyn_cast<VarDecl>(*chain_begin());
- }
-
- IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const IndirectFieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == IndirectField; }
- friend class ASTDeclReader;
-};
-
-/// TypeDecl - Represents a declaration of a type.
-///
-class TypeDecl : public NamedDecl {
- void anchor() override;
- /// TypeForDecl - 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;
- /// LocStart - The start of the source range for this declaration.
- SourceLocation LocStart;
- friend class ASTContext;
-
-protected:
- TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- SourceLocation StartL = SourceLocation())
- : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {}
-
-public:
- // Low-level accessor. If you just want the type defined by this node,
- // check out ASTContext::getTypeDeclType or one of
- // ASTContext::getTypedefType, ASTContext::getRecordType, etc. if you
- // already know the specific kind of node this is.
- const Type *getTypeForDecl() const { return TypeForDecl; }
- void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
- void setLocStart(SourceLocation L) { LocStart = L; }
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (LocStart.isValid())
- return SourceRange(LocStart, getLocation());
- else
- return SourceRange(getLocation());
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstType && K <= lastType; }
-};
-
-
-/// Base class for declarations which introduce a typedef-name.
-class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
- void anchor() override;
- typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
- llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
-
-protected:
- TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
- MaybeModedTInfo(TInfo) {}
-
- typedef Redeclarable<TypedefNameDecl> redeclarable_base;
- TypedefNameDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- TypedefNameDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- TypedefNameDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return isModed()
- ? MaybeModedTInfo.get<ModedTInfo*>()->first
- : MaybeModedTInfo.get<TypeSourceInfo*>();
- }
- QualType getUnderlyingType() const {
- return isModed()
- ? MaybeModedTInfo.get<ModedTInfo*>()->second
- : MaybeModedTInfo.get<TypeSourceInfo*>()->getType();
- }
- void setTypeSourceInfo(TypeSourceInfo *newType) {
- MaybeModedTInfo = newType;
- }
- void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) {
- MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy);
- }
-
- /// Retrieves the canonical declaration of this typedef-name.
- TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- /// Retrieves the tag declaration for which this is the typedef name for
- /// linkage purposes, if any.
- ///
- /// \param AnyRedecl Look for the tag declaration in any redeclaration of
- /// this typedef declaration.
- TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstTypedefName && K <= lastTypedefName;
- }
-};
-
-/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
-/// type specifier.
-class TypedefDecl : public TypedefNameDecl {
- TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {}
-
-public:
- static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo);
- static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Typedef; }
-};
-
-/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
-/// alias-declaration.
-class TypeAliasDecl : public TypedefNameDecl {
- /// The template for which this is the pattern, if any.
- TypeAliasTemplateDecl *Template;
-
- TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo),
- Template(nullptr) {}
-
-public:
- static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo);
- static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- TypeAliasTemplateDecl *getDescribedAliasTemplate() const { return Template; }
- void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT) { Template = TAT; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TypeAlias; }
-};
-
-/// TagDecl - Represents the declaration of a struct/union/class/enum.
-class TagDecl
- : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
-public:
- // This is really ugly.
- typedef TagTypeKind TagKind;
-
-private:
- // FIXME: This can be packed into the bitfields in Decl.
- /// TagDeclKind - 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.
- bool IsCompleteDefinition : 1;
-
-protected:
- /// IsBeingDefined - True if this is currently being defined.
- bool 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.
- bool IsEmbeddedInDeclarator : 1;
-
- /// \brief True if this tag is free standing, e.g. "struct foo;".
- bool IsFreeStanding : 1;
-
-protected:
- // These are used by (and only defined for) EnumDecl.
- unsigned NumPositiveBits : 8;
- unsigned NumNegativeBits : 8;
-
- /// IsScoped - True if this tag declaration is a scoped enumeration. Only
- /// possible in C++11 mode.
- bool IsScoped : 1;
- /// IsScopedUsingClassTag - 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.
- bool IsScopedUsingClassTag : 1;
-
- /// IsFixed - True if this is an enumeration with fixed underlying type. Only
- /// possible in C++11, Microsoft extensions, or Objective C mode.
- bool IsFixed : 1;
-
- /// \brief 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.
- bool MayHaveOutOfDateDef : 1;
-
- /// Has the full definition of this type been required by a use somewhere in
- /// the TU.
- bool IsCompleteDefinitionRequired : 1;
-private:
- SourceLocation RBraceLoc;
-
- // A struct representing syntactic qualifier info,
- // to be used for the (uncommon) case of out-of-line declarations.
- typedef QualifierInfo ExtInfo;
-
- /// \brief 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);
- /// otherwise, if the tag declaration is anonymous and it is used as a
- /// declaration specifier for variables, it points to the first VarDecl (used
- /// for mangling);
- /// otherwise, it is a null (TypedefNameDecl) pointer.
- llvm::PointerUnion<TypedefNameDecl *, ExtInfo *> TypedefNameDeclOrQualifier;
-
- bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo *>(); }
- ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo *>(); }
- const ExtInfo *getExtInfo() const {
- return TypedefNameDeclOrQualifier.get<ExtInfo *>();
- }
-
-protected:
- TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
- SourceLocation StartL)
- : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
- TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false),
- IsEmbeddedInDeclarator(false), IsFreeStanding(false),
- IsCompleteDefinitionRequired(false),
- TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) {
- assert((DK != Enum || TK == TTK_Enum) &&
- "EnumDecl not matched with TTK_Enum");
- setPreviousDecl(PrevDecl);
- }
-
- typedef Redeclarable<TagDecl> redeclarable_base;
- TagDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- TagDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- TagDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
- /// @brief Completes the definition of this tag declaration.
- ///
- /// This is a helper function for derived classes.
- void completeDefinition();
-
-public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- SourceLocation getRBraceLoc() const { return RBraceLoc; }
- void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
-
- /// getInnerLocStart - Return SourceLocation representing start of source
- /// range ignoring outer template declarations.
- SourceLocation getInnerLocStart() const { return getLocStart(); }
-
- /// getOuterLocStart - Return SourceLocation representing start of source
- /// range taking into account any outer template declarations.
- SourceLocation getOuterLocStart() const;
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- TagDecl *getCanonicalDecl() override;
- const TagDecl *getCanonicalDecl() const {
- return const_cast<TagDecl*>(this)->getCanonicalDecl();
- }
-
- /// isThisDeclarationADefinition() - 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.
- bool isCompleteDefinition() const {
- return IsCompleteDefinition;
- }
-
- /// \brief 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.
- bool isBeingDefined() const {
- return IsBeingDefined;
- }
-
- bool isEmbeddedInDeclarator() const {
- return IsEmbeddedInDeclarator;
- }
- void setEmbeddedInDeclarator(bool isInDeclarator) {
- IsEmbeddedInDeclarator = isInDeclarator;
- }
-
- bool isFreeStanding() const { return IsFreeStanding; }
- void setFreeStanding(bool isFreeStanding = true) {
- IsFreeStanding = isFreeStanding;
- }
-
- /// \brief 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.
- ///
- /// 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
- /// 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
- /// whether or not a specific TagDecl is defining declaration, not
- /// whether or not the struct/union/class/enum type is defined.
- /// This method returns NULL if there is no TagDecl that defines
- /// the struct/union/class/enum.
- TagDecl *getDefinition() const;
-
- void setCompleteDefinition(bool V) { IsCompleteDefinition = V; }
-
- void setCompleteDefinitionRequired(bool V = true) {
- IsCompleteDefinitionRequired = V;
- }
-
- StringRef getKindName() const {
- return TypeWithKeyword::getTagTypeKindName(getTagKind());
- }
-
- TagKind getTagKind() const {
- return TagKind(TagDeclKind);
- }
-
- void setTagKind(TagKind TK) { TagDeclKind = TK; }
-
- bool isStruct() const { return getTagKind() == TTK_Struct; }
- bool isInterface() const { return getTagKind() == TTK_Interface; }
- bool isClass() const { return getTagKind() == TTK_Class; }
- bool isUnion() const { return getTagKind() == TTK_Union; }
- bool isEnum() const { return getTagKind() == TTK_Enum; }
-
- /// Is this tag type named, either directly or via being defined in
- /// a typedef of this type?
- ///
- /// C++11 [basic.link]p8:
- /// A type is said to have linkage if and only if:
- /// - it is a class or enumeration type that is named (or has a
- /// name for linkage purposes) and the name has linkage; ...
- /// C++11 [dcl.typedef]p9:
- /// If the typedef declaration defines an unnamed class (or enum),
- /// the first typedef-name declared by the declaration to be that
- /// class type (or enum type) is used to denote the class type (or
- /// enum type) for linkage purposes only.
- ///
- /// C does not have an analogous rule, but the same concept is
- /// nonetheless useful in some places.
- bool hasNameForLinkage() const {
- return (getDeclName() || getTypedefNameForAnonDecl());
- }
-
- TypedefNameDecl *getTypedefNameForAnonDecl() const {
- return hasExtInfo() ? nullptr
- : TypedefNameDeclOrQualifier.get<TypedefNameDecl *>();
- }
-
- void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
-
- /// \brief 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
- /// information) that qualifies the name of this declaration, if it was
- /// present in the source.
- NestedNameSpecifierLoc getQualifierLoc() const {
- return hasExtInfo() ? getExtInfo()->QualifierLoc
- : NestedNameSpecifierLoc();
- }
-
- void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
-
- unsigned getNumTemplateParameterLists() const {
- return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
- }
- TemplateParameterList *getTemplateParameterList(unsigned i) const {
- assert(i < getNumTemplateParameterLists());
- return getExtInfo()->TemplParamLists[i];
- }
- void setTemplateParameterListsInfo(ASTContext &Context,
- ArrayRef<TemplateParameterList *> TPLists);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; }
-
- static DeclContext *castToDeclContext(const TagDecl *D) {
- return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
- }
- static TagDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// EnumDecl - 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 {
- void anchor() override;
- /// IntegerType - This represent the integer type that the enum corresponds
- /// to for code generation purposes. Note that the enumerator constants may
- /// have a different type than this does.
- ///
- /// If the underlying integer type was explicitly stated in the source
- /// code, this is a TypeSourceInfo* for that type. Otherwise this type
- /// was automatically deduced somehow, and this is a Type*.
- ///
- /// Normally if IsFixed(), this would contain a TypeSourceInfo*, but in
- /// some cases it won't.
- ///
- /// The underlying type of an enumeration never has any qualifiers, so
- /// we can get away with just storing a raw Type*, and thus save an
- /// extra pointer when TypeSourceInfo is needed.
-
- llvm::PointerUnion<const Type*, TypeSourceInfo*> IntegerType;
-
- /// PromotionType - 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
- /// of a class template specialization, this is the member specialization
- /// information.
- MemberSpecializationInfo *SpecializationInfo;
-
- EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
- bool Scoped, bool ScopedUsingClassTag, bool Fixed)
- : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc),
- SpecializationInfo(nullptr) {
- assert(Scoped || !ScopedUsingClassTag);
- IntegerType = (const Type *)nullptr;
- NumNegativeBits = 0;
- NumPositiveBits = 0;
- IsScoped = Scoped;
- IsScopedUsingClassTag = ScopedUsingClassTag;
- IsFixed = Fixed;
- }
-
- void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
- TemplateSpecializationKind TSK);
-public:
- EnumDecl *getCanonicalDecl() override {
- return cast<EnumDecl>(TagDecl::getCanonicalDecl());
- }
- const EnumDecl *getCanonicalDecl() const {
- return const_cast<EnumDecl*>(this)->getCanonicalDecl();
- }
-
- EnumDecl *getPreviousDecl() {
- return cast_or_null<EnumDecl>(
- static_cast<TagDecl *>(this)->getPreviousDecl());
- }
- const EnumDecl *getPreviousDecl() const {
- return const_cast<EnumDecl*>(this)->getPreviousDecl();
- }
-
- EnumDecl *getMostRecentDecl() {
- return cast<EnumDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
- }
- const EnumDecl *getMostRecentDecl() const {
- return const_cast<EnumDecl*>(this)->getMostRecentDecl();
- }
-
- EnumDecl *getDefinition() const {
- return cast_or_null<EnumDecl>(TagDecl::getDefinition());
- }
-
- static EnumDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, EnumDecl *PrevDecl,
- bool IsScoped, bool IsScopedUsingClassTag,
- bool IsFixed);
- static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// completeDefinition - 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
- /// added (via DeclContext::addDecl). NewType is the new underlying
- /// type of the enumeration type.
- void completeDefinition(QualType NewType,
- QualType PromotionType,
- unsigned NumPositiveBits,
- unsigned NumNegativeBits);
-
- // enumerator_iterator - Iterates through the enumerators of this
- // enumeration.
- typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>
- enumerator_range;
-
- enumerator_range enumerators() const {
- return enumerator_range(enumerator_begin(), enumerator_end());
- }
-
- enumerator_iterator enumerator_begin() const {
- const EnumDecl *E = getDefinition();
- if (!E)
- E = this;
- return enumerator_iterator(E->decls_begin());
- }
-
- enumerator_iterator enumerator_end() const {
- const EnumDecl *E = getDefinition();
- if (!E)
- E = this;
- return enumerator_iterator(E->decls_end());
- }
-
- /// getPromotionType - Return the integer type that enumerators
- /// should promote to.
- QualType getPromotionType() const { return PromotionType; }
-
- /// \brief Set the promotion type.
- void setPromotionType(QualType T) { PromotionType = T; }
-
- /// getIntegerType - Return the integer type this enum decl corresponds to.
- /// This returns a null QualType for an enum forward definition with no fixed
- /// underlying type.
- QualType getIntegerType() const {
- if (!IntegerType)
- return QualType();
- if (const Type *T = IntegerType.dyn_cast<const Type*>())
- return QualType(T, 0);
- return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
- }
-
- /// \brief Set the underlying integer type.
- void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
-
- /// \brief Set the underlying integer type source info.
- void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
-
- /// \brief 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
- /// specified.
- SourceRange getIntegerTypeRange() const LLVM_READONLY;
-
- /// \brief Returns the width in bits required to store all the
- /// non-negative enumerators of this enum.
- unsigned getNumPositiveBits() const {
- return NumPositiveBits;
- }
- void setNumPositiveBits(unsigned Num) {
- NumPositiveBits = Num;
- assert(NumPositiveBits == Num && "can't store this bitcount");
- }
-
- /// \brief Returns the width in bits required to store all the
- /// negative enumerators of this enum. These widths include
- /// the rightmost leading 1; that is:
- ///
- /// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS
- /// ------------------------ ------- -----------------
- /// -1 1111111 1
- /// -10 1110110 5
- /// -101 1001011 8
- unsigned getNumNegativeBits() const {
- return NumNegativeBits;
- }
- void setNumNegativeBits(unsigned Num) {
- NumNegativeBits = Num;
- }
-
- /// \brief 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.
- bool isScopedUsingClassTag() const {
- return IsScopedUsingClassTag;
- }
-
- /// \brief 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.
- bool isComplete() const {
- return isCompleteDefinition() || isFixed();
- }
-
- /// \brief 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
- /// 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
- /// 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
- /// a class template specialization, retrieves the member specialization
- /// information.
- MemberSpecializationInfo *getMemberSpecializationInfo() const {
- return SpecializationInfo;
- }
-
- /// \brief Specify that this enumeration is an instantiation of the
- /// member enumeration ED.
- void setInstantiationOfMemberEnum(EnumDecl *ED,
- TemplateSpecializationKind TSK) {
- setInstantiationOfMemberEnum(getASTContext(), ED, TSK);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Enum; }
-
- friend class ASTDeclReader;
-};
-
-
-/// RecordDecl - 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 {
- // FIXME: This can be packed into the bitfields in Decl.
- /// HasFlexibleArrayMember - 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;
-
- /// AnonymousStructOrUnion - Whether this is the type of an anonymous struct
- /// or union.
- bool AnonymousStructOrUnion : 1;
-
- /// HasObjectMember - 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
- /// 'volatile' type.
- bool HasVolatileMember : 1;
-
- /// \brief 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;
- friend class DeclContext;
-
-protected:
- RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, RecordDecl *PrevDecl);
-
-public:
- static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr);
- static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
-
- RecordDecl *getPreviousDecl() {
- return cast_or_null<RecordDecl>(
- static_cast<TagDecl *>(this)->getPreviousDecl());
- }
- const RecordDecl *getPreviousDecl() const {
- return const_cast<RecordDecl*>(this)->getPreviousDecl();
- }
-
- RecordDecl *getMostRecentDecl() {
- return cast<RecordDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
- }
- const RecordDecl *getMostRecentDecl() const {
- return const_cast<RecordDecl*>(this)->getMostRecentDecl();
- }
-
- 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.,
- /// @code
- /// union { int i; float f; };
- /// @endcode
- /// is an anonymous union but neither of the following are:
- /// @code
- /// union X { int i; float f; };
- /// union { int i; float f; } obj;
- /// @endcode
- bool isAnonymousStructOrUnion() const { return AnonymousStructOrUnion; }
- void setAnonymousStructOrUnion(bool Anon) {
- AnonymousStructOrUnion = Anon;
- }
-
- bool hasObjectMember() const { return HasObjectMember; }
- void setHasObjectMember (bool val) { HasObjectMember = val; }
-
- bool hasVolatileMember() const { return HasVolatileMember; }
- void setHasVolatileMember (bool val) { HasVolatileMember = val; }
-
- bool hasLoadedFieldsFromExternalStorage() const {
- return LoadedFieldsFromExternalStorage;
- }
- void setHasLoadedFieldsFromExternalStorage(bool val) {
- LoadedFieldsFromExternalStorage = val;
- }
-
- /// \brief Determines whether this declaration represents the
- /// injected class name.
- ///
- /// The injected class name in C++ is the name of the class that
- /// appears inside the class itself. For example:
- ///
- /// \code
- /// struct C {
- /// // C is implicitly declared here as a synonym for the class name.
- /// };
- ///
- /// C::C c; // same as "C c;"
- /// \endcode
- bool isInjectedClassName() const;
-
- /// \brief 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
- /// CapturedStmt construct.
- bool isCapturedRecord() const;
- /// \brief Mark the record as a record for captured variables in CapturedStmt
- /// construct.
- void setCapturedRecord();
-
- /// getDefinition - 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'.
- /// 'isCompleteDefinition' indicates whether or not a specific
- /// RecordDecl is a completed definition, not whether or not the
- /// record type is defined. This method returns NULL if there is
- /// no RecordDecl that defines the struct/union/tag.
- RecordDecl *getDefinition() const {
- return cast_or_null<RecordDecl>(TagDecl::getDefinition());
- }
-
- // Iterator access to field members. The field iterator only visits
- // the non-static data members of this class, ignoring any static
- // data members, functions, constructors, destructors, etc.
- typedef specific_decl_iterator<FieldDecl> field_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range;
-
- field_range fields() const { return field_range(field_begin(), field_end()); }
- field_iterator field_begin() const;
-
- field_iterator field_end() const {
- return field_iterator(decl_iterator());
- }
-
- // field_empty - 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.
- virtual void completeDefinition();
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstRecord && K <= lastRecord;
- }
-
- /// isMsStrust - 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.
- /// These padding are added to help AddressSanitizer detect
- /// intra-object-overflow bugs.
- bool mayInsertExtraPadding(bool EmitRemark = false) const;
-
- /// Finds the first data member which has a name.
- /// nullptr is returned if no named data member exists.
- const FieldDecl *findFirstNamedDataMember() const;
-
-private:
- /// \brief Deserialize just the fields.
- void LoadFieldsFromExternalStorage() const;
-};
-
-class FileScopeAsmDecl : public Decl {
- virtual void anchor();
- StringLiteral *AsmString;
- SourceLocation RParenLoc;
- FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring,
- SourceLocation StartL, SourceLocation EndL)
- : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {}
-public:
- static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
- StringLiteral *Str, SourceLocation AsmLoc,
- SourceLocation RParenLoc);
-
- static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceLocation getAsmLoc() const { return getLocation(); }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getAsmLoc(), getRParenLoc());
- }
-
- const StringLiteral *getAsmString() const { return AsmString; }
- StringLiteral *getAsmString() { return AsmString; }
- void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == FileScopeAsm; }
-};
-
-/// BlockDecl - This represents 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 {
-public:
- /// A class which contains all the information about a particular
- /// captured value.
- class Capture {
- enum {
- flag_isByRef = 0x1,
- flag_isNested = 0x2
- };
-
- /// The variable being captured.
- llvm::PointerIntPair<VarDecl*, 2> VariableAndFlags;
-
- /// The copy expression, expressed in terms of a DeclRef (or
- /// BlockDeclRef) to the captured variable. Only required if the
- /// variable has a C++ class type.
- Expr *CopyExpr;
-
- public:
- Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
- : VariableAndFlags(variable,
- (byRef ? flag_isByRef : 0) | (nested ? flag_isNested : 0)),
- CopyExpr(copy) {}
-
- /// The variable being captured.
- VarDecl *getVariable() const { return VariableAndFlags.getPointer(); }
-
- /// Whether this is a "by ref" capture, i.e. a capture of a __block
- /// variable.
- bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; }
-
- /// Whether this is a nested capture, i.e. the variable captured
- /// is not from outside the immediately enclosing function/block.
- bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; }
-
- bool hasCopyExpr() const { return CopyExpr != nullptr; }
- Expr *getCopyExpr() const { return CopyExpr; }
- void setCopyExpr(Expr *e) { CopyExpr = e; }
- };
-
-private:
- // FIXME: This can be packed into the bitfields in Decl.
- bool IsVariadic : 1;
- bool CapturesCXXThis : 1;
- bool BlockMissingReturnType : 1;
- bool IsConversionFromLambda : 1;
- /// ParamInfo - 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;
- unsigned NumParams;
-
- Stmt *Body;
- TypeSourceInfo *SignatureAsWritten;
-
- const Capture *Captures;
- unsigned NumCaptures;
-
- unsigned ManglingNumber;
- Decl *ManglingContextDecl;
-
-protected:
- BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
- : Decl(Block, DC, CaretLoc), DeclContext(Block),
- IsVariadic(false), CapturesCXXThis(false),
- BlockMissingReturnType(true), IsConversionFromLambda(false),
- ParamInfo(nullptr), NumParams(0), Body(nullptr),
- SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0),
- ManglingNumber(0), ManglingContextDecl(nullptr) {}
-
-public:
- static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
- static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceLocation getCaretLocation() const { return getLocation(); }
-
- bool isVariadic() const { return IsVariadic; }
- void setIsVariadic(bool value) { IsVariadic = value; }
-
- CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
- Stmt *getBody() const override { return (Stmt*) Body; }
- void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
-
- void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
- TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; }
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return getNumParams(); }
- typedef ParmVarDecl **param_iterator;
- typedef ParmVarDecl * const *param_const_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
- typedef llvm::iterator_range<param_const_iterator> param_const_range;
-
- // ArrayRef access to formal parameters.
- // FIXME: Should eventual replace iterator access.
- ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(ParamInfo, param_size());
- }
-
- bool param_empty() const { return NumParams == 0; }
- param_range params() { return param_range(param_begin(), param_end()); }
- param_iterator param_begin() { return param_iterator(ParamInfo); }
- param_iterator param_end() {
- return param_iterator(ParamInfo + param_size());
- }
-
- param_const_range params() const {
- return param_const_range(param_begin(), param_end());
- }
- param_const_iterator param_begin() const {
- return param_const_iterator(ParamInfo);
- }
- param_const_iterator param_end() const {
- return param_const_iterator(ParamInfo + param_size());
- }
-
- unsigned getNumParams() const { return NumParams; }
- const ParmVarDecl *getParamDecl(unsigned i) const {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- ParmVarDecl *getParamDecl(unsigned i) {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- void setParams(ArrayRef<ParmVarDecl *> NewParamInfo);
-
- /// hasCaptures - 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.
- /// Does not include an entry for 'this'.
- unsigned getNumCaptures() const { return NumCaptures; }
-
- typedef const Capture *capture_iterator;
- typedef const Capture *capture_const_iterator;
- typedef llvm::iterator_range<capture_iterator> capture_range;
- typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
-
- capture_range captures() {
- return capture_range(capture_begin(), capture_end());
- }
- capture_const_range captures() const {
- return capture_const_range(capture_begin(), capture_end());
- }
-
- capture_iterator capture_begin() { return Captures; }
- capture_iterator capture_end() { return Captures + NumCaptures; }
- capture_const_iterator capture_begin() const { return Captures; }
- capture_const_iterator capture_end() const { return Captures + NumCaptures; }
-
- bool capturesCXXThis() const { return CapturesCXXThis; }
- bool blockMissingReturnType() const { return BlockMissingReturnType; }
- void setBlockMissingReturnType(bool val) { BlockMissingReturnType = val; }
-
- bool isConversionFromLambda() const { return IsConversionFromLambda; }
- void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; }
-
- bool capturesVariable(const VarDecl *var) const;
-
- void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures,
- bool CapturesCXXThis);
-
- unsigned getBlockManglingNumber() const {
- return ManglingNumber;
- }
- Decl *getBlockManglingContextDecl() const {
- return ManglingContextDecl;
- }
-
- void setBlockMangling(unsigned Number, Decl *Ctx) {
- ManglingNumber = Number;
- ManglingContextDecl = Ctx;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Block; }
- static DeclContext *castToDeclContext(const BlockDecl *D) {
- return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
- }
- static BlockDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<BlockDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief This represents the body of a CapturedStmt, and serves as its
-/// DeclContext.
-class CapturedDecl final
- : public Decl,
- public DeclContext,
- private llvm::TrailingObjects<CapturedDecl, ImplicitParamDecl *> {
-protected:
- size_t numTrailingObjects(OverloadToken<ImplicitParamDecl>) {
- return NumParams;
- }
-
-private:
- /// \brief The number of parameters to the outlined function.
- unsigned NumParams;
- /// \brief The position of context parameter in list of parameters.
- unsigned ContextParam;
- /// \brief The body of the outlined function.
- llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
-
- explicit CapturedDecl(DeclContext *DC, unsigned NumParams);
-
- ImplicitParamDecl *const *getParams() const {
- return getTrailingObjects<ImplicitParamDecl *>();
- }
-
- ImplicitParamDecl **getParams() {
- return getTrailingObjects<ImplicitParamDecl *>();
- }
-
-public:
- static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
- unsigned NumParams);
- static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
- unsigned NumParams);
-
- Stmt *getBody() const override;
- void setBody(Stmt *B);
-
- bool isNothrow() const;
- void setNothrow(bool Nothrow = true);
-
- unsigned getNumParams() const { return NumParams; }
-
- ImplicitParamDecl *getParam(unsigned i) const {
- assert(i < NumParams);
- return getParams()[i];
- }
- void setParam(unsigned i, ImplicitParamDecl *P) {
- assert(i < NumParams);
- getParams()[i] = P;
- }
-
- /// \brief Retrieve the parameter containing captured variables.
- ImplicitParamDecl *getContextParam() const {
- assert(ContextParam < NumParams);
- return getParam(ContextParam);
- }
- void setContextParam(unsigned i, ImplicitParamDecl *P) {
- assert(i < NumParams);
- ContextParam = i;
- setParam(i, P);
- }
- unsigned getContextParamPosition() const { return ContextParam; }
-
- typedef ImplicitParamDecl *const *param_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
-
- /// \brief Retrieve an iterator pointing to the first parameter decl.
- param_iterator param_begin() const { return getParams(); }
- /// \brief Retrieve an iterator one past the last parameter decl.
- param_iterator param_end() const { return getParams() + NumParams; }
-
- /// \brief Retrieve an iterator range for the parameter declarations.
- param_range params() const { return param_range(param_begin(), param_end()); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Captured; }
- static DeclContext *castToDeclContext(const CapturedDecl *D) {
- return static_cast<DeclContext *>(const_cast<CapturedDecl *>(D));
- }
- static CapturedDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
-};
-
-/// \brief 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:
-/// \code
-/// @import std.vector;
-/// \endcode
-///
-/// Import declarations can also be implicitly generated from
-/// \#include/\#import directives.
-class ImportDecl final : public Decl,
- llvm::TrailingObjects<ImportDecl, SourceLocation> {
- /// \brief The imported module, along with a bit that indicates whether
- /// we have source-location information for each identifier in the module
- /// name.
- ///
- /// When the bit is false, we only have a single source location for the
- /// end of the import declaration.
- llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete;
-
- /// \brief The next import in the list of imports local to the translation
- /// unit being parsed (not loaded from an AST file).
- ImportDecl *NextLocalImport;
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTContext;
- friend TrailingObjects;
-
- ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
- ArrayRef<SourceLocation> IdentifierLocs);
-
- ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
- SourceLocation EndLoc);
-
- ImportDecl(EmptyShell Empty) : Decl(Import, Empty), NextLocalImport() { }
-
-public:
- /// \brief 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
- /// import.
- static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, Module *Imported,
- SourceLocation EndLoc);
-
- /// \brief 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.
- Module *getImportedModule() const { return ImportedAndComplete.getPointer(); }
-
- /// \brief 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
- /// identifiers aren't available.
- ArrayRef<SourceLocation> getIdentifierLocs() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Import; }
-};
-
-/// \brief Represents an empty-declaration.
-class EmptyDecl : public Decl {
- virtual void anchor();
- EmptyDecl(DeclContext *DC, SourceLocation L)
- : Decl(Empty, DC, L) { }
-
-public:
- static EmptyDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L);
- static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Empty; }
-};
-
-/// Insertion operator for diagnostics. This allows sending NamedDecl's
-/// into a diagnostic with <<.
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const NamedDecl* ND) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
- DiagnosticsEngine::ak_nameddecl);
- return DB;
-}
-inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const NamedDecl* ND) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
- DiagnosticsEngine::ak_nameddecl);
- return PD;
-}
-
-template<typename decl_type>
-void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
- // Note: This routine is implemented here because we need both NamedDecl
- // and Redeclarable to be defined.
- assert(RedeclLink.NextIsLatest() &&
- "setPreviousDecl on a decl already in a redeclaration chain");
-
- if (PrevDecl) {
- // Point to previous. Make sure that this is actually the most recent
- // 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");
- decl_type *MostRecent = First->getNextRedeclaration();
- RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
-
- // If the declaration was previously visible, a redeclaration of it remains
- // visible even if it wouldn't be visible by itself.
- static_cast<decl_type*>(this)->IdentifierNamespace |=
- MostRecent->getIdentifierNamespace() &
- (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
- } else {
- // Make this first.
- First = static_cast<decl_type*>(this);
- }
-
- // First one will point to this one as latest.
- First->RedeclLink.setLatest(static_cast<decl_type*>(this));
-
- assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||
- cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid());
-}
-
-// Inline function definitions.
-
-/// \brief 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.
-inline bool IsEnumDeclComplete(EnumDecl *ED) {
- return ED->isComplete();
-}
-
-/// \brief 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.
-inline bool IsEnumDeclScoped(EnumDecl *ED) {
- return ED->isScoped();
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h
deleted file mode 100644
index 3c5056c..0000000
--- a/include/clang/AST/DeclAccessPair.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===--- DeclAccessPair.h - A decl bundled with its path access -*- 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 DeclAccessPair class, which provides an
-// efficient representation of a pair of a NamedDecl* and an
-// AccessSpecifier. Generally the access specifier gives the
-// natural access of a declaration when named in a class, as
-// defined in C++ [class.access.base]p1.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
-#define LLVM_CLANG_AST_DECLACCESSPAIR_H
-
-#include "clang/Basic/Specifiers.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace clang {
-
-class NamedDecl;
-
-/// A POD class for pairing a NamedDecl* with an access specifier.
-/// Can be put into unions.
-class DeclAccessPair {
- uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
-
- enum { Mask = 0x3 };
-
-public:
- static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
- DeclAccessPair p;
- p.set(D, AS);
- return p;
- }
-
- NamedDecl *getDecl() const {
- return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
- }
- AccessSpecifier getAccess() const {
- return AccessSpecifier(Mask & Ptr);
- }
-
- void setDecl(NamedDecl *D) {
- set(D, getAccess());
- }
- void setAccess(AccessSpecifier AS) {
- set(getDecl(), AS);
- }
- void set(NamedDecl *D, AccessSpecifier AS) {
- Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
- }
-
- operator NamedDecl*() const { return getDecl(); }
- NamedDecl *operator->() const { return getDecl(); }
-};
-}
-
-// Take a moment to tell SmallVector that DeclAccessPair is POD.
-namespace llvm {
-template<typename> struct isPodLike;
-template<> struct isPodLike<clang::DeclAccessPair> {
- static const bool value = true;
-};
-}
-
-#endif
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
deleted file mode 100644
index 05b2a12..0000000
--- a/include/clang/AST/DeclBase.h
+++ /dev/null
@@ -1,1904 +0,0 @@
-//===-- DeclBase.h - Base Classes for representing declarations -*- 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 Decl and DeclContext interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLBASE_H
-#define LLVM_CLANG_AST_DECLBASE_H
-
-#include "clang/AST/AttrIterator.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/Basic/Specifiers.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/PrettyStackTrace.h"
-
-namespace clang {
-class ASTMutationListener;
-class BlockDecl;
-class CXXRecordDecl;
-class CompoundStmt;
-class DeclContext;
-class DeclarationName;
-class DependentDiagnostic;
-class EnumDecl;
-class FunctionDecl;
-class FunctionType;
-enum Linkage : unsigned char;
-class LinkageComputer;
-class LinkageSpecDecl;
-class Module;
-class NamedDecl;
-class NamespaceDecl;
-class ObjCCategoryDecl;
-class ObjCCategoryImplDecl;
-class ObjCContainerDecl;
-class ObjCImplDecl;
-class ObjCImplementationDecl;
-class ObjCInterfaceDecl;
-class ObjCMethodDecl;
-class ObjCProtocolDecl;
-struct PrintingPolicy;
-class RecordDecl;
-class Stmt;
-class StoredDeclsMap;
-class TranslationUnitDecl;
-class UsingDirectiveDecl;
-}
-
-namespace clang {
-
- /// \brief Captures the result of checking the availability of a
- /// declaration.
- enum AvailabilityResult {
- AR_Available = 0,
- AR_NotYetIntroduced,
- AR_Deprecated,
- AR_Unavailable
- };
-
-/// Decl - This represents one declaration (or definition), e.g. a variable,
-/// typedef, function, struct, etc.
-///
-/// Note: There are objects tacked on before the *beginning* of Decl
-/// (and its subclasses) in its Decl::operator new(). Proper alignment
-/// of all subclasses (not requiring more than DeclObjAlignment) is
-/// asserted in DeclBase.cpp.
-class Decl {
-public:
- /// \brief Alignment guaranteed when allocating Decl and any subtypes.
- enum { DeclObjAlignment = llvm::AlignOf<uint64_t>::Alignment };
-
- /// \brief Lists the kind of concrete classes of Decl.
- enum Kind {
-#define DECL(DERIVED, BASE) DERIVED,
-#define ABSTRACT_DECL(DECL)
-#define DECL_RANGE(BASE, START, END) \
- first##BASE = START, last##BASE = END,
-#define LAST_DECL_RANGE(BASE, START, END) \
- first##BASE = START, last##BASE = END
-#include "clang/AST/DeclNodes.inc"
- };
-
- /// \brief 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 { };
-
- /// IdentifierNamespace - The different namespaces in which
- /// declarations may appear. According to C99 6.2.3, there are
- /// four namespaces, labels, tags, members and ordinary
- /// identifiers. C++ describes lookup completely differently:
- /// certain lookups merely "ignore" certain kinds of declarations,
- /// usually based on whether the declaration is of a type, etc.
- ///
- /// These are meant as bitmasks, so that searches in
- /// C++ can look into the "tag" namespace during ordinary lookup.
- ///
- /// Decl currently provides 15 bits of IDNS bits.
- enum IdentifierNamespace {
- /// Labels, declared with 'x:' and referenced with 'goto x'.
- IDNS_Label = 0x0001,
-
- /// Tags, declared with 'struct foo;' and referenced with
- /// 'struct foo'. All tags are also types. This is what
- /// elaborated-type-specifiers look for in C.
- IDNS_Tag = 0x0002,
-
- /// Types, declared with 'struct foo', typedefs, etc.
- /// This is what elaborated-type-specifiers look for in C++,
- /// but note that it's ill-formed to find a non-tag.
- IDNS_Type = 0x0004,
-
- /// Members, declared with object declarations within tag
- /// definitions. In C, these can only be found by "qualified"
- /// lookup in member expressions. In C++, they're found by
- /// normal lookup.
- IDNS_Member = 0x0008,
-
- /// Namespaces, declared with 'namespace foo {}'.
- /// Lookup for nested-name-specifiers find these.
- IDNS_Namespace = 0x0010,
-
- /// Ordinary names. In C, everything that's not a label, tag,
- /// or member ends up here.
- IDNS_Ordinary = 0x0020,
-
- /// Objective C \@protocol.
- IDNS_ObjCProtocol = 0x0040,
-
- /// This declaration is a friend function. A friend function
- /// declaration is always in this namespace but may also be in
- /// IDNS_Ordinary if it was previously declared.
- IDNS_OrdinaryFriend = 0x0080,
-
- /// This declaration is a friend class. A friend class
- /// declaration is always in this namespace but may also be in
- /// IDNS_Tag|IDNS_Type if it was previously declared.
- IDNS_TagFriend = 0x0100,
-
- /// This declaration is a using declaration. A using declaration
- /// *introduces* a number of other declarations into the current
- /// scope, and those declarations use the IDNS of their targets,
- /// but the actual using declarations go in this namespace.
- IDNS_Using = 0x0200,
-
- /// This declaration is a C++ operator declared in a non-class
- /// context. All such operators are also in IDNS_Ordinary.
- /// C++ lexical operator lookup looks for these.
- IDNS_NonMemberOperator = 0x0400,
-
- /// This declaration is a function-local extern declaration of a
- /// variable or function. This may also be IDNS_Ordinary if it
- /// has been declared outside any function.
- IDNS_LocalExtern = 0x0800
- };
-
- /// ObjCDeclQualifier - 'Qualifiers' written next to the return and
- /// parameter types in method declarations. Other than remembering
- /// them and mangling them into the method's signature string, these
- /// are ignored by the compiler; they are consumed by certain
- /// remote-messaging frameworks.
- ///
- /// in, inout, and out are mutually exclusive and apply only to
- /// method parameters. bycopy and byref are mutually exclusive and
- /// apply only to method parameters (?). oneway applies only to
- /// results. All of these expect their corresponding parameter to
- /// have a particular type. None of this is currently enforced by
- /// clang.
- ///
- /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier.
- enum ObjCDeclQualifier {
- OBJC_TQ_None = 0x0,
- OBJC_TQ_In = 0x1,
- OBJC_TQ_Inout = 0x2,
- OBJC_TQ_Out = 0x4,
- OBJC_TQ_Bycopy = 0x8,
- OBJC_TQ_Byref = 0x10,
- OBJC_TQ_Oneway = 0x20,
-
- /// The nullability qualifier is set when the nullability of the
- /// result or parameter was expressed via a context-sensitive
- /// keyword.
- OBJC_TQ_CSNullability = 0x40
- };
-
-protected:
- // Enumeration values used in the bits stored in NextInContextAndBits.
- enum {
- /// \brief Whether this declaration is a top-level declaration (function,
- /// global variable, etc.) that is lexically inside an objc container
- /// definition.
- TopLevelDeclInObjCContainerFlag = 0x01,
-
- /// \brief Whether this declaration is private to the module in which it was
- /// defined.
- ModulePrivateFlag = 0x02
- };
-
- /// \brief The next declaration within the same lexical
- /// DeclContext. These pointers form the linked list that is
- /// traversed via DeclContext's decls_begin()/decls_end().
- ///
- /// The extra two bits are used for the TopLevelDeclInObjCContainer and
- /// ModulePrivate bits.
- llvm::PointerIntPair<Decl *, 2, unsigned> NextInContextAndBits;
-
-private:
- friend class DeclContext;
-
- struct MultipleDC {
- DeclContext *SemanticDC;
- DeclContext *LexicalDC;
- };
-
-
- /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
- /// For declarations that don't contain C++ scope specifiers, it contains
- /// the DeclContext where the Decl was declared.
- /// For declarations with C++ scope specifiers, it contains a MultipleDC*
- /// with the context where it semantically belongs (SemanticDC) and the
- /// context where it was lexically declared (LexicalDC).
- /// e.g.:
- ///
- /// namespace A {
- /// void f(); // SemanticDC == LexicalDC == 'namespace A'
- /// }
- /// void A::f(); // SemanticDC == namespace 'A'
- /// // LexicalDC == global namespace
- llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
-
- inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
- inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
- inline MultipleDC *getMultipleDC() const {
- return DeclCtx.get<MultipleDC*>();
- }
- inline DeclContext *getSemanticDC() const {
- return DeclCtx.get<DeclContext*>();
- }
-
- /// Loc - The location of this decl.
- SourceLocation Loc;
-
- /// DeclKind - This indicates which class this is.
- unsigned DeclKind : 8;
-
- /// InvalidDecl - This indicates a semantic error occurred.
- unsigned InvalidDecl : 1;
-
- /// HasAttrs - This indicates whether the decl has attributes or not.
- unsigned HasAttrs : 1;
-
- /// Implicit - Whether this declaration was implicitly generated by
- /// the implementation rather than explicitly written by the user.
- unsigned Implicit : 1;
-
- /// \brief Whether this declaration was "used", meaning that a definition is
- /// required.
- unsigned Used : 1;
-
- /// \brief 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 statistic collection is enabled.
- static bool StatisticsEnabled;
-
-protected:
- /// Access - Used by C++ decls for the access specifier.
- // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
- unsigned Access : 2;
- friend class CXXClassMemberWrapper;
-
- /// \brief Whether this declaration was loaded from an AST file.
- unsigned FromASTFile : 1;
-
- /// \brief Whether this declaration is hidden from normal name lookup, e.g.,
- /// because it is was loaded from an AST file is either module-private or
- /// because its submodule has not been made visible.
- unsigned Hidden : 1;
-
- /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
- unsigned IdentifierNamespace : 12;
-
- /// \brief If 0, we have not computed the linkage of this declaration.
- /// Otherwise, it is the linkage + 1.
- mutable unsigned CacheValidAndLinkage : 3;
-
- friend class ASTDeclWriter;
- friend class ASTDeclReader;
- friend class ASTReader;
- friend class LinkageComputer;
-
- template<typename decl_type> friend class Redeclarable;
-
- /// \brief Allocate memory for a deserialized declaration.
- ///
- /// This routine must be used to allocate memory for any declaration that is
- /// deserialized from a module file.
- ///
- /// \param Size The size of the allocated object.
- /// \param Ctx The context in which we will allocate memory.
- /// \param ID The global ID of the deserialized declaration.
- /// \param Extra The amount of extra space to allocate after the object.
- void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID,
- std::size_t Extra = 0);
-
- /// \brief Allocate memory for a non-deserialized declaration.
- void *operator new(std::size_t Size, const ASTContext &Ctx,
- DeclContext *Parent, std::size_t Extra = 0);
-
-private:
- bool AccessDeclContextSanity() const;
-
-protected:
-
- Decl(Kind DK, DeclContext *DC, SourceLocation L)
- : NextInContextAndBits(), DeclCtx(DC),
- Loc(L), DeclKind(DK), InvalidDecl(0),
- HasAttrs(false), Implicit(false), Used(false), Referenced(false),
- Access(AS_none), FromASTFile(0), Hidden(DC && cast<Decl>(DC)->Hidden),
- IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0)
- {
- if (StatisticsEnabled) add(DK);
- }
-
- Decl(Kind DK, EmptyShell Empty)
- : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0),
- HasAttrs(false), Implicit(false), Used(false), Referenced(false),
- Access(AS_none), FromASTFile(0), Hidden(0),
- IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0)
- {
- if (StatisticsEnabled) add(DK);
- }
-
- virtual ~Decl();
-
- /// \brief Update a potentially out-of-date declaration.
- void updateOutOfDate(IdentifierInfo &II) const;
-
- Linkage getCachedLinkage() const {
- return Linkage(CacheValidAndLinkage - 1);
- }
-
- void setCachedLinkage(Linkage L) const {
- CacheValidAndLinkage = L + 1;
- }
-
- bool hasCachedLinkage() const {
- return CacheValidAndLinkage;
- }
-
-public:
-
- /// \brief Source range that this declaration covers.
- virtual SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocation(), getLocation());
- }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSourceRange().getBegin();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSourceRange().getEnd();
- }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- Kind getKind() const { return static_cast<Kind>(DeclKind); }
- const char *getDeclKindName() const;
-
- Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); }
- const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();}
-
- DeclContext *getDeclContext() {
- if (isInSemaDC())
- return getSemanticDC();
- return getMultipleDC()->SemanticDC;
- }
- const DeclContext *getDeclContext() const {
- return const_cast<Decl*>(this)->getDeclContext();
- }
-
- /// Find the innermost non-closure ancestor of this declaration,
- /// walking up through blocks, lambdas, etc. If that ancestor is
- /// not a code context (!isFunctionOrMethod()), returns null.
- ///
- /// A declaration may be its own non-closure context.
- Decl *getNonClosureContext();
- const Decl *getNonClosureContext() const {
- return const_cast<Decl*>(this)->getNonClosureContext();
- }
-
- TranslationUnitDecl *getTranslationUnitDecl();
- const TranslationUnitDecl *getTranslationUnitDecl() const {
- return const_cast<Decl*>(this)->getTranslationUnitDecl();
- }
-
- bool isInAnonymousNamespace() const;
-
- bool isInStdNamespace() const;
-
- ASTContext &getASTContext() const LLVM_READONLY;
-
- void setAccess(AccessSpecifier AS) {
- Access = AS;
- assert(AccessDeclContextSanity());
- }
-
- AccessSpecifier getAccess() const {
- assert(AccessDeclContextSanity());
- return AccessSpecifier(Access);
- }
-
- /// \brief Retrieve the access specifier for this declaration, even though
- /// it may not yet have been properly set.
- AccessSpecifier getAccessUnsafe() const {
- return AccessSpecifier(Access);
- }
-
- bool hasAttrs() const { return HasAttrs; }
- void setAttrs(const AttrVec& Attrs) {
- return setAttrsImpl(Attrs, getASTContext());
- }
- AttrVec &getAttrs() {
- return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
- }
- const AttrVec &getAttrs() const;
- void dropAttrs();
-
- void addAttr(Attr *A) {
- if (hasAttrs())
- getAttrs().push_back(A);
- else
- setAttrs(AttrVec(1, A));
- }
-
- typedef AttrVec::const_iterator attr_iterator;
- typedef llvm::iterator_range<attr_iterator> attr_range;
-
- attr_range attrs() const {
- return attr_range(attr_begin(), attr_end());
- }
-
- attr_iterator attr_begin() const {
- return hasAttrs() ? getAttrs().begin() : nullptr;
- }
- attr_iterator attr_end() const {
- return hasAttrs() ? getAttrs().end() : nullptr;
- }
-
- template <typename T>
- void dropAttr() {
- if (!HasAttrs) return;
-
- AttrVec &Vec = getAttrs();
- Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa<T, Attr*>), Vec.end());
-
- if (Vec.empty())
- HasAttrs = false;
- }
-
- template <typename T>
- llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
- return llvm::make_range(specific_attr_begin<T>(), specific_attr_end<T>());
- }
-
- template <typename T>
- specific_attr_iterator<T> specific_attr_begin() const {
- return specific_attr_iterator<T>(attr_begin());
- }
- template <typename T>
- specific_attr_iterator<T> specific_attr_end() const {
- return specific_attr_iterator<T>(attr_end());
- }
-
- template<typename T> T *getAttr() const {
- return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
- }
- template<typename T> bool hasAttr() const {
- return hasAttrs() && hasSpecificAttr<T>(getAttrs());
- }
-
- /// getMaxAlignment - return the maximum alignment specified by attributes
- /// on this decl, 0 if there are none.
- unsigned getMaxAlignment() const;
-
- /// setInvalidDecl - Indicates the Decl had a semantic error. This
- /// allows for graceful error recovery.
- void setInvalidDecl(bool Invalid = true);
- bool isInvalidDecl() const { return (bool) InvalidDecl; }
-
- /// isImplicit - Indicates whether the declaration was implicitly
- /// generated by the implementation. If false, this declaration
- /// was written explicitly in the source code.
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I = true) { Implicit = I; }
-
- /// \brief Whether this declaration was used, meaning that a definition
- /// is required.
- ///
- /// \param CheckUsedAttr When true, also consider the "used" attribute
- /// (in addition to the "used" bit set by \c setUsed()) when determining
- /// whether the function is used.
- bool isUsed(bool CheckUsedAttr = true) const;
-
- /// \brief Set whether the declaration is used, in the sense of odr-use.
- ///
- /// This should only be used immediately after creating a declaration.
- void setIsUsed() { Used = true; }
-
- /// \brief 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.
- bool isReferenced() const;
-
- /// \brief 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,
- /// global variable, etc.) that is lexically inside an objc container
- /// definition.
- bool isTopLevelDeclInObjCContainer() const {
- return NextInContextAndBits.getInt() & TopLevelDeclInObjCContainerFlag;
- }
-
- void setTopLevelDeclInObjCContainer(bool V = true) {
- unsigned Bits = NextInContextAndBits.getInt();
- if (V)
- Bits |= TopLevelDeclInObjCContainerFlag;
- else
- Bits &= ~TopLevelDeclInObjCContainerFlag;
- NextInContextAndBits.setInt(Bits);
- }
-
- /// \brief Whether this declaration was marked as being private to the
- /// module in which it was defined.
- bool isModulePrivate() const {
- return NextInContextAndBits.getInt() & ModulePrivateFlag;
- }
-
-protected:
- /// \brief Specify whether this declaration was marked as being private
- /// to the module in which it was defined.
- void setModulePrivate(bool MP = true) {
- unsigned Bits = NextInContextAndBits.getInt();
- if (MP)
- Bits |= ModulePrivateFlag;
- else
- Bits &= ~ModulePrivateFlag;
- NextInContextAndBits.setInt(Bits);
- }
-
- /// \brief 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.
- ///
- /// This routine will determine the most restrictive availability of
- /// the given declaration (e.g., preferring 'unavailable' to
- /// 'deprecated').
- ///
- /// \param Message If non-NULL and the result is not \c
- /// AR_Available, will be set to a (possibly empty) message
- /// describing why the declaration has not been introduced, is
- /// deprecated, or is unavailable.
- AvailabilityResult getAvailability(std::string *Message = nullptr) const;
-
- /// \brief Determine whether this declaration is marked 'deprecated'.
- ///
- /// \param Message If non-NULL and the declaration is deprecated,
- /// this will be set to the message describing why the declaration
- /// was deprecated (which may be empty).
- bool isDeprecated(std::string *Message = nullptr) const {
- return getAvailability(Message) == AR_Deprecated;
- }
-
- /// \brief 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
- /// was made unavailable (which may be empty).
- bool isUnavailable(std::string *Message = nullptr) const {
- return getAvailability(Message) == AR_Unavailable;
- }
-
- /// \brief 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
- /// 'availability' attribute where we're targing a platform prior to
- /// the introduction of this feature.
- bool isWeakImported() const;
-
- /// \brief Determines whether this symbol can be weak-imported,
- /// e.g., whether it would be well-formed to add the weak_import
- /// attribute.
- ///
- /// \param IsDefinition Set to \c true to indicate that this
- /// 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
- /// a precompiled header or module) rather than having been parsed.
- bool isFromASTFile() const { return FromASTFile; }
-
- /// \brief Retrieve the global declaration ID associated with this
- /// declaration, which specifies where in the
- unsigned getGlobalID() const {
- if (isFromASTFile())
- return *((const unsigned*)this - 1);
- return 0;
- }
-
- /// \brief Retrieve the global ID of the module that owns this particular
- /// declaration.
- unsigned getOwningModuleID() const {
- if (isFromASTFile())
- return *((const unsigned*)this - 2);
-
- return 0;
- }
-
-private:
- Module *getOwningModuleSlow() const;
-protected:
- bool hasLocalOwningModuleStorage() const;
-
-public:
- /// \brief Get the imported owning module, if this decl is from an imported
- /// (non-local) module.
- Module *getImportedOwningModule() const {
- if (!isFromASTFile())
- return nullptr;
-
- return getOwningModuleSlow();
- }
-
- /// \brief 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() || !Hidden)
- return nullptr;
- return reinterpret_cast<Module *const *>(this)[-1];
- }
- void setLocalOwningModule(Module *M) {
- assert(!isFromASTFile() && Hidden && hasLocalOwningModuleStorage() &&
- "should not have a cached owning module");
- reinterpret_cast<Module **>(this)[-1] = M;
- }
-
- unsigned getIdentifierNamespace() const {
- return IdentifierNamespace;
- }
- bool isInIdentifierNamespace(unsigned NS) const {
- return getIdentifierNamespace() & NS;
- }
- static unsigned getIdentifierNamespaceForKind(Kind DK);
-
- bool hasTagIdentifierNamespace() const {
- return isTagIdentifierNamespace(getIdentifierNamespace());
- }
- static bool isTagIdentifierNamespace(unsigned NS) {
- // TagDecls have Tag and Type set and may also have TagFriend.
- return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
- }
-
- /// getLexicalDeclContext - The declaration context where this Decl was
- /// lexically declared (LexicalDC). May be different from
- /// getDeclContext() (SemanticDC).
- /// e.g.:
- ///
- /// namespace A {
- /// void f(); // SemanticDC == LexicalDC == 'namespace A'
- /// }
- /// void A::f(); // SemanticDC == namespace 'A'
- /// // LexicalDC == global namespace
- DeclContext *getLexicalDeclContext() {
- if (isInSemaDC())
- return getSemanticDC();
- return getMultipleDC()->LexicalDC;
- }
- const DeclContext *getLexicalDeclContext() const {
- return const_cast<Decl*>(this)->getLexicalDeclContext();
- }
-
- /// Determine whether this declaration is declared out of line (outside its
- /// semantic context).
- virtual bool isOutOfLine() const;
-
- /// setDeclContext - Set both the semantic and lexical DeclContext
- /// to DC.
- void setDeclContext(DeclContext *DC);
-
- void setLexicalDeclContext(DeclContext *DC);
-
- /// 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
- /// could be defined inside or outside a function etc).
- bool isDefinedOutsideFunctionOrMethod() const {
- return getParentFunctionOrMethod() == nullptr;
- }
-
- /// \brief Returns true if this declaration lexically is inside a function.
- /// It recognizes non-defining declarations as well as members of local
- /// classes:
- /// \code
- /// void foo() { void bar(); }
- /// void foo2() { class ABC { void bar(); }; }
- /// \endcode
- bool isLexicallyWithinFunctionOrMethod() const;
-
- /// \brief 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() {
- return const_cast<DeclContext*>(
- const_cast<const Decl*>(this)->getParentFunctionOrMethod());
- }
-
- /// \brief 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.
- bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
-
-protected:
- /// \brief 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
- /// subclass that has a redeclaration chain.
- virtual Decl *getPreviousDeclImpl() { return nullptr; }
-
- /// \brief 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.
- class redecl_iterator {
- /// Current - The current declaration.
- Decl *Current;
- Decl *Starter;
-
- public:
- typedef Decl *value_type;
- typedef const value_type &reference;
- typedef const value_type *pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- redecl_iterator() : Current(nullptr) { }
- explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
-
- reference operator*() const { return Current; }
- value_type operator->() const { return Current; }
-
- redecl_iterator& operator++() {
- assert(Current && "Advancing while iterator has reached end");
- // Get either previous decl or latest decl.
- Decl *Next = Current->getNextRedeclarationImpl();
- assert(Next && "Should return next redeclaration or itself, never null!");
- Current = (Next != Starter) ? Next : nullptr;
- return *this;
- }
-
- redecl_iterator operator++(int) {
- redecl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(redecl_iterator x, redecl_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(redecl_iterator x, redecl_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<redecl_iterator> redecl_range;
-
- /// \brief Returns an iterator range for all the redeclarations of the same
- /// decl. It will iterate at least once (when this decl is the only one).
- redecl_range redecls() const {
- return redecl_range(redecls_begin(), redecls_end());
- }
-
- redecl_iterator redecls_begin() const {
- return redecl_iterator(const_cast<Decl *>(this));
- }
- redecl_iterator redecls_end() const { return redecl_iterator(); }
-
- /// \brief 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
- /// 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.
- bool isFirstDecl() const {
- return getPreviousDecl() == nullptr;
- }
-
- /// \brief 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
- /// as this declaration (which may be this declaration).
- const Decl *getMostRecentDecl() const {
- return const_cast<Decl *>(this)->getMostRecentDeclImpl();
- }
-
- /// getBody - If this Decl represents a declaration for a body of code,
- /// such as a function or method definition, this method returns the
- /// top-level Stmt* of that body. Otherwise this method returns null.
- virtual Stmt* getBody() const { return nullptr; }
-
- /// \brief Returns true if this \c Decl represents a declaration for a body of
- /// code, such as a function or method definition.
- /// Note that \c hasBody can also return true if any redeclaration of this
- /// \c Decl represents a declaration for a body of code.
- virtual bool hasBody() const { return getBody() != nullptr; }
-
- /// getBodyRBrace - Gets the right brace of the body, if a body exists.
- /// This works whether the body is a CompoundStmt or a CXXTryStmt.
- SourceLocation getBodyRBrace() const;
-
- // global temp stats (until we have a per-module visitor)
- static void add(Kind k);
- static void EnableStatistics();
- static void PrintStats();
-
- /// isTemplateParameter - Determines whether this declaration is a
- /// template parameter.
- bool isTemplateParameter() const;
-
- /// isTemplateParameter - Determines whether this declaration is a
- /// template parameter pack.
- bool isTemplateParameterPack() const;
-
- /// \brief Whether this declaration is a parameter pack.
- bool isParameterPack() const;
-
- /// \brief returns true if this declaration is a template
- bool isTemplateDecl() const;
-
- /// \brief Whether this declaration is a function or function template.
- bool isFunctionOrFunctionTemplate() const {
- return (DeclKind >= Decl::firstFunction &&
- DeclKind <= Decl::lastFunction) ||
- DeclKind == FunctionTemplate;
- }
-
- /// \brief Returns the function itself, or the templated function if this is a
- /// function template.
- FunctionDecl *getAsFunction() LLVM_READONLY;
-
- const FunctionDecl *getAsFunction() const {
- return const_cast<Decl *>(this)->getAsFunction();
- }
-
- /// \brief Changes the namespace of this declaration to reflect that it's
- /// a function-local extern declaration.
- ///
- /// These declarations appear in the lexical context of the extern
- /// declaration, but in the semantic context of the enclosing namespace
- /// scope.
- void setLocalExternDecl() {
- assert((IdentifierNamespace == IDNS_Ordinary ||
- IdentifierNamespace == IDNS_OrdinaryFriend) &&
- "namespace is not ordinary");
-
- Decl *Prev = getPreviousDecl();
- IdentifierNamespace &= ~IDNS_Ordinary;
-
- IdentifierNamespace |= IDNS_LocalExtern;
- if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
- IdentifierNamespace |= IDNS_Ordinary;
- }
-
- /// \brief 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
- /// the object of a friend declaration.
- ///
- /// These declarations appear in the lexical context of the friending
- /// class, but in the semantic context of the actual entity. This property
- /// applies only to a specific decl object; other redeclarations of the
- /// same entity may not (and probably don't) share this property.
- void setObjectOfFriendDecl(bool PerformFriendInjection = false) {
- unsigned OldNS = IdentifierNamespace;
- assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
- IDNS_TagFriend | IDNS_OrdinaryFriend |
- IDNS_LocalExtern)) &&
- "namespace includes neither ordinary nor tag");
- assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
- IDNS_TagFriend | IDNS_OrdinaryFriend |
- IDNS_LocalExtern)) &&
- "namespace includes other than ordinary or tag");
-
- Decl *Prev = getPreviousDecl();
- IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type);
-
- if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
- IdentifierNamespace |= IDNS_TagFriend;
- if (PerformFriendInjection ||
- (Prev && Prev->getIdentifierNamespace() & IDNS_Tag))
- IdentifierNamespace |= IDNS_Tag | IDNS_Type;
- }
-
- if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) {
- IdentifierNamespace |= IDNS_OrdinaryFriend;
- if (PerformFriendInjection ||
- (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))
- IdentifierNamespace |= IDNS_Ordinary;
- }
- }
-
- enum FriendObjectKind {
- FOK_None, ///< Not a friend object.
- FOK_Declared, ///< A friend of a previously-declared entity.
- FOK_Undeclared ///< A friend of a previously-undeclared entity.
- };
-
- /// \brief 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.
- FriendObjectKind getFriendObjectKind() const {
- unsigned mask =
- (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend));
- if (!mask) return FOK_None;
- return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared
- : FOK_Undeclared);
- }
-
- /// Specifies that this declaration is a C++ overloaded non-member.
- void setNonMemberOperator() {
- assert(getKind() == Function || getKind() == FunctionTemplate);
- assert((IdentifierNamespace & IDNS_Ordinary) &&
- "visible non-member operators should be in ordinary namespace");
- IdentifierNamespace |= IDNS_NonMemberOperator;
- }
-
- static bool classofKind(Kind K) { return true; }
- static DeclContext *castToDeclContext(const Decl *);
- static Decl *castFromDeclContext(const DeclContext *);
-
- void print(raw_ostream &Out, unsigned Indentation = 0,
- bool PrintInstantiation = false) const;
- void print(raw_ostream &Out, const PrintingPolicy &Policy,
- unsigned Indentation = 0, bool PrintInstantiation = false) const;
- static void printGroup(Decl** Begin, unsigned NumDecls,
- raw_ostream &Out, const PrintingPolicy &Policy,
- unsigned Indentation = 0);
- // Debuggers don't usually respect default arguments.
- void dump() const;
- // Same as dump(), but forces color printing.
- void dumpColor() const;
- void dump(raw_ostream &Out) const;
-
- /// \brief Looks through the Decl's underlying type to extract a FunctionType
- /// when possible. Will return null if the type underlying the Decl does not
- /// have a FunctionType.
- const FunctionType *getFunctionType(bool BlocksToo = true) const;
-
-private:
- void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
- void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
- ASTContext &Ctx);
-
-protected:
- ASTMutationListener *getASTMutationListener() const;
-};
-
-/// \brief Determine whether two declarations declare the same entity.
-inline bool declaresSameEntity(const Decl *D1, const Decl *D2) {
- if (!D1 || !D2)
- return false;
-
- if (D1 == D2)
- return true;
-
- return D1->getCanonicalDecl() == D2->getCanonicalDecl();
-}
-
-/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
-/// doing something to a specific decl.
-class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
- const Decl *TheDecl;
- SourceLocation Loc;
- SourceManager &SM;
- const char *Message;
-public:
- PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
- SourceManager &sm, const char *Msg)
- : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
-
- void print(raw_ostream &OS) const override;
-};
-
-/// \brief 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 {
- typedef ArrayRef<NamedDecl *> ResultTy;
- ResultTy Result;
- // If there is only one lookup result, it would be invalidated by
- // reallocations of the name table, so store it separately.
- NamedDecl *Single;
-
- static NamedDecl *const SingleElementDummyList;
-
-public:
- DeclContextLookupResult() : Result(), Single() {}
- DeclContextLookupResult(ArrayRef<NamedDecl *> Result)
- : Result(Result), Single() {}
- DeclContextLookupResult(NamedDecl *Single)
- : Result(SingleElementDummyList), Single(Single) {}
-
- class iterator;
- typedef llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
- std::random_access_iterator_tag,
- NamedDecl *const> IteratorBase;
- class iterator : public IteratorBase {
- value_type SingleElement;
-
- public:
- iterator() : IteratorBase(), SingleElement() {}
- explicit iterator(pointer Pos, value_type Single = nullptr)
- : IteratorBase(Pos), SingleElement(Single) {}
-
- reference operator*() const {
- return SingleElement ? SingleElement : IteratorBase::operator*();
- }
- };
- typedef iterator const_iterator;
- typedef iterator::pointer pointer;
- typedef iterator::reference reference;
-
- iterator begin() const { return iterator(Result.begin(), Single); }
- iterator end() const { return iterator(Result.end(), Single); }
-
- bool empty() const { return Result.empty(); }
- pointer data() const { return Single ? &Single : Result.data(); }
- size_t size() const { return Single ? 1 : Result.size(); }
- reference front() const { return Single ? Single : Result.front(); }
- reference back() const { return Single ? Single : Result.back(); }
- reference operator[](size_t N) const { return Single ? Single : Result[N]; }
-
- // FIXME: Remove this from the interface
- DeclContextLookupResult slice(size_t N) const {
- DeclContextLookupResult Sliced = Result.slice(N);
- Sliced.Single = Single;
- return Sliced;
- }
-};
-
-/// DeclContext - This is used only as base class of specific decl types that
-/// can act as declaration contexts. These decls are (only the top classes
-/// that directly derive from DeclContext are mentioned, not their subclasses):
-///
-/// TranslationUnitDecl
-/// NamespaceDecl
-/// FunctionDecl
-/// TagDecl
-/// ObjCMethodDecl
-/// ObjCContainerDecl
-/// LinkageSpecDecl
-/// BlockDecl
-///
-class DeclContext {
- /// DeclKind - This indicates which class this is.
- unsigned DeclKind : 8;
-
- /// \brief 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
- /// storage that contains additional declarations that are visible
- /// in this context.
- mutable bool ExternalVisibleStorage : 1;
-
- /// \brief 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
- /// that are missing from the lookup table.
- mutable bool HasLazyLocalLexicalLookups : 1;
-
- /// \brief 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
- /// DeclContext scope (for example TranslationUnit). Used in
- /// LookupQualifiedName()
- mutable bool UseQualifiedLookup : 1;
-
- /// \brief 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
- /// omitted anything), then it contains all relevant entries for that
- /// name (modulo the hasExternalDecls() flag).
- mutable StoredDeclsMap *LookupPtr;
-
-protected:
- /// FirstDecl - The first declaration stored within this declaration
- /// context.
- mutable Decl *FirstDecl;
-
- /// LastDecl - The last declaration stored within this declaration
- /// context. FIXME: We could probably cache this value somewhere
- /// outside of the DeclContext, to reduce the size of DeclContext by
- /// another pointer.
- mutable Decl *LastDecl;
-
- friend class ExternalASTSource;
- friend class ASTDeclReader;
- friend class ASTWriter;
-
- /// \brief Build up a chain of declarations.
- ///
- /// \returns the first/last pair of declarations.
- static std::pair<Decl *, Decl *>
- BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded);
-
- DeclContext(Decl::Kind K)
- : DeclKind(K), ExternalLexicalStorage(false),
- ExternalVisibleStorage(false),
- NeedToReconcileExternalVisibleStorage(false),
- HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false),
- UseQualifiedLookup(false),
- LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {}
-
-public:
- ~DeclContext();
-
- Decl::Kind getDeclKind() const {
- return static_cast<Decl::Kind>(DeclKind);
- }
- const char *getDeclKindName() const;
-
- /// getParent - Returns the containing DeclContext.
- DeclContext *getParent() {
- return cast<Decl>(this)->getDeclContext();
- }
- const DeclContext *getParent() const {
- return const_cast<DeclContext*>(this)->getParent();
- }
-
- /// getLexicalParent - Returns the containing lexical DeclContext. May be
- /// different from getParent, e.g.:
- ///
- /// namespace A {
- /// struct S;
- /// }
- /// struct A::S {}; // getParent() == namespace 'A'
- /// // getLexicalParent() == translation unit
- ///
- DeclContext *getLexicalParent() {
- return cast<Decl>(this)->getLexicalDeclContext();
- }
- const DeclContext *getLexicalParent() const {
- return const_cast<DeclContext*>(this)->getLexicalParent();
- }
-
- DeclContext *getLookupParent();
-
- const DeclContext *getLookupParent() const {
- return const_cast<DeclContext*>(this)->getLookupParent();
- }
-
- ASTContext &getParentASTContext() const {
- return cast<Decl>(this)->getASTContext();
- }
-
- bool isClosure() const {
- return DeclKind == Decl::Block;
- }
-
- bool isObjCContainer() const {
- switch (DeclKind) {
- case Decl::ObjCCategory:
- case Decl::ObjCCategoryImpl:
- case Decl::ObjCImplementation:
- case Decl::ObjCInterface:
- case Decl::ObjCProtocol:
- return true;
- }
- return false;
- }
-
- bool isFunctionOrMethod() const {
- switch (DeclKind) {
- case Decl::Block:
- case Decl::Captured:
- case Decl::ObjCMethod:
- return true;
- default:
- return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction;
- }
- }
-
- /// \brief Test whether the context supports looking up names.
- bool isLookupContext() const {
- return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec;
- }
-
- bool isFileContext() const {
- return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
- }
-
- bool isTranslationUnit() const {
- return DeclKind == Decl::TranslationUnit;
- }
-
- bool isRecord() const {
- return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord;
- }
-
- bool isNamespace() const {
- return DeclKind == Decl::Namespace;
- }
-
- bool isStdNamespace() const;
-
- bool isInlineNamespace() const;
-
- /// \brief Determines whether this context is dependent on a
- /// template parameter.
- bool isDependentContext() const;
-
- /// isTransparentContext - Determines whether this context is a
- /// "transparent" context, meaning that the members declared in this
- /// context are semantically declared in the nearest enclosing
- /// non-transparent (opaque) context but are lexically declared in
- /// this context. For example, consider the enumerators of an
- /// enumeration type:
- /// @code
- /// enum E {
- /// Val1
- /// };
- /// @endcode
- /// Here, E is a transparent context, so its enumerator (Val1) will
- /// appear (semantically) that it is in the same context of E.
- /// Examples of transparent contexts include: enumerations (except for
- /// C++0x scoped enums), and C++ linkage specifications.
- bool isTransparentContext() const;
-
- /// \brief Determines whether this context or some of its ancestors is a
- /// linkage specification context that specifies C linkage.
- bool isExternCContext() const;
-
- /// \brief 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
- /// 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
- /// declaration context DC.
- bool Encloses(const DeclContext *DC) const;
-
- /// \brief 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();
- const Decl *getNonClosureAncestor() const {
- return const_cast<DeclContext*>(this)->getNonClosureAncestor();
- }
-
- /// getPrimaryContext - There may be many different
- /// declarations of the same entity (including forward declarations
- /// of classes, multiple definitions of namespaces, etc.), each with
- /// a different set of declarations. This routine returns the
- /// "primary" DeclContext structure, which will contain the
- /// information needed to perform name lookup into this context.
- DeclContext *getPrimaryContext();
- const DeclContext *getPrimaryContext() const {
- return const_cast<DeclContext*>(this)->getPrimaryContext();
- }
-
- /// getRedeclContext - Retrieve the context in which an entity conflicts with
- /// other entities of the same name, or where it is a redeclaration if the
- /// two entities are compatible. This skips through transparent contexts.
- DeclContext *getRedeclContext();
- const DeclContext *getRedeclContext() const {
- return const_cast<DeclContext *>(this)->getRedeclContext();
- }
-
- /// \brief 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.
- 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
- /// the context NS, as defined in C++0x [namespace.def]p9. If either context
- /// isn't a namespace, this is equivalent to Equals().
- ///
- /// The enclosing namespace set of a namespace is the namespace and, if it is
- /// inline, its enclosing namespace, recursively.
- bool InEnclosingNamespaceSetOf(const DeclContext *NS) const;
-
- /// \brief Collects all of the declaration contexts that are semantically
- /// connected to this declaration context.
- ///
- /// For declaration contexts that have multiple semantically connected but
- /// syntactically distinct contexts, such as C++ namespaces, this routine
- /// retrieves the complete set of such declaration contexts in source order.
- /// For example, given:
- ///
- /// \code
- /// namespace N {
- /// int x;
- /// }
- /// namespace N {
- /// int y;
- /// }
- /// \endcode
- ///
- /// The \c Contexts parameter will contain both definitions of N.
- ///
- /// \param Contexts Will be cleared and set to the set of declaration
- /// contexts that are semanticaly connected to this declaration context,
- /// in source order, including this context (which may be the only result,
- /// for non-namespace contexts).
- void collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts);
-
- /// decl_iterator - Iterates through the declarations stored
- /// within this context.
- class decl_iterator {
- /// Current - The current declaration.
- Decl *Current;
-
- public:
- typedef Decl *value_type;
- typedef const value_type &reference;
- typedef const value_type *pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- decl_iterator() : Current(nullptr) { }
- explicit decl_iterator(Decl *C) : Current(C) { }
-
- reference operator*() const { return Current; }
- // This doesn't meet the iterator requirements, but it's convenient
- value_type operator->() const { return Current; }
-
- decl_iterator& operator++() {
- Current = Current->getNextDeclInContext();
- return *this;
- }
-
- decl_iterator operator++(int) {
- decl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(decl_iterator x, decl_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(decl_iterator x, decl_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<decl_iterator> decl_range;
-
- /// decls_begin/decls_end - Iterate over the declarations stored in
- /// this context.
- decl_range decls() const { return decl_range(decls_begin(), decls_end()); }
- decl_iterator decls_begin() const;
- decl_iterator decls_end() const { return decl_iterator(); }
- bool decls_empty() const;
-
- /// noload_decls_begin/end - Iterate over the declarations stored in this
- /// context that are currently loaded; don't attempt to retrieve anything
- /// from an external source.
- decl_range noload_decls() const {
- return decl_range(noload_decls_begin(), noload_decls_end());
- }
- decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
- decl_iterator noload_decls_end() const { return decl_iterator(); }
-
- /// specific_decl_iterator - Iterates over a subrange of
- /// declarations stored in a DeclContext, providing only those that
- /// are of type SpecificDecl (or a class derived from it). This
- /// iterator is used, for example, to provide iteration over just
- /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
- template<typename SpecificDecl>
- class specific_decl_iterator {
- /// Current - The current, underlying declaration iterator, which
- /// will either be NULL or will point to a declaration of
- /// type SpecificDecl.
- DeclContext::decl_iterator Current;
-
- /// SkipToNextDecl - Advances the current position up to the next
- /// declaration of type SpecificDecl that also meets the criteria
- /// required by Acceptable.
- void SkipToNextDecl() {
- while (*Current && !isa<SpecificDecl>(*Current))
- ++Current;
- }
-
- public:
- typedef SpecificDecl *value_type;
- // TODO: Add reference and pointer typedefs (with some appropriate proxy
- // type) if we ever have a need for them.
- typedef void reference;
- typedef void pointer;
- typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
- difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- specific_decl_iterator() : Current() { }
-
- /// specific_decl_iterator - Construct a new iterator over a
- /// subset of the declarations the range [C,
- /// end-of-declarations). If A is non-NULL, it is a pointer to a
- /// member function of SpecificDecl that should return true for
- /// all of the SpecificDecl instances that will be in the subset
- /// of iterators. For example, if you want Objective-C instance
- /// methods, SpecificDecl will be ObjCMethodDecl and A will be
- /// &ObjCMethodDecl::isInstanceMethod.
- explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
- SkipToNextDecl();
- }
-
- value_type operator*() const { return cast<SpecificDecl>(*Current); }
- // This doesn't meet the iterator requirements, but it's convenient
- value_type operator->() const { return **this; }
-
- specific_decl_iterator& operator++() {
- ++Current;
- SkipToNextDecl();
- return *this;
- }
-
- specific_decl_iterator operator++(int) {
- specific_decl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(const specific_decl_iterator& x,
- const specific_decl_iterator& y) {
- return x.Current == y.Current;
- }
-
- friend bool operator!=(const specific_decl_iterator& x,
- const specific_decl_iterator& y) {
- return x.Current != y.Current;
- }
- };
-
- /// \brief Iterates over a filtered subrange of declarations stored
- /// in a DeclContext.
- ///
- /// This iterator visits only those declarations that are of type
- /// SpecificDecl (or a class derived from it) and that meet some
- /// additional run-time criteria. This iterator is used, for
- /// example, to provide access to the instance methods within an
- /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
- /// Acceptable = ObjCMethodDecl::isInstanceMethod).
- template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
- class filtered_decl_iterator {
- /// Current - The current, underlying declaration iterator, which
- /// will either be NULL or will point to a declaration of
- /// type SpecificDecl.
- DeclContext::decl_iterator Current;
-
- /// SkipToNextDecl - Advances the current position up to the next
- /// declaration of type SpecificDecl that also meets the criteria
- /// required by Acceptable.
- void SkipToNextDecl() {
- while (*Current &&
- (!isa<SpecificDecl>(*Current) ||
- (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
- ++Current;
- }
-
- public:
- typedef SpecificDecl *value_type;
- // TODO: Add reference and pointer typedefs (with some appropriate proxy
- // type) if we ever have a need for them.
- typedef void reference;
- typedef void pointer;
- typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
- difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- filtered_decl_iterator() : Current() { }
-
- /// filtered_decl_iterator - Construct a new iterator over a
- /// subset of the declarations the range [C,
- /// end-of-declarations). If A is non-NULL, it is a pointer to a
- /// member function of SpecificDecl that should return true for
- /// all of the SpecificDecl instances that will be in the subset
- /// of iterators. For example, if you want Objective-C instance
- /// methods, SpecificDecl will be ObjCMethodDecl and A will be
- /// &ObjCMethodDecl::isInstanceMethod.
- explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
- SkipToNextDecl();
- }
-
- value_type operator*() const { return cast<SpecificDecl>(*Current); }
- value_type operator->() const { return cast<SpecificDecl>(*Current); }
-
- filtered_decl_iterator& operator++() {
- ++Current;
- SkipToNextDecl();
- return *this;
- }
-
- filtered_decl_iterator operator++(int) {
- filtered_decl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(const filtered_decl_iterator& x,
- const filtered_decl_iterator& y) {
- return x.Current == y.Current;
- }
-
- friend bool operator!=(const filtered_decl_iterator& x,
- const filtered_decl_iterator& y) {
- return x.Current != y.Current;
- }
- };
-
- /// @brief 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
- /// (lexically) defined. Every declaration must be added to one
- /// (and only one!) context, where it can be visited via
- /// [decls_begin(), decls_end()). Once a declaration has been added
- /// to its lexical context, the corresponding DeclContext owns the
- /// declaration.
- ///
- /// If D is also a NamedDecl, it will be made visible within its
- /// semantic context via makeDeclVisibleInContext.
- void addDecl(Decl *D);
-
- /// @brief 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
- /// important check. This is only useful if the Decl is being
- /// added in response to an external search; in all other cases,
- /// addDecl() is the right function to use.
- /// See the ASTImporter for use cases.
- void addDeclInternal(Decl *D);
-
- /// @brief Add the declaration D to this context without modifying
- /// any lookup tables.
- ///
- /// This is useful for some operations in dependent contexts where
- /// the semantic context might not be dependent; this basically
- /// only happens with friends.
- void addHiddenDecl(Decl *D);
-
- /// @brief Removes a declaration from this context.
- void removeDecl(Decl *D);
-
- /// @brief Checks whether a declaration is in this context.
- bool containsDecl(Decl *D) const;
-
- typedef DeclContextLookupResult lookup_result;
- typedef lookup_result::iterator lookup_iterator;
-
- /// lookup - Find the declarations (if any) with the given Name in
- /// this context. Returns a range of iterators that contains all of
- /// the declarations with this name, with object, function, member,
- /// and enumerator names preceding any tag name. Note that this
- /// routine will not look into parent contexts.
- lookup_result lookup(DeclarationName Name) const;
-
- /// \brief 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
- /// into this declaration context without consulting the external source.
- ///
- /// This function should almost never be used, because it subverts the
- /// usual relationship between a DeclContext and the external source.
- /// See the ASTImporter for the (few, but important) use cases.
- ///
- /// FIXME: This is very inefficient; replace uses of it with uses of
- /// noload_lookup.
- void localUncachedLookup(DeclarationName Name,
- SmallVectorImpl<NamedDecl *> &Results);
-
- /// @brief 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,
- /// within its parent contexts up to the first enclosing
- /// non-transparent context. Making a declaration visible within a
- /// context does not transfer ownership of a declaration, and a
- /// declaration can be visible in many contexts that aren't its
- /// lexical context.
- ///
- /// If D is a redeclaration of an existing declaration that is
- /// visible from this context, as determined by
- /// NamedDecl::declarationReplaces, the previous declaration will be
- /// replaced with D.
- void makeDeclVisibleInContext(NamedDecl *D);
-
- /// all_lookups_iterator - An iterator that provides a view over the results
- /// of looking up every possible name.
- class all_lookups_iterator;
-
- typedef llvm::iterator_range<all_lookups_iterator> lookups_range;
-
- lookups_range lookups() const;
- lookups_range noload_lookups() const;
-
- /// \brief Iterators over all possible lookups within this context.
- all_lookups_iterator lookups_begin() const;
- all_lookups_iterator lookups_end() const;
-
- /// \brief 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;
- all_lookups_iterator noload_lookups_end() const;
-
- struct udir_iterator;
- typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
- std::random_access_iterator_tag,
- UsingDirectiveDecl *> udir_iterator_base;
- struct udir_iterator : udir_iterator_base {
- udir_iterator(lookup_iterator I) : udir_iterator_base(I) {}
- UsingDirectiveDecl *operator*() const;
- };
-
- typedef llvm::iterator_range<udir_iterator> udir_range;
-
- udir_range using_directives() const;
-
- // These are all defined in DependentDiagnostic.h.
- class ddiag_iterator;
- typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range;
-
- inline ddiag_range ddiags() const;
-
- // Low-level accessors
-
- /// \brief 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
- /// setHasExternalLexicalStorage() has been called on any decl context for
- /// which this is the primary context.
- void setMustBuildLookupTable() {
- assert(this == getPrimaryContext() &&
- "should only be called on primary context");
- HasLazyExternalLexicalLookups = true;
- }
-
- /// \brief 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.
- StoredDeclsMap *buildLookup();
-
- /// \brief 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
- /// declarations lexically in this context.
- void setHasExternalLexicalStorage(bool ES = true) {
- ExternalLexicalStorage = ES;
- }
-
- /// \brief 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
- /// declarations visible in this context.
- void setHasExternalVisibleStorage(bool ES = true) {
- ExternalVisibleStorage = ES;
- if (ES && LookupPtr)
- NeedToReconcileExternalVisibleStorage = true;
- }
-
- /// \brief 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 ||
- D == LastDecl);
- }
-
- bool setUseQualifiedLookup(bool use = true) {
- bool old_value = UseQualifiedLookup;
- UseQualifiedLookup = use;
- return old_value;
- }
-
- bool shouldUseQualifiedLookup() const {
- return UseQualifiedLookup;
- }
-
- static bool classof(const Decl *D);
- static bool classof(const DeclContext *D) { return true; }
-
- void dumpDeclContext() const;
- void dumpLookups() const;
- void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false) const;
-
-private:
- void reconcileExternalVisibleStorage() const;
- bool LoadLexicalDeclsFromExternalStorage() const;
-
- /// @brief Makes a declaration visible within this context, but
- /// suppresses searches for external declarations with the same
- /// name.
- ///
- /// Analogous to makeDeclVisibleInContext, but for the exclusive
- /// use of addDeclInternal().
- void makeDeclVisibleInContextInternal(NamedDecl *D);
-
- friend class DependentDiagnostic;
- StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
-
- void buildLookupImpl(DeclContext *DCtx, bool Internal);
- void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
- bool Rediscoverable);
- void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal);
-};
-
-inline bool Decl::isTemplateParameter() const {
- return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm ||
- getKind() == TemplateTemplateParm;
-}
-
-// Specialization selected when ToTy is not a known subclass of DeclContext.
-template <class ToTy,
- bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value>
-struct cast_convert_decl_context {
- static const ToTy *doit(const DeclContext *Val) {
- return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
- }
-
- static ToTy *doit(DeclContext *Val) {
- return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
- }
-};
-
-// Specialization selected when ToTy is a known subclass of DeclContext.
-template <class ToTy>
-struct cast_convert_decl_context<ToTy, true> {
- static const ToTy *doit(const DeclContext *Val) {
- return static_cast<const ToTy*>(Val);
- }
-
- static ToTy *doit(DeclContext *Val) {
- return static_cast<ToTy*>(Val);
- }
-};
-
-
-} // end clang.
-
-namespace llvm {
-
-/// isa<T>(DeclContext*)
-template <typename To>
-struct isa_impl<To, ::clang::DeclContext> {
- static bool doit(const ::clang::DeclContext &Val) {
- return To::classofKind(Val.getDeclKind());
- }
-};
-
-/// cast<T>(DeclContext*)
-template<class ToTy>
-struct cast_convert_val<ToTy,
- const ::clang::DeclContext,const ::clang::DeclContext> {
- static const ToTy &doit(const ::clang::DeclContext &Val) {
- return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
- static ToTy &doit(::clang::DeclContext &Val) {
- return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy,
- const ::clang::DeclContext*, const ::clang::DeclContext*> {
- static const ToTy *doit(const ::clang::DeclContext *Val) {
- return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
- static ToTy *doit(::clang::DeclContext *Val) {
- return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
- }
-};
-
-/// Implement cast_convert_val for Decl -> DeclContext conversions.
-template<class FromTy>
-struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
- static ::clang::DeclContext &doit(const FromTy &Val) {
- return *FromTy::castToDeclContext(&Val);
- }
-};
-
-template<class FromTy>
-struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
- static ::clang::DeclContext *doit(const FromTy *Val) {
- return FromTy::castToDeclContext(Val);
- }
-};
-
-template<class FromTy>
-struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
- static const ::clang::DeclContext &doit(const FromTy &Val) {
- return *FromTy::castToDeclContext(&Val);
- }
-};
-
-template<class FromTy>
-struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
- static const ::clang::DeclContext *doit(const FromTy *Val) {
- return FromTy::castToDeclContext(Val);
- }
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
deleted file mode 100644
index 7c54901..0000000
--- a/include/clang/AST/DeclCXX.h
+++ /dev/null
@@ -1,3249 +0,0 @@
-//===-- DeclCXX.h - Classes for representing C++ declarations -*- 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 C++ Decl subclasses, other than those for templates
-/// (found in DeclTemplate.h) and friends (in DeclFriend.h).
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLCXX_H
-#define LLVM_CLANG_AST_DECLCXX_H
-
-#include "clang/AST/ASTUnresolvedSet.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/LambdaCapture.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class ClassTemplateDecl;
-class ClassTemplateSpecializationDecl;
-class CXXBasePath;
-class CXXBasePaths;
-class CXXConstructorDecl;
-class CXXConversionDecl;
-class CXXDestructorDecl;
-class CXXMethodDecl;
-class CXXRecordDecl;
-class CXXMemberLookupCriteria;
-class CXXFinalOverriderMap;
-class CXXIndirectPrimaryBaseSet;
-class FriendDecl;
-class LambdaExpr;
-class UsingDecl;
-
-/// \brief Represents any kind of function declaration, whether it is a
-/// concrete function or a function template.
-class AnyFunctionDecl {
- NamedDecl *Function;
-
- AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
-
-public:
- AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
- AnyFunctionDecl(FunctionTemplateDecl *FTD);
-
- /// \brief Implicily converts any function or function template into a
- /// named declaration.
- operator NamedDecl *() const { return Function; }
-
- /// \brief Retrieve the underlying function or function template.
- NamedDecl *get() const { return Function; }
-
- static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
- return AnyFunctionDecl(ND);
- }
-};
-
-} // end namespace clang
-
-namespace llvm {
- // Provide PointerLikeTypeTraits for non-cvr pointers.
- template<>
- class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
- public:
- static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
- return F.get();
- }
- static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
- return ::clang::AnyFunctionDecl::getFromNamedDecl(
- static_cast< ::clang::NamedDecl*>(P));
- }
-
- enum { NumLowBitsAvailable = 2 };
- };
-
-} // end namespace llvm
-
-namespace clang {
-
-/// \brief 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
-/// specifiers of a C++ class definition.
-///
-/// Note that they do not represent other uses of access specifiers,
-/// such as those occurring in a list of base specifiers.
-/// 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 {
- virtual void anchor();
- /// \brief The location of the ':'.
- SourceLocation ColonLoc;
-
- AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
- SourceLocation ASLoc, SourceLocation ColonLoc)
- : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
- setAccess(AS);
- }
- AccessSpecDecl(EmptyShell Empty)
- : Decl(AccessSpec, Empty) { }
-public:
- /// \brief The location of the access specifier.
- SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
- /// \brief Sets the location of the access specifier.
- void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
-
- /// \brief The location of the colon following the access specifier.
- SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Sets the location of the colon.
- void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getAccessSpecifierLoc(), getColonLoc());
- }
-
- static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
- DeclContext *DC, SourceLocation ASLoc,
- SourceLocation ColonLoc) {
- return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
- }
- static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == AccessSpec; }
-};
-
-
-/// \brief 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
-/// base class, whether it is a virtual or non-virtual base, and what
-/// level of access (public, protected, private) is used for the
-/// derivation. For example:
-///
-/// \code
-/// class A { };
-/// class B { };
-/// class C : public virtual A, protected B { };
-/// \endcode
-///
-/// 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
- /// 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
- /// expansion.
- SourceLocation EllipsisLoc;
-
- /// \brief Whether this is a virtual base class or not.
- bool Virtual : 1;
-
- /// \brief 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.
- bool BaseOfClass : 1;
-
- /// \brief 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
- /// to inherit the named class's constructors.
- bool InheritConstructors : 1;
-
- /// \brief 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.
- TypeSourceInfo *BaseTypeInfo;
-
-public:
- CXXBaseSpecifier() { }
-
- CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
- TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
- : 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.
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
-
- /// \brief 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
- /// 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.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-
- /// \brief 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.
- void setInheritConstructors(bool Inherit = true) {
- InheritConstructors = Inherit;
- }
-
- /// \brief For a pack expansion, determine the location of the ellipsis.
- SourceLocation getEllipsisLoc() const {
- return EllipsisLoc;
- }
-
- /// \brief 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
- /// written in the source code, use getAccessSpecifierAsWritten().
- AccessSpecifier getAccessSpecifier() const {
- if ((AccessSpecifier)Access == AS_none)
- return BaseOfClass? AS_private : AS_public;
- else
- return (AccessSpecifier)Access;
- }
-
- /// \brief 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
- /// semantic analysis.
- AccessSpecifier getAccessSpecifierAsWritten() const {
- return (AccessSpecifier)Access;
- }
-
- /// \brief 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.
- TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
-};
-
-/// \brief A lazy pointer to the definition data for a declaration.
-/// FIXME: This is a little CXXRecordDecl-specific that the moment.
-template<typename Decl, typename T> class LazyDefinitionDataPtr {
- llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
-
- LazyDefinitionDataPtr update() {
- if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
- if (Canon->isCanonicalDecl())
- Canon->getMostRecentDecl();
- else
- // Declaration isn't canonical any more;
- // update it and perform path compression.
- *this = Canon->getPreviousDecl()->DefinitionData.update();
- }
- return *this;
- }
-
-public:
- LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
- LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
- T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
- T *get() { return update().getNotUpdated(); }
-};
-
-/// \brief Represents a C++ struct/union/class.
-class CXXRecordDecl : public RecordDecl {
-
- friend void TagDecl::startDefinition();
-
- /// Values used in DefinitionData fields to represent special members.
- enum SpecialMemberFlags {
- SMF_DefaultConstructor = 0x1,
- SMF_CopyConstructor = 0x2,
- SMF_MoveConstructor = 0x4,
- SMF_CopyAssignment = 0x8,
- SMF_MoveAssignment = 0x10,
- SMF_Destructor = 0x20,
- SMF_All = 0x3f
- };
-
- struct DefinitionData {
- DefinitionData(CXXRecordDecl *D);
-
- /// \brief True if this class has any user-declared constructors.
- bool UserDeclaredConstructor : 1;
-
- /// \brief The user-declared special members which this class has.
- unsigned UserDeclaredSpecialMembers : 6;
-
- /// \brief True when this class is an aggregate.
- bool Aggregate : 1;
-
- /// \brief True when this class is a POD-type.
- bool PlainOldData : 1;
-
- /// true when this class is empty for traits purposes,
- /// i.e. has no data members other than 0-width bit-fields, has no
- /// virtual function/base, and doesn't inherit from a non-empty
- /// class. Doesn't take union-ness into account.
- bool Empty : 1;
-
- /// \brief True when this class is polymorphic, i.e., has at
- /// least one virtual member or derives from a polymorphic class.
- bool Polymorphic : 1;
-
- /// \brief True when this class is abstract, i.e., has at least
- /// one pure virtual function, (that can come from a base class).
- bool Abstract : 1;
-
- /// \brief True when this class has standard layout.
- ///
- /// 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
- /// array of such types) or reference,
- /// * has no virtual functions (10.3) and no virtual base classes (10.1),
- /// * has the same access control (Clause 11) for all non-static data
- /// members
- /// * has no non-standard-layout base classes,
- /// * either has no non-static data members in the most derived class and at
- /// most one base class with non-static data members, or has no base
- /// classes with non-static data members, and
- /// * has no base classes of the same type as the first non-static data
- /// member.
- bool IsStandardLayout : 1;
-
- /// \brief True when there are no non-empty base classes.
- ///
- /// This is a helper bit of state used to implement IsStandardLayout more
- /// efficiently.
- bool HasNoNonEmptyBases : 1;
-
- /// \brief True when there are private non-static data members.
- bool HasPrivateFields : 1;
-
- /// \brief True when there are protected non-static data members.
- bool HasProtectedFields : 1;
-
- /// \brief True when there are private non-static data members.
- bool HasPublicFields : 1;
-
- /// \brief True if this class (or any subobject) has mutable fields.
- bool HasMutableFields : 1;
-
- /// \brief True if this class (or any nested anonymous struct or union)
- /// has variant members.
- bool HasVariantMembers : 1;
-
- /// \brief True if there no non-field members declared by the user.
- bool HasOnlyCMembers : 1;
-
- /// \brief True if any field has an in-class initializer, including those
- /// within anonymous unions or structs.
- bool HasInClassInitializer : 1;
-
- /// \brief 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.
- bool HasUninitializedReferenceMember : 1;
-
- /// \brief These flags are \c true if a defaulted corresponding special
- /// member can't be fully analyzed without performing overload resolution.
- /// @{
- bool NeedOverloadResolutionForMoveConstructor : 1;
- bool NeedOverloadResolutionForMoveAssignment : 1;
- bool NeedOverloadResolutionForDestructor : 1;
- /// @}
-
- /// \brief These flags are \c true if an implicit defaulted corresponding
- /// special member would be defined as deleted.
- /// @{
- bool DefaultedMoveConstructorIsDeleted : 1;
- bool DefaultedMoveAssignmentIsDeleted : 1;
- bool DefaultedDestructorIsDeleted : 1;
- /// @}
-
- /// \brief 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.
- ///
- /// This excludes any user-declared but not user-provided special members
- /// which have been declared but not yet defined.
- unsigned HasTrivialSpecialMembers : 6;
-
- /// \brief 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
- /// which have been declared but not yet defined, and any implicit special
- /// members which have not yet been declared.
- unsigned DeclaredNonTrivialSpecialMembers : 6;
-
- /// \brief True when this class has a destructor with no semantic effect.
- bool HasIrrelevantDestructor : 1;
-
- /// \brief True when this class has at least one user-declared constexpr
- /// constructor which is neither the copy nor move constructor.
- bool HasConstexprNonCopyMoveConstructor : 1;
-
- /// \brief True if a defaulted default constructor for this class would
- /// be constexpr.
- bool DefaultedDefaultConstructorIsConstexpr : 1;
-
- /// \brief True if this class has a constexpr default constructor.
- ///
- /// This is true for either a user-declared constexpr default constructor
- /// or an implicitly declared constexpr default constructor.
- bool HasConstexprDefaultConstructor : 1;
-
- /// \brief True when this class contains at least one non-static data
- /// member or base class of non-literal or volatile type.
- bool HasNonLiteralTypeFieldsOrBases : 1;
-
- /// \brief True when visible conversion functions are already computed
- /// and are available.
- bool ComputedVisibleConversions : 1;
-
- /// \brief Whether we have a C++11 user-provided default constructor (not
- /// explicitly deleted or defaulted).
- bool UserProvidedDefaultConstructor : 1;
-
- /// \brief 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 would have a const-qualified
- /// parameter.
- bool ImplicitCopyConstructorHasConstParam : 1;
-
- /// \brief Whether an implicit copy assignment operator would have a
- /// const-qualified parameter.
- bool ImplicitCopyAssignmentHasConstParam : 1;
-
- /// \brief Whether any declared copy constructor has a const-qualified
- /// parameter.
- bool HasDeclaredCopyConstructorWithConstParam : 1;
-
- /// \brief Whether any declared copy assignment operator has either a
- /// const-qualified reference parameter or a non-reference parameter.
- bool HasDeclaredCopyAssignmentWithConstParam : 1;
-
- /// \brief Whether this class describes a C++ lambda.
- bool IsLambda : 1;
-
- /// \brief Whether we are currently parsing base specifiers.
- bool IsParsingBaseSpecifiers : 1;
-
- /// \brief The number of base class specifiers in Bases.
- unsigned NumBases;
-
- /// \brief The number of virtual base class specifiers in VBases.
- unsigned NumVBases;
-
- /// \brief 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.
- LazyCXXBaseSpecifiersPtr VBases;
-
- /// \brief 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
- /// 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.
- CXXRecordDecl *Definition;
-
- /// \brief The first friend declaration in this class, or null if there
- /// aren't any.
- ///
- /// This is actually currently stored in reverse order.
- LazyDeclPtr FirstFriend;
-
- /// \brief 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.
- CXXBaseSpecifier *getVBases() const {
- if (!VBases.isOffset())
- return VBases.get(nullptr);
- return getVBasesSlowCase();
- }
-
- private:
- CXXBaseSpecifier *getBasesSlowCase() const;
- CXXBaseSpecifier *getVBasesSlowCase() const;
- };
-
- typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
- DefinitionDataPtr;
- friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
-
- mutable DefinitionDataPtr DefinitionData;
-
- /// \brief Describes a C++ closure type (generated by a lambda expression).
- struct LambdaDefinitionData : public DefinitionData {
- typedef LambdaCapture Capture;
-
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
- bool Dependent, bool IsGeneric,
- LambdaCaptureDefault CaptureDefault)
- : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
- CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
- ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
- MethodTyInfo(Info) {
- IsLambda = true;
-
- // C++11 [expr.prim.lambda]p3:
- // This class type is neither an aggregate nor a literal type.
- Aggregate = false;
- PlainOldData = false;
- HasNonLiteralTypeFieldsOrBases = true;
- }
-
- /// \brief 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
- /// within the default argument of a function template, because the
- /// lambda will have been created with the enclosing context as its
- /// declaration context, rather than function. This is an unfortunate
- /// artifact of having to parse the default arguments before.
- unsigned Dependent : 1;
-
- /// \brief Whether this lambda is a generic lambda.
- unsigned IsGenericLambda : 1;
-
- /// \brief The Default Capture.
- unsigned CaptureDefault : 2;
-
- /// \brief The number of captures in this lambda is limited 2^NumCaptures.
- unsigned NumCaptures : 15;
-
- /// \brief The number of explicit captures in this lambda.
- unsigned NumExplicitCaptures : 13;
-
- /// \brief The number used to indicate this lambda expression for name
- /// mangling in the Itanium C++ ABI.
- unsigned ManglingNumber;
-
- /// \brief 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.
- Decl *ContextDecl;
-
- /// \brief The list of captures, both explicit and implicit, for this
- /// lambda.
- Capture *Captures;
-
- /// \brief The type of the call method.
- TypeSourceInfo *MethodTyInfo;
-
- };
-
- struct DefinitionData &data() const {
- auto *DD = DefinitionData.get();
- assert(DD && "queried property of class with no definition");
- return *DD;
- }
-
- struct LambdaDefinitionData &getLambdaData() const {
- // No update required: a merged definition cannot change any lambda
- // properties.
- auto *DD = DefinitionData.getNotUpdated();
- assert(DD && DD->IsLambda && "queried lambda property of non-lambda class");
- return static_cast<LambdaDefinitionData&>(*DD);
- }
-
- /// \brief The template or declaration that this declaration
- /// describes or was instantiated from, respectively.
- ///
- /// For non-templates, this value will be null. For record
- /// declarations that describe a class template, this will be a
- /// pointer to a ClassTemplateDecl. For member
- /// classes of class template specializations, this will be the
- /// MemberSpecializationInfo referring to the member class that was
- /// instantiated or specialized.
- llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
- TemplateOrInstantiation;
-
- friend class DeclContext;
- friend class LambdaExpr;
-
- /// \brief 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.
- ///
- /// This routine helps maintain information about the class based on which
- /// members have been added. It will be invoked by DeclContext::addDecl()
- /// whenever a member is added to this record.
- void addedMember(Decl *D);
-
- void markedVirtualFunctionPure();
- friend void FunctionDecl::setPure(bool);
-
- friend class ASTNodeImporter;
-
- /// \brief Get the head of our list of friend declarations, possibly
- /// deserializing the friends from an external AST source.
- FriendDecl *getFirstFriend() const;
-
-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.
- typedef CXXBaseSpecifier* base_class_iterator;
-
- /// \brief Iterator that traverses the base classes of a class.
- typedef const CXXBaseSpecifier* base_class_const_iterator;
-
- CXXRecordDecl *getCanonicalDecl() override {
- return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
- }
- const CXXRecordDecl *getCanonicalDecl() const {
- return const_cast<CXXRecordDecl*>(this)->getCanonicalDecl();
- }
-
- CXXRecordDecl *getPreviousDecl() {
- return cast_or_null<CXXRecordDecl>(
- static_cast<RecordDecl *>(this)->getPreviousDecl());
- }
- const CXXRecordDecl *getPreviousDecl() const {
- return const_cast<CXXRecordDecl*>(this)->getPreviousDecl();
- }
-
- CXXRecordDecl *getMostRecentDecl() {
- return cast<CXXRecordDecl>(
- static_cast<RecordDecl *>(this)->getMostRecentDecl());
- }
-
- const CXXRecordDecl *getMostRecentDecl() const {
- return const_cast<CXXRecordDecl*>(this)->getMostRecentDecl();
- }
-
- CXXRecordDecl *getDefinition() const {
- auto *DD = DefinitionData.get();
- return DD ? DD->Definition : nullptr;
- }
-
- bool hasDefinition() const { return DefinitionData.get(); }
-
- static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id,
- CXXRecordDecl *PrevDecl = nullptr,
- bool DelayTypeCreation = false);
- static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
- TypeSourceInfo *Info, SourceLocation Loc,
- bool DependentLambda, bool IsGeneric,
- LambdaCaptureDefault CaptureDefault);
- static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
-
- bool isDynamicClass() const {
- return data().Polymorphic || data().NumVBases != 0;
- }
-
- void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
-
- bool isParsingBaseSpecifiers() const {
- return data().IsParsingBaseSpecifiers;
- }
-
- /// \brief Sets the base classes of this struct or class.
- void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
-
- /// \brief Retrieves the number of base classes of this class.
- unsigned getNumBases() const { return data().NumBases; }
-
- typedef llvm::iterator_range<base_class_iterator> base_class_range;
- typedef llvm::iterator_range<base_class_const_iterator>
- base_class_const_range;
-
- base_class_range bases() {
- return base_class_range(bases_begin(), bases_end());
- }
- base_class_const_range bases() const {
- return base_class_const_range(bases_begin(), bases_end());
- }
-
- base_class_iterator bases_begin() { return data().getBases(); }
- base_class_const_iterator bases_begin() const { return data().getBases(); }
- base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
- base_class_const_iterator bases_end() const {
- return bases_begin() + data().NumBases;
- }
-
- /// \brief Retrieves the number of virtual base classes of this class.
- unsigned getNumVBases() const { return data().NumVBases; }
-
- base_class_range vbases() {
- return base_class_range(vbases_begin(), vbases_end());
- }
- base_class_const_range vbases() const {
- return base_class_const_range(vbases_begin(), vbases_end());
- }
-
- base_class_iterator vbases_begin() { return data().getVBases(); }
- base_class_const_iterator vbases_begin() const { return data().getVBases(); }
- base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
- base_class_const_iterator vbases_end() const {
- return vbases_begin() + data().NumVBases;
- }
-
- /// \brief Determine whether this class has any dependent base classes which
- /// are not the current instantiation.
- bool hasAnyDependentBases() const;
-
- /// Iterator access to method members. The method iterator visits
- /// all method members of the class, including non-instance methods,
- /// special methods, etc.
- typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>
- method_range;
-
- method_range methods() const {
- return method_range(method_begin(), method_end());
- }
-
- /// \brief Method begin iterator. Iterates in the order the methods
- /// were declared.
- method_iterator method_begin() const {
- return method_iterator(decls_begin());
- }
- /// \brief Method past-the-end iterator.
- method_iterator method_end() const {
- return method_iterator(decls_end());
- }
-
- /// Iterator access to constructor members.
- typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
- ctor_range;
-
- ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); }
-
- ctor_iterator ctor_begin() const {
- return ctor_iterator(decls_begin());
- }
- ctor_iterator ctor_end() const {
- return ctor_iterator(decls_end());
- }
-
- /// An iterator over friend declarations. All of these are defined
- /// in DeclFriend.h.
- class friend_iterator;
- typedef llvm::iterator_range<friend_iterator> friend_range;
-
- friend_range friends() const;
- friend_iterator friend_begin() const;
- friend_iterator friend_end() const;
- void pushFriendDecl(FriendDecl *FD);
-
- /// Determines whether this record has any friends.
- bool hasFriends() const {
- return data().FirstFriend.isValid();
- }
-
- /// \brief \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,
- /// 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
- /// destructor that is not deleted.
- bool hasSimpleDestructor() const {
- return !hasUserDeclaredDestructor() &&
- !data().DefaultedDestructorIsDeleted;
- }
-
- /// \brief 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
- /// this class.
- ///
- /// This value is used for lazy creation of default constructors.
- bool needsImplicitDefaultConstructor() const {
- return !data().UserDeclaredConstructor &&
- !(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
- // C++14 [expr.prim.lambda]p20:
- // The closure type associated with a lambda-expression has no
- // default constructor.
- !isLambda();
- }
-
- /// \brief 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
- /// per C++11.
- bool hasUserProvidedDefaultConstructor() const {
- return data().UserProvidedDefaultConstructor;
- }
-
- /// \brief 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
- /// constructor to be lazily declared.
- bool needsImplicitCopyConstructor() const {
- return !(data().DeclaredSpecialMembers & SMF_CopyConstructor);
- }
-
- /// \brief Determine whether we need to eagerly declare a defaulted copy
- /// constructor for this class.
- bool needsOverloadResolutionForCopyConstructor() const {
- return data().HasMutableFields;
- }
-
- /// \brief Determine whether an implicit copy constructor for this type
- /// would have a parameter with a const-qualified reference type.
- bool implicitCopyConstructorHasConstParam() const {
- return data().ImplicitCopyConstructorHasConstParam;
- }
-
- /// \brief 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 ||
- (needsImplicitCopyConstructor() &&
- implicitCopyConstructorHasConstParam());
- }
-
- /// \brief Whether this class has a user-declared move constructor or
- /// assignment operator.
- ///
- /// When false, a move constructor and assignment operator may be
- /// implicitly declared.
- bool hasUserDeclaredMoveOperation() const {
- return data().UserDeclaredSpecialMembers &
- (SMF_MoveConstructor | SMF_MoveAssignment);
- }
-
- /// \brief 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.
- bool hasMoveConstructor() const {
- return (data().DeclaredSpecialMembers & SMF_MoveConstructor) ||
- needsImplicitMoveConstructor();
- }
-
- /// \brief Set that we attempted to declare an implicitly move
- /// constructor, but overload resolution failed so we deleted it.
- void setImplicitMoveConstructorIsDeleted() {
- assert((data().DefaultedMoveConstructorIsDeleted ||
- needsOverloadResolutionForMoveConstructor()) &&
- "move constructor should not be deleted");
- data().DefaultedMoveConstructorIsDeleted = true;
- }
-
- /// \brief 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) &&
- !hasUserDeclaredCopyConstructor() &&
- !hasUserDeclaredCopyAssignment() &&
- !hasUserDeclaredMoveAssignment() &&
- !hasUserDeclaredDestructor();
- }
-
- /// \brief 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
- /// operator.
- ///
- /// When false, a copy assigment operator will be implicitly declared.
- bool hasUserDeclaredCopyAssignment() const {
- return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
- }
-
- /// \brief 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
- /// assignment operator for this class.
- bool needsOverloadResolutionForCopyAssignment() const {
- return data().HasMutableFields;
- }
-
- /// \brief 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
- /// a parameter type which is a reference to a const-qualified type or is not
- /// a reference.
- bool hasCopyAssignmentWithConstParam() const {
- return data().HasDeclaredCopyAssignmentWithConstParam ||
- (needsImplicitCopyAssignment() &&
- implicitCopyAssignmentHasConstParam());
- }
-
- /// \brief 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.
- bool hasMoveAssignment() const {
- return (data().DeclaredSpecialMembers & SMF_MoveAssignment) ||
- needsImplicitMoveAssignment();
- }
-
- /// \brief Set that we attempted to declare an implicit move assignment
- /// operator, but overload resolution failed so we deleted it.
- void setImplicitMoveAssignmentIsDeleted() {
- assert((data().DefaultedMoveAssignmentIsDeleted ||
- needsOverloadResolutionForMoveAssignment()) &&
- "move assignment should not be deleted");
- data().DefaultedMoveAssignmentIsDeleted = true;
- }
-
- /// \brief Determine whether this class should get an implicit move
- /// assignment operator or if any existing special member function inhibits
- /// this.
- bool needsImplicitMoveAssignment() const {
- return !(data().DeclaredSpecialMembers & SMF_MoveAssignment) &&
- !hasUserDeclaredCopyConstructor() &&
- !hasUserDeclaredCopyAssignment() &&
- !hasUserDeclaredMoveConstructor() &&
- !hasUserDeclaredDestructor();
- }
-
- /// \brief 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.
- ///
- /// 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
- /// be lazily declared.
- bool needsImplicitDestructor() const {
- return !(data().DeclaredSpecialMembers & SMF_Destructor);
- }
-
- /// \brief 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.
- bool isLambda() const {
- // An update record can't turn a non-lambda into a lambda.
- auto *DD = DefinitionData.getNotUpdated();
- return DD && DD->IsLambda;
- }
-
- /// \brief Determine whether this class describes a generic
- /// lambda function object (i.e. function call operator is
- /// a template).
- bool isGenericLambda() const;
-
- /// \brief 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
- /// 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.
- /// Returns null if the class does not represent a lambda or a generic
- /// lambda.
- TemplateParameterList *getGenericLambdaTemplateParameterList() const;
-
- LambdaCaptureDefault getLambdaCaptureDefault() const {
- assert(isLambda());
- return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
- }
-
- /// \brief 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.
- ///
- /// \param Captures Will be populated with the mapping from captured
- /// variables to the corresponding fields.
- ///
- /// \param ThisCapture Will be set to the field declaration for the
- /// \c this capture.
- ///
- /// \note No entries will be added for init-captures, as they do not capture
- /// variables.
- void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
- FieldDecl *&ThisCapture) const;
-
- typedef const LambdaCapture *capture_const_iterator;
- typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
-
- capture_const_range captures() const {
- return capture_const_range(captures_begin(), captures_end());
- }
- capture_const_iterator captures_begin() const {
- return isLambda() ? getLambdaData().Captures : nullptr;
- }
- capture_const_iterator captures_end() const {
- return isLambda() ? captures_begin() + getLambdaData().NumCaptures
- : nullptr;
- }
-
- typedef UnresolvedSetIterator conversion_iterator;
- conversion_iterator conversion_begin() const {
- return data().Conversions.get(getASTContext()).begin();
- }
- conversion_iterator conversion_end() const {
- return data().Conversions.get(getASTContext()).end();
- }
-
- /// Removes a conversion function from this class. The conversion
- /// function must currently be a member of this class. Furthermore,
- /// 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,
- /// including conversion function templates.
- llvm::iterator_range<conversion_iterator> getVisibleConversionFunctions();
-
- /// Determine whether this class is an aggregate (C++ [dcl.init.aggr]),
- /// which is a class with no user-declared constructors, no private
- /// or protected non-static data members, no base classes, and no virtual
- /// functions (C++ [dcl.init.aggr]p1).
- bool isAggregate() const { return data().Aggregate; }
-
- /// \brief 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
- /// reference type which would make value-initialization ill-formed.
- ///
- /// Per C++03 [dcl.init]p5:
- /// - if T is a non-union class type without a user-declared constructor,
- /// then every non-static data member and base-class component of T is
- /// value-initialized [...] A program that calls for [...]
- /// value-initialization of an entity of reference type is ill-formed.
- bool hasUninitializedReferenceMember() const {
- return !isUnion() && !hasUserDeclaredConstructor() &&
- data().HasUninitializedReferenceMember;
- }
-
- /// \brief 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
- /// members, no user-defined copy assignment operator and no
- /// user-defined destructor.
- ///
- /// 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.
- /// 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
- /// (C++11 [meta.unary.prop]).
- ///
- /// A non-union class is empty iff it has a virtual function, virtual base,
- /// data member (other than 0-width bit-field) or inherits from a non-empty
- /// class.
- ///
- /// \note This does NOT include a check for union-ness.
- bool isEmpty() const { return data().Empty; }
-
- /// Whether this class is polymorphic (C++ [class.virtual]),
- /// 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.
- ///
- /// 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)
- bool isStandardLayout() const { return data().IsStandardLayout; }
-
- /// \brief 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.
- bool hasVariantMembers() const { return data().HasVariantMembers; }
-
- /// \brief 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
- /// (C++11 [class.ctor]p5).
- bool hasNonTrivialDefaultConstructor() const {
- return (data().DeclaredNonTrivialSpecialMembers & SMF_DefaultConstructor) ||
- (needsImplicitDefaultConstructor() &&
- !(data().HasTrivialSpecialMembers & SMF_DefaultConstructor));
- }
-
- /// \brief Determine whether this class has at least one constexpr constructor
- /// other than the copy or move constructors.
- bool hasConstexprNonCopyMoveConstructor() const {
- return data().HasConstexprNonCopyMoveConstructor ||
- (needsImplicitDefaultConstructor() &&
- defaultedDefaultConstructorIsConstexpr());
- }
-
- /// \brief 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.
- bool hasConstexprDefaultConstructor() const {
- return data().HasConstexprDefaultConstructor ||
- (needsImplicitDefaultConstructor() &&
- defaultedDefaultConstructorIsConstexpr());
- }
-
- /// \brief 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
- /// (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
- /// (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
- /// (C++11 [class.copy]p12)
- bool hasNonTrivialMoveConstructor() const {
- return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveConstructor) ||
- (needsImplicitMoveConstructor() &&
- !(data().HasTrivialSpecialMembers & SMF_MoveConstructor));
- }
-
- /// \brief 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
- /// 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
- /// (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
- /// operator (C++11 [class.copy]p25)
- bool hasNonTrivialMoveAssignment() const {
- return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveAssignment) ||
- (needsImplicitMoveAssignment() &&
- !(data().HasTrivialSpecialMembers & SMF_MoveAssignment));
- }
-
- /// \brief 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
- /// (C++ [class.dtor]p3)
- bool hasNonTrivialDestructor() const {
- return !(data().HasTrivialSpecialMembers & SMF_Destructor);
- }
-
- /// \brief Determine whether this class has a destructor which has no
- /// semantic effect.
- ///
- /// Any such destructor will be trivial, public, defaulted and not deleted,
- /// and will call only irrelevant destructors.
- bool hasIrrelevantDestructor() const {
- return data().HasIrrelevantDestructor;
- }
-
- /// \brief 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 is considered trivially copyable per
- /// (C++11 [class]p6).
- bool isTriviallyCopyable() const;
-
- /// \brief Determine whether this class is considered trivial.
- ///
- /// C++11 [class]p6:
- /// "A trivial class is a class that has a trivial default constructor and
- /// is trivially copiable."
- bool isTrivial() const {
- return isTriviallyCopyable() && hasTrivialDefaultConstructor();
- }
-
- /// \brief Determine whether this class is a literal type.
- ///
- /// C++11 [basic.types]p10:
- /// A class type that has all the following properties:
- /// - it has a trivial destructor
- /// - every constructor call and full-expression in the
- /// brace-or-equal-intializers for non-static data members (if any) is
- /// a constant expression.
- /// - it is an aggregate type or has at least one constexpr constructor
- /// or constructor template that is not a copy or move constructor, and
- /// - all of its non-static data members and base classes are of literal
- /// types
- ///
- /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
- /// treating types with trivial default constructors as literal types.
- bool isLiteral() const {
- return hasTrivialDestructor() &&
- (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
- hasTrivialDefaultConstructor()) &&
- !hasNonLiteralTypeFieldsOrBases();
- }
-
- /// \brief 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
- /// classes of class templates. For example, given:
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// struct A { };
- /// };
- /// \endcode
- ///
- /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl
- /// whose parent is the class template specialization X<int>. For
- /// this declaration, getInstantiatedFromMemberClass() will return
- /// the CXXRecordDecl X<T>::A. When a complete definition of
- /// X<int>::A is required, it will be instantiated from the
- /// declaration returned by getInstantiatedFromMemberClass().
- CXXRecordDecl *getInstantiatedFromMemberClass() const;
-
- /// \brief 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
- /// member class \p RD.
- void setInstantiationOfMemberClass(CXXRecordDecl *RD,
- TemplateSpecializationKind TSK);
-
- /// \brief Retrieves the class template that is described by this
- /// class declaration.
- ///
- /// Every class template is represented as a ClassTemplateDecl and a
- /// CXXRecordDecl. The former contains template properties (such as
- /// the template parameter lists) while the latter contains the
- /// actual description of the template's
- /// contents. ClassTemplateDecl::getTemplatedDecl() retrieves the
- /// CXXRecordDecl that from a ClassTemplateDecl, while
- /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from
- /// a CXXRecordDecl.
- ClassTemplateDecl *getDescribedClassTemplate() const;
-
- void setDescribedClassTemplate(ClassTemplateDecl *Template);
-
- /// \brief 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.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
-
- /// \brief 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;
-
- CXXRecordDecl *getTemplateInstantiationPattern() {
- return const_cast<CXXRecordDecl *>(const_cast<const CXXRecordDecl *>(this)
- ->getTemplateInstantiationPattern());
- }
-
- /// \brief Returns the destructor decl for this class.
- CXXDestructorDecl *getDestructor() const;
-
- /// \brief 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
- /// the enclosing function declaration.
- const FunctionDecl *isLocalClass() const {
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
- return RD->isLocalClass();
-
- return dyn_cast<FunctionDecl>(getDeclContext());
- }
-
- FunctionDecl *isLocalClass() {
- return const_cast<FunctionDecl*>(
- const_cast<const CXXRecordDecl*>(this)->isLocalClass());
- }
-
- /// \brief 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.
- ///
- /// 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
- /// ill-formed, such as private/protected inheritance or multiple, ambiguous
- /// base class subobjects.
- ///
- /// \param Base the base class we are searching for.
- ///
- /// \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.
- ///
- /// 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
- /// ill-formed, such as private/protected inheritance or multiple, ambiguous
- /// base class subobjects.
- ///
- /// \param Base the base class we are searching for.
- ///
- /// \param Paths will contain the paths taken from the current class to the
- /// given \p Base class.
- ///
- /// \returns true if this class is derived from \p Base, false otherwise.
- ///
- /// \todo add a separate parameter to configure IsDerivedFrom, rather than
- /// tangling input and output in \p Paths
- bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
-
- /// \brief Determine whether this class is virtually derived from
- /// the class \p Base.
- ///
- /// This routine only determines whether this class is virtually
- /// derived from \p Base, but does not account for factors that may
- /// make a Derived -> Base class ill-formed, such as
- /// private/protected inheritance or multiple, ambiguous base class
- /// subobjects.
- ///
- /// \param Base the base class we are searching for.
- ///
- /// \returns true if this class is virtually derived from Base,
- /// false otherwise.
- bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const;
-
- /// \brief 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.
- ///
- /// \param BaseDefinition the definition of the base class
- ///
- /// \returns true if this base matched the search criteria
- typedef llvm::function_ref<bool(const CXXRecordDecl *BaseDefinition)>
- ForallBasesCallback;
-
- /// \brief 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
- /// returns false if the class has non-computable base classes.
- ///
- /// \param BaseMatches Callback invoked for each (direct or indirect) base
- /// class of this type, or if \p AllowShortCircuit is true then until a call
- /// returns false.
- ///
- /// \param AllowShortCircuit if false, forces the callback to be called
- /// for every base class, even if a dependent or non-matching base was
- /// found.
- bool forallBases(ForallBasesCallback BaseMatches,
- bool AllowShortCircuit = true) const;
-
- /// \brief 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
- /// from the base class we are trying to match.
- ///
- /// \param Path the current path, from the most-derived class down to the
- /// base named by the \p Specifier.
- ///
- /// \returns true if this base matched the search criteria, false otherwise.
- typedef llvm::function_ref<bool(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path)> BaseMatchesCallback;
-
- /// \brief 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
- /// classes meeting some search criteria, walking all base class subobjects
- /// and populating the given \p Paths structure with the paths through the
- /// inheritance hierarchy that resulted in a match. On a successful search,
- /// the \p Paths structure can be queried to retrieve the matching paths and
- /// to determine if there were any ambiguities.
- ///
- /// \param BaseMatches callback function used to determine whether a given
- /// base matches the user-defined search criteria.
- ///
- /// \param Paths used to record the paths from this class to its base class
- /// subobjects that match the search criteria.
- ///
- /// \returns true if there exists any path from this class to a base class
- /// subobject that matches the search criteria.
- bool lookupInBases(BaseMatchesCallback BaseMatches,
- CXXBasePaths &Paths) const;
-
- /// \brief 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
- /// a given derived class has is a base class subobject of a particular type.
- /// The base record pointer should refer to the canonical CXXRecordDecl of the
- /// base class that we are searching for.
- static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path, const CXXRecordDecl *BaseRecord);
-
- /// \brief Base-class lookup callback that determines whether the
- /// given base class specifier refers to a specific class
- /// declaration and describes virtual derivation.
- ///
- /// This callback can be used with \c lookupInBases() to determine
- /// whether a given derived class has is a virtual base class
- /// subobject of a particular type. The base record pointer should
- /// refer to the canonical CXXRecordDecl of the base class that we
- /// are searching for.
- static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path,
- const CXXRecordDecl *BaseRecord);
-
- /// \brief 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
- /// of the given name within a C++ class hierarchy.
- static bool FindTagMember(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path, DeclarationName Name);
-
- /// \brief 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
- /// of the given name within a C++ class hierarchy.
- static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path, DeclarationName Name);
-
- /// \brief 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
- /// the given name within a C++ class hierarchy that can occur within
- /// nested-name-specifiers.
- static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path,
- DeclarationName Name);
-
- /// \brief 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.
- void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
-
- /// Renders and displays an inheritance diagram
- /// for this C++ class and all of its base classes (transitively) using
- /// GraphViz.
- void viewInheritance(ASTContext& Context) const;
-
- /// \brief Calculates the access of a decl that is reached
- /// along a path.
- static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
- AccessSpecifier DeclAccess) {
- assert(DeclAccess != AS_none);
- if (DeclAccess == AS_private) return AS_none;
- return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
- }
-
- /// \brief 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 completeDefinition() override;
-
- /// \brief 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
- /// be provided as an optimization for abstract-class checking. If NULL,
- /// final overriders will be computed if they are needed to complete the
- /// definition.
- void completeDefinition(CXXFinalOverriderMap *FinalOverriders);
-
- /// \brief 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
- /// base classes that are abstract. In this case, \c completeDefinition()
- /// will need to compute final overriders to determine whether the class is
- /// actually abstract.
- bool mayBeAbstract() const;
-
- /// \brief 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
- /// mangling number does not matter, while a non-zero value indicates which
- /// lambda expression this is in this particular context.
- unsigned getLambdaManglingNumber() const {
- assert(isLambda() && "Not a lambda closure type!");
- return getLambdaData().ManglingNumber;
- }
-
- /// \brief 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
- /// the initializers of data members) have separate name mangling rules for
- /// lambdas within the Itanium C++ ABI. For these cases, this routine provides
- /// the declaration in which the lambda occurs, e.g., the function parameter
- /// or the non-static data member. Otherwise, it returns NULL to imply that
- /// the declaration context suffices.
- Decl *getLambdaContextDecl() const {
- assert(isLambda() && "Not a lambda closure type!");
- return getLambdaData().ContextDecl;
- }
-
- /// \brief 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.
- MSInheritanceAttr::Spelling getMSInheritanceModel() const;
- /// \brief Calculate what the inheritance model would be for this class.
- MSInheritanceAttr::Spelling calculateInheritanceModel() const;
-
- /// In the Microsoft C++ ABI, use zero for the field offset of a null data
- /// member pointer if we can guarantee that zero is not a valid field offset,
- /// or if the member pointer has multiple fields. Polymorphic classes have a
- /// vfptr at offset zero, so we can use zero for null. If there are multiple
- /// fields, we can use zero even if it is a valid field offset because
- /// null-ness testing will check the other fields.
- bool nullFieldOffsetIsZero() const {
- return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false,
- getMSInheritanceModel()) ||
- (hasDefinition() && isPolymorphic());
- }
-
- /// \brief Controls when vtordisps will be emitted if this record is used as a
- /// virtual base.
- MSVtorDispAttr::Mode getMSVtorDispMode() const;
-
- /// \brief Determine whether this lambda expression was known to be dependent
- /// at the time it was created, even if its context does not appear to be
- /// dependent.
- ///
- /// This flag is a workaround for an issue with parsing, where default
- /// arguments are parsed before their enclosing function declarations have
- /// been created. This means that any lambda expressions within those
- /// default arguments will have as their DeclContext the context enclosing
- /// the function declaration, which may be non-dependent even when the
- /// function declaration itself is dependent. This flag indicates when we
- /// know that the lambda is dependent despite that.
- bool isDependentLambda() const {
- return isLambda() && getLambdaData().Dependent;
- }
-
- TypeSourceInfo *getLambdaTypeInfo() const {
- return getLambdaData().MethodTyInfo;
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstCXXRecord && K <= lastCXXRecord;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend class ASTReader;
- friend class ASTWriter;
-};
-
-/// \brief 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.
-class CXXMethodDecl : public FunctionDecl {
- void anchor() override;
-protected:
- CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass SC, bool isInline,
- bool isConstexpr, SourceLocation EndLocation)
- : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo,
- SC, isInline, isConstexpr) {
- if (EndLocation.isValid())
- setRangeEnd(EndLocation);
- }
-
-public:
- static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass SC,
- bool isInline,
- bool isConstexpr,
- SourceLocation EndLocation);
-
- static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- bool isStatic() const;
- bool isInstance() const { return !isStatic(); }
-
- /// Returns true if the given operator is implicitly static in a record
- /// context.
- static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK) {
- // [class.free]p1:
- // Any allocation function for a class T is a static member
- // (even if not explicitly declared static).
- // [class.free]p6 Any deallocation function for a class X is a static member
- // (even if not explicitly declared static).
- return OOK == OO_New || OOK == OO_Array_New || OOK == OO_Delete ||
- OOK == OO_Array_Delete;
- }
-
- bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); }
- bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); }
-
- bool isVirtual() const {
- CXXMethodDecl *CD =
- cast<CXXMethodDecl>(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.
- if (CD->isVirtualAsWritten() || CD->isPure())
- return true;
-
- return (CD->begin_overridden_methods() != CD->end_overridden_methods());
- }
-
- /// \brief 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
- /// of whether it was declared implicitly or explicitly.
- bool isCopyAssignmentOperator() const;
-
- /// \brief Determine whether this is a move assignment operator.
- bool isMoveAssignmentOperator() const;
-
- CXXMethodDecl *getCanonicalDecl() override {
- return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
- }
- const CXXMethodDecl *getCanonicalDecl() const {
- return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
- }
-
- CXXMethodDecl *getMostRecentDecl() {
- return cast<CXXMethodDecl>(
- static_cast<FunctionDecl *>(this)->getMostRecentDecl());
- }
- const CXXMethodDecl *getMostRecentDecl() const {
- return const_cast<CXXMethodDecl*>(this)->getMostRecentDecl();
- }
-
- /// True if this method is user-declared and was not
- /// deleted or defaulted on its first declaration.
- bool isUserProvided() const {
- return !(isDeleted() || getCanonicalDecl()->isDefaulted());
- }
-
- ///
- void addOverriddenMethod(const CXXMethodDecl *MD);
-
- typedef const CXXMethodDecl *const* method_iterator;
-
- method_iterator begin_overridden_methods() const;
- method_iterator end_overridden_methods() const;
- unsigned size_overridden_methods() const;
-
- /// Returns the parent of this method declaration, which
- /// is the class in which this method is defined.
- const CXXRecordDecl *getParent() const {
- return cast<CXXRecordDecl>(FunctionDecl::getParent());
- }
-
- /// Returns the parent of this method declaration, which
- /// is the class in which this method is defined.
- CXXRecordDecl *getParent() {
- return const_cast<CXXRecordDecl *>(
- cast<CXXRecordDecl>(FunctionDecl::getParent()));
- }
-
- /// \brief Returns the type of the \c this pointer.
- ///
- /// Should only be called for instance (i.e., non-static) methods.
- QualType getThisType(ASTContext &C) const;
-
- unsigned getTypeQualifiers() const {
- return getType()->getAs<FunctionProtoType>()->getTypeQuals();
- }
-
- /// \brief 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.
- /// @code
- /// struct X {
- /// void f() &;
- /// void g() &&;
- /// void h();
- /// };
- /// @endcode
- RefQualifierKind getRefQualifier() const {
- return getType()->getAs<FunctionProtoType>()->getRefQualifier();
- }
-
- bool hasInlineBody() const;
-
- /// \brief 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).
- ///
- /// The function itself, if used, will have a placeholder body that will be
- /// supplied by IR generation to either forward to the function call operator
- /// or clone the function call operator.
- bool isLambdaStaticInvoker() const;
-
- /// \brief 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
- /// this method (or be the class itself), unless \p MayBeBase is set to true.
- CXXMethodDecl *
- getCorrespondingMethodInClass(const CXXRecordDecl *RD,
- bool MayBeBase = false);
-
- const CXXMethodDecl *
- getCorrespondingMethodInClass(const CXXRecordDecl *RD,
- bool MayBeBase = false) const {
- return const_cast<CXXMethodDecl *>(this)
- ->getCorrespondingMethodInClass(RD, MayBeBase);
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstCXXMethod && K <= lastCXXMethod;
- }
-};
-
-/// \brief 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
-/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
-/// initializers:
-///
-/// \code
-/// class A { };
-/// class B : public A {
-/// float f;
-/// public:
-/// B(A& a) : A(a), f(3.14159) { }
-/// };
-/// \endcode
-class CXXCtorInitializer final
- : private llvm::TrailingObjects<CXXCtorInitializer, VarDecl *> {
- /// \brief 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
- /// pack expansion, the location of the ellipsis.
- ///
- /// In the case of a delegating
- /// constructor, it will still include the type's source location as the
- /// Initializee points to the CXXConstructorDecl (to allow loop detection).
- SourceLocation MemberOrEllipsisLocation;
-
- /// \brief 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.
- SourceLocation LParenLoc;
-
- /// \brief Location of the right paren of the ctor-initializer.
- SourceLocation RParenLoc;
-
- /// \brief If the initializee is a type, whether that type makes this
- /// a delegating initialization.
- bool IsDelegating : 1;
-
- /// \brief If the initializer is a base initializer, this keeps track
- /// of whether the base is virtual or not.
- bool IsVirtual : 1;
-
- /// \brief Whether or not the initializer is explicitly written
- /// in the sources.
- bool IsWritten : 1;
-
- /// If IsWritten is true, then this number keeps track of the textual order
- /// of this initializer in the original sources, counting from 0; otherwise,
- /// it stores the number of array index variables stored after this object
- /// in memory.
- unsigned SourceOrderOrNumArrayIndices : 13;
-
- CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L, Expr *Init,
- SourceLocation R, VarDecl **Indices, unsigned NumIndices);
-
-public:
- /// \brief 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.
- explicit
- CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L, Expr *Init,
- SourceLocation R);
-
- /// \brief 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.
- explicit
- CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
- SourceLocation L, Expr *Init, SourceLocation R);
-
- /// \brief Creates a new member initializer that optionally contains
- /// array indices used to describe an elementwise initialization.
- static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L,
- Expr *Init, SourceLocation R,
- VarDecl **Indices, unsigned NumIndices);
-
- /// \brief 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
- /// data member.
- bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
-
- bool isAnyMemberInitializer() const {
- return isMemberInitializer() || isIndirectMemberInitializer();
- }
-
- bool isIndirectMemberInitializer() const {
- return Initializee.is<IndirectFieldDecl*>();
- }
-
- /// \brief Determine whether this initializer is an implicit initializer
- /// generated for a field with an initializer defined on the member
- /// declaration.
- ///
- /// In-class member initializers (also known as "non-static data member
- /// initializations", NSDMIs) were introduced in C++11.
- bool isInClassMemberInitializer() const {
- return Init->getStmtClass() == Stmt::CXXDefaultInitExprClass;
- }
-
- /// \brief 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.
- bool isPackExpansion() const {
- return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
- }
-
- // \brief For a pack expansion, returns the location of the ellipsis.
- SourceLocation getEllipsisLoc() const {
- assert(isPackExpansion() && "Initializer is not a pack expansion");
- return MemberOrEllipsisLocation;
- }
-
- /// If this is a base class initializer, returns the type of the
- /// base class with location information. Otherwise, returns an NULL
- /// type location.
- TypeLoc getBaseClassLoc() const;
-
- /// If this is a base class initializer, returns the type of the base class.
- /// Otherwise, returns null.
- const Type *getBaseClass() const;
-
- /// Returns whether the base is virtual or not.
- bool isBaseVirtual() const {
- assert(isBaseInitializer() && "Must call this on base initializer!");
-
- return IsVirtual;
- }
-
- /// \brief 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
- /// non-static data member being initialized. Otherwise, returns null.
- FieldDecl *getMember() const {
- if (isMemberInitializer())
- return Initializee.get<FieldDecl*>();
- return nullptr;
- }
- FieldDecl *getAnyMember() const {
- if (isMemberInitializer())
- return Initializee.get<FieldDecl*>();
- if (isIndirectMemberInitializer())
- return Initializee.get<IndirectFieldDecl*>()->getAnonField();
- return nullptr;
- }
-
- IndirectFieldDecl *getIndirectMember() const {
- if (isIndirectMemberInitializer())
- return Initializee.get<IndirectFieldDecl*>();
- return nullptr;
- }
-
- SourceLocation getMemberLocation() const {
- return MemberOrEllipsisLocation;
- }
-
- /// \brief Determine the source location of the initializer.
- SourceLocation getSourceLocation() const;
-
- /// \brief Determine the source range covering the entire initializer.
- SourceRange getSourceRange() const LLVM_READONLY;
-
- /// \brief 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.
- /// If the initializer was implicit, -1 is returned.
- int getSourceOrder() const {
- return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
- }
-
- /// \brief 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.
- ///
- /// This assumes that the initializer was written in the source code, and
- /// ensures that isWritten() returns true.
- void setSourceOrder(int pos) {
- assert(!IsWritten &&
- "calling twice setSourceOrder() on the same initializer");
- assert(SourceOrderOrNumArrayIndices == 0 &&
- "setSourceOrder() used when there are implicit array indices");
- assert(pos >= 0 &&
- "setSourceOrder() used to make an initializer implicit");
- IsWritten = true;
- SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
- }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- /// \brief Determine the number of implicit array indices used while
- /// described an array member initialization.
- unsigned getNumArrayIndices() const {
- return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
- }
-
- /// \brief Retrieve a particular array index variable used to
- /// describe an array member initialization.
- VarDecl *getArrayIndex(unsigned I) {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- return getTrailingObjects<VarDecl *>()[I];
- }
- const VarDecl *getArrayIndex(unsigned I) const {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- return getTrailingObjects<VarDecl *>()[I];
- }
- void setArrayIndex(unsigned I, VarDecl *Index) {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- getTrailingObjects<VarDecl *>()[I] = Index;
- }
- ArrayRef<VarDecl *> getArrayIndexes() {
- assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
- return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(),
- getNumArrayIndices());
- }
-
- /// \brief Get the initializer.
- Expr *getInit() const { return static_cast<Expr*>(Init); }
-
- friend TrailingObjects;
-};
-
-/// \brief Represents a C++ constructor within a class.
-///
-/// For example:
-///
-/// \code
-/// class X {
-/// public:
-/// explicit X(int); // represented by a CXXConstructorDecl.
-/// };
-/// \endcode
-class CXXConstructorDecl : public CXXMethodDecl {
- void anchor() override;
- /// \brief Whether this constructor declaration has the \c explicit keyword
- /// specified.
- bool IsExplicitSpecified : 1;
-
- /// \name Support for base and member initializers.
- /// \{
- /// \brief The arguments used to initialize the base or member.
- LazyCXXCtorInitializersPtr CtorInitializers;
- unsigned NumCtorInitializers;
- /// \}
-
- CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isExplicitSpecified, bool isInline,
- bool isImplicitlyDeclared, bool isConstexpr)
- : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, isConstexpr, SourceLocation()),
- IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
- NumCtorInitializers(0) {
- setImplicit(isImplicitlyDeclared);
- }
-
-public:
- static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isExplicit,
- bool isInline, bool isImplicitlyDeclared,
- bool isConstexpr);
-
- /// \brief Determine whether this constructor declaration has the
- /// \c explicit keyword specified.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
- /// \brief Determine whether this constructor was marked "explicit" or not.
- bool isExplicit() const {
- return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified();
- }
-
- /// \brief Iterates through the member/base initializer list.
- typedef CXXCtorInitializer **init_iterator;
-
- /// \brief Iterates through the member/base initializer list.
- typedef CXXCtorInitializer *const *init_const_iterator;
-
- typedef llvm::iterator_range<init_iterator> init_range;
- typedef llvm::iterator_range<init_const_iterator> init_const_range;
-
- init_range inits() { return init_range(init_begin(), init_end()); }
- init_const_range inits() const {
- return init_const_range(init_begin(), init_end());
- }
-
- /// \brief Retrieve an iterator to the first initializer.
- init_iterator init_begin() {
- const auto *ConstThis = this;
- return const_cast<init_iterator>(ConstThis->init_begin());
- }
- /// \brief Retrieve an iterator to the first initializer.
- init_const_iterator init_begin() const;
-
- /// \brief Retrieve an iterator past the last initializer.
- init_iterator init_end() {
- return init_begin() + NumCtorInitializers;
- }
- /// \brief Retrieve an iterator past the last initializer.
- init_const_iterator init_end() const {
- return init_begin() + NumCtorInitializers;
- }
-
- typedef std::reverse_iterator<init_iterator> init_reverse_iterator;
- typedef std::reverse_iterator<init_const_iterator>
- init_const_reverse_iterator;
-
- init_reverse_iterator init_rbegin() {
- return init_reverse_iterator(init_end());
- }
- init_const_reverse_iterator init_rbegin() const {
- return init_const_reverse_iterator(init_end());
- }
-
- init_reverse_iterator init_rend() {
- return init_reverse_iterator(init_begin());
- }
- init_const_reverse_iterator init_rend() const {
- return init_const_reverse_iterator(init_begin());
- }
-
- /// \brief Determine the number of arguments used to initialize the member
- /// or base.
- unsigned getNumCtorInitializers() const {
- return NumCtorInitializers;
- }
-
- void setNumCtorInitializers(unsigned numCtorInitializers) {
- NumCtorInitializers = numCtorInitializers;
- }
-
- void setCtorInitializers(CXXCtorInitializer **Initializers) {
- CtorInitializers = Initializers;
- }
-
- /// \brief 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.
- CXXConstructorDecl *getTargetConstructor() const;
-
- /// Whether this constructor is a default
- /// constructor (C++ [class.ctor]p5), which can be used to
- /// default-initialize a class of this type.
- bool isDefaultConstructor() const;
-
- /// \brief 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
- /// argument type. For example, \p TypeQuals would be set to \c
- /// Qualifiers::Const for the following copy constructor:
- ///
- /// \code
- /// class X {
- /// public:
- /// X(const X&);
- /// };
- /// \endcode
- bool isCopyConstructor(unsigned &TypeQuals) const;
-
- /// Whether this constructor is a copy
- /// constructor (C++ [class.copy]p2, which can be used to copy the
- /// class.
- bool isCopyConstructor() const {
- unsigned TypeQuals = 0;
- return isCopyConstructor(TypeQuals);
- }
-
- /// \brief 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
- /// (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.
- ///
- /// \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.
- bool isCopyOrMoveConstructor() const {
- unsigned Quals;
- return isCopyOrMoveConstructor(Quals);
- }
-
- /// Whether this constructor is a
- /// converting constructor (C++ [class.conv.ctor]), which can be
- /// used for user-defined conversions.
- bool isConvertingConstructor(bool AllowExplicit) const;
-
- /// \brief 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 Get the constructor that this inheriting constructor is based on.
- const CXXConstructorDecl *getInheritedConstructor() const;
-
- /// \brief Set the constructor that this inheriting constructor is based on.
- void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
-
- CXXConstructorDecl *getCanonicalDecl() override {
- return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
- }
- const CXXConstructorDecl *getCanonicalDecl() const {
- return const_cast<CXXConstructorDecl*>(this)->getCanonicalDecl();
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == CXXConstructor; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a C++ destructor within a class.
-///
-/// For example:
-///
-/// \code
-/// class X {
-/// public:
-/// ~X(); // represented by a CXXDestructorDecl.
-/// };
-/// \endcode
-class CXXDestructorDecl : public CXXMethodDecl {
- void anchor() override;
-
- FunctionDecl *OperatorDelete;
-
- CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
- OperatorDelete(nullptr) {
- setImplicit(isImplicitlyDeclared);
- }
-
-public:
- static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo* TInfo,
- bool isInline,
- bool isImplicitlyDeclared);
- static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
-
- void setOperatorDelete(FunctionDecl *OD);
- const FunctionDecl *getOperatorDelete() const {
- return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == CXXDestructor; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a C++ conversion function within a class.
-///
-/// For example:
-///
-/// \code
-/// class X {
-/// public:
-/// operator bool();
-/// };
-/// \endcode
-class CXXConversionDecl : public CXXMethodDecl {
- void anchor() override;
- /// Whether this conversion function declaration is marked
- /// "explicit", meaning that it can only be applied when the user
- /// explicitly wrote a cast. This is a C++11 feature.
- bool IsExplicitSpecified : 1;
-
- CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicitSpecified,
- bool isConstexpr, SourceLocation EndLocation)
- : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, isConstexpr, EndLocation),
- IsExplicitSpecified(isExplicitSpecified) { }
-
-public:
- static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicit,
- bool isConstexpr,
- SourceLocation EndLocation);
- static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// Whether this conversion function declaration is marked
- /// "explicit", meaning that it can only be used for direct initialization
- /// (including explitly written casts). This is a C++11 feature.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
- /// \brief Whether this is an explicit conversion operator (C++11 and later).
- ///
- /// Explicit conversion operators are only considered for direct
- /// initialization, e.g., when the user has explicitly written a cast.
- bool isExplicit() const {
- return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified();
- }
-
- /// \brief 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
- /// a lambda closure type to a block pointer.
- bool isLambdaToBlockPointerConversion() const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == CXXConversion; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a linkage specification.
-///
-/// For example:
-/// \code
-/// extern "C" void foo();
-/// \endcode
-class LinkageSpecDecl : public Decl, public DeclContext {
- virtual void anchor();
-public:
- /// \brief 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
- /// ensure a stable ABI for this, we choose the DW_LANG_ encodings
- /// from the dwarf standard.
- enum LanguageIDs {
- lang_c = /* DW_LANG_C */ 0x0002,
- lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
- };
-private:
- /// \brief The language for this linkage specification.
- unsigned Language : 3;
- /// \brief 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.
- SourceLocation ExternLoc;
- /// \brief The source location for the right brace (if valid).
- SourceLocation RBraceLoc;
-
- LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs lang, bool HasBraces)
- : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
- Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc),
- RBraceLoc(SourceLocation()) { }
-
-public:
- static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs Lang,
- bool HasBraces);
- static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief Return the language specified by this linkage specification.
- LanguageIDs getLanguage() const { return LanguageIDs(Language); }
- /// \brief Set the language specified by this linkage specification.
- void setLanguage(LanguageIDs L) { Language = L; }
-
- /// \brief Determines whether this linkage specification had braces in
- /// its syntactic form.
- bool hasBraces() const {
- assert(!RBraceLoc.isValid() || HasBraces);
- return HasBraces;
- }
-
- SourceLocation getExternLoc() const { return ExternLoc; }
- SourceLocation getRBraceLoc() const { return RBraceLoc; }
- void setExternLoc(SourceLocation L) { ExternLoc = L; }
- void setRBraceLoc(SourceLocation L) {
- RBraceLoc = L;
- HasBraces = RBraceLoc.isValid();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasBraces())
- return getRBraceLoc();
- // No braces: get the end location of the (only) declaration in context
- // (if present).
- return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(ExternLoc, getLocEnd());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == LinkageSpec; }
- static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
- return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
- }
- static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief Represents C++ using-directive.
-///
-/// For example:
-/// \code
-/// using namespace std;
-/// \endcode
-///
-/// \note UsingDirectiveDecl should be Decl not NamedDecl, but we provide
-/// artificial names for all using-directives in order to store
-/// them in DeclContext effectively.
-class UsingDirectiveDecl : public NamedDecl {
- void anchor() override;
- /// \brief The location of the \c using keyword.
- SourceLocation UsingLoc;
-
- /// \brief The location of the \c namespace keyword.
- SourceLocation NamespaceLoc;
-
- /// \brief The nested-name-specifier that precedes the namespace.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The namespace nominated by this using-directive.
- NamedDecl *NominatedNamespace;
-
- /// Enclosing context containing both using-directive and nominated
- /// namespace.
- DeclContext *CommonAncestor;
-
- /// \brief Returns special DeclarationName used by using-directives.
- ///
- /// This is only used by DeclContext for storing UsingDirectiveDecls in
- /// its lookup structure.
- static DeclarationName getName() {
- return DeclarationName::getUsingDirectiveName();
- }
-
- UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
- SourceLocation NamespcLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Nominated,
- DeclContext *CommonAncestor)
- : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
- NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
- NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { }
-
-public:
- /// \brief 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
- /// name of the namespace.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
- const NamedDecl *getNominatedNamespaceAsWritten() const {
- return NominatedNamespace;
- }
-
- /// \brief 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
- /// its nominated namespace.
- DeclContext *getCommonAncestor() { return CommonAncestor; }
- const DeclContext *getCommonAncestor() const { return CommonAncestor; }
-
- /// \brief 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.
- SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
-
- /// \brief Returns the location of this using declaration's identifier.
- SourceLocation getIdentLocation() const { return getLocation(); }
-
- static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceLocation NamespaceLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Nominated,
- DeclContext *CommonAncestor);
- static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(UsingLoc, getLocation());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == UsingDirective; }
-
- // Friend for getUsingDirectiveName.
- friend class DeclContext;
-
- friend class ASTDeclReader;
-};
-
-/// \brief Represents a C++ namespace alias.
-///
-/// For example:
-///
-/// \code
-/// namespace Foo = Bar;
-/// \endcode
-class NamespaceAliasDecl : public NamedDecl,
- public Redeclarable<NamespaceAliasDecl> {
- void anchor() override;
-
- /// \brief The location of the \c namespace keyword.
- SourceLocation NamespaceLoc;
-
- /// \brief The location of the namespace's identifier.
- ///
- /// This is accessed by TargetNameLoc.
- SourceLocation IdentLoc;
-
- /// \brief The nested-name-specifier that precedes the namespace.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The Decl that this alias points to, either a NamespaceDecl or
- /// a NamespaceAliasDecl.
- NamedDecl *Namespace;
-
- NamespaceAliasDecl(ASTContext &C, DeclContext *DC,
- SourceLocation NamespaceLoc, SourceLocation AliasLoc,
- IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), redeclarable_base(C),
- NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
- QualifierLoc(QualifierLoc), Namespace(Namespace) {}
-
- typedef Redeclarable<NamespaceAliasDecl> redeclarable_base;
- NamespaceAliasDecl *getNextRedeclarationImpl() override;
- NamespaceAliasDecl *getPreviousDeclImpl() override;
- NamespaceAliasDecl *getMostRecentDeclImpl() override;
-
- friend class ASTDeclReader;
-
-public:
- static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Namespace);
-
- static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
-
- NamespaceAliasDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const NamespaceAliasDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- /// \brief 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
- /// name of the namespace.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Retrieve the namespace declaration aliased by this directive.
- NamespaceDecl *getNamespace() {
- if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
- return AD->getNamespace();
-
- return cast<NamespaceDecl>(Namespace);
- }
-
- const NamespaceDecl *getNamespace() const {
- return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
- }
-
- /// Returns the location of the alias name, i.e. 'foo' in
- /// "namespace foo = ns::bar;".
- SourceLocation getAliasLoc() const { return getLocation(); }
-
- /// Returns the location of the \c namespace keyword.
- SourceLocation getNamespaceLoc() const { return NamespaceLoc; }
-
- /// 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
- /// may either be a NamespaceDecl or a NamespaceAliasDecl.
- NamedDecl *getAliasedNamespace() const { return Namespace; }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(NamespaceLoc, IdentLoc);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == NamespaceAlias; }
-};
-
-/// \brief Represents a shadow declaration introduced into a scope by a
-/// (resolved) using declaration.
-///
-/// For example,
-/// \code
-/// namespace A {
-/// void foo();
-/// }
-/// namespace B {
-/// using A::foo; // <- a UsingDecl
-/// // Also creates a UsingShadowDecl for A::foo() in B
-/// }
-/// \endcode
-class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
- void anchor() override;
-
- /// The referenced declaration.
- NamedDecl *Underlying;
-
- /// \brief The using declaration which introduced this decl or the next using
- /// shadow declaration contained in the aforementioned using declaration.
- NamedDecl *UsingOrNextShadow;
- friend class UsingDecl;
-
- UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
- UsingDecl *Using, NamedDecl *Target)
- : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
- redeclarable_base(C), Underlying(Target),
- UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
- if (Target) {
- setDeclName(Target->getDeclName());
- IdentifierNamespace = Target->getIdentifierNamespace();
- }
- setImplicit();
- }
-
- typedef Redeclarable<UsingShadowDecl> redeclarable_base;
- UsingShadowDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- UsingShadowDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- UsingShadowDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation Loc, UsingDecl *Using,
- NamedDecl *Target) {
- return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
- }
-
- static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
-
- UsingShadowDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const UsingShadowDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- /// \brief 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
- /// local scope.
- void setTargetDecl(NamedDecl* ND) {
- assert(ND && "Target decl is null!");
- Underlying = ND;
- IdentifierNamespace = ND->getIdentifierNamespace();
- }
-
- /// \brief Gets the using declaration to which this declaration is tied.
- UsingDecl *getUsingDecl() const;
-
- /// \brief 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);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a C++ using-declaration.
-///
-/// For example:
-/// \code
-/// using someNameSpace::someIdentifier;
-/// \endcode
-class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> {
- void anchor() override;
-
- /// \brief The source location of the 'using' keyword itself.
- SourceLocation UsingLocation;
-
- /// \brief The nested-name-specifier that precedes the name.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief 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
- /// with this using declaration.
- ///
- /// The bool member of the pair store whether this decl has the \c typename
- /// keyword.
- llvm::PointerIntPair<UsingShadowDecl *, 1, bool> FirstUsingShadow;
-
- UsingDecl(DeclContext *DC, SourceLocation UL,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
- : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
- UsingLocation(UL), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) {
- }
-
-public:
- /// \brief Return the source location of the 'using' keyword.
- SourceLocation getUsingLoc() const { return UsingLocation; }
-
- /// \brief Set the source location of the 'using' keyword.
- void setUsingLoc(SourceLocation L) { UsingLocation = L; }
-
- /// \brief 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.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
- }
-
- /// \brief 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'.
- bool hasTypename() const { return FirstUsingShadow.getInt(); }
-
- /// \brief Sets whether the using declaration has 'typename'.
- void setTypename(bool TN) { FirstUsingShadow.setInt(TN); }
-
- /// \brief Iterates through the using shadow declarations associated with
- /// this using declaration.
- class shadow_iterator {
- /// \brief The current using shadow declaration.
- UsingShadowDecl *Current;
-
- public:
- typedef UsingShadowDecl* value_type;
- typedef UsingShadowDecl* reference;
- typedef UsingShadowDecl* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- shadow_iterator() : Current(nullptr) { }
- explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
-
- reference operator*() const { return Current; }
- pointer operator->() const { return Current; }
-
- shadow_iterator& operator++() {
- Current = Current->getNextUsingShadowDecl();
- return *this;
- }
-
- shadow_iterator operator++(int) {
- shadow_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(shadow_iterator x, shadow_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(shadow_iterator x, shadow_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<shadow_iterator> shadow_range;
-
- shadow_range shadows() const {
- return shadow_range(shadow_begin(), shadow_end());
- }
- shadow_iterator shadow_begin() const {
- return shadow_iterator(FirstUsingShadow.getPointer());
- }
- shadow_iterator shadow_end() const { return shadow_iterator(); }
-
- /// \brief Return the number of shadowed declarations associated with this
- /// using declaration.
- unsigned shadow_size() const {
- return std::distance(shadow_begin(), shadow_end());
- }
-
- void addShadowDecl(UsingShadowDecl *S);
- void removeShadowDecl(UsingShadowDecl *S);
-
- static UsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingL,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo,
- bool HasTypenameKeyword);
-
- static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Retrieves the canonical declaration of this declaration.
- UsingDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const UsingDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Using; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a dependent using declaration which was not marked with
-/// \c typename.
-///
-/// Unlike non-dependent using declarations, these *only* bring through
-/// non-types; otherwise they would break two-phase lookup.
-///
-/// \code
-/// template \<class T> class A : public Base<T> {
-/// using Base<T>::foo;
-/// };
-/// \endcode
-class UnresolvedUsingValueDecl : public ValueDecl,
- public Mergeable<UnresolvedUsingValueDecl> {
- void anchor() override;
-
- /// \brief The source location of the 'using' keyword
- SourceLocation UsingLocation;
-
- /// \brief The nested-name-specifier that precedes the name.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief Provides source/type location info for the declaration name
- /// embedded in the ValueDecl base class.
- DeclarationNameLoc DNLoc;
-
- UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
- SourceLocation UsingLoc,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo)
- : ValueDecl(UnresolvedUsingValue, DC,
- NameInfo.getLoc(), NameInfo.getName(), Ty),
- UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo())
- { }
-
-public:
- /// \brief Returns the source location of the 'using' keyword.
- SourceLocation getUsingLoc() const { return UsingLocation; }
-
- /// \brief 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').
- bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
-
- /// \brief 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.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
- }
-
- static UnresolvedUsingValueDecl *
- Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo);
-
- static UnresolvedUsingValueDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Retrieves the canonical declaration of this declaration.
- UnresolvedUsingValueDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const UnresolvedUsingValueDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a dependent using declaration which was marked with
-/// \c typename.
-///
-/// \code
-/// template \<class T> class A : public Base<T> {
-/// using typename Base<T>::foo;
-/// };
-/// \endcode
-///
-/// The type associated with an unresolved using typename decl is
-/// currently always a typename type.
-class UnresolvedUsingTypenameDecl
- : public TypeDecl,
- public Mergeable<UnresolvedUsingTypenameDecl> {
- void anchor() override;
-
- /// \brief The source location of the 'typename' keyword
- SourceLocation TypenameLocation;
-
- /// \brief The nested-name-specifier that precedes the name.
- NestedNameSpecifierLoc QualifierLoc;
-
- UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
- SourceLocation TypenameLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TargetNameLoc,
- IdentifierInfo *TargetName)
- : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
- UsingLoc),
- TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
-
- friend class ASTDeclReader;
-
-public:
- /// \brief Returns the source location of the 'using' keyword.
- SourceLocation getUsingLoc() const { return getLocStart(); }
-
- /// \brief Returns the source location of the 'typename' keyword.
- SourceLocation getTypenameLoc() const { return TypenameLocation; }
-
- /// \brief 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.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- static UnresolvedUsingTypenameDecl *
- Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
- SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TargetNameLoc, DeclarationName TargetName);
-
- static UnresolvedUsingTypenameDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// Retrieves the canonical declaration of this declaration.
- UnresolvedUsingTypenameDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const UnresolvedUsingTypenameDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
-};
-
-/// \brief Represents a C++11 static_assert declaration.
-class StaticAssertDecl : public Decl {
- virtual void anchor();
- llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed;
- StringLiteral *Message;
- SourceLocation RParenLoc;
-
- StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
- Expr *AssertExpr, StringLiteral *Message,
- SourceLocation RParenLoc, bool Failed)
- : Decl(StaticAssert, DC, StaticAssertLoc),
- AssertExprAndFailed(AssertExpr, Failed), Message(Message),
- RParenLoc(RParenLoc) { }
-
-public:
- static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StaticAssertLoc,
- Expr *AssertExpr, StringLiteral *Message,
- SourceLocation RParenLoc, bool Failed);
- static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); }
- const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); }
-
- StringLiteral *getMessage() { return Message; }
- const StringLiteral *getMessage() const { return Message; }
-
- bool isFailed() const { return AssertExprAndFailed.getInt(); }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getLocation(), getRParenLoc());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == StaticAssert; }
-
- friend class ASTDeclReader;
-};
-
-/// An instance of this class represents the declaration of a property
-/// member. This is a Microsoft extension to C++, first introduced in
-/// Visual Studio .NET 2003 as a parallel to similar features in C#
-/// and Managed C++.
-///
-/// A property must always be a non-static class member.
-///
-/// A property member superficially resembles a non-static data
-/// member, except preceded by a property attribute:
-/// __declspec(property(get=GetX, put=PutX)) int x;
-/// Either (but not both) of the 'get' and 'put' names may be omitted.
-///
-/// A reference to a property is always an lvalue. If the lvalue
-/// undergoes lvalue-to-rvalue conversion, then a getter name is
-/// required, and that member is called with no arguments.
-/// If the lvalue is assigned into, then a setter name is required,
-/// and that member is called with one argument, the value assigned.
-/// Both operations are potentially overloaded. Compound assignments
-/// are permitted, as are the increment and decrement operators.
-///
-/// The getter and putter methods are permitted to be overloaded,
-/// although their return and parameter types are subject to certain
-/// restrictions according to the type of the property.
-///
-/// A property declared using an incomplete array type may
-/// additionally be subscripted, adding extra parameters to the getter
-/// and putter methods.
-class MSPropertyDecl : public DeclaratorDecl {
- IdentifierInfo *GetterId, *SetterId;
-
- MSPropertyDecl(DeclContext *DC, SourceLocation L, DeclarationName N,
- QualType T, TypeSourceInfo *TInfo, SourceLocation StartL,
- IdentifierInfo *Getter, IdentifierInfo *Setter)
- : DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
- GetterId(Getter), SetterId(Setter) {}
-
-public:
- static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, DeclarationName N, QualType T,
- TypeSourceInfo *TInfo, SourceLocation StartL,
- IdentifierInfo *Getter, IdentifierInfo *Setter);
- static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
-
- bool hasGetter() const { return GetterId != nullptr; }
- IdentifierInfo* getGetterId() const { return GetterId; }
- bool hasSetter() const { return SetterId != nullptr; }
- IdentifierInfo* getSetterId() const { return SetterId; }
-
- friend class ASTDeclReader;
-};
-
-/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
-/// into a diagnostic with <<.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- AccessSpecifier AS);
-
-const PartialDiagnostic &operator<<(const PartialDiagnostic &DB,
- AccessSpecifier AS);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
deleted file mode 100644
index ff37758..0000000
--- a/include/clang/AST/DeclContextInternals.h
+++ /dev/null
@@ -1,264 +0,0 @@
-//===-- DeclContextInternals.h - DeclContext Representation -----*- 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 data structures used in the implementation
-// of DeclContext.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
-#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclarationName.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SmallVector.h"
-#include <algorithm>
-
-namespace clang {
-
-class DependentDiagnostic;
-
-/// \brief 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.
- typedef SmallVector<NamedDecl *, 4> DeclsTy;
-
- /// \brief A collection of declarations, with a flag to indicate if we have
- /// further external declarations.
- typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy;
-
- /// \brief 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;
-
-public:
- StoredDeclsList() {}
-
- StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
- RHS.Data = (NamedDecl *)nullptr;
- }
-
- ~StoredDeclsList() {
- // If this is a vector-form, free the vector.
- if (DeclsTy *Vector = getAsVector())
- delete Vector;
- }
-
- StoredDeclsList &operator=(StoredDeclsList &&RHS) {
- if (DeclsTy *Vector = getAsVector())
- delete Vector;
- Data = RHS.Data;
- RHS.Data = (NamedDecl *)nullptr;
- return *this;
- }
-
- bool isNull() const { return Data.isNull(); }
-
- NamedDecl *getAsDecl() const {
- return Data.dyn_cast<NamedDecl *>();
- }
-
- DeclsAndHasExternalTy getAsVectorAndHasExternal() const {
- return Data.dyn_cast<DeclsAndHasExternalTy>();
- }
-
- DeclsTy *getAsVector() const {
- return getAsVectorAndHasExternal().getPointer();
- }
-
- bool hasExternalDecls() const {
- return getAsVectorAndHasExternal().getInt();
- }
-
- void setHasExternalDecls() {
- if (DeclsTy *Vec = getAsVector())
- Data = DeclsAndHasExternalTy(Vec, true);
- else {
- DeclsTy *VT = new DeclsTy();
- if (NamedDecl *OldD = getAsDecl())
- VT->push_back(OldD);
- Data = DeclsAndHasExternalTy(VT, true);
- }
- }
-
- void setOnlyValue(NamedDecl *ND) {
- assert(!getAsVector() && "Not inline");
- Data = ND;
- // Make sure that Data is a plain NamedDecl* so we can use its address
- // at getLookupResult.
- assert(*(NamedDecl **)&Data == ND &&
- "PointerUnion mangles the NamedDecl pointer!");
- }
-
- void remove(NamedDecl *D) {
- assert(!isNull() && "removing from empty list");
- if (NamedDecl *Singleton = getAsDecl()) {
- assert(Singleton == D && "list is different singleton");
- (void)Singleton;
- Data = (NamedDecl *)nullptr;
- return;
- }
-
- DeclsTy &Vec = *getAsVector();
- DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
- assert(I != Vec.end() && "list does not contain decl");
- Vec.erase(I);
-
- assert(std::find(Vec.begin(), Vec.end(), D)
- == Vec.end() && "list still contains decl");
- }
-
- /// \brief Remove any declarations which were imported from an external
- /// AST source.
- void removeExternalDecls() {
- if (isNull()) {
- // Nothing to do.
- } else if (NamedDecl *Singleton = getAsDecl()) {
- if (Singleton->isFromASTFile())
- *this = StoredDeclsList();
- } else {
- DeclsTy &Vec = *getAsVector();
- Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
- std::mem_fun(&Decl::isFromASTFile)),
- Vec.end());
- // Don't have any external decls any more.
- Data = DeclsAndHasExternalTy(&Vec, false);
- }
- }
-
- /// getLookupResult - Return an array of all the decls that this list
- /// represents.
- DeclContext::lookup_result getLookupResult() {
- if (isNull())
- return DeclContext::lookup_result();
-
- // If we have a single NamedDecl, return it.
- if (NamedDecl *ND = getAsDecl()) {
- assert(!isNull() && "Empty list isn't allowed");
-
- // Data is a raw pointer to a NamedDecl*, return it.
- return DeclContext::lookup_result(ND);
- }
-
- assert(getAsVector() && "Must have a vector at this point");
- DeclsTy &Vector = *getAsVector();
-
- // Otherwise, we have a range result.
- return DeclContext::lookup_result(Vector);
- }
-
- /// HandleRedeclaration - If this is a redeclaration of an existing decl,
- /// replace the old one with D and return true. Otherwise return false.
- bool HandleRedeclaration(NamedDecl *D, bool IsKnownNewer) {
- // Most decls only have one entry in their list, special case it.
- if (NamedDecl *OldD = getAsDecl()) {
- if (!D->declarationReplaces(OldD, IsKnownNewer))
- return false;
- setOnlyValue(D);
- return true;
- }
-
- // Determine if this declaration is actually a redeclaration.
- DeclsTy &Vec = *getAsVector();
- for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
- OD != ODEnd; ++OD) {
- NamedDecl *OldD = *OD;
- if (D->declarationReplaces(OldD, IsKnownNewer)) {
- *OD = D;
- return true;
- }
- }
-
- return false;
- }
-
- /// AddSubsequentDecl - This is called on the second and later decl when it is
- /// not a redeclaration to merge it into the appropriate place in our list.
- ///
- void AddSubsequentDecl(NamedDecl *D) {
- assert(!isNull() && "don't AddSubsequentDecl when we have no decls");
-
- // If this is the second decl added to the list, convert this to vector
- // form.
- if (NamedDecl *OldD = getAsDecl()) {
- DeclsTy *VT = new DeclsTy();
- VT->push_back(OldD);
- Data = DeclsAndHasExternalTy(VT, false);
- }
-
- DeclsTy &Vec = *getAsVector();
-
- // Using directives end up in a special entry which contains only
- // other using directives, so all this logic is wasted for them.
- // But avoiding the logic wastes time in the far-more-common case
- // that we're *not* adding a new using directive.
-
- // Tag declarations always go at the end of the list so that an
- // iterator which points at the first tag will start a span of
- // decls that only contains tags.
- if (D->hasTagIdentifierNamespace())
- Vec.push_back(D);
-
- // Resolved using declarations go at the front of the list so that
- // they won't show up in other lookup results. Unresolved using
- // declarations (which are always in IDNS_Using | IDNS_Ordinary)
- // follow that so that the using declarations will be contiguous.
- else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
- DeclsTy::iterator I = Vec.begin();
- if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
- while (I != Vec.end() &&
- (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
- ++I;
- }
- Vec.insert(I, D);
-
- // All other declarations go at the end of the list, but before any
- // tag declarations. But we can be clever about tag declarations
- // because there can only ever be one in a scope.
- } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) {
- NamedDecl *TagD = Vec.back();
- Vec.back() = D;
- Vec.push_back(TagD);
- } else
- Vec.push_back(D);
- }
-};
-
-class StoredDeclsMap
- : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
-
-public:
- static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
-
-private:
- friend class ASTContext; // walks the chain deleting these
- friend class DeclContext;
- llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
-};
-
-class DependentStoredDeclsMap : public StoredDeclsMap {
-public:
- DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
-
-private:
- friend class DependentDiagnostic;
- friend class DeclContext; // iterates over diagnostics
-
- DependentDiagnostic *FirstDiagnostic;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
deleted file mode 100644
index 27b0388..0000000
--- a/include/clang/AST/DeclFriend.h
+++ /dev/null
@@ -1,243 +0,0 @@
-//===-- DeclFriend.h - Classes for C++ friend declarations -*- 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 section of the AST representing C++ friend
-// declarations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLFRIEND_H
-#define LLVM_CLANG_AST_DECLFRIEND_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/TypeLoc.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-/// FriendDecl - Represents the declaration of a friend entity,
-/// which can be a function, a type, or a templated function or type.
-// For example:
-///
-/// @code
-/// template <typename T> class A {
-/// friend int foo(T);
-/// friend class B;
-/// friend T; // only in C++0x
-/// template <typename U> friend class C;
-/// template <typename U> friend A& operator+=(A&, const U&) { ... }
-/// };
-/// @endcode
-///
-/// The semantic context of a friend decl is its declaring class.
-class FriendDecl final
- : public Decl,
- private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> {
- virtual void anchor();
-public:
- typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
-
-private:
- // The declaration that's a friend of this class.
- FriendUnion Friend;
-
- // A pointer to the next friend in the sequence.
- LazyDeclPtr NextFriend;
-
- // Location of the 'friend' specifier.
- SourceLocation FriendLoc;
-
- /// True if this 'friend' declaration is unsupported. Eventually we
- /// will support every possible friend declaration, but for now we
- /// silently ignore some and set this flag to authorize all access.
- bool UnsupportedFriend : 1;
-
- // The number of "outer" template parameter lists in non-templatic
- // (currently unsupported) friend type declarations, such as
- // template <class T> friend class A<T>::B;
- unsigned NumTPLists : 31;
-
- friend class CXXRecordDecl::friend_iterator;
- friend class CXXRecordDecl;
-
- FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
- SourceLocation FriendL,
- ArrayRef<TemplateParameterList*> FriendTypeTPLists)
- : Decl(Decl::Friend, DC, L),
- Friend(Friend),
- NextFriend(),
- FriendLoc(FriendL),
- UnsupportedFriend(false),
- NumTPLists(FriendTypeTPLists.size()) {
- for (unsigned i = 0; i < NumTPLists; ++i)
- getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
- }
-
- FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
- : Decl(Decl::Friend, Empty), NextFriend(),
- NumTPLists(NumFriendTypeTPLists) { }
-
- FriendDecl *getNextFriend() {
- if (!NextFriend.isOffset())
- return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
- return getNextFriendSlowCase();
- }
- FriendDecl *getNextFriendSlowCase();
-
-public:
- static FriendDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, FriendUnion Friend_,
- SourceLocation FriendL,
- ArrayRef<TemplateParameterList*> FriendTypeTPLists
- = None);
- static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
- unsigned FriendTypeNumTPLists);
-
- /// If this friend declaration names an (untemplated but possibly
- /// dependent) type, return the type; otherwise return null. This
- /// is used for elaborated-type-specifiers and, in C++0x, for
- /// arbitrary friend type declarations.
- TypeSourceInfo *getFriendType() const {
- return Friend.dyn_cast<TypeSourceInfo*>();
- }
- unsigned getFriendTypeNumTemplateParameterLists() const {
- return NumTPLists;
- }
- TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
- assert(N < NumTPLists);
- return getTrailingObjects<TemplateParameterList *>()[N];
- }
-
- /// If this friend declaration doesn't name a type, return the inner
- /// declaration.
- NamedDecl *getFriendDecl() const {
- return Friend.dyn_cast<NamedDecl*>();
- }
-
- /// Retrieves the location of the 'friend' keyword.
- SourceLocation getFriendLoc() const {
- return FriendLoc;
- }
-
- /// 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))
- return FD->getSourceRange();
- if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
- return FTD->getSourceRange();
- if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
- return CTD->getSourceRange();
- if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
- if (DD->getOuterLocStart() != DD->getInnerLocStart())
- return DD->getSourceRange();
- }
- return SourceRange(getFriendLoc(), ND->getLocEnd());
- }
- else if (TypeSourceInfo *TInfo = getFriendType()) {
- SourceLocation StartL =
- (NumTPLists == 0) ? getFriendLoc()
- : getTrailingObjects<TemplateParameterList *>()[0]
- ->getTemplateLoc();
- return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc());
- }
- else
- return SourceRange(getFriendLoc(), getLocation());
- }
-
- /// Determines if this friend kind is unsupported.
- bool isUnsupportedFriend() const {
- return UnsupportedFriend;
- }
- void setUnsupportedFriend(bool Unsupported) {
- UnsupportedFriend = Unsupported;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Decl::Friend; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
-};
-
-/// An iterator over the friend declarations of a class.
-class CXXRecordDecl::friend_iterator {
- FriendDecl *Ptr;
-
- friend class CXXRecordDecl;
- explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
-public:
- friend_iterator() {}
-
- typedef FriendDecl *value_type;
- typedef FriendDecl *reference;
- typedef FriendDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- reference operator*() const { return Ptr; }
-
- friend_iterator &operator++() {
- assert(Ptr && "attempt to increment past end of friend list");
- Ptr = Ptr->getNextFriend();
- return *this;
- }
-
- friend_iterator operator++(int) {
- friend_iterator tmp = *this;
- ++*this;
- return tmp;
- }
-
- bool operator==(const friend_iterator &Other) const {
- return Ptr == Other.Ptr;
- }
-
- bool operator!=(const friend_iterator &Other) const {
- return Ptr != Other.Ptr;
- }
-
- friend_iterator &operator+=(difference_type N) {
- assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator");
- while (N--)
- ++*this;
- return *this;
- }
-
- friend_iterator operator+(difference_type N) const {
- friend_iterator tmp = *this;
- tmp += N;
- return tmp;
- }
-};
-
-inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const {
- return friend_iterator(getFirstFriend());
-}
-
-inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
- return friend_iterator(nullptr);
-}
-
-inline CXXRecordDecl::friend_range CXXRecordDecl::friends() const {
- return friend_range(friend_begin(), friend_end());
-}
-
-inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
- assert(!FD->NextFriend && "friend already has next friend?");
- FD->NextFriend = data().FirstFriend;
- data().FirstFriend = FD;
-}
-
-}
-
-#endif
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
deleted file mode 100644
index c84bb5e..0000000
--- a/include/clang/AST/DeclGroup.h
+++ /dev/null
@@ -1,154 +0,0 @@
-//===--- DeclGroup.h - Classes for representing groups of Decls -*- 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 DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLGROUP_H
-#define LLVM_CLANG_AST_DECLGROUP_H
-
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/TrailingObjects.h"
-#include <cassert>
-
-namespace clang {
-
-class ASTContext;
-class Decl;
-class DeclGroup;
-class DeclGroupIterator;
-
-class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> {
- // FIXME: Include a TypeSpecifier object.
- unsigned NumDecls;
-
-private:
- DeclGroup() : NumDecls(0) {}
- DeclGroup(unsigned numdecls, Decl** decls);
-
-public:
- static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
-
- unsigned size() const { return NumDecls; }
-
- Decl*& operator[](unsigned i) {
- assert (i < NumDecls && "Out-of-bounds access.");
- return getTrailingObjects<Decl *>()[i];
- }
-
- Decl* const& operator[](unsigned i) const {
- assert (i < NumDecls && "Out-of-bounds access.");
- return getTrailingObjects<Decl *>()[i];
- }
-
- friend TrailingObjects;
-};
-
-class DeclGroupRef {
- // Note this is not a PointerIntPair because we need the address of the
- // non-group case to be valid as a Decl** for iteration.
- enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
- Decl* D;
-
- Kind getKind() const {
- return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
- }
-
-public:
- DeclGroupRef() : D(nullptr) {}
-
- explicit DeclGroupRef(Decl* d) : D(d) {}
- explicit DeclGroupRef(DeclGroup* dg)
- : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
-
- static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
- if (NumDecls == 0)
- return DeclGroupRef();
- if (NumDecls == 1)
- return DeclGroupRef(Decls[0]);
- return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
- }
-
- typedef Decl** iterator;
- typedef Decl* const * const_iterator;
-
- bool isNull() const { return D == nullptr; }
- bool isSingleDecl() const { return getKind() == SingleDeclKind; }
- bool isDeclGroup() const { return getKind() == DeclGroupKind; }
-
- Decl *getSingleDecl() {
- assert(isSingleDecl() && "Isn't a declgroup");
- return D;
- }
- const Decl *getSingleDecl() const {
- return const_cast<DeclGroupRef*>(this)->getSingleDecl();
- }
-
- DeclGroup &getDeclGroup() {
- assert(isDeclGroup() && "Isn't a declgroup");
- return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask));
- }
- const DeclGroup &getDeclGroup() const {
- return const_cast<DeclGroupRef*>(this)->getDeclGroup();
- }
-
- iterator begin() {
- if (isSingleDecl())
- return D ? &D : nullptr;
- return &getDeclGroup()[0];
- }
-
- iterator end() {
- if (isSingleDecl())
- return D ? &D+1 : nullptr;
- DeclGroup &G = getDeclGroup();
- return &G[0] + G.size();
- }
-
- const_iterator begin() const {
- if (isSingleDecl())
- return D ? &D : nullptr;
- return &getDeclGroup()[0];
- }
-
- const_iterator end() const {
- if (isSingleDecl())
- return D ? &D+1 : nullptr;
- const DeclGroup &G = getDeclGroup();
- return &G[0] + G.size();
- }
-
- void *getAsOpaquePtr() const { return D; }
- static DeclGroupRef getFromOpaquePtr(void *Ptr) {
- DeclGroupRef X;
- X.D = static_cast<Decl*>(Ptr);
- return X;
- }
-};
-
-} // end clang namespace
-
-namespace llvm {
- // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
- template <typename T>
- class PointerLikeTypeTraits;
- template <>
- class PointerLikeTypeTraits<clang::DeclGroupRef> {
- public:
- static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
- return P.getAsOpaquePtr();
- }
- static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
- return clang::DeclGroupRef::getFromOpaquePtr(P);
- }
- enum { NumLowBitsAvailable = 0 };
- };
-}
-#endif
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
deleted file mode 100644
index eba2266..0000000
--- a/include/clang/AST/DeclLookups.h
+++ /dev/null
@@ -1,115 +0,0 @@
-//===-- DeclLookups.h - Low-level interface to all names in a DC-*- 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 DeclContext::all_lookups_iterator.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H
-#define LLVM_CLANG_AST_DECLLOOKUPS_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclContextInternals.h"
-#include "clang/AST/DeclarationName.h"
-
-namespace clang {
-
-/// all_lookups_iterator - An iterator that provides a view over the results
-/// of looking up every possible name.
-class DeclContext::all_lookups_iterator {
- StoredDeclsMap::iterator It, End;
-public:
- typedef lookup_result value_type;
- typedef lookup_result reference;
- typedef lookup_result pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- all_lookups_iterator() {}
- all_lookups_iterator(StoredDeclsMap::iterator It,
- StoredDeclsMap::iterator End)
- : It(It), End(End) {}
-
- DeclarationName getLookupName() const { return It->first; }
-
- reference operator*() const { return It->second.getLookupResult(); }
- pointer operator->() const { return It->second.getLookupResult(); }
-
- all_lookups_iterator& operator++() {
- // Filter out using directives. They don't belong as results from name
- // lookup anyways, except as an implementation detail. Users of the API
- // should not expect to get them (or worse, rely on it).
- do {
- ++It;
- } while (It != End &&
- It->first == DeclarationName::getUsingDirectiveName());
-
- return *this;
- }
-
- all_lookups_iterator operator++(int) {
- all_lookups_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
- return x.It == y.It;
- }
- friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
- return x.It != y.It;
- }
-};
-
-inline DeclContext::lookups_range DeclContext::lookups() const {
- DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (Primary->hasExternalVisibleStorage())
- getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
- if (StoredDeclsMap *Map = Primary->buildLookup())
- return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
- all_lookups_iterator(Map->end(), Map->end()));
-
- // Synthesize an empty range. This requires that two default constructed
- // versions of these iterators form a valid empty range.
- 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 {
- DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (StoredDeclsMap *Map = Primary->getLookupPtr())
- return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
- all_lookups_iterator(Map->end(), Map->end()));
-
- // Synthesize an empty range. This requires that two default constructed
- // versions of these iterators form a valid empty range.
- 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();
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
deleted file mode 100644
index f46078f..0000000
--- a/include/clang/AST/DeclObjC.h
+++ /dev/null
@@ -1,2742 +0,0 @@
-//===--- DeclObjC.h - Classes for representing declarations -----*- 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 DeclObjC interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLOBJC_H
-#define LLVM_CLANG_AST_DECLOBJC_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/SelectorLocationsKind.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-class Expr;
-class Stmt;
-class FunctionDecl;
-class RecordDecl;
-class ObjCIvarDecl;
-class ObjCMethodDecl;
-class ObjCProtocolDecl;
-class ObjCCategoryDecl;
-class ObjCPropertyDecl;
-class ObjCPropertyImplDecl;
-class CXXCtorInitializer;
-
-class ObjCListBase {
- ObjCListBase(const ObjCListBase &) = delete;
- void operator=(const ObjCListBase &) = delete;
-protected:
- /// List is an array of pointers to objects that are not owned by this object.
- void **List;
- unsigned NumElts;
-
-public:
- ObjCListBase() : List(nullptr), NumElts(0) {}
- unsigned size() const { return NumElts; }
- bool empty() const { return NumElts == 0; }
-
-protected:
- void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
-};
-
-
-/// ObjCList - This is a simple template class used to hold various lists of
-/// decls etc, which is heavily used by the ObjC front-end. This only use case
-/// this supports is setting the list all at once and then reading elements out
-/// of it.
-template <typename T>
-class ObjCList : public ObjCListBase {
-public:
- void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
- ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
- }
-
- typedef T* const * iterator;
- iterator begin() const { return (iterator)List; }
- iterator end() const { return (iterator)List+NumElts; }
-
- T* operator[](unsigned Idx) const {
- assert(Idx < NumElts && "Invalid access");
- return (T*)List[Idx];
- }
-};
-
-/// \brief A list of Objective-C protocols, along with the source
-/// locations at which they were referenced.
-class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
- SourceLocation *Locations;
-
- using ObjCList<ObjCProtocolDecl>::set;
-
-public:
- ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
-
- typedef const SourceLocation *loc_iterator;
- loc_iterator loc_begin() const { return Locations; }
- loc_iterator loc_end() const { return Locations + size(); }
-
- void set(ObjCProtocolDecl* const* InList, unsigned Elts,
- const SourceLocation *Locs, ASTContext &Ctx);
-};
-
-
-/// ObjCMethodDecl - Represents an instance or class method declaration.
-/// ObjC methods can be declared within 4 contexts: class interfaces,
-/// categories, protocols, and class implementations. While C++ member
-/// functions leverage C syntax, Objective-C method syntax is modeled after
-/// Smalltalk (using colons to specify argument types/expressions).
-/// Here are some brief examples:
-///
-/// Setter/getter instance methods:
-/// - (void)setMenu:(NSMenu *)menu;
-/// - (NSMenu *)menu;
-///
-/// Instance method that takes 2 NSView arguments:
-/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
-///
-/// Getter class method:
-/// + (NSMenu *)defaultMenu;
-///
-/// A selector represents a unique name for a method. The selector names for
-/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
-///
-class ObjCMethodDecl : public NamedDecl, public DeclContext {
-public:
- enum ImplementationControl { None, Required, Optional };
-private:
- // The conventional meaning of this method; an ObjCMethodFamily.
- // This is not serialized; instead, it is computed on demand and
- // cached.
- mutable unsigned Family : ObjCMethodFamilyBitWidth;
-
- /// instance (true) or class (false) method.
- unsigned IsInstance : 1;
- unsigned IsVariadic : 1;
-
- /// True if this method is the getter or setter for an explicit property.
- unsigned IsPropertyAccessor : 1;
-
- // Method has a definition.
- unsigned IsDefined : 1;
-
- /// \brief Method redeclaration in the same interface.
- unsigned IsRedeclaration : 1;
-
- /// \brief Is redeclared in the same interface.
- mutable unsigned HasRedeclaration : 1;
-
- // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
- /// \@required/\@optional
- unsigned DeclImplementation : 2;
-
- // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
- /// in, inout, etc.
- unsigned objcDeclQualifier : 7;
-
- /// \brief Indicates whether this method has a related result type.
- unsigned RelatedResultType : 1;
-
- /// \brief 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.
- ///
- /// A method is said to override any method in the class's
- /// base classes, its protocols, or its categories' protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- unsigned IsOverriding : 1;
-
- /// \brief Indicates if the method was a definition but its body was skipped.
- unsigned HasSkippedBody : 1;
-
- // Return type of this method.
- QualType MethodDeclType;
-
- // Type source information for the return type.
- TypeSourceInfo *ReturnTInfo;
-
- /// \brief Array of ParmVarDecls for the formal parameters of this method
- /// and optionally followed by selector locations.
- void *ParamsAndSelLocs;
- unsigned NumParams;
-
- /// List of attributes for this method declaration.
- SourceLocation DeclEndLoc; // the location of the ';' or '{'.
-
- // The following are only used for method definitions, null otherwise.
- LazyDeclStmtPtr Body;
-
- /// SelfDecl - Decl for the implicit self parameter. This is lazily
- /// constructed by createImplicitParams.
- ImplicitParamDecl *SelfDecl;
- /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
- /// constructed by createImplicitParams.
- ImplicitParamDecl *CmdDecl;
-
- SelectorLocationsKind getSelLocsKind() const {
- return (SelectorLocationsKind)SelLocsKind;
- }
- bool hasStandardSelLocs() const {
- return getSelLocsKind() != SelLoc_NonStandard;
- }
-
- /// \brief 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);
- }
- const SourceLocation *getStoredSelLocs() const {
- return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
- }
-
- /// \brief 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);
- }
- const ParmVarDecl *const *getParams() const {
- return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
- }
-
- /// \brief Get the number of stored selector identifiers locations.
- /// No locations will be stored if HasStandardSelLocs is true.
- unsigned getNumStoredSelLocs() const {
- if (hasStandardSelLocs())
- return 0;
- return getNumSelectorLocs();
- }
-
- void setParamsAndSelLocs(ASTContext &C,
- ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs);
-
- ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- bool isVariadic = false, bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false)
- : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
- DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
- IsInstance(isInstance), IsVariadic(isVariadic),
- IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
- IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
- objcDeclQualifier(OBJC_TQ_None),
- RelatedResultType(HasRelatedResultType),
- SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
- MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr),
- NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
- CmdDecl(nullptr) {
- setImplicit(isImplicitlyDeclared);
- }
-
- /// \brief A definition will return its interface declaration.
- /// An interface declaration will return its definition.
- /// Otherwise it will return itself.
- ObjCMethodDecl *getNextRedeclarationImpl() override;
-
-public:
- static ObjCMethodDecl *
- Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- bool isVariadic = false, bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false);
-
- static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ObjCMethodDecl *getCanonicalDecl() override;
- const ObjCMethodDecl *getCanonicalDecl() const {
- return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
- }
-
- ObjCDeclQualifier getObjCDeclQualifier() const {
- return ObjCDeclQualifier(objcDeclQualifier);
- }
- void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
-
- /// \brief 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.
- void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
-
- /// \brief 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
- /// the location of ';' for a method declaration and the location of '{'
- /// for a method definition.
- SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
-
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY;
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getLocation(), getLocEnd());
- }
-
- SourceLocation getSelectorStartLoc() const {
- if (isImplicit())
- return getLocStart();
- return getSelectorLoc(0);
- }
- SourceLocation getSelectorLoc(unsigned Index) const {
- assert(Index < getNumSelectorLocs() && "Index out of range!");
- if (hasStandardSelLocs())
- return getStandardSelectorLoc(Index, getSelector(),
- getSelLocsKind() == SelLoc_StandardWithSpace,
- parameters(),
- DeclEndLoc);
- return getStoredSelLocs()[Index];
- }
-
- void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
-
- unsigned getNumSelectorLocs() const {
- if (isImplicit())
- return 0;
- Selector Sel = getSelector();
- if (Sel.isUnarySelector())
- return 1;
- return Sel.getNumArgs();
- }
-
- ObjCInterfaceDecl *getClassInterface();
- const ObjCInterfaceDecl *getClassInterface() const {
- return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
- }
-
- Selector getSelector() const { return getDeclName().getObjCSelector(); }
-
- QualType getReturnType() const { return MethodDeclType; }
- void setReturnType(QualType T) { MethodDeclType = T; }
- SourceRange getReturnTypeSourceRange() const;
-
- /// \brief 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').
- QualType getSendResultType() const;
-
- /// Determine the type of an expression that sends a message to this
- /// function with the given receiver type.
- QualType getSendResultType(QualType receiverType) const;
-
- TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
- void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return NumParams; }
- typedef const ParmVarDecl *const *param_const_iterator;
- typedef ParmVarDecl *const *param_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
- typedef llvm::iterator_range<param_const_iterator> param_const_range;
-
- param_range params() { return param_range(param_begin(), param_end()); }
- param_const_range params() const {
- return param_const_range(param_begin(), param_end());
- }
-
- param_const_iterator param_begin() const {
- return param_const_iterator(getParams());
- }
- param_const_iterator param_end() const {
- return param_const_iterator(getParams() + NumParams);
- }
- param_iterator param_begin() { return param_iterator(getParams()); }
- param_iterator param_end() { return param_iterator(getParams() + NumParams); }
-
- // This method returns and of the parameters which are part of the selector
- // name mangling requirements.
- param_const_iterator sel_param_end() const {
- return param_begin() + getSelector().getNumArgs();
- }
-
- // ArrayRef access to formal parameters. This should eventually
- // replace the iterator interface above.
- ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
- NumParams);
- }
-
- /// \brief Sets the method's parameters and selector source locations.
- /// If the method is implicit (not coming from source) \p SelLocs is
- /// ignored.
- void setMethodParams(ASTContext &C,
- ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs = llvm::None);
-
- // Iterator access to parameter types.
- typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
- typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
- param_type_iterator;
-
- param_type_iterator param_type_begin() const {
- return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
- }
- param_type_iterator param_type_end() const {
- return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
- }
-
- /// createImplicitParams - Used to lazily create the self and cmd
- /// implict parameters. This must be called prior to using getSelfDecl()
- /// or getCmdDecl(). The call is ignored if the implicit paramters
- /// have already been created.
- void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
-
- /// \return the type for \c self and set \arg selfIsPseudoStrong and
- /// \arg selfIsConsumed accordingly.
- QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID,
- bool &selfIsPseudoStrong, bool &selfIsConsumed);
-
- ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
- void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
- ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
- void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
-
- /// Determines the family of this method.
- ObjCMethodFamily getMethodFamily() const;
-
- bool isInstanceMethod() const { return IsInstance; }
- void setInstanceMethod(bool isInst) { IsInstance = isInst; }
- bool isVariadic() const { return IsVariadic; }
- void setVariadic(bool isVar) { IsVariadic = isVar; }
-
- bool isClassMethod() const { return !IsInstance; }
-
- bool isPropertyAccessor() const { return IsPropertyAccessor; }
- void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
-
- bool isDefined() const { return IsDefined; }
- void setDefined(bool isDefined) { IsDefined = isDefined; }
-
- /// \brief 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
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- bool isOverriding() const { return IsOverriding; }
- void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
-
- /// \brief 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'
- /// protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- void getOverriddenMethods(
- SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
-
- /// \brief 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.
- ///
- /// 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
- /// superclass. Pass \c false if you only want to check the current class.
- const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
-
- // Related to protocols declared in \@protocol
- void setDeclImplementation(ImplementationControl ic) {
- DeclImplementation = ic;
- }
- ImplementationControl getImplementationControl() const {
- return ImplementationControl(DeclImplementation);
- }
-
- /// Returns true if this specific method declaration is marked with the
- /// designated initializer attribute.
- bool isThisDeclarationADesignatedInitializer() const;
-
- /// Returns true if the method selector resolves to a designated initializer
- /// in the class's interface.
- ///
- /// \param InitMethod if non-null and the function returns true, it receives
- /// the method declaration that was marked with the designated initializer
- /// attribute.
- bool isDesignatedInitializerForTheInterface(
- const ObjCMethodDecl **InitMethod = nullptr) const;
-
- /// \brief Determine whether this method has a body.
- bool hasBody() const override { return Body.isValid(); }
-
- /// \brief Retrieve the body of this method, if it has one.
- Stmt *getBody() const override;
-
- void setLazyBody(uint64_t Offset) { Body = Offset; }
-
- CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
- void setBody(Stmt *B) { Body = B; }
-
- /// \brief Returns whether this specific method is a definition.
- bool isThisDeclarationADefinition() const { return hasBody(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCMethod; }
- static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
- return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
- }
- static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Describes the variance of a given generic parameter.
-enum class ObjCTypeParamVariance : uint8_t {
- /// The parameter is invariant: must match exactly.
- Invariant,
- /// The parameter is covariant, e.g., X<T> is a subtype of X<U> when
- /// the type parameter is covariant and T is a subtype of U.
- Covariant,
- /// The parameter is contravariant, e.g., X<T> is a subtype of X<U>
- /// when the type parameter is covariant and U is a subtype of T.
- Contravariant,
-};
-
-/// Represents the declaration of an Objective-C type parameter.
-///
-/// \code
-/// @interface NSDictionary<Key : id<NSCopying>, Value>
-/// @end
-/// \endcode
-///
-/// In the example above, both \c Key and \c Value are represented by
-/// \c ObjCTypeParamDecl. \c Key has an explicit bound of \c id<NSCopying>,
-/// while \c Value gets an implicit bound of \c id.
-///
-/// Objective-C type parameters are typedef-names in the grammar,
-class ObjCTypeParamDecl : public TypedefNameDecl {
- void anchor() override;
-
- /// Index of this type parameter in the type parameter list.
- unsigned Index : 14;
-
- /// The variance of the type parameter.
- unsigned Variance : 2;
-
- /// The location of the variance, if any.
- SourceLocation VarianceLoc;
-
- /// The location of the ':', which will be valid when the bound was
- /// explicitly specified.
- SourceLocation ColonLoc;
-
- ObjCTypeParamDecl(ASTContext &ctx, DeclContext *dc,
- ObjCTypeParamVariance variance, SourceLocation varianceLoc,
- unsigned index,
- SourceLocation nameLoc, IdentifierInfo *name,
- SourceLocation colonLoc, TypeSourceInfo *boundInfo)
- : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name,
- boundInfo),
- Index(index), Variance(static_cast<unsigned>(variance)),
- VarianceLoc(varianceLoc), ColonLoc(colonLoc) { }
-
-public:
- static ObjCTypeParamDecl *Create(ASTContext &ctx, DeclContext *dc,
- ObjCTypeParamVariance variance,
- SourceLocation varianceLoc,
- unsigned index,
- SourceLocation nameLoc,
- IdentifierInfo *name,
- SourceLocation colonLoc,
- TypeSourceInfo *boundInfo);
- static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Determine the variance of this type parameter.
- ObjCTypeParamVariance getVariance() const {
- return static_cast<ObjCTypeParamVariance>(Variance);
- }
-
- /// Set the variance of this type parameter.
- void setVariance(ObjCTypeParamVariance variance) {
- Variance = static_cast<unsigned>(variance);
- }
-
- /// Retrieve the location of the variance keyword.
- SourceLocation getVarianceLoc() const { return VarianceLoc; }
-
- /// Retrieve the index into its type parameter list.
- unsigned getIndex() const { return Index; }
-
- /// Whether this type parameter has an explicitly-written type bound, e.g.,
- /// "T : NSView".
- bool hasExplicitBound() const { return ColonLoc.isValid(); }
-
- /// Retrieve the location of the ':' separating the type parameter name
- /// from the explicitly-specified bound.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCTypeParam; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Stores a list of Objective-C type parameters for a parameterized class
-/// or a category/extension thereof.
-///
-/// \code
-/// @interface NSArray<T> // stores the <T>
-/// @end
-/// \endcode
-class ObjCTypeParamList final
- : private llvm::TrailingObjects<ObjCTypeParamList, ObjCTypeParamDecl *> {
- /// Stores the components of a SourceRange as a POD.
- struct PODSourceRange {
- unsigned Begin;
- unsigned End;
- };
-
- union {
- /// Location of the left and right angle brackets.
- PODSourceRange Brackets;
-
- // Used only for alignment.
- ObjCTypeParamDecl *AlignmentHack;
- };
-
- /// The number of parameters in the list, which are tail-allocated.
- unsigned NumParams;
-
- ObjCTypeParamList(SourceLocation lAngleLoc,
- ArrayRef<ObjCTypeParamDecl *> typeParams,
- SourceLocation rAngleLoc);
-
-public:
- /// Create a new Objective-C type parameter list.
- static ObjCTypeParamList *create(ASTContext &ctx,
- SourceLocation lAngleLoc,
- ArrayRef<ObjCTypeParamDecl *> typeParams,
- SourceLocation rAngleLoc);
-
- /// Iterate through the type parameters in the list.
- typedef ObjCTypeParamDecl **iterator;
-
- iterator begin() { return getTrailingObjects<ObjCTypeParamDecl *>(); }
-
- iterator end() { return begin() + size(); }
-
- /// Determine the number of type parameters in this list.
- unsigned size() const { return NumParams; }
-
- // Iterate through the type parameters in the list.
- typedef ObjCTypeParamDecl * const *const_iterator;
-
- const_iterator begin() const {
- return getTrailingObjects<ObjCTypeParamDecl *>();
- }
-
- const_iterator end() const {
- return begin() + size();
- }
-
- ObjCTypeParamDecl *front() const {
- assert(size() > 0 && "empty Objective-C type parameter list");
- return *begin();
- }
-
- ObjCTypeParamDecl *back() const {
- assert(size() > 0 && "empty Objective-C type parameter list");
- return *(end() - 1);
- }
-
- SourceLocation getLAngleLoc() const {
- return SourceLocation::getFromRawEncoding(Brackets.Begin);
- }
- SourceLocation getRAngleLoc() const {
- return SourceLocation::getFromRawEncoding(Brackets.End);
- }
- SourceRange getSourceRange() const {
- return SourceRange(getLAngleLoc(), getRAngleLoc());
- }
-
- /// Gather the default set of type arguments to be substituted for
- /// these type parameters when dealing with an unspecialized type.
- void gatherDefaultTypeArgs(SmallVectorImpl<QualType> &typeArgs) const;
- friend TrailingObjects;
-};
-
-/// ObjCContainerDecl - Represents a container for method declarations.
-/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
-/// ObjCProtocolDecl, and ObjCImplDecl.
-///
-class ObjCContainerDecl : public NamedDecl, public DeclContext {
- void anchor() override;
-
- SourceLocation AtStart;
-
- // These two locations in the range mark the end of the method container.
- // The first points to the '@' token, and the second to the 'end' token.
- SourceRange AtEnd;
-public:
-
- ObjCContainerDecl(Kind DK, DeclContext *DC,
- IdentifierInfo *Id, SourceLocation nameLoc,
- SourceLocation atStartLoc)
- : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
-
- // Iterator access to properties.
- typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
- prop_range;
-
- prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
- prop_iterator prop_begin() const {
- return prop_iterator(decls_begin());
- }
- prop_iterator prop_end() const {
- return prop_iterator(decls_end());
- }
-
- // Iterator access to instance/class methods.
- typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
- method_range;
-
- method_range methods() const {
- return method_range(meth_begin(), meth_end());
- }
- method_iterator meth_begin() const {
- return method_iterator(decls_begin());
- }
- method_iterator meth_end() const {
- return method_iterator(decls_end());
- }
-
- typedef filtered_decl_iterator<ObjCMethodDecl,
- &ObjCMethodDecl::isInstanceMethod>
- instmeth_iterator;
- typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
-
- instmeth_range instance_methods() const {
- return instmeth_range(instmeth_begin(), instmeth_end());
- }
- instmeth_iterator instmeth_begin() const {
- return instmeth_iterator(decls_begin());
- }
- instmeth_iterator instmeth_end() const {
- return instmeth_iterator(decls_end());
- }
-
- typedef filtered_decl_iterator<ObjCMethodDecl,
- &ObjCMethodDecl::isClassMethod>
- classmeth_iterator;
- typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
-
- classmeth_range class_methods() const {
- return classmeth_range(classmeth_begin(), classmeth_end());
- }
- classmeth_iterator classmeth_begin() const {
- return classmeth_iterator(decls_begin());
- }
- classmeth_iterator classmeth_end() const {
- return classmeth_iterator(decls_end());
- }
-
- // Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getMethod(Selector Sel, bool isInstance,
- bool AllowHidden = false) const;
- ObjCMethodDecl *getInstanceMethod(Selector Sel,
- bool AllowHidden = false) const {
- return getMethod(Sel, true/*isInstance*/, AllowHidden);
- }
- ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const {
- return getMethod(Sel, false/*isInstance*/, AllowHidden);
- }
- bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
- ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
-
- ObjCPropertyDecl *
- FindPropertyDeclaration(const IdentifierInfo *PropertyId) const;
-
- typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
-
- typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*>
- ProtocolPropertyMap;
-
- typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
-
- /// This routine collects list of properties to be implemented in the class.
- /// This includes, class's and its conforming protocols' properties.
- /// Note, the superclass's properties are not included in the list.
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const {}
-
- SourceLocation getAtStartLoc() const { return AtStart; }
- void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
-
- // Marks the end of the container.
- SourceRange getAtEndRange() const {
- return AtEnd;
- }
- void setAtEndRange(SourceRange atEnd) {
- AtEnd = atEnd;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(AtStart, getAtEndRange().getEnd());
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstObjCContainer &&
- K <= lastObjCContainer;
- }
-
- static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
- return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
- }
- static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief Represents an ObjC class declaration.
-///
-/// For example:
-///
-/// \code
-/// // MostPrimitive declares no super class (not particularly useful).
-/// \@interface MostPrimitive
-/// // no instance variables or methods.
-/// \@end
-///
-/// // NSResponder inherits from NSObject & implements NSCoding (a protocol).
-/// \@interface NSResponder : NSObject \<NSCoding>
-/// { // instance variables are represented by ObjCIvarDecl.
-/// id nextResponder; // nextResponder instance variable.
-/// }
-/// - (NSResponder *)nextResponder; // return a pointer to NSResponder.
-/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
-/// \@end // to an NSEvent.
-/// \endcode
-///
-/// Unlike C/C++, forward class declarations are accomplished with \@class.
-/// Unlike C/C++, \@class allows for a list of classes to be forward declared.
-/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
-/// typically inherit from NSObject (an exception is NSProxy).
-///
-class ObjCInterfaceDecl : public ObjCContainerDecl
- , public Redeclarable<ObjCInterfaceDecl> {
- void anchor() override;
-
- /// TypeForDecl - This indicates the Type object that represents this
- /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
- mutable const Type *TypeForDecl;
- friend class ASTContext;
-
- struct DefinitionData {
- /// \brief The definition of this class, for quick access from any
- /// declaration.
- ObjCInterfaceDecl *Definition;
-
- /// When non-null, this is always an ObjCObjectType.
- TypeSourceInfo *SuperClassTInfo;
-
- /// Protocols referenced in the \@interface declaration
- ObjCProtocolList ReferencedProtocols;
-
- /// Protocols reference in both the \@interface and class extensions.
- ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
-
- /// \brief 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,
- /// and we avoid dynamically-resized arrays in the AST wherever possible.
- ObjCCategoryDecl *CategoryList;
-
- /// IvarList - List of all ivars defined by this class; including class
- /// extensions and implementation. This list is built lazily.
- ObjCIvarDecl *IvarList;
-
- /// \brief Indicates that the contents of this Objective-C class will be
- /// completed by the external AST source when required.
- mutable bool ExternallyCompleted : 1;
-
- /// \brief Indicates that the ivar cache does not yet include ivars
- /// declared in the implementation.
- mutable bool IvarListMissingImplementation : 1;
-
- /// Indicates that this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- bool HasDesignatedInitializers : 1;
-
- enum InheritedDesignatedInitializersState {
- /// We didn't calculate whether the designated initializers should be
- /// inherited or not.
- IDI_Unknown = 0,
- /// Designated initializers are inherited for the super class.
- IDI_Inherited = 1,
- /// The class does not inherit designated initializers.
- IDI_NotInherited = 2
- };
- /// One of the \c InheritedDesignatedInitializersState enumeratos.
- mutable unsigned InheritedDesignatedInitializers : 2;
-
- /// \brief The location of the last location in this declaration, before
- /// the properties/methods. For example, this will be the '>', '}', or
- /// identifier,
- SourceLocation EndLoc;
-
- DefinitionData() : Definition(), SuperClassTInfo(), CategoryList(), IvarList(),
- ExternallyCompleted(),
- IvarListMissingImplementation(true),
- HasDesignatedInitializers(),
- InheritedDesignatedInitializers(IDI_Unknown) { }
- };
-
- ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
- IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
- SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
- bool IsInternal);
-
- void LoadExternalDefinition() const;
-
- /// The type parameters associated with this class, if any.
- ObjCTypeParamList *TypeParamList;
-
- /// \brief 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
- /// declarations. It will be set unless modules are enabled.
- llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
-
- DefinitionData &data() const {
- assert(Data.getPointer() && "Declaration has no definition!");
- return *Data.getPointer();
- }
-
- /// \brief Allocate the definition data for this class.
- void allocateDefinitionData();
-
- typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
- ObjCInterfaceDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- ObjCInterfaceDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- ObjCInterfaceDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation atLoc,
- IdentifierInfo *Id,
- ObjCTypeParamList *typeParamList,
- ObjCInterfaceDecl *PrevDecl,
- SourceLocation ClassLoc = SourceLocation(),
- bool isInternal = false);
-
- static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
-
- /// Retrieve the type parameters of this class.
- ///
- /// This function looks for a type parameter list for the given
- /// class; if the class has been declared (with \c \@class) but not
- /// defined (with \c \@interface), it will search for a declaration that
- /// has type parameters, skipping any declarations that do not.
- ObjCTypeParamList *getTypeParamList() const;
-
- /// Set the type parameters of this class.
- ///
- /// This function is used by the AST importer, which must import the type
- /// parameters after creating their DeclContext to avoid loops.
- void setTypeParamList(ObjCTypeParamList *TPL);
-
- /// Retrieve the type parameters written on this particular declaration of
- /// the class.
- ObjCTypeParamList *getTypeParamListAsWritten() const {
- return TypeParamList;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (isThisDeclarationADefinition())
- return ObjCContainerDecl::getSourceRange();
-
- return SourceRange(getAtStartLoc(), getLocation());
- }
-
- /// \brief 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();
-
- /// Indicate that this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- void setHasDesignatedInitializers();
-
- /// Returns true if this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- bool hasDesignatedInitializers() const;
-
- /// Returns true if this interface decl declares a designated initializer
- /// or it inherites one from its super class.
- bool declaresOrInheritsDesignatedInitializers() const {
- return hasDesignatedInitializers() || inheritsDesignatedInitializers();
- }
-
- const ObjCProtocolList &getReferencedProtocols() const {
- assert(hasDefinition() && "Caller did not check for forward reference!");
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols;
- }
-
- ObjCImplementationDecl *getImplementation() const;
- void setImplementation(ObjCImplementationDecl *ImplD);
-
- ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
-
- // Get the local instance/class method declared in a category.
- ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
- ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
- ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
- return isInstance ? getCategoryInstanceMethod(Sel)
- : getCategoryClassMethod(Sel);
- }
-
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.end();
- }
-
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.loc_begin();
- }
-
- protocol_loc_iterator protocol_loc_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.loc_end();
- }
-
- typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
- typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
-
- all_protocol_range all_referenced_protocols() const {
- return all_protocol_range(all_referenced_protocol_begin(),
- all_referenced_protocol_end());
- }
- all_protocol_iterator all_referenced_protocol_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return all_protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().AllReferencedProtocols.empty()
- ? protocol_begin()
- : data().AllReferencedProtocols.begin();
- }
- all_protocol_iterator all_referenced_protocol_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return all_protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().AllReferencedProtocols.empty()
- ? protocol_end()
- : data().AllReferencedProtocols.end();
- }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- if (const ObjCInterfaceDecl *Def = getDefinition())
- return ivar_iterator(Def->decls_begin());
-
- // FIXME: Should make sure no callers ever do this.
- return ivar_iterator();
- }
- ivar_iterator ivar_end() const {
- if (const ObjCInterfaceDecl *Def = getDefinition())
- return ivar_iterator(Def->decls_end());
-
- // FIXME: Should make sure no callers ever do this.
- return ivar_iterator();
- }
-
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
-
- bool ivar_empty() const { return ivar_begin() == ivar_end(); }
-
- ObjCIvarDecl *all_declared_ivar_begin();
- const ObjCIvarDecl *all_declared_ivar_begin() const {
- // Even though this modifies IvarList, it's conceptually const:
- // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
- return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
- }
- void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- data().ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- /// mergeClassExtensionProtocolList - Merge class extension's protocol list
- /// into the protocol list for this class.
- void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
- unsigned Num,
- ASTContext &C);
-
- /// Produce a name to be used for class's metadata. It comes either via
- /// objc_runtime_name attribute or class name.
- StringRef getObjCRuntimeNameAsString() const;
-
- /// Returns the designated initializers for the interface.
- ///
- /// If this declaration does not have methods marked as designated
- /// initializers then the interface inherits the designated initializers of
- /// its super class.
- void getDesignatedInitializers(
- llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
-
- /// Returns true if the given selector is a designated initializer for the
- /// interface.
- ///
- /// If this declaration does not have methods marked as designated
- /// initializers then the interface inherits the designated initializers of
- /// its super class.
- ///
- /// \param InitMethod if non-null and the function returns true, it receives
- /// the method that was marked as a designated initializer.
- bool
- isDesignatedInitializer(Selector Sel,
- const ObjCMethodDecl **InitMethod = nullptr) const;
-
- /// \brief Determine whether this particular declaration of this class is
- /// actually also a definition.
- bool isThisDeclarationADefinition() const {
- return getDefinition() == this;
- }
-
- /// \brief 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.
- // Note: a null value indicates that we don't have a definition and that
- // modules are enabled.
- if (!Data.getOpaqueValue())
- getMostRecentDecl();
-
- return Data.getPointer();
- }
-
- /// \brief 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
- /// 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
- /// a forward declaration (\@class) to a definition (\@interface).
- void startDefinition();
-
- /// Retrieve the superclass type.
- const ObjCObjectType *getSuperClassType() const {
- if (TypeSourceInfo *TInfo = getSuperClassTInfo())
- return TInfo->getType()->castAs<ObjCObjectType>();
-
- return nullptr;
- }
-
- // Retrieve the type source information for the superclass.
- TypeSourceInfo *getSuperClassTInfo() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return nullptr;
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().SuperClassTInfo;
- }
-
- // Retrieve the declaration for the superclass of this class, which
- // does not include any type arguments that apply to the superclass.
- ObjCInterfaceDecl *getSuperClass() const;
-
- void setSuperClass(TypeSourceInfo *superClass) {
- data().SuperClassTInfo = superClass;
- }
-
- /// \brief 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
- /// and extension iterators.
- template<bool (*Filter)(ObjCCategoryDecl *)>
- class filtered_category_iterator {
- ObjCCategoryDecl *Current;
-
- void findAcceptableCategory();
-
- public:
- typedef ObjCCategoryDecl * value_type;
- typedef value_type reference;
- typedef value_type pointer;
- typedef std::ptrdiff_t difference_type;
- typedef std::input_iterator_tag iterator_category;
-
- filtered_category_iterator() : Current(nullptr) { }
- explicit filtered_category_iterator(ObjCCategoryDecl *Current)
- : Current(Current)
- {
- findAcceptableCategory();
- }
-
- reference operator*() const { return Current; }
- pointer operator->() const { return Current; }
-
- filtered_category_iterator &operator++();
-
- filtered_category_iterator operator++(int) {
- filtered_category_iterator Tmp = *this;
- ++(*this);
- return Tmp;
- }
-
- friend bool operator==(filtered_category_iterator X,
- filtered_category_iterator Y) {
- return X.Current == Y.Current;
- }
-
- friend bool operator!=(filtered_category_iterator X,
- filtered_category_iterator Y) {
- return X.Current != Y.Current;
- }
- };
-
-private:
- /// \brief 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
- /// that are visible, i.e., not hidden in a non-imported submodule.
- typedef filtered_category_iterator<isVisibleCategory>
- visible_categories_iterator;
-
- typedef llvm::iterator_range<visible_categories_iterator>
- visible_categories_range;
-
- visible_categories_range visible_categories() const {
- return visible_categories_range(visible_categories_begin(),
- visible_categories_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the visible-categories
- /// list.
- visible_categories_iterator visible_categories_begin() const {
- return visible_categories_iterator(getCategoryListRaw());
- }
-
- /// \brief 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.
- bool visible_categories_empty() const {
- return visible_categories_begin() == visible_categories_end();
- }
-
-private:
- /// \brief 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
- /// extensions, including those that are hidden.
- typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
- typedef llvm::iterator_range<known_categories_iterator>
- known_categories_range;
-
- known_categories_range known_categories() const {
- return known_categories_range(known_categories_begin(),
- known_categories_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the known-categories
- /// list.
- known_categories_iterator known_categories_begin() const {
- return known_categories_iterator(getCategoryListRaw());
- }
-
- /// \brief 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.
- bool known_categories_empty() const {
- return known_categories_begin() == known_categories_end();
- }
-
-private:
- /// \brief 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
- /// any that are known but hidden.
- typedef filtered_category_iterator<isVisibleExtension>
- visible_extensions_iterator;
-
- typedef llvm::iterator_range<visible_extensions_iterator>
- visible_extensions_range;
-
- visible_extensions_range visible_extensions() const {
- return visible_extensions_range(visible_extensions_begin(),
- visible_extensions_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the visible-extensions
- /// list.
- visible_extensions_iterator visible_extensions_begin() const {
- return visible_extensions_iterator(getCategoryListRaw());
- }
-
- /// \brief 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.
- bool visible_extensions_empty() const {
- return visible_extensions_begin() == visible_extensions_end();
- }
-
-private:
- /// \brief Test whether the given category is an extension.
- ///
- /// Used in the \c known_extensions_iterator.
- static bool isKnownExtension(ObjCCategoryDecl *Cat);
-
-public:
- /// \brief Iterator that walks over all of the known extensions.
- typedef filtered_category_iterator<isKnownExtension>
- known_extensions_iterator;
- typedef llvm::iterator_range<known_extensions_iterator>
- known_extensions_range;
-
- known_extensions_range known_extensions() const {
- return known_extensions_range(known_extensions_begin(),
- known_extensions_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the known-extensions
- /// list.
- known_extensions_iterator known_extensions_begin() const {
- return known_extensions_iterator(getCategoryListRaw());
- }
-
- /// \brief 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.
- bool known_extensions_empty() const {
- return known_extensions_begin() == known_extensions_end();
- }
-
- /// \brief Retrieve the raw pointer to the start of the category/extension
- /// list.
- ObjCCategoryDecl* getCategoryListRaw() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return nullptr;
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().CategoryList;
- }
-
- /// \brief Set the raw pointer to the start of the category/extension
- /// list.
- void setCategoryListRaw(ObjCCategoryDecl *category) {
- data().CategoryList = category;
- }
-
- ObjCPropertyDecl
- *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
-
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
-
- /// isSuperClassOf - Return true if this class is the specified class or is a
- /// super class of the specified interface class.
- bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
- // If RHS is derived from LHS it is OK; else it is not OK.
- while (I != nullptr) {
- if (declaresSameEntity(this, I))
- return true;
-
- I = I->getSuperClass();
- }
- return false;
- }
-
- /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
- /// to be incompatible with __weak references. Returns true if it is.
- bool isArcWeakrefUnavailable() const;
-
- /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
- /// classes must not be auto-synthesized. Returns class decl. if it must not
- /// be; 0, otherwise.
- const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const;
-
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
- ObjCInterfaceDecl *&ClassDeclared);
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
- ObjCInterfaceDecl *ClassDeclared;
- return lookupInstanceVariable(IVarName, ClassDeclared);
- }
-
- ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
-
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
- bool shallowCategoryLookup = false,
- bool followSuper = true,
- const ObjCCategoryDecl *C = nullptr) const;
-
- /// Lookup an instance method for a given selector.
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
- return lookupMethod(Sel, true/*isInstance*/);
- }
-
- /// Lookup a class method for a given selector.
- ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
- return lookupMethod(Sel, false/*isInstance*/);
- }
- ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
-
- /// \brief Lookup a method in the classes implementation hierarchy.
- ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
- bool Instance=true) const;
-
- ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
- return lookupPrivateMethod(Sel, false);
- }
-
- /// \brief Lookup a setter or getter in the class hierarchy,
- /// including in all categories except for category passed
- /// as argument.
- ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
- const ObjCCategoryDecl *Cat) const {
- return lookupMethod(Sel, true/*isInstance*/,
- false/*shallowCategoryLookup*/,
- true /* followsSuper */,
- Cat);
- }
-
- SourceLocation getEndOfDefinitionLoc() const {
- if (!hasDefinition())
- return getLocation();
-
- return data().EndLoc;
- }
-
- void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
-
- /// Retrieve the starting location of the superclass.
- SourceLocation getSuperClassLoc() const;
-
- /// isImplicitInterfaceDecl - check that this is an implicitly declared
- /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
- /// declaration without an \@interface declaration.
- bool isImplicitInterfaceDecl() const {
- return hasDefinition() ? data().Definition->isImplicit() : isImplicit();
- }
-
- /// ClassImplementsProtocol - Checks that 'lProto' protocol
- /// has been implemented in IDecl class, its super class or categories (if
- /// lookupCategory is true).
- bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
- bool lookupCategory,
- bool RHSIsQualifiedID = false);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- /// Retrieves the canonical declaration of this Objective-C class.
- ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Low-level accessor
- const Type *getTypeForDecl() const { return TypeForDecl; }
- void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCInterface; }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-
-private:
- const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
- bool inheritsDesignatedInitializers() const;
-};
-
-/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
-/// instance variables are identical to C. The only exception is Objective-C
-/// supports C++ style access control. For example:
-///
-/// \@interface IvarExample : NSObject
-/// {
-/// id defaultToProtected;
-/// \@public:
-/// id canBePublic; // same as C++.
-/// \@protected:
-/// id canBeProtected; // same as C++.
-/// \@package:
-/// id canBePackage; // framework visibility (not available in C++).
-/// }
-///
-class ObjCIvarDecl : public FieldDecl {
- void anchor() override;
-
-public:
- enum AccessControl {
- None, Private, Protected, Public, Package
- };
-
-private:
- ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
- bool synthesized)
- : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
- /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
-
-public:
- static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW = nullptr,
- bool synthesized=false);
-
- static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief 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.
- const ObjCInterfaceDecl *getContainingInterface() const;
-
- ObjCIvarDecl *getNextIvar() { return NextIvar; }
- const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
- void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
-
- void setAccessControl(AccessControl ac) { DeclAccess = ac; }
-
- AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
-
- AccessControl getCanonicalAccessControl() const {
- return DeclAccess == None ? Protected : AccessControl(DeclAccess);
- }
-
- void setSynthesize(bool synth) { Synthesized = synth; }
- bool getSynthesize() const { return Synthesized; }
-
- /// Retrieve the type of this instance variable when viewed as a member of a
- /// specific object type.
- QualType getUsageType(QualType objectType) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCIvar; }
-private:
- /// NextIvar - Next Ivar in the list of ivars declared in class; class's
- /// extensions and class's implementation
- ObjCIvarDecl *NextIvar;
-
- // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
- unsigned DeclAccess : 3;
- unsigned Synthesized : 1;
-};
-
-
-/// \brief Represents a field declaration created by an \@defs(...).
-class ObjCAtDefsFieldDecl : public FieldDecl {
- void anchor() override;
- ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, Expr *BW)
- : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
- /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
- BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
-
-public:
- static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, Expr *BW);
-
- static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
-};
-
-/// \brief 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
-/// C++ pure virtual functions (a C++ feature with nice semantics and lousy
-/// syntax:-). Here is an example:
-///
-/// \code
-/// \@protocol NSDraggingInfo <refproto1, refproto2>
-/// - (NSWindow *)draggingDestinationWindow;
-/// - (NSImage *)draggedImage;
-/// \@end
-/// \endcode
-///
-/// This says that NSDraggingInfo requires two methods and requires everything
-/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
-/// well.
-///
-/// \code
-/// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo>
-/// \@end
-/// \endcode
-///
-/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
-/// protocols are in distinct namespaces. For example, Cocoa defines both
-/// an NSObject protocol and class (which isn't allowed in Java). As a result,
-/// protocols are referenced using angle brackets as follows:
-///
-/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
-///
-class ObjCProtocolDecl : public ObjCContainerDecl,
- public Redeclarable<ObjCProtocolDecl> {
- void anchor() override;
-
- struct DefinitionData {
- // \brief The declaration that defines this protocol.
- ObjCProtocolDecl *Definition;
-
- /// \brief Referenced protocols
- ObjCProtocolList ReferencedProtocols;
- };
-
- /// \brief 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
- /// declarations. It will be set unless modules are enabled.
- llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
-
- DefinitionData &data() const {
- assert(Data.getPointer() && "Objective-C protocol has no definition!");
- return *Data.getPointer();
- }
-
- ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- ObjCProtocolDecl *PrevDecl);
-
- void allocateDefinitionData();
-
- typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
- ObjCProtocolDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- ObjCProtocolDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- ObjCProtocolDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
- IdentifierInfo *Id,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- ObjCProtocolDecl *PrevDecl);
-
- static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- const ObjCProtocolList &getReferencedProtocols() const {
- assert(hasDefinition() && "No definition available!");
- return data().ReferencedProtocols;
- }
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- if (!hasDefinition())
- return protocol_iterator();
-
- return data().ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const {
- if (!hasDefinition())
- return protocol_iterator();
-
- return data().ReferencedProtocols.end();
- }
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- return data().ReferencedProtocols.loc_begin();
- }
- protocol_loc_iterator protocol_loc_end() const {
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- return data().ReferencedProtocols.loc_end();
- }
- unsigned protocol_size() const {
- if (!hasDefinition())
- return 0;
-
- return data().ReferencedProtocols.size();
- }
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- assert(hasDefinition() && "Protocol is not defined");
- data().ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
-
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
- return lookupMethod(Sel, true/*isInstance*/);
- }
- ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
- return lookupMethod(Sel, false/*isInstance*/);
- }
-
- /// \brief 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.
- // Note: a null value indicates that we don't have a definition and that
- // modules are enabled.
- if (!Data.getOpaqueValue())
- getMostRecentDecl();
-
- return Data.getPointer();
- }
-
- /// \brief 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.
- const ObjCProtocolDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Determine whether this particular declaration is also the
- /// definition.
- bool isThisDeclarationADefinition() const {
- return getDefinition() == this;
- }
-
- /// \brief Starts the definition of this Objective-C protocol.
- void startDefinition();
-
- /// Produce a name to be used for protocol's metadata. It comes either via
- /// objc_runtime_name attribute or protocol name.
- StringRef getObjCRuntimeNameAsString() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (isThisDeclarationADefinition())
- return ObjCContainerDecl::getSourceRange();
-
- return SourceRange(getAtStartLoc(), getLocation());
- }
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- /// Retrieves the canonical declaration of this Objective-C protocol.
- ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
-
- void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
- ProtocolPropertyMap &PM) const;
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCProtocol; }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// ObjCCategoryDecl - Represents a category declaration. A category allows
-/// you to add methods to an existing class (without subclassing or modifying
-/// the original class interface or implementation:-). Categories don't allow
-/// you to add instance data. The following example adds "myMethod" to all
-/// NSView's within a process:
-///
-/// \@interface NSView (MyViewMethods)
-/// - myMethod;
-/// \@end
-///
-/// Categories also allow you to split the implementation of a class across
-/// several files (a feature more naturally supported in C++).
-///
-/// Categories were originally inspired by dynamic languages such as Common
-/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
-/// don't support this level of dynamism, which is both powerful and dangerous.
-///
-class ObjCCategoryDecl : public ObjCContainerDecl {
- void anchor() override;
-
- /// Interface belonging to this category
- ObjCInterfaceDecl *ClassInterface;
-
- /// The type parameters associated with this category, if any.
- ObjCTypeParamList *TypeParamList;
-
- /// referenced protocols in this category.
- ObjCProtocolList ReferencedProtocols;
-
- /// Next category belonging to this class.
- /// FIXME: this should not be a singly-linked list. Move storage elsewhere.
- ObjCCategoryDecl *NextClassCategory;
-
- /// \brief The location of the category name in this declaration.
- SourceLocation CategoryNameLoc;
-
- /// class extension may have private ivars.
- SourceLocation IvarLBraceLoc;
- SourceLocation IvarRBraceLoc;
-
- ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
- SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
- IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
- ObjCTypeParamList *typeParamList,
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
-
-public:
-
- static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation AtLoc,
- SourceLocation ClassNameLoc,
- SourceLocation CategoryNameLoc,
- IdentifierInfo *Id,
- ObjCInterfaceDecl *IDecl,
- ObjCTypeParamList *typeParamList,
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
- static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
-
- /// Retrieve the type parameter list associated with this category or
- /// extension.
- ObjCTypeParamList *getTypeParamList() const { return TypeParamList; }
-
- /// Set the type parameters of this category.
- ///
- /// This function is used by the AST importer, which must import the type
- /// parameters after creating their DeclContext to avoid loops.
- void setTypeParamList(ObjCTypeParamList *TPL);
-
-
- ObjCCategoryImplDecl *getImplementation() const;
- void setImplementation(ObjCCategoryImplDecl *ImplD);
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- const ObjCProtocolList &getReferencedProtocols() const {
- return ReferencedProtocols;
- }
-
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- return ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
- unsigned protocol_size() const { return ReferencedProtocols.size(); }
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- return ReferencedProtocols.loc_begin();
- }
- protocol_loc_iterator protocol_loc_end() const {
- return ReferencedProtocols.loc_end();
- }
-
- ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
-
- /// \brief Retrieve the pointer to the next stored category (or extension),
- /// which may be hidden.
- ObjCCategoryDecl *getNextClassCategoryRaw() const {
- return NextClassCategory;
- }
-
- bool IsClassExtension() const { return getIdentifier() == nullptr; }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- return ivar_iterator(decls_begin());
- }
- ivar_iterator ivar_end() const {
- return ivar_iterator(decls_end());
- }
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
- bool ivar_empty() const {
- return ivar_begin() == ivar_end();
- }
-
- SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
- void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
-
- void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
- SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
- void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
- SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCategory; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class ObjCImplDecl : public ObjCContainerDecl {
- void anchor() override;
-
- /// Class interface for this class/category implementation
- ObjCInterfaceDecl *ClassInterface;
-
-protected:
- ObjCImplDecl(Kind DK, DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc, SourceLocation atStartLoc)
- : ObjCContainerDecl(DK, DC,
- classInterface? classInterface->getIdentifier()
- : nullptr,
- nameLoc, atStartLoc),
- ClassInterface(classInterface) {}
-
-public:
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- void setClassInterface(ObjCInterfaceDecl *IFace);
-
- void addInstanceMethod(ObjCMethodDecl *method) {
- // FIXME: Context should be set correctly before we get here.
- method->setLexicalDeclContext(this);
- addDecl(method);
- }
- void addClassMethod(ObjCMethodDecl *method) {
- // FIXME: Context should be set correctly before we get here.
- method->setLexicalDeclContext(this);
- addDecl(method);
- }
-
- void addPropertyImplementation(ObjCPropertyImplDecl *property);
-
- ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
- ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
-
- // Iterator access to properties.
- typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
- propimpl_range;
-
- propimpl_range property_impls() const {
- return propimpl_range(propimpl_begin(), propimpl_end());
- }
- propimpl_iterator propimpl_begin() const {
- return propimpl_iterator(decls_begin());
- }
- propimpl_iterator propimpl_end() const {
- return propimpl_iterator(decls_end());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstObjCImpl && K <= lastObjCImpl;
- }
-};
-
-/// ObjCCategoryImplDecl - An object of this class encapsulates a category
-/// \@implementation declaration. If a category class has declaration of a
-/// property, its implementation must be specified in the category's
-/// \@implementation declaration. Example:
-/// \@interface I \@end
-/// \@interface I(CATEGORY)
-/// \@property int p1, d1;
-/// \@end
-/// \@implementation I(CATEGORY)
-/// \@dynamic p1,d1;
-/// \@end
-///
-/// ObjCCategoryImplDecl
-class ObjCCategoryImplDecl : public ObjCImplDecl {
- void anchor() override;
-
- // Category name
- IdentifierInfo *Id;
-
- // Category name location
- SourceLocation CategoryNameLoc;
-
- ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- SourceLocation CategoryNameLoc)
- : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
- Id(Id), CategoryNameLoc(CategoryNameLoc) {}
-public:
- static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
- IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- SourceLocation CategoryNameLoc);
- static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// getIdentifier - Get the identifier that names the category
- /// interface associated with this implementation.
- /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
- /// with a different meaning. For example:
- /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
- /// returns the class interface name, whereas
- /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
- /// returns the category name.
- IdentifierInfo *getIdentifier() const {
- return Id;
- }
- void setIdentifier(IdentifierInfo *II) { Id = II; }
-
- ObjCCategoryDecl *getCategoryDecl() const;
-
- SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
-
- /// getName - Get the name of identifier for the class interface associated
- /// with this implementation as a StringRef.
- //
- // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
- // meaning.
- StringRef getName() const { return Id ? Id->getName() : StringRef(); }
-
- /// @brief Get the name of the class associated with this interface.
- //
- // FIXME: Deprecated, move clients to getName().
- std::string getNameAsString() const {
- return getName();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
-
-/// ObjCImplementationDecl - Represents a class definition - this is where
-/// method definitions are specified. For example:
-///
-/// @code
-/// \@implementation MyClass
-/// - (void)myMethod { /* do something */ }
-/// \@end
-/// @endcode
-///
-/// In a non-fragile runtime, instance variables can appear in the class
-/// interface, class extensions (nameless categories), and in the implementation
-/// itself, as well as being synthesized as backing storage for properties.
-///
-/// In a fragile runtime, instance variables are specified in the class
-/// interface, \em not in the implementation. Nevertheless (for legacy reasons),
-/// we allow instance variables to be specified in the implementation. When
-/// specified, they need to be \em identical to the interface.
-class ObjCImplementationDecl : public ObjCImplDecl {
- void anchor() override;
- /// Implementation Class's super class.
- ObjCInterfaceDecl *SuperClass;
- SourceLocation SuperLoc;
-
- /// \@implementation may have private ivars.
- SourceLocation IvarLBraceLoc;
- SourceLocation IvarRBraceLoc;
-
- /// Support for ivar initialization.
- /// \brief The arguments used to initialize the ivars
- LazyCXXCtorInitializersPtr IvarInitializers;
- unsigned NumIvarInitializers;
-
- /// Do the ivars of this class require initialization other than
- /// zero-initialization?
- bool HasNonZeroConstructors : 1;
-
- /// Do the ivars of this class require non-trivial destruction?
- bool HasDestructors : 1;
-
- ObjCImplementationDecl(DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- ObjCInterfaceDecl *superDecl,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- SourceLocation superLoc = SourceLocation(),
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation())
- : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
- SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
- IvarRBraceLoc(IvarRBraceLoc),
- IvarInitializers(nullptr), NumIvarInitializers(0),
- HasNonZeroConstructors(false), HasDestructors(false) {}
-public:
- static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- ObjCInterfaceDecl *superDecl,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- SourceLocation superLoc = SourceLocation(),
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
-
- static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// init_iterator - Iterates through the ivar initializer list.
- typedef CXXCtorInitializer **init_iterator;
-
- /// init_const_iterator - Iterates through the ivar initializer list.
- typedef CXXCtorInitializer * const * init_const_iterator;
-
- typedef llvm::iterator_range<init_iterator> init_range;
- typedef llvm::iterator_range<init_const_iterator> init_const_range;
-
- init_range inits() { return init_range(init_begin(), init_end()); }
- init_const_range inits() const {
- return init_const_range(init_begin(), init_end());
- }
-
- /// init_begin() - Retrieve an iterator to the first initializer.
- init_iterator init_begin() {
- const auto *ConstThis = this;
- return const_cast<init_iterator>(ConstThis->init_begin());
- }
- /// begin() - Retrieve an iterator to the first initializer.
- init_const_iterator init_begin() const;
-
- /// init_end() - Retrieve an iterator past the last initializer.
- init_iterator init_end() {
- return init_begin() + NumIvarInitializers;
- }
- /// end() - Retrieve an iterator past the last initializer.
- init_const_iterator init_end() const {
- return init_begin() + NumIvarInitializers;
- }
- /// getNumArgs - Number of ivars which must be initialized.
- unsigned getNumIvarInitializers() const {
- return NumIvarInitializers;
- }
-
- void setNumIvarInitializers(unsigned numNumIvarInitializers) {
- NumIvarInitializers = numNumIvarInitializers;
- }
-
- void setIvarInitializers(ASTContext &C,
- CXXCtorInitializer ** initializers,
- unsigned numInitializers);
-
- /// Do any of the ivars of this class (not counting its base classes)
- /// require construction other than zero-initialization?
- bool hasNonZeroConstructors() const { return HasNonZeroConstructors; }
- void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; }
-
- /// Do any of the ivars of this class (not counting its base classes)
- /// require non-trivial destruction?
- bool hasDestructors() const { return HasDestructors; }
- void setHasDestructors(bool val) { HasDestructors = val; }
-
- /// getIdentifier - Get the identifier that names the class
- /// interface associated with this implementation.
- IdentifierInfo *getIdentifier() const {
- return getClassInterface()->getIdentifier();
- }
-
- /// getName - Get the name of identifier for the class interface associated
- /// with this implementation as a StringRef.
- //
- // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
- // meaning.
- StringRef getName() const {
- assert(getIdentifier() && "Name is not a simple identifier");
- return getIdentifier()->getName();
- }
-
- /// @brief Get the name of the class associated with this interface.
- //
- // FIXME: Move to StringRef API.
- std::string getNameAsString() const {
- return getName();
- }
-
- /// Produce a name to be used for class's metadata. It comes either via
- /// class's objc_runtime_name attribute or class name.
- StringRef getObjCRuntimeNameAsString() const;
-
- const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
- ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
- SourceLocation getSuperClassLoc() const { return SuperLoc; }
-
- void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
-
- void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
- SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
- void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
- SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- return ivar_iterator(decls_begin());
- }
- ivar_iterator ivar_end() const {
- return ivar_iterator(decls_end());
- }
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
- bool ivar_empty() const {
- return ivar_begin() == ivar_end();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCImplementation; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
-
-/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
-/// declared as \@compatibility_alias alias class.
-class ObjCCompatibleAliasDecl : public NamedDecl {
- void anchor() override;
- /// Class that this is an alias of.
- ObjCInterfaceDecl *AliasedClass;
-
- ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl* aliasedClass)
- : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
-public:
- static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl* aliasedClass);
-
- static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
- ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
- void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
-
-};
-
-/// \brief Represents one property declaration in an Objective-C interface.
-///
-/// For example:
-/// \code{.mm}
-/// \@property (assign, readwrite) int MyProperty;
-/// \endcode
-class ObjCPropertyDecl : public NamedDecl {
- void anchor() override;
-public:
- enum PropertyAttributeKind {
- OBJC_PR_noattr = 0x00,
- OBJC_PR_readonly = 0x01,
- OBJC_PR_getter = 0x02,
- OBJC_PR_assign = 0x04,
- OBJC_PR_readwrite = 0x08,
- OBJC_PR_retain = 0x10,
- OBJC_PR_copy = 0x20,
- OBJC_PR_nonatomic = 0x40,
- OBJC_PR_setter = 0x80,
- OBJC_PR_atomic = 0x100,
- OBJC_PR_weak = 0x200,
- OBJC_PR_strong = 0x400,
- OBJC_PR_unsafe_unretained = 0x800,
- /// Indicates that the nullability of the type was spelled with a
- /// property attribute rather than a type qualifier.
- OBJC_PR_nullability = 0x1000,
- OBJC_PR_null_resettable = 0x2000
- // Adding a property should change NumPropertyAttrsBits
- };
-
- enum {
- /// \brief Number of bits fitting all the property attributes.
- NumPropertyAttrsBits = 14
- };
-
- enum SetterKind { Assign, Retain, Copy, Weak };
- enum PropertyControl { None, Required, Optional };
-private:
- SourceLocation AtLoc; // location of \@property
- SourceLocation LParenLoc; // location of '(' starting attribute list or null.
- QualType DeclType;
- TypeSourceInfo *DeclTypeSourceInfo;
- unsigned PropertyAttributes : NumPropertyAttrsBits;
- unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
- // \@required/\@optional
- unsigned PropertyImplementation : 2;
-
- Selector GetterName; // getter name of NULL if no getter
- Selector SetterName; // setter name of NULL if no setter
-
- ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
- ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
- ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
-
- ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- SourceLocation AtLocation, SourceLocation LParenLocation,
- QualType T, TypeSourceInfo *TSI,
- PropertyControl propControl)
- : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
- LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
- PropertyAttributes(OBJC_PR_noattr),
- PropertyAttributesAsWritten(OBJC_PR_noattr),
- PropertyImplementation(propControl),
- GetterName(Selector()),
- SetterName(Selector()),
- GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
- PropertyIvarDecl(nullptr) {}
-
-public:
- static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, SourceLocation AtLocation,
- SourceLocation LParenLocation,
- QualType T,
- TypeSourceInfo *TSI,
- PropertyControl propControl = None);
-
- static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
-
- TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
-
- QualType getType() const { return DeclType; }
-
- void setType(QualType T, TypeSourceInfo *TSI) {
- DeclType = T;
- DeclTypeSourceInfo = TSI;
- }
-
- /// Retrieve the type when this property is used with a specific base object
- /// type.
- QualType getUsageType(QualType objectType) const;
-
- PropertyAttributeKind getPropertyAttributes() const {
- return PropertyAttributeKind(PropertyAttributes);
- }
- void setPropertyAttributes(PropertyAttributeKind PRVal) {
- PropertyAttributes |= PRVal;
- }
- void overwritePropertyAttributes(unsigned PRVal) {
- PropertyAttributes = PRVal;
- }
-
- PropertyAttributeKind getPropertyAttributesAsWritten() const {
- return PropertyAttributeKind(PropertyAttributesAsWritten);
- }
-
- void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
- PropertyAttributesAsWritten = PRVal;
- }
-
- // Helper methods for accessing attributes.
-
- /// isReadOnly - Return true iff the property has a setter.
- bool isReadOnly() const {
- return (PropertyAttributes & OBJC_PR_readonly);
- }
-
- /// isAtomic - Return true if the property is atomic.
- bool isAtomic() const {
- return (PropertyAttributes & OBJC_PR_atomic);
- }
-
- /// isRetaining - Return true if the property retains its value.
- bool isRetaining() const {
- return (PropertyAttributes &
- (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
- }
-
- /// getSetterKind - Return the method used for doing assignment in
- /// the property setter. This is only valid if the property has been
- /// defined to have a setter.
- SetterKind getSetterKind() const {
- if (PropertyAttributes & OBJC_PR_strong)
- return getType()->isBlockPointerType() ? Copy : Retain;
- if (PropertyAttributes & OBJC_PR_retain)
- return Retain;
- if (PropertyAttributes & OBJC_PR_copy)
- return Copy;
- if (PropertyAttributes & OBJC_PR_weak)
- return Weak;
- return Assign;
- }
-
- Selector getGetterName() const { return GetterName; }
- void setGetterName(Selector Sel) { GetterName = Sel; }
-
- Selector getSetterName() const { return SetterName; }
- void setSetterName(Selector Sel) { SetterName = Sel; }
-
- ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
- void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
-
- ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
- void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
-
- // Related to \@optional/\@required declared in \@protocol
- void setPropertyImplementation(PropertyControl pc) {
- PropertyImplementation = pc;
- }
- PropertyControl getPropertyImplementation() const {
- return PropertyControl(PropertyImplementation);
- }
-
- void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
- PropertyIvarDecl = Ivar;
- }
- ObjCIvarDecl *getPropertyIvarDecl() const {
- return PropertyIvarDecl;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(AtLoc, getLocation());
- }
-
- /// Get the default name of the synthesized ivar.
- IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
-
- /// Lookup a property by name in the specified DeclContext.
- static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
- const IdentifierInfo *propertyID);
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCProperty; }
-};
-
-/// ObjCPropertyImplDecl - Represents implementation declaration of a property
-/// in a class or category implementation block. For example:
-/// \@synthesize prop1 = ivar1;
-///
-class ObjCPropertyImplDecl : public Decl {
-public:
- enum Kind {
- Synthesize,
- Dynamic
- };
-private:
- SourceLocation AtLoc; // location of \@synthesize or \@dynamic
-
- /// \brief For \@synthesize, the location of the ivar, if it was written in
- /// the source code.
- ///
- /// \code
- /// \@synthesize int a = b
- /// \endcode
- SourceLocation IvarLoc;
-
- /// Property declaration being implemented
- ObjCPropertyDecl *PropertyDecl;
-
- /// Null for \@dynamic. Required for \@synthesize.
- ObjCIvarDecl *PropertyIvarDecl;
-
- /// Null for \@dynamic. Non-null if property must be copy-constructed in
- /// getter.
- Expr *GetterCXXConstructor;
-
- /// Null for \@dynamic. Non-null if property has assignment operator to call
- /// in Setter synthesis.
- Expr *SetterCXXAssignment;
-
- ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivarDecl,
- SourceLocation ivarLoc)
- : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
- IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
- GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
- assert (PK == Dynamic || PropertyIvarDecl);
- }
-
-public:
- static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation atLoc, SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivarDecl,
- SourceLocation ivarLoc);
-
- static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
-
- ObjCPropertyDecl *getPropertyDecl() const {
- return PropertyDecl;
- }
- void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
-
- Kind getPropertyImplementation() const {
- return PropertyIvarDecl ? Synthesize : Dynamic;
- }
-
- ObjCIvarDecl *getPropertyIvarDecl() const {
- return PropertyIvarDecl;
- }
- SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
-
- void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
- SourceLocation IvarLoc) {
- PropertyIvarDecl = Ivar;
- this->IvarLoc = IvarLoc;
- }
-
- /// \brief For \@synthesize, returns true if an ivar name was explicitly
- /// specified.
- ///
- /// \code
- /// \@synthesize int a = b; // true
- /// \@synthesize int a; // false
- /// \endcode
- bool isIvarNameSpecified() const {
- return IvarLoc.isValid() && IvarLoc != getLocation();
- }
-
- Expr *getGetterCXXConstructor() const {
- return GetterCXXConstructor;
- }
- void setGetterCXXConstructor(Expr *getterCXXConstructor) {
- GetterCXXConstructor = getterCXXConstructor;
- }
-
- Expr *getSetterCXXAssignment() const {
- return SetterCXXAssignment;
- }
- void setSetterCXXAssignment(Expr *setterCXXAssignment) {
- SetterCXXAssignment = setterCXXAssignment;
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
-
- friend class ASTDeclReader;
-};
-
-template<bool (*Filter)(ObjCCategoryDecl *)>
-void
-ObjCInterfaceDecl::filtered_category_iterator<Filter>::
-findAcceptableCategory() {
- while (Current && !Filter(Current))
- Current = Current->getNextClassCategoryRaw();
-}
-
-template<bool (*Filter)(ObjCCategoryDecl *)>
-inline ObjCInterfaceDecl::filtered_category_iterator<Filter> &
-ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
- Current = Current->getNextClassCategoryRaw();
- findAcceptableCategory();
- return *this;
-}
-
-inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
- return !Cat->isHidden();
-}
-
-inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension() && !Cat->isHidden();
-}
-
-inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension();
-}
-
-} // end namespace clang
-#endif
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
deleted file mode 100644
index 598f418..0000000
--- a/include/clang/AST/DeclOpenMP.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file defines OpenMP nodes for declarative directives.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLOPENMP_H
-#define LLVM_CLANG_AST_DECLOPENMP_H
-
-#include "clang/AST/DeclBase.h"
-#include "llvm/ADT/ArrayRef.h"
-
-namespace clang {
-class Expr;
-
-/// \brief This represents '#pragma omp threadprivate ...' directive.
-/// For example, in the following, both 'a' and 'A::b' are threadprivate:
-///
-/// \code
-/// int a;
-/// #pragma omp threadprivate(a)
-/// struct A {
-/// static int b;
-/// #pragma omp threadprivate(b)
-/// };
-/// \endcode
-///
-class OMPThreadPrivateDecl final
- : public Decl,
- private llvm::TrailingObjects<OMPThreadPrivateDecl, Expr *> {
- friend class ASTDeclReader;
- friend TrailingObjects;
-
- unsigned NumVars;
-
- virtual void anchor();
-
- OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
- Decl(DK, DC, L), NumVars(0) { }
-
- ArrayRef<const Expr *> getVars() const {
- return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
- }
-
- MutableArrayRef<Expr *> getVars() {
- return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
- }
-
- void setVars(ArrayRef<Expr *> VL);
-
-public:
- static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- ArrayRef<Expr *> VL);
- static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
- unsigned ID, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
- typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
- typedef llvm::iterator_range<varlist_iterator> varlist_range;
- typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
-
- unsigned varlist_size() const { return NumVars; }
- bool varlist_empty() const { return NumVars == 0; }
-
- varlist_range varlists() {
- return varlist_range(varlist_begin(), varlist_end());
- }
- varlist_const_range varlists() const {
- return varlist_const_range(varlist_begin(), varlist_end());
- }
- varlist_iterator varlist_begin() { return getVars().begin(); }
- varlist_iterator varlist_end() { return getVars().end(); }
- varlist_const_iterator varlist_begin() const { return getVars().begin(); }
- varlist_const_iterator varlist_end() const { return getVars().end(); }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
deleted file mode 100644
index a9109ef..0000000
--- a/include/clang/AST/DeclTemplate.h
+++ /dev/null
@@ -1,2927 +0,0 @@
-//===-- DeclTemplate.h - Classes for representing C++ templates -*- 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 C++ template declaration subclasses.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
-#define LLVM_CLANG_AST_DECLTEMPLATE_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Redeclarable.h"
-#include "clang/AST/TemplateBase.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/TrailingObjects.h"
-#include <limits>
-
-namespace clang {
-
-enum BuiltinTemplateKind : int;
-class TemplateParameterList;
-class TemplateDecl;
-class RedeclarableTemplateDecl;
-class FunctionTemplateDecl;
-class ClassTemplateDecl;
-class ClassTemplatePartialSpecializationDecl;
-class TemplateTypeParmDecl;
-class NonTypeTemplateParmDecl;
-class TemplateTemplateParmDecl;
-class TypeAliasTemplateDecl;
-class VarTemplateDecl;
-class VarTemplatePartialSpecializationDecl;
-
-/// \brief Stores a template parameter of any kind.
-typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
- TemplateTemplateParmDecl*> TemplateParameter;
-
-/// \brief Stores a list of template parameters for a TemplateDecl and its
-/// derived classes.
-class TemplateParameterList final
- : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> {
-
- /// The location of the 'template' keyword.
- SourceLocation TemplateLoc;
-
- /// The locations of the '<' and '>' angle brackets.
- SourceLocation LAngleLoc, RAngleLoc;
-
- /// The number of template parameters in this template
- /// parameter list.
- unsigned NumParams : 31;
-
- /// Whether this template parameter list contains an unexpanded parameter
- /// pack.
- unsigned ContainsUnexpandedParameterPack : 1;
-
-protected:
- size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
- return NumParams;
- }
-
- TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc);
-
-public:
- static TemplateParameterList *Create(const ASTContext &C,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc);
-
- /// \brief Iterates through the template parameters in this list.
- typedef NamedDecl** iterator;
-
- /// \brief Iterates through the template parameters in this list.
- typedef NamedDecl* const* const_iterator;
-
- iterator begin() { return getTrailingObjects<NamedDecl *>(); }
- const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
- iterator end() { return begin() + NumParams; }
- const_iterator end() const { return begin() + NumParams; }
-
- unsigned size() const { return NumParams; }
-
- ArrayRef<NamedDecl*> asArray() {
- return llvm::makeArrayRef(begin(), end());
- }
- ArrayRef<const NamedDecl*> asArray() const {
- return llvm::makeArrayRef(begin(), size());
- }
-
- NamedDecl* getParam(unsigned Idx) {
- assert(Idx < size() && "Template parameter index out-of-range");
- return begin()[Idx];
- }
-
- const NamedDecl* getParam(unsigned Idx) const {
- assert(Idx < size() && "Template parameter index out-of-range");
- return begin()[Idx];
- }
-
- /// \brief 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
- /// 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
- /// unexpanded parameter pack.
- bool containsUnexpandedParameterPack() const {
- return ContainsUnexpandedParameterPack;
- }
-
- SourceLocation getTemplateLoc() const { return TemplateLoc; }
- SourceLocation getLAngleLoc() const { return LAngleLoc; }
- SourceLocation getRAngleLoc() const { return RAngleLoc; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(TemplateLoc, RAngleLoc);
- }
-
- friend TrailingObjects;
- template <size_t N> friend class FixedSizeTemplateParameterListStorage;
-};
-
-/// \brief Stores a list of template parameters for a TemplateDecl and its
-/// derived classes. Suitable for creating on the stack.
-template <size_t N> class FixedSizeTemplateParameterListStorage {
- // This is kinda ugly: TemplateParameterList usually gets allocated
- // in a block of memory with NamedDecls appended to it. Here, to get
- // it stack allocated, we include the params as a separate
- // variable. After allocation, the TemplateParameterList object
- // treats them as part of itself.
- TemplateParameterList List;
- NamedDecl *Params[N];
-
-public:
- FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc)
- : List(TemplateLoc, LAngleLoc, Params, RAngleLoc) {
- // Because we're doing an evil layout hack above, have some
- // asserts, just to double-check everything is laid out like
- // expected.
- assert(sizeof(*this) ==
- TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) &&
- "Object layout not as expected");
- assert(this->Params == List.getTrailingObjects<NamedDecl *>() &&
- "Object layout not as expected");
- }
- TemplateParameterList *get() { return &List; }
-};
-
-/// \brief A template argument list.
-class TemplateArgumentList final
- : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
- /// \brief The template argument list.
- const TemplateArgument *Arguments;
-
- /// \brief The number of template arguments in this template
- /// argument list.
- unsigned NumArguments;
-
- TemplateArgumentList(const TemplateArgumentList &Other) = delete;
- void operator=(const TemplateArgumentList &Other) = delete;
-
- // Constructs an instance with an internal Argument list, containing
- // a copy of the Args array. (Called by CreateCopy)
- TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs);
-
-public:
- /// \brief 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
- /// template arguments.
- static TemplateArgumentList *CreateCopy(ASTContext &Context,
- const TemplateArgument *Args,
- unsigned NumArgs);
-
- /// \brief Construct a new, temporary template argument list on the stack.
- ///
- /// The template argument list does not own the template arguments
- /// provided.
- explicit TemplateArgumentList(OnStackType, const TemplateArgument *Args,
- unsigned NumArgs)
- : Arguments(Args), NumArguments(NumArgs) {}
-
- /// \brief 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
- /// constructor, since this really really isn't safe to use that
- /// way.
- explicit TemplateArgumentList(const TemplateArgumentList *Other)
- : Arguments(Other->data()), NumArguments(Other->size()) {}
-
- /// \brief 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.
- const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
-
- /// \brief Produce this as an array ref.
- ArrayRef<TemplateArgument> asArray() const {
- return llvm::makeArrayRef(data(), size());
- }
-
- /// \brief 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.
- const TemplateArgument *data() const { return Arguments; }
-
- friend TrailingObjects;
-};
-
-void *allocateDefaultArgStorageChain(const ASTContext &C);
-
-/// Storage for a default argument. This is conceptually either empty, or an
-/// argument value, or a pointer to a previous declaration that had a default
-/// argument.
-///
-/// However, this is complicated by modules: while we require all the default
-/// arguments for a template to be equivalent, there may be more than one, and
-/// we need to track all the originating parameters to determine if the default
-/// argument is visible.
-template<typename ParmDecl, typename ArgType>
-class DefaultArgStorage {
- /// Storage for both the value *and* another parameter from which we inherit
- /// the default argument. This is used when multiple default arguments for a
- /// parameter are merged together from different modules.
- struct Chain {
- ParmDecl *PrevDeclWithDefaultArg;
- ArgType Value;
- };
- static_assert(sizeof(Chain) == sizeof(void *) * 2,
- "non-pointer argument type?");
-
- llvm::PointerUnion3<ArgType, ParmDecl*, Chain*> ValueOrInherited;
-
- static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
- const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
- if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl*>())
- Parm = Prev;
- assert(!Parm->getDefaultArgStorage()
- .ValueOrInherited.template is<ParmDecl *>() &&
- "should only be one level of indirection");
- return Parm;
- }
-
-public:
- DefaultArgStorage() : ValueOrInherited(ArgType()) {}
-
- /// Determine whether there is a default argument for this parameter.
- bool isSet() const { return !ValueOrInherited.isNull(); }
- /// Determine whether the default argument for this parameter was inherited
- /// from a previous declaration of the same entity.
- bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
- /// Get the default argument's value. This does not consider whether the
- /// default argument is visible.
- ArgType get() const {
- const DefaultArgStorage *Storage = this;
- if (auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl*>())
- Storage = &Prev->getDefaultArgStorage();
- if (auto *C = Storage->ValueOrInherited.template dyn_cast<Chain*>())
- return C->Value;
- return Storage->ValueOrInherited.template get<ArgType>();
- }
- /// 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*>())
- return D;
- if (auto *C = ValueOrInherited.template dyn_cast<Chain*>())
- return C->PrevDeclWithDefaultArg;
- return nullptr;
- }
- /// Set the default argument.
- void set(ArgType Arg) {
- assert(!isSet() && "default argument already set");
- ValueOrInherited = Arg;
- }
- /// Set that the default argument was inherited from another parameter.
- void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
- assert(!isInherited() && "default argument already inherited");
- InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
- if (!isSet())
- ValueOrInherited = InheritedFrom;
- else
- ValueOrInherited = new (allocateDefaultArgStorageChain(C))
- Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
- }
- /// Remove the default argument, even if it was inherited.
- void clear() {
- ValueOrInherited = ArgType();
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Kinds of Templates
-//===----------------------------------------------------------------------===//
-
-/// \brief 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
-/// reference to the templated scoped declaration: the underlying AST node.
-class TemplateDecl : public NamedDecl {
- void anchor() override;
-protected:
- // This is probably never used.
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
- TemplateParams(nullptr) {}
-
- // Construct a template decl with the given name and parameters.
- // Used when there is not templated element (tt-params).
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
- TemplateParams(Params) {}
-
- // Construct a template decl with name, parameters, and templated element.
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
- TemplateParams(Params) { }
-public:
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the underlying, templated declaration.
- NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstTemplate && K <= lastTemplate;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(TemplateParams->getTemplateLoc(),
- TemplatedDecl->getSourceRange().getEnd());
- }
-
-protected:
- NamedDecl *TemplatedDecl;
- TemplateParameterList* TemplateParams;
-
-public:
- /// \brief Initialize the underlying templated declaration and
- /// template parameters.
- void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
- assert(!TemplatedDecl && "TemplatedDecl already set!");
- assert(!TemplateParams && "TemplateParams already set!");
- TemplatedDecl = templatedDecl;
- TemplateParams = templateParams;
- }
-};
-
-/// \brief 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 {
- FunctionTemplateSpecializationInfo(FunctionDecl *FD,
- FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI)
- : Function(FD),
- Template(Template, TSK - 1),
- TemplateArguments(TemplateArgs),
- TemplateArgumentsAsWritten(TemplateArgsAsWritten),
- PointOfInstantiation(POI) { }
-
-public:
- static FunctionTemplateSpecializationInfo *
- Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI);
-
- /// \brief The function template specialization that this structure
- /// describes.
- FunctionDecl *Function;
-
- /// \brief 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
- /// specialization from the function template.
- const TemplateArgumentList *TemplateArguments;
-
- /// \brief The template arguments as written in the sources, if provided.
- const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
-
- /// \brief The point at which this function template specialization was
- /// first instantiated.
- SourceLocation PointOfInstantiation;
-
- /// \brief Retrieve the template from which this function was specialized.
- FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
-
- /// \brief Determine what kind of template specialization this is.
- TemplateSpecializationKind getTemplateSpecializationKind() const {
- return (TemplateSpecializationKind)(Template.getInt() + 1);
- }
-
- bool isExplicitSpecialization() const {
- return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- /// \brief 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
- /// template specialization.
- ///
- /// The point of instantiation may be an invalid source location if this
- /// function has yet to be instantiated.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- /// \brief Set the (first) point of instantiation of this function template
- /// specialization.
- void setPointOfInstantiation(SourceLocation POI) {
- PointOfInstantiation = POI;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, TemplateArguments->asArray(),
- Function->getASTContext());
- }
-
- static void
- Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-};
-
-/// \brief 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 {
- // The member declaration from which this member was instantiated, and the
- // manner in which the instantiation occurred (in the lower two bits).
- llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
-
- // The point at which this member was first instantiated.
- SourceLocation PointOfInstantiation;
-
-public:
- explicit
- MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
- SourceLocation POI = SourceLocation())
- : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
- assert(TSK != TSK_Undeclared &&
- "Cannot encode undeclared template specializations for members");
- }
-
- /// \brief 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.
- TemplateSpecializationKind getTemplateSpecializationKind() const {
- return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
- }
-
- bool isExplicitSpecialization() const {
- return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief 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.
- /// 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.
- void setPointOfInstantiation(SourceLocation POI) {
- PointOfInstantiation = POI;
- }
-};
-
-/// \brief Provides information about a dependent function-template
-/// specialization declaration.
-///
-/// Since explicit function template specialization and instantiation
-/// declarations can only appear in namespace scope, and you can only
-/// specialize a member of a fully-specialized class, the only way to
-/// get one of these is in a friend declaration like the following:
-///
-/// \code
-/// template \<class T> void foo(T);
-/// template \<class T> class A {
-/// friend void foo<>(T);
-/// };
-/// \endcode
-class DependentFunctionTemplateSpecializationInfo final
- : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
- TemplateArgumentLoc,
- FunctionTemplateDecl *> {
- /// The number of potential template candidates.
- unsigned NumTemplates;
-
- /// The number of template arguments.
- unsigned NumArgs;
-
- /// The locations of the left and right angle brackets.
- SourceRange AngleLocs;
-
- size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
- return NumArgs;
- }
- size_t numTrailingObjects(OverloadToken<FunctionTemplateDecl *>) const {
- return NumTemplates;
- }
-
- DependentFunctionTemplateSpecializationInfo(
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
-
-public:
- static DependentFunctionTemplateSpecializationInfo *
- Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
-
- /// \brief 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.
- 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.
- const TemplateArgumentLoc *getTemplateArgs() const {
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Returns the number of explicit template arguments that were given.
- unsigned getNumTemplateArgs() const { return NumArgs; }
-
- /// \brief Returns the nth template argument.
- const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
- assert(I < getNumTemplateArgs() && "template arg index out of range");
- return getTemplateArgs()[I];
- }
-
- SourceLocation getLAngleLoc() const {
- return AngleLocs.getBegin();
- }
-
- SourceLocation getRAngleLoc() const {
- return AngleLocs.getEnd();
- }
-
- friend TrailingObjects;
-};
-
-/// Declaration of a redeclarable template.
-class RedeclarableTemplateDecl : public TemplateDecl,
- public Redeclarable<RedeclarableTemplateDecl>
-{
- typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
- RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- RedeclarableTemplateDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-protected:
- template <typename EntryType> struct SpecEntryTraits {
- typedef EntryType DeclType;
-
- static DeclType *getDecl(EntryType *D) {
- return D;
- }
- static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) {
- return D->getTemplateArgs().asArray();
- }
- };
-
- template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
- typename DeclType = typename SETraits::DeclType>
- struct SpecIterator
- : llvm::iterator_adaptor_base<
- SpecIterator<EntryType, SETraits, DeclType>,
- typename llvm::FoldingSetVector<EntryType>::iterator,
- typename std::iterator_traits<typename llvm::FoldingSetVector<
- EntryType>::iterator>::iterator_category,
- DeclType *, ptrdiff_t, DeclType *, DeclType *> {
- SpecIterator() {}
- explicit SpecIterator(
- typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
- : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
-
- DeclType *operator*() const {
- return SETraits::getDecl(&*this->I)->getMostRecentDecl();
- }
- DeclType *operator->() const { return **this; }
- };
-
- template <typename EntryType>
- static SpecIterator<EntryType>
- makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
- return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
- }
-
- template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
- findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
- ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- template <class Derived, class EntryType>
- void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
- EntryType *Entry, void *InsertPos);
-
- struct CommonBase {
- CommonBase() : InstantiatedFromMember(nullptr, false) { }
-
- /// \brief The template from which this was most
- /// directly instantiated (or null).
- ///
- /// The boolean value indicates whether this template
- /// was explicitly specialized.
- llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
- InstantiatedFromMember;
- };
-
- /// \brief Pointer to the common data shared by all declarations of this
- /// template.
- mutable CommonBase *Common;
-
- /// \brief 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;
-
- virtual CommonBase *newCommon(ASTContext &C) const = 0;
-
- // Construct a template decl with name, parameters, and templated element.
- RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
- Common() {}
-
-public:
- template <class decl_type> friend class RedeclarableTemplate;
-
- /// \brief Retrieves the canonical declaration of this template.
- RedeclarableTemplateDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const RedeclarableTemplateDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- /// \brief Determines whether this template was a specialization of a
- /// member template.
- ///
- /// In the following example, the function template \c X<int>::f and the
- /// member template \c X<int>::Inner are member specializations.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> void f(T, U);
- /// template<typename U> struct Inner;
- /// };
- ///
- /// template<> template<typename T>
- /// void X<int>::f(int, T);
- /// template<> template<typename T>
- /// struct X<int>::Inner { /* ... */ };
- /// \endcode
- bool isMemberSpecialization() const {
- return getCommonPtr()->InstantiatedFromMember.getInt();
- }
-
- /// \brief 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
- /// instantiated, or NULL if this template was not instantiated from a
- /// member template.
- ///
- /// A template is instantiated from a member template when the member
- /// template itself is part of a class template (or member thereof). For
- /// example, given
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> void f(T, U);
- /// };
- ///
- /// void test(X<int> x) {
- /// x.f(1, 'a');
- /// };
- /// \endcode
- ///
- /// \c X<int>::f is a FunctionTemplateDecl that describes the function
- /// template
- ///
- /// \code
- /// template<typename U> void X<int>::f(int, U);
- /// \endcode
- ///
- /// which was itself created during the instantiation of \c X<int>. Calling
- /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
- /// retrieve the FunctionTemplateDecl for the original template \c f within
- /// the class template \c X<T>, i.e.,
- ///
- /// \code
- /// template<typename T>
- /// template<typename U>
- /// void X<T>::f(T, U);
- /// \endcode
- RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return getCommonPtr()->InstantiatedFromMember.getPointer();
- }
-
- void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
- assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
- getCommonPtr()->InstantiatedFromMember.setPointer(TD);
- }
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
- }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-template <> struct RedeclarableTemplateDecl::
-SpecEntryTraits<FunctionTemplateSpecializationInfo> {
- typedef FunctionDecl DeclType;
-
- static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) {
- return I->Function;
- }
- static ArrayRef<TemplateArgument>
- getTemplateArgs(FunctionTemplateSpecializationInfo *I) {
- return I->TemplateArguments->asArray();
- }
-};
-
-/// Declaration of a template function.
-class FunctionTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// function template.
- struct Common : CommonBase {
- Common() : InjectedArgs(), LazySpecializations() { }
-
- /// \brief 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
- /// function template.
- ///
- /// This pointer refers to the template arguments (there are as
- /// many template arguments as template parameaters) for the function
- /// template, and is allocated lazily, since most function templates do not
- /// require the use of this information.
- TemplateArgument *InjectedArgs;
-
- /// \brief If non-null, points to an array of specializations known only
- /// by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations
- /// that follow.
- uint32_t *LazySpecializations;
- };
-
- FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
- Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
- friend class FunctionDecl;
-
- /// \brief Retrieve the set of function template specializations of this
- /// function template.
- llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
- getSpecializations() const;
-
- /// \brief Add a specialization of this function template.
- ///
- /// \param InsertPos Insert position in the FoldingSetVector, must have been
- /// retrieved by an earlier call to findSpecialization().
- void addSpecialization(FunctionTemplateSpecializationInfo* Info,
- void *InsertPos);
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// Get the underlying function declaration of the template.
- FunctionDecl *getTemplatedDecl() const {
- return static_cast<FunctionDecl*>(TemplatedDecl);
- }
-
- /// Returns whether this template declaration defines the primary
- /// pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- /// \brief Return the specialization with the provided arguments if it exists,
- /// otherwise return the insertion point.
- FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
- void *&InsertPos);
-
- FunctionTemplateDecl *getCanonicalDecl() override {
- return cast<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const FunctionTemplateDecl *getCanonicalDecl() const {
- return cast<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- FunctionTemplateDecl *getPreviousDecl() {
- return cast_or_null<FunctionTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- const FunctionTemplateDecl *getPreviousDecl() const {
- return cast_or_null<FunctionTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- FunctionTemplateDecl *getMostRecentDecl() {
- return cast<FunctionTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)
- ->getMostRecentDecl());
- }
- const FunctionTemplateDecl *getMostRecentDecl() const {
- return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
- }
-
- FunctionTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- /// \brief 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
- /// arguments for a function template, the notion is convenient when
- /// we need to perform substitutions inside the definition of a function
- /// template.
- ArrayRef<TemplateArgument> getInjectedTemplateArgs();
-
- /// \brief 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.
- static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == FunctionTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-//===----------------------------------------------------------------------===//
-// Kinds of Template Parameters
-//===----------------------------------------------------------------------===//
-
-/// \brief Defines the position of a template parameter within a template
-/// parameter list.
-///
-/// Because template parameter can be listed
-/// sequentially for out-of-line template members, each template parameter is
-/// given a Depth - the nesting of template parameter scopes - and a Position -
-/// the occurrence within the parameter list.
-/// This class is inheritedly privately by different kinds of template
-/// parameters and is not part of the Decl hierarchy. Just a facility.
-class TemplateParmPosition {
- TemplateParmPosition() = delete;
-
-protected:
- TemplateParmPosition(unsigned D, unsigned P)
- : Depth(D), Position(P)
- { }
-
- // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
- // position? Maybe?
- unsigned Depth;
- unsigned Position;
-
-public:
- /// Get the nesting depth of the template parameter.
- unsigned getDepth() const { return Depth; }
- void setDepth(unsigned D) { Depth = D; }
-
- /// Get the position of the template parameter within its parameter list.
- unsigned getPosition() const { return Position; }
- void setPosition(unsigned P) { Position = P; }
-
- /// Get the index of the template parameter within its parameter list.
- unsigned getIndex() const { return Position; }
-};
-
-/// \brief Declaration of a template type parameter.
-///
-/// For example, "T" in
-/// \code
-/// template<typename T> class vector;
-/// \endcode
-class TemplateTypeParmDecl : public TypeDecl {
- /// \brief 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.
- typedef DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>
- DefArgStorage;
- DefArgStorage DefaultArgument;
-
- TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- bool Typename)
- : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
- DefaultArgument() { }
-
- /// Sema creates these on the stack during auto type deduction.
- friend class Sema;
-
-public:
- static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation KeyLoc,
- SourceLocation NameLoc,
- unsigned D, unsigned P,
- IdentifierInfo *Id, bool Typename,
- bool ParameterPack);
- static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
- unsigned ID);
-
- /// \brief Whether this template type parameter was declared with
- /// the 'typename' keyword.
- ///
- /// If not, it was declared with the 'class' keyword.
- bool wasDeclaredWithTypename() const { return Typename; }
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief Retrieve the default argument, if any.
- QualType getDefaultArgument() const {
- return DefaultArgument.get()->getType();
- }
-
- /// \brief Retrieves the default argument's source information, if any.
- TypeSourceInfo *getDefaultArgumentInfo() const {
- return DefaultArgument.get();
- }
-
- /// \brief Retrieves the location of the default argument declaration.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief 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.
- void setDefaultArgument(TypeSourceInfo *DefArg) {
- DefaultArgument.set(DefArg);
- }
- /// \brief 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.
- void removeDefaultArgument() {
- DefaultArgument.clear();
- }
-
- /// \brief 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.
- unsigned getDepth() const;
-
- /// \brief Retrieve the index of the template parameter.
- unsigned getIndex() const;
-
- /// \brief Returns whether this is a parameter pack.
- bool isParameterPack() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TemplateTypeParm; }
-};
-
-/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
-/// e.g., "Size" in
-/// @code
-/// template<int Size> class array { };
-/// @endcode
-class NonTypeTemplateParmDecl final
- : public DeclaratorDecl,
- protected TemplateParmPosition,
- private llvm::TrailingObjects<NonTypeTemplateParmDecl,
- std::pair<QualType, TypeSourceInfo *>> {
- /// \brief The default template argument, if any, and whether or not
- /// it was inherited.
- typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage;
- DefArgStorage DefaultArgument;
-
- // 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.
- bool ParameterPack;
-
- /// \brief 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;
-
- /// \brief The number of types in an expanded parameter pack.
- unsigned NumExpandedTypes;
-
- size_t numTrailingObjects(
- OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
- return NumExpandedTypes;
- }
-
- NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P,
- IdentifierInfo *Id, QualType T,
- bool ParameterPack, TypeSourceInfo *TInfo)
- : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), ParameterPack(ParameterPack),
- ExpandedParameterPack(false), NumExpandedTypes(0)
- { }
-
- NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P,
- IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo,
- const QualType *ExpandedTypes,
- unsigned NumExpandedTypes,
- TypeSourceInfo **ExpandedTInfos);
-
- friend class ASTDeclReader;
- friend TrailingObjects;
-
-public:
- static NonTypeTemplateParmDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
- QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
-
- static NonTypeTemplateParmDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo,
- const QualType *ExpandedTypes, unsigned NumExpandedTypes,
- TypeSourceInfo **ExpandedTInfos);
-
- static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
- static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID,
- unsigned NumExpandedTypes);
-
- using TemplateParmPosition::getDepth;
- using TemplateParmPosition::setDepth;
- using TemplateParmPosition::getPosition;
- using TemplateParmPosition::setPosition;
- using TemplateParmPosition::getIndex;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief Retrieve the default argument, if any.
- Expr *getDefaultArgument() const { return DefaultArgument.get(); }
-
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief 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
- /// whether that default argument was inherited from another
- /// declaration.
- void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
- void setInheritedDefaultArgument(const ASTContext &C,
- NonTypeTemplateParmDecl *Parm) {
- DefaultArgument.setInherited(C, Parm);
- }
-
- /// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() { DefaultArgument.clear(); }
-
- /// \brief 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
- /// is a parameter pack (whose type is 'unsigned').
- ///
- /// \code
- /// template<typename T, unsigned ...Dims> struct multi_array;
- /// \endcode
- bool isParameterPack() const { return ParameterPack; }
-
- /// \brief 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
- /// built a PackExpansionType wrapping the type.
- bool isPackExpansion() const {
- return ParameterPack && getType()->getAs<PackExpansionType>();
- }
-
- /// \brief 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
- /// parameter pack's type was itself a pack expansion, and that expansion
- /// has already been expanded. For example, given:
- ///
- /// \code
- /// template<typename ...Types>
- /// struct X {
- /// template<Types ...Values>
- /// struct Y { /* ... */ };
- /// };
- /// \endcode
- ///
- /// The parameter pack \c Values has a \c PackExpansionType as its type,
- /// which expands \c Types. When \c Types is supplied with template arguments
- /// by instantiating \c X, the instantiation of \c Values becomes an
- /// expanded parameter pack. For example, instantiating
- /// \c X<int, unsigned int> results in \c Values being an expanded parameter
- /// pack with expansion types \c int and \c unsigned int.
- ///
- /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
- /// return the expansion types.
- bool isExpandedParameterPack() const { return ExpandedParameterPack; }
-
- /// \brief 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
- /// pack.
- QualType getExpansionType(unsigned I) const {
- assert(I < NumExpandedTypes && "Out-of-range expansion type index");
- auto TypesAndInfos =
- getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
- return TypesAndInfos[I].first;
- }
-
- /// \brief 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");
- auto TypesAndInfos =
- getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
- return TypesAndInfos[I].second;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
-};
-
-/// TemplateTemplateParmDecl - Declares a template template parameter,
-/// e.g., "T" in
-/// @code
-/// template <template <typename> class T> class container { };
-/// @endcode
-/// A template template parameter is a TemplateDecl because it defines the
-/// name of a template and the template parameters allowable for substitution.
-class TemplateTemplateParmDecl final
- : public TemplateDecl,
- protected TemplateParmPosition,
- private llvm::TrailingObjects<TemplateTemplateParmDecl,
- TemplateParameterList *> {
- void anchor() override;
-
- /// \brief The default template argument, if any.
- typedef DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>
- DefArgStorage;
- DefArgStorage DefaultArgument;
-
- /// \brief Whether this parameter is a parameter pack.
- bool ParameterPack;
-
- /// \brief 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;
-
- /// \brief The number of parameters in an expanded parameter pack.
- unsigned NumExpandedParams;
-
- TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
- unsigned D, unsigned P, bool ParameterPack,
- IdentifierInfo *Id, TemplateParameterList *Params)
- : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), ParameterPack(ParameterPack),
- ExpandedParameterPack(false), NumExpandedParams(0)
- { }
-
- TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
- unsigned D, unsigned P,
- IdentifierInfo *Id, TemplateParameterList *Params,
- unsigned NumExpansions,
- TemplateParameterList * const *Expansions);
-
-public:
- static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D,
- unsigned P, bool ParameterPack,
- IdentifierInfo *Id,
- TemplateParameterList *Params);
- static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D,
- unsigned P,
- IdentifierInfo *Id,
- TemplateParameterList *Params,
- ArrayRef<TemplateParameterList *> Expansions);
-
- static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
- static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID,
- unsigned NumExpansions);
-
- using TemplateParmPosition::getDepth;
- using TemplateParmPosition::getPosition;
- using TemplateParmPosition::getIndex;
-
- /// \brief Whether this template template parameter is a template
- /// parameter pack.
- ///
- /// \code
- /// template<template <class T> ...MetaFunctions> struct Apply;
- /// \endcode
- bool isParameterPack() const { return ParameterPack; }
-
- /// \brief 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.
- bool isPackExpansion() const {
- return ParameterPack &&
- getTemplateParameters()->containsUnexpandedParameterPack();
- }
-
- /// \brief Whether this parameter is a template template parameter pack that
- /// has a known list of different template parameter lists at different
- /// positions.
- ///
- /// A parameter pack is an expanded parameter pack when the original parameter
- /// pack's template parameter list was itself a pack expansion, and that
- /// expansion has already been expanded. For exampe, given:
- ///
- /// \code
- /// template<typename...Types> struct Outer {
- /// template<template<Types> class...Templates> struct Inner;
- /// };
- /// \endcode
- ///
- /// The parameter pack \c Templates is a pack expansion, which expands the
- /// pack \c Types. When \c Types is supplied with template arguments by
- /// instantiating \c Outer, the instantiation of \c Templates is an expanded
- /// parameter pack.
- bool isExpandedParameterPack() const { return ExpandedParameterPack; }
-
- /// \brief 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
- /// pack.
- TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
- assert(I < NumExpandedParams && "Out-of-range expansion type index");
- return getTrailingObjects<TemplateParameterList *>()[I];
- }
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief 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.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief 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
- /// whether that default argument was inherited from another
- /// declaration.
- void setDefaultArgument(const ASTContext &C,
- const TemplateArgumentLoc &DefArg);
- void setInheritedDefaultArgument(const ASTContext &C,
- TemplateTemplateParmDecl *Prev) {
- DefaultArgument.setInherited(C, Prev);
- }
-
- /// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() { DefaultArgument.clear(); }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- SourceLocation End = getLocation();
- if (hasDefaultArgument() && !defaultArgumentWasInherited())
- End = getDefaultArgument().getSourceRange().getEnd();
- return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
-};
-
-/// \brief Represents the builtin template declaration which is used to
-/// implement __make_integer_seq. It serves no real purpose beyond existing as
-/// a place to hold template parameters.
-class BuiltinTemplateDecl : public TemplateDecl {
- void anchor() override;
-
- BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
- DeclarationName Name, BuiltinTemplateKind BTK);
-
- BuiltinTemplateKind BTK;
-
-public:
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == BuiltinTemplate; }
-
- static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
- DeclarationName Name,
- BuiltinTemplateKind BTK) {
- return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange();
- }
-
- BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
-};
-
-/// \brief Represents a class template specialization, which refers to
-/// a class template with a given set of template arguments.
-///
-/// Class template specializations represent both explicit
-/// specialization of class templates, as in the example below, and
-/// implicit instantiations of class templates.
-///
-/// \code
-/// template<typename T> class array;
-///
-/// template<>
-/// class array<bool> { }; // class template specialization array<bool>
-/// \endcode
-class ClassTemplateSpecializationDecl
- : public CXXRecordDecl, public llvm::FoldingSetNode {
-
- /// \brief 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
- /// class template specialization was instantiated.
- ClassTemplatePartialSpecializationDecl *PartialSpecialization;
-
- /// \brief The template argument list deduced for the class template
- /// partial specialization itself.
- const TemplateArgumentList *TemplateArgs;
- };
-
- /// \brief The template that this specialization specializes
- llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
- SpecializedTemplate;
-
- /// \brief Further info for explicit template specialization/instantiation.
- struct ExplicitSpecializationInfo {
- /// \brief The type-as-written.
- TypeSourceInfo *TypeAsWritten;
- /// \brief The location of the extern keyword.
- SourceLocation ExternLoc;
- /// \brief The location of the template keyword.
- SourceLocation TemplateKeywordLoc;
-
- ExplicitSpecializationInfo()
- : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
- };
-
- /// \brief Further info for explicit template specialization/instantiation.
- /// Does not apply to implicit specializations.
- ExplicitSpecializationInfo *ExplicitInfo;
-
- /// \brief The template arguments used to describe this specialization.
- const TemplateArgumentList *TemplateArgs;
-
- /// \brief The point where this template was instantiated (if any)
- SourceLocation PointOfInstantiation;
-
- /// \brief The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
- unsigned SpecializationKind : 3;
-
-protected:
- ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
- DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- ClassTemplateSpecializationDecl *PrevDecl);
-
- explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
-
-public:
- static ClassTemplateSpecializationDecl *
- Create(ASTContext &Context, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- ClassTemplateSpecializationDecl *PrevDecl);
- static ClassTemplateSpecializationDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
- bool Qualified) const override;
-
- // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
- // different "most recent" declaration from this function for the same
- // declaration, because we don't override getMostRecentDeclImpl(). But
- // it's not clear that we should override that, because the most recent
- // declaration as a CXXRecordDecl sometimes is the injected-class-name.
- ClassTemplateSpecializationDecl *getMostRecentDecl() {
- CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
- this)->getMostRecentDecl();
- 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);
- }
-
- /// \brief Retrieve the template that this specialization specializes.
- ClassTemplateDecl *getSpecializedTemplate() const;
-
- /// \brief Retrieve the template arguments of the class template
- /// specialization.
- const TemplateArgumentList &getTemplateArgs() const {
- return *TemplateArgs;
- }
-
- /// \brief Determine the kind of specialization that this
- /// declaration represents.
- TemplateSpecializationKind getSpecializationKind() const {
- return static_cast<TemplateSpecializationKind>(SpecializationKind);
- }
-
- bool isExplicitSpecialization() const {
- return getSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- void setSpecializationKind(TemplateSpecializationKind TSK) {
- SpecializationKind = TSK;
- }
-
- /// \brief Get the point of instantiation (if any), or null if none.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- void setPointOfInstantiation(SourceLocation Loc) {
- assert(Loc.isValid() && "point of instantiation must be valid!");
- PointOfInstantiation = Loc;
- }
-
- /// \brief 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.
- llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>
- getInstantiatedFrom() const {
- if (!isTemplateInstantiation(getSpecializationKind()))
- return llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>();
-
- return getSpecializedTemplateOrPartial();
- }
-
- /// \brief 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*>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<ClassTemplateDecl*>();
- }
-
- /// \brief 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.
- ///
- /// \returns For a class template specialization instantiated from the primary
- /// template, this function will return the same template arguments as
- /// getTemplateArgs(). For a class template specialization instantiated from
- /// a class template partial specialization, this function will return the
- /// deduced template arguments for the class template partial specialization
- /// itself.
- const TemplateArgumentList &getTemplateInstantiationArgs() const {
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
- return *PartialSpec->TemplateArgs;
-
- return getTemplateArgs();
- }
-
- /// \brief 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();
- PS->PartialSpecialization = PartialSpec;
- PS->TemplateArgs = TemplateArgs;
- SpecializedTemplate = PS;
- }
-
- /// \brief Note that this class template specialization is an instantiation
- /// of the given class template.
- void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
- "Previously set to a class template partial specialization!");
- SpecializedTemplate = TemplDecl;
- }
-
- /// \brief 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)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = T;
- }
- /// \brief Gets the type of this specialization as it was written by
- /// the user, if it was so written.
- TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
- }
-
- /// \brief 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.
- void setExternLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->ExternLoc = Loc;
- }
-
- /// \brief 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.
- SourceLocation getTemplateKeywordLoc() const {
- return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs->asArray(), getASTContext());
- }
-
- static void
- Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstClassTemplateSpecialization &&
- K <= lastClassTemplateSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class ClassTemplatePartialSpecializationDecl
- : public ClassTemplateSpecializationDecl {
- void anchor() override;
-
- /// \brief The list of template parameters
- TemplateParameterList* TemplateParams;
-
- /// \brief The source info for the template arguments as written.
- /// FIXME: redundant with TypeAsWritten?
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
-
- /// \brief 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
- /// partial specialization was specialized at this level.
- llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
- InstantiatedFromMember;
-
- ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
- DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc,
- TemplateParameterList *Params,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
-
- ClassTemplatePartialSpecializationDecl(ASTContext &C)
- : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
- TemplateParams(nullptr), ArgsAsWritten(nullptr),
- InstantiatedFromMember(nullptr, false) {}
-
-public:
- static ClassTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- TemplateParameterList *Params,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const TemplateArgumentListInfo &ArgInfos,
- QualType CanonInjectedType,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
-
- static ClassTemplatePartialSpecializationDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
- return cast<ClassTemplatePartialSpecializationDecl>(
- static_cast<ClassTemplateSpecializationDecl *>(
- this)->getMostRecentDecl());
- }
-
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the template arguments as written.
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return ArgsAsWritten;
- }
-
- /// \brief Retrieve the member class template partial specialization from
- /// which this particular class template partial specialization was
- /// instantiated.
- ///
- /// \code
- /// template<typename T>
- /// struct Outer {
- /// template<typename U> struct Inner;
- /// template<typename U> struct Inner<U*> { }; // #1
- /// };
- ///
- /// Outer<float>::Inner<int*> ii;
- /// \endcode
- ///
- /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
- /// end up instantiating the partial specialization
- /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
- /// template partial specialization \c Outer<T>::Inner<U*>. Given
- /// \c Outer<float>::Inner<U*>, this function would return
- /// \c Outer<T>::Inner<U*>.
- ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
- const ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getPointer();
- }
-
- void setInstantiatedFromMember(
- ClassTemplatePartialSpecializationDecl *PartialSpec) {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- First->InstantiatedFromMember.setPointer(PartialSpec);
- }
-
- /// \brief 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
- /// \c X<int>::Inner<T*> is a member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> struct Inner;
- /// template<typename U> struct Inner<U*>;
- /// };
- ///
- /// template<> template<typename T>
- /// struct X<int>::Inner<T*> { /* ... */ };
- /// \endcode
- bool isMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- assert(First->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- return First->InstantiatedFromMember.setInt(true);
- }
-
- /// Retrieves the injected specialization type for this partial
- /// specialization. This is not the same as the type-decl-type for
- /// this partial specialization, which is an InjectedClassNameType.
- QualType getInjectedSpecializationType() const {
- assert(getTypeForDecl() && "partial specialization has no type set!");
- return cast<InjectedClassNameType>(getTypeForDecl())
- ->getInjectedSpecializationType();
- }
-
- // FIXME: Add Profile support!
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == ClassTemplatePartialSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Declaration of a class template.
-class ClassTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// class template.
- struct Common : CommonBase {
- Common() : LazySpecializations() { }
-
- /// \brief 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
- /// template.
- llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
- PartialSpecializations;
-
- /// \brief The injected-class-name type for this class template.
- QualType InjectedClassNameType;
-
- /// \brief 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 of specializations/
- /// partial specializations that follow.
- uint32_t *LazySpecializations;
- };
-
- /// \brief Retrieve the set of specializations of this class template.
- llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
- getSpecializations() const;
-
- /// \brief Retrieve the set of partial specializations of this class
- /// template.
- llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
- getPartialSpecializations();
-
- ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// \brief 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
- /// class pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- /// \brief Create a class template node.
- static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl,
- ClassTemplateDecl *PrevDecl);
-
- /// \brief Create an empty class template node.
- static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief 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
- /// in. InsertPos must be obtained from findSpecialization.
- void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
-
- ClassTemplateDecl *getCanonicalDecl() override {
- return cast<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const ClassTemplateDecl *getCanonicalDecl() const {
- return cast<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
- ClassTemplateDecl *getPreviousDecl() {
- return cast_or_null<ClassTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
- const ClassTemplateDecl *getPreviousDecl() const {
- return cast_or_null<ClassTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- ClassTemplateDecl *getMostRecentDecl() {
- return cast<ClassTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
- }
- const ClassTemplateDecl *getMostRecentDecl() const {
- return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
- }
-
- ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- /// \brief 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
- /// already in. InsertPos must be obtained from findPartialSpecialization.
- void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
- void *InsertPos);
-
- /// \brief Retrieve the partial specializations as an ordered list.
- void getPartialSpecializations(
- SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
-
- /// \brief Find a class template partial specialization with the given
- /// type T.
- ///
- /// \param T a dependent type that names a specialization of this class
- /// template.
- ///
- /// \returns the class template partial specialization that exactly matches
- /// the type \p T, or NULL if no such partial specialization exists.
- ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
-
- /// \brief Find a class template partial specialization which was instantiated
- /// from the given member partial specialization.
- ///
- /// \param D a member class template partial specialization.
- ///
- /// \returns the class template partial specialization which was instantiated
- /// from the given member partial specialization, or NULL if no such partial
- /// specialization exists.
- ClassTemplatePartialSpecializationDecl *
- findPartialSpecInstantiatedFromMember(
- ClassTemplatePartialSpecializationDecl *D);
-
- /// \brief 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
- /// X<template-args>, where \c template-args is formed from the
- /// template arguments that correspond to the template parameters of
- /// \c X. For example:
- ///
- /// \code
- /// template<typename T, int N>
- /// struct array {
- /// typedef array this_type; // "array" is equivalent to "array<T, N>"
- /// };
- /// \endcode
- QualType getInjectedClassNameSpecialization();
-
- typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
-
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ClassTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Declaration of a friend template.
-///
-/// For example:
-/// \code
-/// template \<typename T> class A {
-/// friend class MyVector<T>; // not a friend template
-/// template \<typename U> friend class B; // not a friend template
-/// template \<typename U> friend class Foo<T>::Nested; // friend template
-/// };
-/// \endcode
-///
-/// \note This class is not currently in use. All of the above
-/// will yield a FriendDecl, not a FriendTemplateDecl.
-class FriendTemplateDecl : public Decl {
- virtual void anchor();
-public:
- typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
-
-private:
- // The number of template parameters; always non-zero.
- unsigned NumParams;
-
- // The parameter list.
- TemplateParameterList **Params;
-
- // The declaration that's a friend of this class.
- FriendUnion Friend;
-
- // Location of the 'friend' specifier.
- SourceLocation FriendLoc;
-
-
- FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
- unsigned NParams,
- TemplateParameterList **Params,
- FriendUnion Friend,
- SourceLocation FriendLoc)
- : Decl(Decl::FriendTemplate, DC, Loc),
- NumParams(NParams),
- Params(Params),
- Friend(Friend),
- FriendLoc(FriendLoc)
- {}
-
- FriendTemplateDecl(EmptyShell Empty)
- : Decl(Decl::FriendTemplate, Empty),
- NumParams(0),
- Params(nullptr)
- {}
-
-public:
- static FriendTemplateDecl *Create(ASTContext &Context,
- DeclContext *DC, SourceLocation Loc,
- unsigned NParams,
- TemplateParameterList **Params,
- FriendUnion Friend,
- SourceLocation FriendLoc);
-
- static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// If this friend declaration names a templated type (or
- /// a dependent member type of a templated type), return that
- /// type; otherwise return null.
- TypeSourceInfo *getFriendType() const {
- return Friend.dyn_cast<TypeSourceInfo*>();
- }
-
- /// If this friend declaration names a templated function (or
- /// a member function of a templated type), return that type;
- /// otherwise return null.
- NamedDecl *getFriendDecl() const {
- return Friend.dyn_cast<NamedDecl*>();
- }
-
- /// \brief Retrieves the location of the 'friend' keyword.
- SourceLocation getFriendLoc() const {
- return FriendLoc;
- }
-
- TemplateParameterList *getTemplateParameterList(unsigned i) const {
- assert(i <= NumParams);
- return Params[i];
- }
-
- unsigned getNumTemplateParameters() const {
- return NumParams;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
-
- friend class ASTDeclReader;
-};
-
-/// \brief Declaration of an alias template.
-///
-/// For example:
-/// \code
-/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
-/// \endcode
-class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- typedef CommonBase Common;
-
- TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
- Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// Get the underlying function declaration of the template.
- TypeAliasDecl *getTemplatedDecl() const {
- return static_cast<TypeAliasDecl*>(TemplatedDecl);
- }
-
-
- TypeAliasTemplateDecl *getCanonicalDecl() override {
- return cast<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const TypeAliasTemplateDecl *getCanonicalDecl() const {
- return cast<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- TypeAliasTemplateDecl *getPreviousDecl() {
- return cast_or_null<TypeAliasTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- const TypeAliasTemplateDecl *getPreviousDecl() const {
- return cast_or_null<TypeAliasTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
-
- /// \brief 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.
- static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Declaration of a function specialization at template class scope.
-///
-/// This is a non-standard extension needed to support MSVC.
-///
-/// For example:
-/// \code
-/// template <class T>
-/// class A {
-/// template <class U> void foo(U a) { }
-/// template<> void foo(int a) { }
-/// }
-/// \endcode
-///
-/// "template<> foo(int a)" will be saved in Specialization as a normal
-/// CXXMethodDecl. Then during an instantiation of class A, it will be
-/// transformed into an actual function specialization.
-class ClassScopeFunctionSpecializationDecl : public Decl {
- virtual void anchor();
-
- ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
- CXXMethodDecl *FD, bool Args,
- TemplateArgumentListInfo TemplArgs)
- : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
- Specialization(FD), HasExplicitTemplateArgs(Args),
- TemplateArgs(TemplArgs) {}
-
- ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
- : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
-
- CXXMethodDecl *Specialization;
- bool HasExplicitTemplateArgs;
- TemplateArgumentListInfo TemplateArgs;
-
-public:
- CXXMethodDecl *getSpecialization() const { return Specialization; }
- bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
- const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
-
- static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
- DeclContext *DC,
- SourceLocation Loc,
- CXXMethodDecl *FD,
- bool HasExplicitTemplateArgs,
- TemplateArgumentListInfo TemplateArgs) {
- return new (C, DC) ClassScopeFunctionSpecializationDecl(
- DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
- }
-
- static ClassScopeFunctionSpecializationDecl *
- CreateDeserialized(ASTContext &Context, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == Decl::ClassScopeFunctionSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Implementation of inline functions that require the template declarations
-inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
- : Function(FTD) { }
-
-/// \brief Represents a variable template specialization, which refers to
-/// a variable template with a given set of template arguments.
-///
-/// Variable template specializations represent both explicit
-/// specializations of variable templates, as in the example below, and
-/// implicit instantiations of variable templates.
-///
-/// \code
-/// template<typename T> constexpr T pi = T(3.1415926535897932385);
-///
-/// template<>
-/// constexpr float pi<float>; // variable template specialization pi<float>
-/// \endcode
-class VarTemplateSpecializationDecl : public VarDecl,
- public llvm::FoldingSetNode {
-
- /// \brief 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
- /// variable template specialization was instantiated.
- VarTemplatePartialSpecializationDecl *PartialSpecialization;
-
- /// \brief The template argument list deduced for the variable template
- /// partial specialization itself.
- const TemplateArgumentList *TemplateArgs;
- };
-
- /// \brief The template that this specialization specializes.
- llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
- SpecializedTemplate;
-
- /// \brief Further info for explicit template specialization/instantiation.
- struct ExplicitSpecializationInfo {
- /// \brief The type-as-written.
- TypeSourceInfo *TypeAsWritten;
- /// \brief The location of the extern keyword.
- SourceLocation ExternLoc;
- /// \brief The location of the template keyword.
- SourceLocation TemplateKeywordLoc;
-
- ExplicitSpecializationInfo()
- : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
- };
-
- /// \brief Further info for explicit template specialization/instantiation.
- /// Does not apply to implicit specializations.
- ExplicitSpecializationInfo *ExplicitInfo;
-
- /// \brief The template arguments used to describe this specialization.
- const TemplateArgumentList *TemplateArgs;
- TemplateArgumentListInfo TemplateArgsInfo;
-
- /// \brief The point where this template was instantiated (if any).
- SourceLocation PointOfInstantiation;
-
- /// \brief The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
- unsigned SpecializationKind : 3;
-
-protected:
- VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- VarTemplateDecl *SpecializedTemplate,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs);
-
- explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
-
-public:
- static VarTemplateSpecializationDecl *
- Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs);
- static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
- bool Qualified) const override;
-
- VarTemplateSpecializationDecl *getMostRecentDecl() {
- VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
- return cast<VarTemplateSpecializationDecl>(Recent);
- }
-
- /// \brief Retrieve the template that this specialization specializes.
- VarTemplateDecl *getSpecializedTemplate() const;
-
- /// \brief Retrieve the template arguments of the variable template
- /// specialization.
- const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
-
- // TODO: Always set this when creating the new specialization?
- void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
-
- const TemplateArgumentListInfo &getTemplateArgsInfo() const {
- return TemplateArgsInfo;
- }
-
- /// \brief Determine the kind of specialization that this
- /// declaration represents.
- TemplateSpecializationKind getSpecializationKind() const {
- return static_cast<TemplateSpecializationKind>(SpecializationKind);
- }
-
- bool isExplicitSpecialization() const {
- return getSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- void setSpecializationKind(TemplateSpecializationKind TSK) {
- SpecializationKind = TSK;
- }
-
- /// \brief Get the point of instantiation (if any), or null if none.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- void setPointOfInstantiation(SourceLocation Loc) {
- assert(Loc.isValid() && "point of instantiation must be valid!");
- PointOfInstantiation = Loc;
- }
-
- /// \brief 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.
- llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
- getInstantiatedFrom() const {
- if (getSpecializationKind() != TSK_ImplicitInstantiation &&
- getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
- getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
- return llvm::PointerUnion<VarTemplateDecl *,
- VarTemplatePartialSpecializationDecl *>();
-
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<VarTemplateDecl *>();
- }
-
- /// \brief Retrieve the variable template or variable template partial
- /// specialization which was specialized by this.
- llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
- getSpecializedTemplateOrPartial() const {
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<VarTemplateDecl *>();
- }
-
- /// \brief 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.
- ///
- /// \returns For a variable template specialization instantiated from the
- /// primary template, this function will return the same template arguments
- /// as getTemplateArgs(). For a variable template specialization instantiated
- /// from a variable template partial specialization, this function will the
- /// return deduced template arguments for the variable template partial
- /// specialization itself.
- const TemplateArgumentList &getTemplateInstantiationArgs() const {
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return *PartialSpec->TemplateArgs;
-
- return getTemplateArgs();
- }
-
- /// \brief 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();
- PS->PartialSpecialization = PartialSpec;
- PS->TemplateArgs = TemplateArgs;
- SpecializedTemplate = PS;
- }
-
- /// \brief Note that this variable template specialization is an instantiation
- /// of the given variable template.
- void setInstantiationOf(VarTemplateDecl *TemplDecl) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
- "Previously set to a variable template partial specialization!");
- SpecializedTemplate = TemplDecl;
- }
-
- /// \brief Sets the type of this specialization as it was written by
- /// the user.
- void setTypeAsWritten(TypeSourceInfo *T) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = T;
- }
- /// \brief Gets the type of this specialization as it was written by
- /// the user, if it was so written.
- TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
- }
-
- /// \brief 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.
- void setExternLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->ExternLoc = Loc;
- }
-
- /// \brief 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.
- SourceLocation getTemplateKeywordLoc() const {
- return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs->asArray(), getASTContext());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstVarTemplateSpecialization &&
- K <= lastVarTemplateSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class VarTemplatePartialSpecializationDecl
- : public VarTemplateSpecializationDecl {
- void anchor() override;
-
- /// \brief The list of template parameters
- TemplateParameterList *TemplateParams;
-
- /// \brief The source info for the template arguments as written.
- /// FIXME: redundant with TypeAsWritten?
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
-
- /// \brief 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
- /// partial specialization was specialized at this level.
- llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
- InstantiatedFromMember;
-
- VarTemplatePartialSpecializationDecl(
- ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, TemplateParameterList *Params,
- VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
- const ASTTemplateArgumentListInfo *ArgInfos);
-
- VarTemplatePartialSpecializationDecl(ASTContext &Context)
- : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
- TemplateParams(nullptr), ArgsAsWritten(nullptr),
- InstantiatedFromMember(nullptr, false) {}
-
-public:
- static VarTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, TemplateParameterList *Params,
- VarTemplateDecl *SpecializedTemplate, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
-
- static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
- return cast<VarTemplatePartialSpecializationDecl>(
- static_cast<VarTemplateSpecializationDecl *>(
- this)->getMostRecentDecl());
- }
-
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the template arguments as written.
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return ArgsAsWritten;
- }
-
- /// \brief Retrieve the member variable template partial specialization from
- /// which this particular variable template partial specialization was
- /// instantiated.
- ///
- /// \code
- /// template<typename T>
- /// struct Outer {
- /// template<typename U> U Inner;
- /// template<typename U> U* Inner<U*> = (U*)(0); // #1
- /// };
- ///
- /// template int* Outer<float>::Inner<int*>;
- /// \endcode
- ///
- /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
- /// end up instantiating the partial specialization
- /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
- /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
- /// \c Outer<float>::Inner<U*>, this function would return
- /// \c Outer<T>::Inner<U*>.
- VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
- const VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getPointer();
- }
-
- void
- setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- First->InstantiatedFromMember.setPointer(PartialSpec);
- }
-
- /// \brief Determines whether this variable template partial specialization
- /// was a specialization of a member partial specialization.
- ///
- /// In the following example, the member template partial specialization
- /// \c X<int>::Inner<T*> is a member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> U Inner;
- /// template<typename U> U* Inner<U*> = (U*)(0);
- /// };
- ///
- /// template<> template<typename T>
- /// U* X<int>::Inner<T*> = (T*)(0) + 1;
- /// \endcode
- bool isMemberSpecialization() {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- assert(First->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- return First->InstantiatedFromMember.setInt(true);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == VarTemplatePartialSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Declaration of a variable template.
-class VarTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// variable template.
- struct Common : CommonBase {
- Common() : LazySpecializations() {}
-
- /// \brief 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
- /// template.
- llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
- PartialSpecializations;
-
- /// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known ownly by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations/
- /// partial specializations that follow.
- uint32_t *LazySpecializations;
- };
-
- /// \brief Retrieve the set of specializations of this variable template.
- llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
- getSpecializations() const;
-
- /// \brief Retrieve the set of partial specializations of this class
- /// template.
- llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
- getPartialSpecializations();
-
- VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// \brief 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
- /// variable pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- VarTemplateDecl *getDefinition();
-
- /// \brief 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.
- static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief 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
- /// in. InsertPos must be obtained from findSpecialization.
- void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
-
- VarTemplateDecl *getCanonicalDecl() override {
- return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const VarTemplateDecl *getCanonicalDecl() const {
- return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this variable template, or
- /// NULL if no such declaration exists.
- VarTemplateDecl *getPreviousDecl() {
- return cast_or_null<VarTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this variable template, or
- /// NULL if no such declaration exists.
- const VarTemplateDecl *getPreviousDecl() const {
- return cast_or_null<VarTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- VarTemplateDecl *getMostRecentDecl() {
- return cast<VarTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
- }
- const VarTemplateDecl *getMostRecentDecl() const {
- return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
- }
-
- VarTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<VarTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- /// \brief 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
- /// already in. InsertPos must be obtained from findPartialSpecialization.
- void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
- void *InsertPos);
-
- /// \brief Retrieve the partial specializations as an ordered list.
- void getPartialSpecializations(
- SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
-
- /// \brief Find a variable template partial specialization which was
- /// instantiated
- /// from the given member partial specialization.
- ///
- /// \param D a member variable template partial specialization.
- ///
- /// \returns the variable template partial specialization which was
- /// instantiated
- /// from the given member partial specialization, or NULL if no such partial
- /// specialization exists.
- VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
- VarTemplatePartialSpecializationDecl *D);
-
- typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
-
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == VarTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-} /* end of namespace clang */
-
-#endif
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
deleted file mode 100644
index 4eaae35..0000000
--- a/include/clang/AST/DeclVisitor.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===--- DeclVisitor.h - Visitor for Decl subclasses ------------*- 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 DeclVisitor interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DECLVISITOR_H
-#define LLVM_CLANG_AST_DECLVISITOR_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclTemplate.h"
-
-namespace clang {
-namespace declvisitor {
-
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
-
-/// \brief A simple visitor class that helps create declaration visitors.
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
-class Base {
-public:
-
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
-
- RetTy Visit(PTR(Decl) D) {
- switch (D->getKind()) {
-#define DECL(DERIVED, BASE) \
- case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl);
-#define ABSTRACT_DECL(DECL)
-#include "clang/AST/DeclNodes.inc"
- }
- llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
- }
-
- // If the implementation chooses not to implement a certain visit
- // method, fall back to the parent.
-#define DECL(DERIVED, BASE) \
- RetTy Visit##DERIVED##Decl(PTR(DERIVED##Decl) D) { DISPATCH(BASE, BASE); }
-#include "clang/AST/DeclNodes.inc"
-
- RetTy VisitDecl(PTR(Decl) D) { return RetTy(); }
-
-#undef PTR
-#undef DISPATCH
-};
-
-} // end namespace declvisitor
-
-/// \brief A simple visitor class that helps create declaration visitors.
-///
-/// This class does not preserve constness of Decl pointers (see also
-/// ConstDeclVisitor).
-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.
-///
-/// This class preserves constness of Decl pointers (see also DeclVisitor).
-template<typename ImplClass, typename RetTy=void>
-class ConstDeclVisitor
- : public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_DECLVISITOR_H
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
deleted file mode 100644
index 9482e83e..0000000
--- a/include/clang/AST/DeclarationName.h
+++ /dev/null
@@ -1,598 +0,0 @@
-//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the DeclarationName and DeclarationNameTable classes.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
-#define LLVM_CLANG_AST_DECLARATIONNAME_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm {
- template <typename T> struct DenseMapInfo;
-}
-
-namespace clang {
- class ASTContext;
- class CXXLiteralOperatorIdName;
- class CXXOperatorIdName;
- class CXXSpecialName;
- class DeclarationNameExtra;
- class IdentifierInfo;
- class MultiKeywordSelector;
- enum OverloadedOperatorKind : int;
- class QualType;
- class Type;
- class TypeSourceInfo;
- class UsingDirectiveDecl;
-
- template <typename> class CanQual;
- typedef CanQual<Type> CanQualType;
-
-/// DeclarationName - The name of a declaration. In the common case,
-/// this just stores an IdentifierInfo pointer to a normal
-/// name. However, it also provides encodings for Objective-C
-/// selectors (optimizing zero- and one-argument selectors, which make
-/// up 78% percent of all selectors in Cocoa.h) and special C++ names
-/// for constructors, destructors, and conversion functions.
-class DeclarationName {
-public:
- /// NameKind - The kind of name this object contains.
- enum NameKind {
- Identifier,
- ObjCZeroArgSelector,
- ObjCOneArgSelector,
- ObjCMultiArgSelector,
- CXXConstructorName,
- CXXDestructorName,
- CXXConversionFunctionName,
- CXXOperatorName,
- CXXLiteralOperatorName,
- CXXUsingDirective
- };
- static const unsigned NumNameKinds = CXXUsingDirective + 1;
-
-private:
- /// StoredNameKind - The kind of name that is actually stored in the
- /// upper bits of the Ptr field. This is only used internally.
- ///
- /// Note: The entries here are synchronized with the entries in Selector,
- /// for efficient translation between the two.
- enum StoredNameKind {
- StoredIdentifier = 0,
- StoredObjCZeroArgSelector = 0x01,
- StoredObjCOneArgSelector = 0x02,
- StoredDeclarationNameExtra = 0x03,
- PtrMask = 0x03
- };
-
- /// Ptr - The lowest two bits are used to express what kind of name
- /// we're actually storing, using the values of NameKind. Depending
- /// on the kind of name this is, the upper bits of Ptr may have one
- /// of several different meanings:
- ///
- /// StoredIdentifier - The name is a normal identifier, and Ptr is
- /// a normal IdentifierInfo pointer.
- ///
- /// StoredObjCZeroArgSelector - The name is an Objective-C
- /// selector with zero arguments, and Ptr is an IdentifierInfo
- /// pointer pointing to the selector name.
- ///
- /// StoredObjCOneArgSelector - The name is an Objective-C selector
- /// with one argument, and Ptr is an IdentifierInfo pointer
- /// pointing to the selector name.
- ///
- /// StoredDeclarationNameExtra - Ptr is actually a pointer to a
- /// DeclarationNameExtra structure, whose first value will tell us
- /// whether this is an Objective-C selector, C++ operator-id name,
- /// or special C++ name.
- uintptr_t Ptr;
-
- /// getStoredNameKind - Return the kind of object that is stored in
- /// Ptr.
- StoredNameKind getStoredNameKind() const {
- return static_cast<StoredNameKind>(Ptr & PtrMask);
- }
-
- /// getExtra - Get the "extra" information associated with this
- /// multi-argument selector or C++ special name.
- DeclarationNameExtra *getExtra() const {
- assert(getStoredNameKind() == StoredDeclarationNameExtra &&
- "Declaration name does not store an Extra structure");
- return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
- }
-
- /// getAsCXXSpecialName - If the stored pointer is actually a
- /// CXXSpecialName, returns a pointer to it. Otherwise, returns
- /// a NULL pointer.
- CXXSpecialName *getAsCXXSpecialName() const {
- NameKind Kind = getNameKind();
- if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
- return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
- return nullptr;
- }
-
- /// getAsCXXOperatorIdName
- CXXOperatorIdName *getAsCXXOperatorIdName() const {
- if (getNameKind() == CXXOperatorName)
- return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
- return nullptr;
- }
-
- CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
- if (getNameKind() == CXXLiteralOperatorName)
- return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
- return nullptr;
- }
-
- // Construct a declaration name from the name of a C++ constructor,
- // destructor, or conversion function.
- DeclarationName(CXXSpecialName *Name)
- : Ptr(reinterpret_cast<uintptr_t>(Name)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
- Ptr |= StoredDeclarationNameExtra;
- }
-
- // Construct a declaration name from the name of a C++ overloaded
- // operator.
- DeclarationName(CXXOperatorIdName *Name)
- : Ptr(reinterpret_cast<uintptr_t>(Name)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
- Ptr |= StoredDeclarationNameExtra;
- }
-
- DeclarationName(CXXLiteralOperatorIdName *Name)
- : Ptr(reinterpret_cast<uintptr_t>(Name)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
- Ptr |= StoredDeclarationNameExtra;
- }
-
- /// Construct a declaration name from a raw pointer.
- DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
-
- friend class DeclarationNameTable;
- friend class NamedDecl;
-
- /// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
- /// for this name as a void pointer if it's not an identifier.
- void *getFETokenInfoAsVoidSlow() const;
-
-public:
- /// DeclarationName - Used to create an empty selector.
- DeclarationName() : Ptr(0) { }
-
- // Construct a declaration name from an IdentifierInfo *.
- DeclarationName(const IdentifierInfo *II)
- : Ptr(reinterpret_cast<uintptr_t>(II)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
- }
-
- // Construct a declaration name from an Objective-C selector.
- DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { }
-
- /// getUsingDirectiveName - Return name for all using-directives.
- static DeclarationName getUsingDirectiveName();
-
- // operator bool() - Evaluates true when this declaration name is
- // non-empty.
- explicit operator bool() const {
- return ((Ptr & PtrMask) != 0) ||
- (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
- }
-
- /// \brief Evaluates true when this declaration name is empty.
- bool isEmpty() const {
- return !*this;
- }
-
- /// Predicate functions for querying what type of name this is.
- bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
- bool isObjCZeroArgSelector() const {
- return getStoredNameKind() == StoredObjCZeroArgSelector;
- }
- bool isObjCOneArgSelector() const {
- return getStoredNameKind() == StoredObjCOneArgSelector;
- }
-
- /// getNameKind - Determine what kind of name this is.
- NameKind getNameKind() const;
-
- /// \brief 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",
- /// because an identifier can be a dependent name if it is used as the
- /// callee in a call expression with dependent arguments.
- bool isDependentName() const;
-
- /// getNameAsString - Retrieve the human-readable string for this name.
- std::string getAsString() const;
-
- /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
- /// this declaration name, or NULL if this declaration name isn't a
- /// simple identifier.
- IdentifierInfo *getAsIdentifierInfo() const {
- if (isIdentifier())
- return reinterpret_cast<IdentifierInfo *>(Ptr);
- return nullptr;
- }
-
- /// getAsOpaqueInteger - Get the representation of this declaration
- /// name as an opaque integer.
- uintptr_t getAsOpaqueInteger() const { return Ptr; }
-
- /// getAsOpaquePtr - Get the representation of this declaration name as
- /// an opaque pointer.
- void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
-
- static DeclarationName getFromOpaquePtr(void *P) {
- DeclarationName N;
- N.Ptr = reinterpret_cast<uintptr_t> (P);
- return N;
- }
-
- static DeclarationName getFromOpaqueInteger(uintptr_t P) {
- DeclarationName N;
- N.Ptr = P;
- return N;
- }
-
- /// getCXXNameType - If this name is one of the C++ names (of a
- /// constructor, destructor, or conversion function), return the
- /// type associated with that name.
- QualType getCXXNameType() const;
-
- /// getCXXOverloadedOperator - If this name is the name of an
- /// overloadable operator in C++ (e.g., @c operator+), retrieve the
- /// kind of overloaded operator.
- OverloadedOperatorKind getCXXOverloadedOperator() const;
-
- /// getCXXLiteralIdentifier - If this name is the name of a literal
- /// operator, retrieve the identifier associated with it.
- IdentifierInfo *getCXXLiteralIdentifier() const;
-
- /// getObjCSelector - Get the Objective-C selector stored in this
- /// declaration name.
- Selector getObjCSelector() const {
- assert((getNameKind() == ObjCZeroArgSelector ||
- getNameKind() == ObjCOneArgSelector ||
- getNameKind() == ObjCMultiArgSelector ||
- Ptr == 0) && "Not a selector!");
- return Selector(Ptr);
- }
-
- /// getFETokenInfo/setFETokenInfo - The language front-end is
- /// allowed to associate arbitrary metadata with some kinds of
- /// declaration names, including normal identifiers and C++
- /// constructors, destructors, and conversion functions.
- template<typename T>
- T *getFETokenInfo() const {
- if (const IdentifierInfo *Info = getAsIdentifierInfo())
- return Info->getFETokenInfo<T>();
- return static_cast<T*>(getFETokenInfoAsVoidSlow());
- }
-
- void setFETokenInfo(void *T);
-
- /// operator== - Determine whether the specified names are identical..
- friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
- return LHS.Ptr == RHS.Ptr;
- }
-
- /// operator!= - Determine whether the specified names are different.
- friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
- return LHS.Ptr != RHS.Ptr;
- }
-
- static DeclarationName getEmptyMarker() {
- return DeclarationName(uintptr_t(-1));
- }
-
- static DeclarationName getTombstoneMarker() {
- return DeclarationName(uintptr_t(-2));
- }
-
- static int compare(DeclarationName LHS, DeclarationName RHS);
-
- void dump() const;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, DeclarationName N);
-
-/// Ordering on two declaration names. If both names are identifiers,
-/// this provides a lexicographical ordering.
-inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
- return DeclarationName::compare(LHS, RHS) < 0;
-}
-
-/// Ordering on two declaration names. If both names are identifiers,
-/// this provides a lexicographical ordering.
-inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
- return DeclarationName::compare(LHS, RHS) > 0;
-}
-
-/// Ordering on two declaration names. If both names are identifiers,
-/// this provides a lexicographical ordering.
-inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
- return DeclarationName::compare(LHS, RHS) <= 0;
-}
-
-/// Ordering on two declaration names. If both names are identifiers,
-/// this provides a lexicographical ordering.
-inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
- return DeclarationName::compare(LHS, RHS) >= 0;
-}
-
-/// DeclarationNameTable - Used to store and retrieve DeclarationName
-/// instances for the various kinds of declaration names, e.g., normal
-/// identifiers, C++ constructor names, etc. This class contains
-/// uniqued versions of each of the C++ special names, which can be
-/// retrieved using its member functions (e.g.,
-/// getCXXConstructorName).
-class DeclarationNameTable {
- const ASTContext &Ctx;
- void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
- CXXOperatorIdName *CXXOperatorNames; // Operator names
- void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
-
- DeclarationNameTable(const DeclarationNameTable&) = delete;
- void operator=(const DeclarationNameTable&) = delete;
-
-public:
- DeclarationNameTable(const ASTContext &C);
- ~DeclarationNameTable();
-
- /// getIdentifier - Create a declaration name that is a simple
- /// identifier.
- DeclarationName getIdentifier(const IdentifierInfo *ID) {
- return DeclarationName(ID);
- }
-
- /// getCXXConstructorName - Returns the name of a C++ constructor
- /// for the given Type.
- DeclarationName getCXXConstructorName(CanQualType Ty);
-
- /// getCXXDestructorName - Returns the name of a C++ destructor
- /// for the given Type.
- DeclarationName getCXXDestructorName(CanQualType Ty);
-
- /// getCXXConversionFunctionName - Returns the name of a C++
- /// conversion function for the given Type.
- DeclarationName getCXXConversionFunctionName(CanQualType Ty);
-
- /// getCXXSpecialName - Returns a declaration name for special kind
- /// of C++ name, e.g., for a constructor, destructor, or conversion
- /// function.
- DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
- CanQualType Ty);
-
- /// getCXXOperatorName - Get the name of the overloadable C++
- /// operator corresponding to Op.
- DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
-
- /// getCXXLiteralOperatorName - Get the name of the literal operator function
- /// with II as the identifier.
- DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
-};
-
-/// DeclarationNameLoc - Additional source/type location info
-/// for a declaration name. Needs a DeclarationName in order
-/// to be interpreted correctly.
-struct DeclarationNameLoc {
- // The source location for identifier stored elsewhere.
- // struct {} Identifier;
-
- // Type info for constructors, destructors and conversion functions.
- // Locations (if any) for the tilde (destructor) or operator keyword
- // (conversion) are stored elsewhere.
- struct NT {
- TypeSourceInfo *TInfo;
- };
-
- // The location (if any) of the operator keyword is stored elsewhere.
- struct CXXOpName {
- unsigned BeginOpNameLoc;
- unsigned EndOpNameLoc;
- };
-
- // The location (if any) of the operator keyword is stored elsewhere.
- struct CXXLitOpName {
- unsigned OpNameLoc;
- };
-
- // struct {} CXXUsingDirective;
- // struct {} ObjCZeroArgSelector;
- // struct {} ObjCOneArgSelector;
- // struct {} ObjCMultiArgSelector;
- union {
- struct NT NamedType;
- struct CXXOpName CXXOperatorName;
- struct CXXLitOpName CXXLiteralOperatorName;
- };
-
- DeclarationNameLoc(DeclarationName Name);
- // FIXME: this should go away once all DNLocs are properly initialized.
- DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
-}; // struct DeclarationNameLoc
-
-
-/// DeclarationNameInfo - A collector data type for bundling together
-/// a DeclarationName and the correspnding source/type location info.
-struct DeclarationNameInfo {
-private:
- /// Name - The declaration name, also encoding name kind.
- DeclarationName Name;
- /// Loc - The main source location for the declaration name.
- SourceLocation NameLoc;
- /// Info - Further source/type location info for special kinds of names.
- DeclarationNameLoc LocInfo;
-
-public:
- // FIXME: remove it.
- DeclarationNameInfo() {}
-
- DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
- : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
-
- DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
- DeclarationNameLoc LocInfo)
- : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
-
- /// getName - Returns the embedded declaration name.
- DeclarationName getName() const { return Name; }
- /// setName - Sets the embedded declaration name.
- void setName(DeclarationName N) { Name = N; }
-
- /// getLoc - Returns the main location of the declaration name.
- SourceLocation getLoc() const { return NameLoc; }
- /// setLoc - Sets the main location of the declaration name.
- void setLoc(SourceLocation L) { NameLoc = L; }
-
- const DeclarationNameLoc &getInfo() const { return LocInfo; }
- DeclarationNameLoc &getInfo() { return LocInfo; }
- void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
-
- /// getNamedTypeInfo - Returns the source type info associated to
- /// the name. Assumes it is a constructor, destructor or conversion.
- TypeSourceInfo *getNamedTypeInfo() const {
- assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXDestructorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
- return LocInfo.NamedType.TInfo;
- }
- /// setNamedTypeInfo - Sets the source type info associated to
- /// the name. Assumes it is a constructor, destructor or conversion.
- void setNamedTypeInfo(TypeSourceInfo *TInfo) {
- assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXDestructorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
- LocInfo.NamedType.TInfo = TInfo;
- }
-
- /// getCXXOperatorNameRange - Gets the range of the operator name
- /// (without the operator keyword). Assumes it is a (non-literal) operator.
- SourceRange getCXXOperatorNameRange() const {
- assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
- return SourceRange(
- SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
- SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
- );
- }
- /// setCXXOperatorNameRange - Sets the range of the operator name
- /// (without the operator keyword). Assumes it is a C++ operator.
- void setCXXOperatorNameRange(SourceRange R) {
- assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
- LocInfo.CXXOperatorName.BeginOpNameLoc = R.getBegin().getRawEncoding();
- LocInfo.CXXOperatorName.EndOpNameLoc = R.getEnd().getRawEncoding();
- }
-
- /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
- /// operator name (not the operator keyword).
- /// Assumes it is a literal operator.
- SourceLocation getCXXLiteralOperatorNameLoc() const {
- assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
- return SourceLocation::
- getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
- }
- /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
- /// operator name (not the operator keyword).
- /// Assumes it is a literal operator.
- void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
- assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
- LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
- }
-
- /// \brief Determine whether this name involves a template parameter.
- bool isInstantiationDependent() const;
-
- /// \brief Determine whether this name contains an unexpanded
- /// parameter pack.
- bool containsUnexpandedParameterPack() const;
-
- /// getAsString - Retrieve the human-readable string for this name.
- std::string getAsString() const;
-
- /// printName - Print the human-readable name to a stream.
- void printName(raw_ostream &OS) const;
-
- /// getBeginLoc - Retrieve the location of the first token.
- SourceLocation getBeginLoc() const { return NameLoc; }
- /// getEndLoc - Retrieve the location of the last token.
- SourceLocation getEndLoc() const;
- /// getSourceRange - The range of the declaration name.
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
- }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBeginLoc();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- SourceLocation EndLoc = getEndLoc();
- return EndLoc.isValid() ? EndLoc : getLocStart();
- }
-};
-
-/// Insertion operator for diagnostics. This allows sending DeclarationName's
-/// into a diagnostic with <<.
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- DeclarationName N) {
- DB.AddTaggedVal(N.getAsOpaqueInteger(),
- DiagnosticsEngine::ak_declarationname);
- return DB;
-}
-
-/// Insertion operator for partial diagnostics. This allows binding
-/// DeclarationName's into a partial diagnostic with <<.
-inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- DeclarationName N) {
- PD.AddTaggedVal(N.getAsOpaqueInteger(),
- DiagnosticsEngine::ak_declarationname);
- return PD;
-}
-
-inline raw_ostream &operator<<(raw_ostream &OS,
- DeclarationNameInfo DNInfo) {
- DNInfo.printName(OS);
- return OS;
-}
-
-} // end namespace clang
-
-namespace llvm {
-/// Define DenseMapInfo so that DeclarationNames can be used as keys
-/// in DenseMap and DenseSets.
-template<>
-struct DenseMapInfo<clang::DeclarationName> {
- static inline clang::DeclarationName getEmptyKey() {
- return clang::DeclarationName::getEmptyMarker();
- }
-
- static inline clang::DeclarationName getTombstoneKey() {
- return clang::DeclarationName::getTombstoneMarker();
- }
-
- static unsigned getHashValue(clang::DeclarationName Name) {
- return DenseMapInfo<void*>::getHashValue(Name.getAsOpaquePtr());
- }
-
- static inline bool
- isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
- return LHS == RHS;
- }
-};
-
-template <>
-struct isPodLike<clang::DeclarationName> { static const bool value = true; };
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
deleted file mode 100644
index 8e038c8..0000000
--- a/include/clang/AST/DependentDiagnostic.h
+++ /dev/null
@@ -1,189 +0,0 @@
-//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- 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 interfaces for diagnostics which may or may
-// fire based on how a template is instantiated.
-//
-// At the moment, the only consumer of this interface is access
-// control.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
-#define LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
-
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclContextInternals.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-class ASTContext;
-class CXXRecordDecl;
-class NamedDecl;
-
-/// A dependently-generated diagnostic.
-class DependentDiagnostic {
-public:
- enum AccessNonce { Access = 0 };
-
- static DependentDiagnostic *Create(ASTContext &Context,
- DeclContext *Parent,
- AccessNonce _,
- SourceLocation Loc,
- bool IsMemberAccess,
- AccessSpecifier AS,
- NamedDecl *TargetDecl,
- CXXRecordDecl *NamingClass,
- QualType BaseObjectType,
- const PartialDiagnostic &PDiag) {
- DependentDiagnostic *DD = Create(Context, Parent, PDiag);
- DD->AccessData.Loc = Loc.getRawEncoding();
- DD->AccessData.IsMember = IsMemberAccess;
- DD->AccessData.Access = AS;
- DD->AccessData.TargetDecl = TargetDecl;
- DD->AccessData.NamingClass = NamingClass;
- DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
- return DD;
- }
-
- unsigned getKind() const {
- return Access;
- }
-
- bool isAccessToMember() const {
- assert(getKind() == Access);
- return AccessData.IsMember;
- }
-
- AccessSpecifier getAccess() const {
- assert(getKind() == Access);
- return AccessSpecifier(AccessData.Access);
- }
-
- SourceLocation getAccessLoc() const {
- assert(getKind() == Access);
- return SourceLocation::getFromRawEncoding(AccessData.Loc);
- }
-
- NamedDecl *getAccessTarget() const {
- assert(getKind() == Access);
- return AccessData.TargetDecl;
- }
-
- NamedDecl *getAccessNamingClass() const {
- assert(getKind() == Access);
- return AccessData.NamingClass;
- }
-
- QualType getAccessBaseObjectType() const {
- assert(getKind() == Access);
- return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
- }
-
- const PartialDiagnostic &getDiagnostic() const {
- return Diag;
- }
-
-private:
- DependentDiagnostic(const PartialDiagnostic &PDiag,
- PartialDiagnostic::Storage *Storage)
- : Diag(PDiag, Storage) {}
-
- static DependentDiagnostic *Create(ASTContext &Context,
- DeclContext *Parent,
- const PartialDiagnostic &PDiag);
-
- friend class DependentStoredDeclsMap;
- friend class DeclContext::ddiag_iterator;
- DependentDiagnostic *NextDiagnostic;
-
- PartialDiagnostic Diag;
-
- struct {
- unsigned Loc;
- unsigned Access : 2;
- unsigned IsMember : 1;
- NamedDecl *TargetDecl;
- CXXRecordDecl *NamingClass;
- void *BaseObjectType;
- } AccessData;
-};
-
-///
-
-/// An iterator over the dependent diagnostics in a dependent context.
-class DeclContext::ddiag_iterator {
-public:
- ddiag_iterator() : Ptr(nullptr) {}
- explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
-
- typedef DependentDiagnostic *value_type;
- typedef DependentDiagnostic *reference;
- typedef DependentDiagnostic *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- reference operator*() const { return Ptr; }
-
- ddiag_iterator &operator++() {
- assert(Ptr && "attempt to increment past end of diag list");
- Ptr = Ptr->NextDiagnostic;
- return *this;
- }
-
- ddiag_iterator operator++(int) {
- ddiag_iterator tmp = *this;
- ++*this;
- return tmp;
- }
-
- bool operator==(ddiag_iterator Other) const {
- return Ptr == Other.Ptr;
- }
-
- bool operator!=(ddiag_iterator Other) const {
- return Ptr != Other.Ptr;
- }
-
- ddiag_iterator &operator+=(difference_type N) {
- assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
- while (N--)
- ++*this;
- return *this;
- }
-
- ddiag_iterator operator+(difference_type N) const {
- ddiag_iterator tmp = *this;
- tmp += N;
- return tmp;
- }
-
-private:
- DependentDiagnostic *Ptr;
-};
-
-inline DeclContext::ddiag_range DeclContext::ddiags() const {
- assert(isDependentContext()
- && "cannot iterate dependent diagnostics of non-dependent context");
- const DependentStoredDeclsMap *Map
- = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
-
- if (!Map)
- // Return an empty range using the always-end default constructor.
- return ddiag_range(ddiag_iterator(), ddiag_iterator());
-
- return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
-}
-
-}
-
-#endif
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
deleted file mode 100644
index aad7726..0000000
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the EvaluatedExprVisitor class template, which visits
-// the potentially-evaluated subexpressions of a potentially-evaluated
-// expression.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
-#define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/StmtVisitor.h"
-
-namespace clang {
-
-class ASTContext;
-
-/// \brief 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> {
-protected:
- const ASTContext &Context;
-
-public:
-#define PTR(CLASS) typename Ptr<CLASS>::type
-
- explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { }
-
- // Expressions that have no potentially-evaluated subexpressions (but may have
- // other sub-expressions).
- void VisitDeclRefExpr(PTR(DeclRefExpr) E) { }
- void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { }
- void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { }
- void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { }
- void VisitBlockExpr(PTR(BlockExpr) E) { }
- void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { }
- void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { }
-
- void VisitMemberExpr(PTR(MemberExpr) E) {
- // Only the base matters.
- return this->Visit(E->getBase());
- }
-
- void VisitChooseExpr(PTR(ChooseExpr) E) {
- // Don't visit either child expression if the condition is dependent.
- if (E->getCond()->isValueDependent())
- return;
- // Only the selected subexpression matters; the other one is not evaluated.
- return this->Visit(E->getChosenSubExpr());
- }
-
- void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) {
- // The controlling expression of a generic selection is not evaluated.
-
- // Don't visit either child expression if the condition is type-dependent.
- if (E->isResultDependent())
- return;
- // Only the selected subexpression matters; the other subexpressions and the
- // controlling expression are not evaluated.
- return this->Visit(E->getResultExpr());
- }
-
- void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) {
- // Only the actual initializer matters; the designators are all constant
- // expressions.
- return this->Visit(E->getInit());
- }
-
- void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) {
- if (E->isPotentiallyEvaluated())
- return this->Visit(E->getExprOperand());
- }
-
- void VisitCallExpr(PTR(CallExpr) CE) {
- if (!CE->isUnevaluatedBuiltinCall(Context))
- return static_cast<ImplClass*>(this)->VisitExpr(CE);
- }
-
- void VisitLambdaExpr(PTR(LambdaExpr) LE) {
- // Only visit the capture initializers, and not the body.
- for (LambdaExpr::const_capture_init_iterator I = LE->capture_init_begin(),
- E = LE->capture_init_end();
- I != E; ++I)
- if (*I)
- this->Visit(*I);
- }
-
- /// \brief 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())
- if (SubStmt)
- this->Visit(SubStmt);
- }
-
-#undef PTR
-};
-
-/// EvaluatedExprVisitor - This class visits 'Expr *'s
-template<typename ImplClass>
-class EvaluatedExprVisitor
- : public EvaluatedExprVisitorBase<make_ptr, ImplClass> {
-public:
- explicit EvaluatedExprVisitor(const ASTContext &Context) :
- EvaluatedExprVisitorBase<make_ptr, ImplClass>(Context) { }
-};
-
-/// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
-template<typename ImplClass>
-class ConstEvaluatedExprVisitor
- : public EvaluatedExprVisitorBase<make_const_ptr, ImplClass> {
-public:
- explicit ConstEvaluatedExprVisitor(const ASTContext &Context) :
- EvaluatedExprVisitorBase<make_const_ptr, ImplClass>(Context) { }
-};
-
-}
-
-#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
deleted file mode 100644
index 095dd6a..0000000
--- a/include/clang/AST/Expr.h
+++ /dev/null
@@ -1,4941 +0,0 @@
-//===--- Expr.h - Classes for representing expressions ----------*- 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 Expr interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPR_H
-#define LLVM_CLANG_AST_EXPR_H
-
-#include "clang/AST/APValue.h"
-#include "clang/AST/ASTVector.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclAccessPair.h"
-#include "clang/AST/OperationKinds.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/TypeTraits.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
- class APValue;
- class ASTContext;
- class BlockDecl;
- class CXXBaseSpecifier;
- class CXXMemberCallExpr;
- class CXXOperatorCallExpr;
- class CastExpr;
- class Decl;
- class IdentifierInfo;
- class MaterializeTemporaryExpr;
- class NamedDecl;
- class ObjCPropertyRefExpr;
- class OpaqueValueExpr;
- class ParmVarDecl;
- class StringLiteral;
- class TargetInfo;
- class ValueDecl;
-
-/// \brief A simple array of base specifiers.
-typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
-
-/// \brief 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 {
- DerivedToBaseAdjustment,
- FieldAdjustment,
- MemberPointerAdjustment
- } Kind;
-
- struct DTB {
- const CastExpr *BasePath;
- const CXXRecordDecl *DerivedClass;
- };
-
- struct P {
- const MemberPointerType *MPT;
- Expr *RHS;
- };
-
- union {
- struct DTB DerivedToBase;
- FieldDecl *Field;
- struct P Ptr;
- };
-
- SubobjectAdjustment(const CastExpr *BasePath,
- const CXXRecordDecl *DerivedClass)
- : Kind(DerivedToBaseAdjustment) {
- DerivedToBase.BasePath = BasePath;
- DerivedToBase.DerivedClass = DerivedClass;
- }
-
- SubobjectAdjustment(FieldDecl *Field)
- : Kind(FieldAdjustment) {
- this->Field = Field;
- }
-
- SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS)
- : Kind(MemberPointerAdjustment) {
- this->Ptr.MPT = MPT;
- this->Ptr.RHS = RHS;
- }
-};
-
-/// Expr - This represents one expression. Note that Expr's are subclasses of
-/// Stmt. This allows an expression to be transparently used any place a Stmt
-/// is required.
-///
-class Expr : public Stmt {
- QualType TR;
-
-protected:
- Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK,
- bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack)
- : Stmt(SC)
- {
- ExprBits.TypeDependent = TD;
- ExprBits.ValueDependent = VD;
- ExprBits.InstantiationDependent = ID;
- ExprBits.ValueKind = VK;
- ExprBits.ObjectKind = OK;
- ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
- setType(T);
- }
-
- /// \brief Construct an empty expression.
- explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
-
-public:
- QualType getType() const { return TR; }
- void setType(QualType t) {
- // In C++, the type of an expression is always adjusted so that it
- // will not have reference type (C++ [expr]p6). Use
- // QualType::getNonReferenceType() to retrieve the non-reference
- // type. Additionally, inspect Expr::isLvalue to determine whether
- // an expression that is adjusted in this manner should be
- // considered an lvalue.
- assert((t.isNull() || !t->isReferenceType()) &&
- "Expressions can't have reference type");
-
- TR = t;
- }
-
- /// isValueDependent - Determines whether this expression is
- /// value-dependent (C++ [temp.dep.constexpr]). For example, the
- /// array bound of "Chars" in the following example is
- /// value-dependent.
- /// @code
- /// template<int Size, char (&Chars)[Size]> struct meta_string;
- /// @endcode
- bool isValueDependent() const { return ExprBits.ValueDependent; }
-
- /// \brief Set whether this expression is value-dependent or not.
- void setValueDependent(bool VD) {
- ExprBits.ValueDependent = VD;
- }
-
- /// isTypeDependent - Determines whether this expression is
- /// type-dependent (C++ [temp.dep.expr]), which means that its type
- /// could change from one template instantiation to the next. For
- /// example, the expressions "x" and "x + y" are type-dependent in
- /// the following code, but "y" is not type-dependent:
- /// @code
- /// template<typename T>
- /// void add(T x, int y) {
- /// x + y;
- /// }
- /// @endcode
- bool isTypeDependent() const { return ExprBits.TypeDependent; }
-
- /// \brief 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
- /// it depends in some way on a template parameter, even if neither its type
- /// nor (constant) value can change due to the template instantiation.
- ///
- /// In the following example, the expression \c sizeof(sizeof(T() + T())) is
- /// instantiation-dependent (since it involves a template parameter \c T), but
- /// is neither type- nor value-dependent, since the type of the inner
- /// \c sizeof is known (\c std::size_t) and therefore the size of the outer
- /// \c sizeof is known.
- ///
- /// \code
- /// template<typename T>
- /// void f(T x, T y) {
- /// sizeof(sizeof(T() + T());
- /// }
- /// \endcode
- ///
- bool isInstantiationDependent() const {
- return ExprBits.InstantiationDependent;
- }
-
- /// \brief Set whether this expression is instantiation-dependent or not.
- void setInstantiationDependent(bool ID) {
- ExprBits.InstantiationDependent = ID;
- }
-
- /// \brief Whether this expression contains an unexpanded parameter
- /// pack (for C++11 variadic templates).
- ///
- /// Given the following function template:
- ///
- /// \code
- /// template<typename F, typename ...Types>
- /// void forward(const F &f, Types &&...args) {
- /// f(static_cast<Types&&>(args)...);
- /// }
- /// \endcode
- ///
- /// The expressions \c args and \c static_cast<Types&&>(args) both
- /// contain parameter packs.
- bool containsUnexpandedParameterPack() const {
- return ExprBits.ContainsUnexpandedParameterPack;
- }
-
- /// \brief Set the bit that describes whether this expression
- /// contains an unexpanded parameter pack.
- void setContainsUnexpandedParameterPack(bool PP = true) {
- ExprBits.ContainsUnexpandedParameterPack = PP;
- }
-
- /// getExprLoc - Return the preferred location for the arrow when diagnosing
- /// a problem with a generic expression.
- SourceLocation getExprLoc() const LLVM_READONLY;
-
- /// isUnusedResultAWarning - Return true if this immediate expression should
- /// be warned about if the result is unused. If so, fill in expr, location,
- /// and ranges with expr to warn on and source locations/ranges appropriate
- /// for a warning.
- bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc,
- SourceRange &R1, SourceRange &R2,
- ASTContext &Ctx) const;
-
- /// isLValue - True if this expression is an "l-value" according to
- /// the rules of the current language. C and C++ give somewhat
- /// different rules for this concept, but in general, the result of
- /// an l-value expression identifies a specific object whereas the
- /// result of an r-value expression is a value detached from any
- /// specific storage.
- ///
- /// C++11 divides the concept of "r-value" into pure r-values
- /// ("pr-values") and so-called expiring values ("x-values"), which
- /// identify specific objects that can be safely cannibalized for
- /// their resources. This is an unfortunate abuse of terminology on
- /// the part of the C++ committee. In Clang, when we say "r-value",
- /// we generally mean a pr-value.
- bool isLValue() const { return getValueKind() == VK_LValue; }
- bool isRValue() const { return getValueKind() == VK_RValue; }
- bool isXValue() const { return getValueKind() == VK_XValue; }
- bool isGLValue() const { return getValueKind() != VK_RValue; }
-
- enum LValueClassification {
- LV_Valid,
- LV_NotObjectType,
- LV_IncompleteVoidType,
- LV_DuplicateVectorComponents,
- LV_InvalidExpression,
- LV_InvalidMessageExpression,
- LV_MemberFunction,
- LV_SubObjCPropertySetting,
- LV_ClassTemporary,
- LV_ArrayTemporary
- };
- /// Reasons why an expression might not be an l-value.
- LValueClassification ClassifyLValue(ASTContext &Ctx) const;
-
- enum isModifiableLvalueResult {
- MLV_Valid,
- MLV_NotObjectType,
- MLV_IncompleteVoidType,
- MLV_DuplicateVectorComponents,
- MLV_InvalidExpression,
- MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
- MLV_IncompleteType,
- MLV_ConstQualified,
- MLV_ConstAddrSpace,
- MLV_ArrayType,
- MLV_NoSetterProperty,
- MLV_MemberFunction,
- MLV_SubObjCPropertySetting,
- MLV_InvalidMessageExpression,
- MLV_ClassTemporary,
- MLV_ArrayTemporary
- };
- /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
- /// does not have an incomplete type, does not have a const-qualified type,
- /// and if it is a structure or union, does not have any member (including,
- /// recursively, any member or element of all contained aggregates or unions)
- /// with a const-qualified type.
- ///
- /// \param Loc [in,out] - A source location which *may* be filled
- /// in with the location of the expression making this a
- /// non-modifiable lvalue, if specified.
- isModifiableLvalueResult
- isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
-
- /// \brief The return type of classify(). Represents the C++11 expression
- /// taxonomy.
- class Classification {
- public:
- /// \brief The various classification results. Most of these mean prvalue.
- enum Kinds {
- CL_LValue,
- CL_XValue,
- CL_Function, // Functions cannot be lvalues in C.
- CL_Void, // Void cannot be an lvalue in C.
- CL_AddressableVoid, // Void expression whose address can be taken in C.
- CL_DuplicateVectorComponents, // A vector shuffle with dupes.
- CL_MemberFunction, // An expression referring to a member function
- CL_SubObjCPropertySetting,
- CL_ClassTemporary, // A temporary of class type, or subobject thereof.
- CL_ArrayTemporary, // A temporary of array type.
- 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.
- enum ModifiableType {
- CM_Untested, // testModifiable was false.
- CM_Modifiable,
- CM_RValue, // Not modifiable because it's an rvalue
- CM_Function, // Not modifiable because it's a function; C++ only
- CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
- CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
- CM_ConstQualified,
- CM_ConstAddrSpace,
- CM_ArrayType,
- CM_IncompleteType
- };
-
- private:
- friend class Expr;
-
- unsigned short Kind;
- unsigned short Modifiable;
-
- explicit Classification(Kinds k, ModifiableType m)
- : Kind(k), Modifiable(m)
- {}
-
- public:
- Classification() {}
-
- Kinds getKind() const { return static_cast<Kinds>(Kind); }
- ModifiableType getModifiable() const {
- assert(Modifiable != CM_Untested && "Did not test for modifiability.");
- return static_cast<ModifiableType>(Modifiable);
- }
- bool isLValue() const { return Kind == CL_LValue; }
- bool isXValue() const { return Kind == CL_XValue; }
- bool isGLValue() const { return Kind <= CL_XValue; }
- bool isPRValue() const { return Kind >= CL_Function; }
- bool isRValue() const { return Kind >= CL_XValue; }
- bool isModifiable() const { return getModifiable() == CM_Modifiable; }
-
- /// \brief Create a simple, modifiably lvalue
- static Classification makeSimpleLValue() {
- return Classification(CL_LValue, CM_Modifiable);
- }
-
- };
- /// \brief Classify - Classify this expression according to the C++11
- /// expression taxonomy.
- ///
- /// C++11 defines ([basic.lval]) a new taxonomy of expressions to replace the
- /// old lvalue vs rvalue. This function determines the type of expression this
- /// is. There are three expression types:
- /// - lvalues are classical lvalues as in C++03.
- /// - prvalues are equivalent to rvalues in C++03.
- /// - xvalues are expressions yielding unnamed rvalue references, e.g. a
- /// function returning an rvalue reference.
- /// lvalues and xvalues are collectively referred to as glvalues, while
- /// prvalues and xvalues together form rvalues.
- Classification Classify(ASTContext &Ctx) const {
- return ClassifyImpl(Ctx, nullptr);
- }
-
- /// \brief ClassifyModifiable - Classify this expression according to the
- /// C++11 expression taxonomy, and see if it is valid on the left side
- /// of an assignment.
- ///
- /// This function extends classify in that it also tests whether the
- /// expression is modifiable (C99 6.3.2.1p1).
- /// \param Loc A source location that might be filled with a relevant location
- /// if the expression is not modifiable.
- Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const{
- return ClassifyImpl(Ctx, &Loc);
- }
-
- /// getValueKindForType - Given a formal return or parameter type,
- /// give its value kind.
- static ExprValueKind getValueKindForType(QualType T) {
- if (const ReferenceType *RT = T->getAs<ReferenceType>())
- return (isa<LValueReferenceType>(RT)
- ? VK_LValue
- : (RT->getPointeeType()->isFunctionType()
- ? VK_LValue : VK_XValue));
- return VK_RValue;
- }
-
- /// getValueKind - The value kind that this expression produces.
- ExprValueKind getValueKind() const {
- return static_cast<ExprValueKind>(ExprBits.ValueKind);
- }
-
- /// getObjectKind - The object kind that this expression produces.
- /// Object kinds are meaningful only for expressions that yield an
- /// l-value or x-value.
- ExprObjectKind getObjectKind() const {
- return static_cast<ExprObjectKind>(ExprBits.ObjectKind);
- }
-
- bool isOrdinaryOrBitFieldObject() const {
- ExprObjectKind OK = getObjectKind();
- return (OK == OK_Ordinary || OK == OK_BitField);
- }
-
- /// setValueKind - Set the value kind produced by this expression.
- void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; }
-
- /// setObjectKind - Set the object kind produced by this expression.
- void setObjectKind(ExprObjectKind Cat) { ExprBits.ObjectKind = Cat; }
-
-private:
- Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const;
-
-public:
-
- /// \brief 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
- /// declaration of that bit-field.
- ///
- /// Note that this returns a non-null pointer in subtly different
- /// places than refersToBitField returns true. In particular, this can
- /// return a non-null pointer even for r-values loaded from
- /// bit-fields, but it will return null for a conditional bit-field.
- FieldDecl *getSourceBitField();
-
- const FieldDecl *getSourceBitField() const {
- return const_cast<Expr*>(this)->getSourceBitField();
- }
-
- /// \brief 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.
- bool isObjCSelfExpr() const;
-
- /// \brief Returns whether this expression refers to a vector element.
- bool refersToVectorElement() const;
-
- /// \brief Returns whether this expression refers to a global register
- /// variable.
- bool refersToGlobalRegisterVar() const;
-
- /// \brief Returns whether this expression has a placeholder type.
- bool hasPlaceholderType() const {
- return getType()->isPlaceholderType();
- }
-
- /// \brief 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()))
- return BT->getKind() == K;
- return false;
- }
-
- /// isKnownToHaveBooleanValue - Return true if this is an integer expression
- /// that is known to return 0 or 1. This happens for _Bool/bool expressions
- /// but also int expressions which are produced by things like comparisons in
- /// C.
- bool isKnownToHaveBooleanValue() const;
-
- /// isIntegerConstantExpr - Return true if this expression is a valid integer
- /// constant expression, and, if so, return its value in Result. If not a
- /// valid i-c-e, return false and fill in Loc (if specified) with the location
- /// of the invalid expression.
- ///
- /// Note: This does not perform the implicit conversions required by C++11
- /// [expr.const]p5.
- bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
- SourceLocation *Loc = nullptr,
- bool isEvaluated = true) const;
- bool isIntegerConstantExpr(const ASTContext &Ctx,
- SourceLocation *Loc = nullptr) const;
-
- /// isCXX98IntegralConstantExpr - Return true if this expression is an
- /// integral constant expression in C++98. Can only be used in C++.
- bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const;
-
- /// isCXX11ConstantExpr - Return true if this expression is a constant
- /// expression in C++11. Can only be used in C++.
- ///
- /// Note: This does not perform the implicit conversions required by C++11
- /// [expr.const]p5.
- bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = nullptr,
- SourceLocation *Loc = nullptr) const;
-
- /// isPotentialConstantExpr - Return true if this function's definition
- /// might be usable in a constant expression in C++11, if it were marked
- /// constexpr. Return false if the function can never produce a constant
- /// expression, along with diagnostics describing why not.
- static bool isPotentialConstantExpr(const FunctionDecl *FD,
- SmallVectorImpl<
- PartialDiagnosticAt> &Diags);
-
- /// isPotentialConstantExprUnevaluted - Return true if this expression might
- /// be usable in a constant expression in C++11 in an unevaluated context, if
- /// it were in function FD marked constexpr. Return false if the function can
- /// never produce a constant expression, along with diagnostics describing
- /// why not.
- static bool isPotentialConstantExprUnevaluated(Expr *E,
- const FunctionDecl *FD,
- SmallVectorImpl<
- PartialDiagnosticAt> &Diags);
-
- /// isConstantInitializer - Returns true if this expression can be emitted to
- /// IR as a constant, and thus can be used as a constant initializer in C.
- /// If this expression is not constant and Culprit is non-null,
- /// it is used to store the address of first non constant expr.
- bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
- const Expr **Culprit = nullptr) const;
-
- /// EvalStatus is a struct with detailed info about an evaluation in progress.
- struct EvalStatus {
- /// \brief 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.
- /// 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;
-
- /// Diag - If this is non-null, it will be filled in with a stack of notes
- /// indicating why evaluation failed (or why it failed to produce a constant
- /// expression).
- /// If the expression is unfoldable, the notes will indicate why it's not
- /// foldable. If the expression is foldable, but not a constant expression,
- /// the notes will describes why it isn't a constant expression. If the
- /// expression *is* a constant expression, no notes will be produced.
- SmallVectorImpl<PartialDiagnosticAt> *Diag;
-
- EvalStatus()
- : HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {}
-
- // hasSideEffects - Return true if the evaluated expression has
- // side effects.
- bool hasSideEffects() const {
- return HasSideEffects;
- }
- };
-
- /// EvalResult is a struct with detailed info about an evaluated expression.
- struct EvalResult : EvalStatus {
- /// Val - This is the value the expression can be folded to.
- APValue Val;
-
- // isGlobalLValue - Return true if the evaluated lvalue expression
- // is global.
- bool isGlobalLValue() const;
- };
-
- /// EvaluateAsRValue - Return true if this is a constant which we can fold to
- /// an rvalue using any crazy technique (that has nothing to do with language
- /// standards) that we want to, even if the expression has side-effects. If
- /// this function returns true, it returns the folded constant in Result. If
- /// the expression is a glvalue, an lvalue-to-rvalue conversion will be
- /// applied.
- 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
- /// any crazy technique that we want to, even if the expression has
- /// side-effects.
- bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const;
-
- enum SideEffectsKind {
- SE_NoSideEffects, ///< Strictly evaluate the expression.
- SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not
- ///< arbitrary unmodeled side effects.
- SE_AllowSideEffects ///< Allow any unmodeled side effect.
- };
-
- /// EvaluateAsInt - Return true if this is a constant which we can fold and
- /// convert to an integer, using any crazy technique that we want to.
- bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,
- SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
-
- /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
- /// constant folded without side-effects, but discard the result.
- bool isEvaluatable(const ASTContext &Ctx,
- SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
-
- /// HasSideEffects - This routine returns true for all those expressions
- /// which have any effect other than producing a value. Example is a function
- /// call, volatile variable read, or throwing an exception. If
- /// IncludePossibleEffects is false, this call treats certain expressions with
- /// potential side effects (such as function call-like expressions,
- /// instantiation-dependent expressions, or invocations from a macro) as not
- /// having side effects.
- bool HasSideEffects(const ASTContext &Ctx,
- bool IncludePossibleEffects = true) const;
-
- /// \brief Determine whether this expression involves a call to any function
- /// that is not trivial.
- bool hasNonTrivialCall(const ASTContext &Ctx) const;
-
- /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
- /// integer. This must be called on an expression that constant folds to an
- /// integer.
- llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
- SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
-
- void EvaluateForOverflow(const ASTContext &Ctx) const;
-
- /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
- /// lvalue with link time known address, with no side-effects.
- bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const;
-
- /// EvaluateAsInitializer - Evaluate an expression as if it were the
- /// initializer of the given declaration. Returns true if the initializer
- /// can be folded to a constant, and produces any relevant notes. In C++11,
- /// notes will be produced if the expression is not a constant expression.
- bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
- const VarDecl *VD,
- SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
-
- /// EvaluateWithSubstitution - Evaluate an expression as if from the context
- /// of a call to the given function with the given arguments, inside an
- /// unevaluated context. Returns true if the expression could be folded to a
- /// constant.
- bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
- const FunctionDecl *Callee,
- ArrayRef<const Expr*> Args) const;
-
- /// \brief 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.
- ///
- /// \param Type - How to evaluate the size of the Expr, as defined by the
- /// "type" parameter of __builtin_object_size
- bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
- unsigned Type) const;
-
- /// \brief Enumeration used to describe the kind of Null pointer constant
- /// returned from \c isNullPointerConstant().
- enum NullPointerConstantKind {
- /// \brief Expression is not a Null pointer constant.
- NPCK_NotNull = 0,
-
- /// \brief 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.
- NPCK_ZeroLiteral,
-
- /// \brief Expression is a C++11 nullptr.
- NPCK_CXX11_nullptr,
-
- /// \brief Expression is a GNU-style __null constant.
- NPCK_GNUNull
- };
-
- /// \brief 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.
- NPC_NeverValueDependent = 0,
-
- /// \brief 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
- /// to never be a null pointer constant.
- NPC_ValueDependentIsNotNull
- };
-
- /// isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to
- /// a Null pointer constant. The return value can further distinguish the
- /// kind of NULL pointer constant that was detected.
- NullPointerConstantKind isNullPointerConstant(
- ASTContext &Ctx,
- NullPointerConstantValueDependence NPC) const;
-
- /// isOBJCGCCandidate - Return true if this expression may be used in a read/
- /// write barrier.
- bool isOBJCGCCandidate(ASTContext &Ctx) const;
-
- /// \brief 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
- /// of the member. Returns null if this is an *overloaded* bound
- /// member expression.
- static QualType findBoundMemberType(const Expr *expr);
-
- /// IgnoreImpCasts - Skip past any implicit casts which might
- /// surround this expression. Only skips ImplicitCastExprs.
- Expr *IgnoreImpCasts() LLVM_READONLY;
-
- /// IgnoreImplicit - Skip past any implicit AST nodes which might
- /// surround this expression.
- Expr *IgnoreImplicit() LLVM_READONLY {
- return cast<Expr>(Stmt::IgnoreImplicit());
- }
-
- const Expr *IgnoreImplicit() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreImplicit();
- }
-
- /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return
- /// its subexpression. If that subexpression is also a ParenExpr,
- /// then this method recursively returns its subexpression, and so forth.
- /// Otherwise, the method returns the current Expr.
- Expr *IgnoreParens() LLVM_READONLY;
-
- /// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
- /// or CastExprs, returning their operand.
- Expr *IgnoreParenCasts() LLVM_READONLY;
-
- /// Ignore casts. Strip off any CastExprs, returning their operand.
- Expr *IgnoreCasts() LLVM_READONLY;
-
- /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
- /// any ParenExpr or ImplicitCastExprs, returning their operand.
- Expr *IgnoreParenImpCasts() LLVM_READONLY;
-
- /// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a
- /// call to a conversion operator, return the argument.
- Expr *IgnoreConversionOperator() LLVM_READONLY;
-
- const Expr *IgnoreConversionOperator() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreConversionOperator();
- }
-
- const Expr *IgnoreParenImpCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenImpCasts();
- }
-
- /// Ignore parentheses and lvalue casts. Strip off any ParenExpr and
- /// CastExprs that represent lvalue casts, returning their operand.
- Expr *IgnoreParenLValueCasts() LLVM_READONLY;
-
- const Expr *IgnoreParenLValueCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenLValueCasts();
- }
-
- /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
- /// value (including ptr->int casts of the same size). Strip off any
- /// ParenExpr or CastExprs, returning their operand.
- Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY;
-
- /// Ignore parentheses and derived-to-base casts.
- Expr *ignoreParenBaseCasts() LLVM_READONLY;
-
- const Expr *ignoreParenBaseCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->ignoreParenBaseCasts();
- }
-
- /// \brief 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
- /// C++. Default arguments are represented by \c CXXDefaultArgExpr nodes;
- /// this routine also looks through any implicit casts to determine whether
- /// the expression is a default argument.
- bool isDefaultArgument() const;
-
- /// \brief 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++.
- bool isImplicitCXXThis() const;
-
- const Expr *IgnoreImpCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreImpCasts();
- }
- const Expr *IgnoreParens() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParens();
- }
- const Expr *IgnoreParenCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenCasts();
- }
- /// Strip off casts, but keep parentheses.
- const Expr *IgnoreCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreCasts();
- }
-
- const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
- }
-
- static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
-
- /// \brief 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
- /// most derived decl that can be inferred from the expression.
- /// This is valid because derived-to-base conversions have undefined
- /// behavior if the object isn't dynamically of the derived type.
- const CXXRecordDecl *getBestDynamicClassType() const;
-
- /// Walk outwards from an expression we want to bind a reference to and
- /// find the expression whose lifetime needs to be extended. Record
- /// the LHSs of comma expressions and adjustments needed along the path.
- const Expr *skipRValueSubobjectAdjustments(
- SmallVectorImpl<const Expr *> &CommaLHS,
- SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstExprConstant &&
- T->getStmtClass() <= lastExprConstant;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Primary Expressions.
-//===----------------------------------------------------------------------===//
-
-/// OpaqueValueExpr - An expression referring to an opaque object of a
-/// fixed type and value class. These don't correspond to concrete
-/// syntax; instead they're used to express operations (usually copy
-/// operations) on values whose source is generally obvious from
-/// context.
-class OpaqueValueExpr : public Expr {
- friend class ASTStmtReader;
- Expr *SourceExpr;
- SourceLocation Loc;
-
-public:
- OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
- ExprObjectKind OK = OK_Ordinary,
- Expr *SourceExpr = nullptr)
- : Expr(OpaqueValueExprClass, T, VK, OK,
- T->isDependentType(),
- T->isDependentType() ||
- (SourceExpr && SourceExpr->isValueDependent()),
- T->isInstantiationDependentType(),
- false),
- SourceExpr(SourceExpr), Loc(Loc) {
- }
-
- /// Given an expression which invokes a copy constructor --- i.e. a
- /// CXXConstructExpr, possibly wrapped in an ExprWithCleanups ---
- /// find the OpaqueValueExpr that's the source of the construction.
- static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
-
- explicit OpaqueValueExpr(EmptyShell Empty)
- : Expr(OpaqueValueExprClass, Empty) { }
-
- /// \brief Retrieve the location of this expression.
- SourceLocation getLocation() const { return Loc; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getLocStart() : Loc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getLocEnd() : Loc;
- }
- SourceLocation getExprLoc() const LLVM_READONLY {
- if (SourceExpr) return SourceExpr->getExprLoc();
- return Loc;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- /// The source expression of an opaque value expression is the
- /// expression which originally generated the value. This is
- /// provided as a convenience for analyses that don't wish to
- /// precisely model the execution behavior of the program.
- ///
- /// The source expression is typically set when building the
- /// expression which binds the opaque value expression in the first
- /// place.
- Expr *getSourceExpr() const { return SourceExpr; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OpaqueValueExprClass;
- }
-};
-
-/// \brief A reference to a declared variable, function, enum, etc.
-/// [C99 6.5.1p2]
-///
-/// This encodes all the information about how a declaration is referenced
-/// within an expression.
-///
-/// There are several optional constructs attached to DeclRefExprs only when
-/// they apply in order to conserve memory. These are laid out past the end of
-/// the object, and flags in the DeclRefExprBitfield track whether they exist:
-///
-/// DeclRefExprBits.HasQualifier:
-/// Specifies when this declaration reference expression has a C++
-/// nested-name-specifier.
-/// DeclRefExprBits.HasFoundDecl:
-/// Specifies when this declaration reference expression has a record of
-/// a NamedDecl (different from the referenced ValueDecl) which was found
-/// during name lookup and/or overload resolution.
-/// DeclRefExprBits.HasTemplateKWAndArgsInfo:
-/// Specifies when this declaration reference expression has an explicit
-/// C++ template keyword and/or template argument list.
-/// DeclRefExprBits.RefersToEnclosingVariableOrCapture
-/// Specifies when this declaration reference expression (validly)
-/// refers to an enclosed local or a captured variable.
-class DeclRefExpr final
- : public Expr,
- private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc,
- NamedDecl *, ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// \brief The declaration that we are referencing.
- ValueDecl *D;
-
- /// \brief The location of the declaration name itself.
- SourceLocation Loc;
-
- /// \brief Provides source/type location info for the declaration name
- /// embedded in D.
- DeclarationNameLoc DNLoc;
-
- size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
- return hasQualifier() ? 1 : 0;
- }
-
- size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
- return hasFoundDecl() ? 1 : 0;
- }
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return hasTemplateKWAndArgsInfo() ? 1 : 0;
- }
-
- /// \brief Test whether there is a distinct FoundDecl attached to the end of
- /// this DRE.
- bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
-
- DeclRefExpr(const ASTContext &Ctx,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D, bool RefersToEnlosingVariableOrCapture,
- const DeclarationNameInfo &NameInfo,
- NamedDecl *FoundD,
- const TemplateArgumentListInfo *TemplateArgs,
- QualType T, ExprValueKind VK);
-
- /// \brief Construct an empty declaration reference expression.
- explicit DeclRefExpr(EmptyShell Empty)
- : Expr(DeclRefExprClass, Empty) { }
-
- /// \brief Computes the type- and value-dependence flags for this
- /// declaration reference expression.
- void computeDependence(const ASTContext &C);
-
-public:
- DeclRefExpr(ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T,
- ExprValueKind VK, SourceLocation L,
- const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
- D(D), Loc(L), DNLoc(LocInfo) {
- DeclRefExprBits.HasQualifier = 0;
- DeclRefExprBits.HasTemplateKWAndArgsInfo = 0;
- DeclRefExprBits.HasFoundDecl = 0;
- DeclRefExprBits.HadMultipleCandidates = 0;
- DeclRefExprBits.RefersToEnclosingVariableOrCapture =
- RefersToEnclosingVariableOrCapture;
- computeDependence(D->getASTContext());
- }
-
- static DeclRefExpr *
- Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *D,
- bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc,
- QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr,
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
-
- static DeclRefExpr *
- Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *D,
- bool RefersToEnclosingVariableOrCapture,
- const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
- NamedDecl *FoundD = nullptr,
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
-
- /// \brief Construct an empty declaration reference expression.
- static DeclRefExpr *CreateEmpty(const ASTContext &Context,
- bool HasQualifier,
- bool HasFoundDecl,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- ValueDecl *getDecl() { return D; }
- const ValueDecl *getDecl() const { return D; }
- void setDecl(ValueDecl *NewD) { D = NewD; }
-
- DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
- }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- /// \brief 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
- /// that precedes the name, with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const {
- if (!hasQualifier())
- return NestedNameSpecifierLoc();
- return *getTrailingObjects<NestedNameSpecifierLoc>();
- }
-
- /// \brief 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.
- ///
- /// 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
- /// simple return the ValueDecl when appropriate.
-
- NamedDecl *getFoundDecl() {
- return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
- }
-
- /// \brief Get the NamedDecl through which this reference occurred.
- /// See non-const variant.
- const NamedDecl *getFoundDecl() const {
- return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
- }
-
- bool hasTemplateKWAndArgsInfo() const {
- return DeclRefExprBits.HasTemplateKWAndArgsInfo;
- }
-
- /// \brief 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
- /// 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
- /// 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
- /// was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// \brief 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
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- /// \brief 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
- /// 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
- /// variable?
- bool refersToEnclosingVariableOrCapture() const {
- return DeclRefExprBits.RefersToEnclosingVariableOrCapture;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclRefExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief [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.
- FuncDName,
- FuncSig,
- PrettyFunction,
- /// \brief The same as PrettyFunction, except that the
- /// 'virtual' keyword is omitted for virtual member functions.
- PrettyFunctionNoVirtual
- };
-
-private:
- SourceLocation Loc;
- IdentType Type;
- Stmt *FnName;
-
-public:
- PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
- StringLiteral *SL);
-
- /// \brief Construct an empty predefined expression.
- explicit PredefinedExpr(EmptyShell Empty)
- : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {}
-
- IdentType getIdentType() const { return Type; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- StringLiteral *getFunctionName();
- const StringLiteral *getFunctionName() const {
- return const_cast<PredefinedExpr *>(this)->getFunctionName();
- }
-
- static StringRef getIdentTypeName(IdentType IT);
- static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PredefinedExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&FnName, &FnName + 1); }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
-/// leaking memory.
-///
-/// For large floats/integers, APFloat/APInt will allocate memory from the heap
-/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
-/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
-/// the APFloat/APInt values will never get freed. APNumericStorage uses
-/// ASTContext's allocator for memory allocation.
-class APNumericStorage {
- union {
- uint64_t VAL; ///< Used to store the <= 64 bits integer value.
- uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
- unsigned BitWidth;
-
- bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
-
- APNumericStorage(const APNumericStorage &) = delete;
- void operator=(const APNumericStorage &) = delete;
-
-protected:
- APNumericStorage() : VAL(0), BitWidth(0) { }
-
- llvm::APInt getIntValue() const {
- unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
- if (NumWords > 1)
- return llvm::APInt(BitWidth, NumWords, pVal);
- else
- return llvm::APInt(BitWidth, VAL);
- }
- void setIntValue(const ASTContext &C, const llvm::APInt &Val);
-};
-
-class APIntStorage : private APNumericStorage {
-public:
- llvm::APInt getValue() const { return getIntValue(); }
- void setValue(const ASTContext &C, const llvm::APInt &Val) {
- setIntValue(C, Val);
- }
-};
-
-class APFloatStorage : private APNumericStorage {
-public:
- llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
- return llvm::APFloat(Semantics, getIntValue());
- }
- void setValue(const ASTContext &C, const llvm::APFloat &Val) {
- setIntValue(C, Val.bitcastToAPInt());
- }
-};
-
-class IntegerLiteral : public Expr, public APIntStorage {
- SourceLocation Loc;
-
- /// \brief Construct an empty integer literal.
- explicit IntegerLiteral(EmptyShell Empty)
- : Expr(IntegerLiteralClass, Empty) { }
-
-public:
- // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
- // or UnsignedLongLongTy
- IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
- SourceLocation l);
-
- /// \brief 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.
- 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.
- SourceLocation getLocation() const { return Loc; }
-
- void setLocation(SourceLocation Location) { Loc = Location; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IntegerLiteralClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-class CharacterLiteral : public Expr {
-public:
- enum CharacterKind {
- Ascii,
- Wide,
- UTF16,
- UTF32
- };
-
-private:
- unsigned Value;
- SourceLocation Loc;
-public:
- // type should be IntTy
- CharacterLiteral(unsigned value, CharacterKind kind, QualType type,
- SourceLocation l)
- : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(value), Loc(l) {
- CharacterLiteralBits.Kind = kind;
- }
-
- /// \brief Construct an empty character literal.
- CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
-
- SourceLocation getLocation() const { return Loc; }
- CharacterKind getKind() const {
- return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- unsigned getValue() const { return Value; }
-
- void setLocation(SourceLocation Location) { Loc = Location; }
- void setKind(CharacterKind kind) { CharacterLiteralBits.Kind = kind; }
- void setValue(unsigned Val) { Value = Val; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CharacterLiteralClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-class FloatingLiteral : public Expr, private APFloatStorage {
- SourceLocation Loc;
-
- FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact,
- QualType Type, SourceLocation L);
-
- /// \brief Construct an empty floating-point literal.
- explicit FloatingLiteral(const ASTContext &C, EmptyShell Empty);
-
-public:
- static FloatingLiteral *Create(const ASTContext &C, const llvm::APFloat &V,
- bool isexact, QualType Type, SourceLocation L);
- static FloatingLiteral *Create(const ASTContext &C, EmptyShell Empty);
-
- llvm::APFloat getValue() const {
- return APFloatStorage::getValue(getSemantics());
- }
- void setValue(const ASTContext &C, const llvm::APFloat &Val) {
- assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics");
- APFloatStorage::setValue(C, Val);
- }
-
- /// Get a raw enumeration value representing the floating-point semantics of
- /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
- APFloatSemantics getRawSemantics() const {
- return static_cast<APFloatSemantics>(FloatingLiteralBits.Semantics);
- }
-
- /// Set the raw enumeration value representing the floating-point semantics of
- /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
- void setRawSemantics(APFloatSemantics Sem) {
- FloatingLiteralBits.Semantics = Sem;
- }
-
- /// Return the APFloat semantics this literal uses.
- const llvm::fltSemantics &getSemantics() const;
-
- /// Set the APFloat semantics this literal uses.
- void setSemantics(const llvm::fltSemantics &Sem);
-
- bool isExact() const { return FloatingLiteralBits.IsExact; }
- void setExact(bool E) { FloatingLiteralBits.IsExact = E; }
-
- /// getValueAsApproximateDouble - This returns the value as an inaccurate
- /// double. Note that this may cause loss of precision, but is useful for
- /// debugging dumps, etc.
- double getValueAsApproximateDouble() const;
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == FloatingLiteralClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ImaginaryLiteral - We support imaginary integer and floating point literals,
-/// like "1.0i". We represent these as a wrapper around FloatingLiteral and
-/// IntegerLiteral classes. Instances of this class always have a Complex type
-/// whose element type matches the subexpression.
-///
-class ImaginaryLiteral : public Expr {
- Stmt *Val;
-public:
- ImaginaryLiteral(Expr *val, QualType Ty)
- : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Val(val) {}
-
- /// \brief Build an empty imaginary literal.
- explicit ImaginaryLiteral(EmptyShell Empty)
- : Expr(ImaginaryLiteralClass, Empty) { }
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
- void setSubExpr(Expr *E) { Val = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Val->getLocStart(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Val->getLocEnd(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImaginaryLiteralClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Val, &Val+1); }
-};
-
-/// StringLiteral - This represents a string literal expression, e.g. "foo"
-/// or L"bar" (wide strings). The actual string is returned by getBytes()
-/// is NOT null-terminated, and the length of the string is determined by
-/// calling getByteLength(). The C type for a string is always a
-/// ConstantArrayType. In C++, the char type is const qualified, in C it is
-/// not.
-///
-/// Note that strings in C can be formed by concatenation of multiple string
-/// literal pptokens in translation phase #6. This keeps track of the locations
-/// of each of these pieces.
-///
-/// Strings in C can also be truncated and extended by assigning into arrays,
-/// e.g. with constructs like:
-/// char X[2] = "foobar";
-/// In this case, getByteLength() will return 6, but the string literal will
-/// have type "char[2]".
-class StringLiteral : public Expr {
-public:
- enum StringKind {
- Ascii,
- Wide,
- UTF8,
- UTF16,
- UTF32
- };
-
-private:
- friend class ASTStmtReader;
-
- union {
- const char *asChar;
- const uint16_t *asUInt16;
- const uint32_t *asUInt32;
- } StrData;
- unsigned Length;
- unsigned CharByteWidth : 4;
- unsigned Kind : 3;
- unsigned IsPascal : 1;
- unsigned NumConcatenated;
- SourceLocation TokLocs[1];
-
- StringLiteral(QualType Ty) :
- Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
- false) {}
-
- static int mapCharByteWidth(TargetInfo const &target,StringKind k);
-
-public:
- /// This is the "fully general" constructor that allows representation of
- /// strings formed from multiple concatenated tokens.
- static StringLiteral *Create(const ASTContext &C, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
- const SourceLocation *Loc, unsigned NumStrs);
-
- /// Simple constructor for string literals made from one token.
- static StringLiteral *Create(const ASTContext &C, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
- SourceLocation Loc) {
- return Create(C, Str, Kind, Pascal, Ty, &Loc, 1);
- }
-
- /// \brief Construct an empty string literal.
- static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs);
-
- StringRef getString() const {
- assert(CharByteWidth==1
- && "This function is used in places that assume strings use char");
- return StringRef(StrData.asChar, getByteLength());
- }
-
- /// Allow access to clients that need the byte representation, such as
- /// ASTWriterStmt::VisitStringLiteral().
- StringRef getBytes() const {
- // FIXME: StringRef may not be the right type to use as a result for this.
- if (CharByteWidth == 1)
- return StringRef(StrData.asChar, getByteLength());
- if (CharByteWidth == 4)
- return StringRef(reinterpret_cast<const char*>(StrData.asUInt32),
- getByteLength());
- assert(CharByteWidth == 2 && "unsupported CharByteWidth");
- return StringRef(reinterpret_cast<const char*>(StrData.asUInt16),
- getByteLength());
- }
-
- void outputString(raw_ostream &OS) const;
-
- uint32_t getCodeUnit(size_t i) const {
- assert(i < Length && "out of bounds access");
- if (CharByteWidth == 1)
- return static_cast<unsigned char>(StrData.asChar[i]);
- if (CharByteWidth == 4)
- return StrData.asUInt32[i];
- assert(CharByteWidth == 2 && "unsupported CharByteWidth");
- return StrData.asUInt16[i];
- }
-
- unsigned getByteLength() const { return CharByteWidth*Length; }
- unsigned getLength() const { return Length; }
- unsigned getCharByteWidth() const { return CharByteWidth; }
-
- /// \brief Sets the string data to the given string data.
- void setString(const ASTContext &C, StringRef Str,
- StringKind Kind, bool IsPascal);
-
- StringKind getKind() const { return static_cast<StringKind>(Kind); }
-
-
- bool isAscii() const { return Kind == Ascii; }
- bool isWide() const { return Kind == Wide; }
- bool isUTF8() const { return Kind == UTF8; }
- bool isUTF16() const { return Kind == UTF16; }
- bool isUTF32() const { return Kind == UTF32; }
- bool isPascal() const { return IsPascal; }
-
- bool containsNonAsciiOrNull() const {
- StringRef Str = getString();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- if (!isASCII(Str[i]) || !Str[i])
- return true;
- return false;
- }
-
- /// getNumConcatenated - Get the number of string literal tokens that were
- /// concatenated in translation phase #6 to form this string literal.
- unsigned getNumConcatenated() const { return NumConcatenated; }
-
- SourceLocation getStrTokenLoc(unsigned TokNum) const {
- assert(TokNum < NumConcatenated && "Invalid tok number");
- return TokLocs[TokNum];
- }
- void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
- assert(TokNum < NumConcatenated && "Invalid tok number");
- TokLocs[TokNum] = L;
- }
-
- /// getLocationOfByte - Return a source location that points to the specified
- /// byte of this string literal.
- ///
- /// Strings are amazingly complex. They can be formed from multiple tokens
- /// and can have escape sequences in them in addition to the usual trigraph
- /// and escaped newline business. This routine handles this complexity.
- ///
- SourceLocation
- getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
- const LangOptions &Features, const TargetInfo &Target,
- unsigned *StartToken = nullptr,
- unsigned *StartTokenByteOffset = nullptr) const;
-
- typedef const SourceLocation *tokloc_iterator;
- tokloc_iterator tokloc_begin() const { return TokLocs; }
- tokloc_iterator tokloc_end() const { return TokLocs + NumConcatenated; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return TokLocs[NumConcatenated - 1];
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == StringLiteralClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
-/// AST node is only formed if full location information is requested.
-class ParenExpr : public Expr {
- SourceLocation L, R;
- Stmt *Val;
-public:
- ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
- : Expr(ParenExprClass, val->getType(),
- val->getValueKind(), val->getObjectKind(),
- val->isTypeDependent(), val->isValueDependent(),
- val->isInstantiationDependent(),
- val->containsUnexpandedParameterPack()),
- L(l), R(r), Val(val) {}
-
- /// \brief Construct an empty parenthesized expression.
- explicit ParenExpr(EmptyShell Empty)
- : Expr(ParenExprClass, Empty) { }
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
- void setSubExpr(Expr *E) { Val = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return L; }
- SourceLocation getLocEnd() const LLVM_READONLY { return R; }
-
- /// \brief 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 ')'.
- SourceLocation getRParen() const { return R; }
- void setRParen(SourceLocation Loc) { R = Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ParenExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Val, &Val+1); }
-};
-
-/// UnaryOperator - This represents the unary-expression's (except sizeof and
-/// alignof), the postinc/postdec operators from postfix-expression, and various
-/// extensions.
-///
-/// Notes on various nodes:
-///
-/// Real/Imag - These return the real/imag part of a complex operand. If
-/// applied to a non-complex value, the former returns its operand and the
-/// later returns zero in the type of the operand.
-///
-class UnaryOperator : public Expr {
-public:
- typedef UnaryOperatorKind Opcode;
-
-private:
- unsigned Opc : 5;
- 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.
- explicit UnaryOperator(EmptyShell Empty)
- : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { }
-
- Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
- void setOpcode(Opcode O) { Opc = O; }
-
- Expr *getSubExpr() const { return cast<Expr>(Val); }
- void setSubExpr(Expr *E) { Val = E; }
-
- /// getOperatorLoc - Return the location of the operator.
- SourceLocation getOperatorLoc() const { return Loc; }
- void setOperatorLoc(SourceLocation L) { Loc = L; }
-
- /// isPostfix - Return true if this is a postfix operation, like x++.
- static bool isPostfix(Opcode Op) {
- return Op == UO_PostInc || Op == UO_PostDec;
- }
-
- /// isPrefix - Return true if this is a prefix operation, like --x.
- static bool isPrefix(Opcode Op) {
- return Op == UO_PreInc || Op == UO_PreDec;
- }
-
- bool isPrefix() const { return isPrefix(getOpcode()); }
- bool isPostfix() const { return isPostfix(getOpcode()); }
-
- static bool isIncrementOp(Opcode Op) {
- return Op == UO_PreInc || Op == UO_PostInc;
- }
- bool isIncrementOp() const {
- return isIncrementOp(getOpcode());
- }
-
- static bool isDecrementOp(Opcode Op) {
- return Op == UO_PreDec || Op == UO_PostDec;
- }
- bool isDecrementOp() const {
- return isDecrementOp(getOpcode());
- }
-
- static bool isIncrementDecrementOp(Opcode Op) { return Op <= UO_PreDec; }
- bool isIncrementDecrementOp() const {
- return isIncrementDecrementOp(getOpcode());
- }
-
- static bool isArithmeticOp(Opcode Op) {
- return Op >= UO_Plus && Op <= UO_LNot;
- }
- bool isArithmeticOp() const { return isArithmeticOp(getOpcode()); }
-
- /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
- /// corresponds to, e.g. "sizeof" or "[pre]++"
- static StringRef getOpcodeStr(Opcode Op);
-
- /// \brief 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
- /// the given unary opcode.
- static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return isPostfix() ? Val->getLocStart() : Loc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return isPostfix() ? Loc : Val->getLocEnd();
- }
- SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnaryOperatorClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Val, &Val+1); }
-};
-
-/// Helper class for OffsetOfExpr.
-
-// __builtin_offsetof(type, identifier(.identifier|[expr])*)
-class OffsetOfNode {
-public:
- /// \brief The kind of offsetof node we have.
- enum Kind {
- /// \brief An index into an array.
- Array = 0x00,
- /// \brief A field.
- Field = 0x01,
- /// \brief A field in a dependent type, known only by its name.
- Identifier = 0x02,
- /// \brief An implicit indirection through a C++ base class, when the
- /// field found is in a base class.
- Base = 0x03
- };
-
-private:
- enum { MaskBits = 2, Mask = 0x03 };
-
- /// \brief The source range that covers this part of the designator.
- SourceRange Range;
-
- /// \brief 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.
- /// - A FieldDecl*, for references to a known field.
- /// - An IdentifierInfo*, for references to a field with a given name
- /// when the class type is dependent.
- /// - A CXXBaseSpecifier*, for references that look at a field in a
- /// base class.
- uintptr_t Data;
-
-public:
- /// \brief 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.
- 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.
- 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.
- explicit OffsetOfNode(const CXXBaseSpecifier *Base)
- : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
-
- /// \brief 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
- /// of expressions.
- unsigned getArrayExprIndex() const {
- assert(getKind() == Array);
- return Data >> 2;
- }
-
- /// \brief 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
- /// the field.
- IdentifierInfo *getFieldName() const;
-
- /// \brief 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.
- ///
- /// For an array element node, the source range contains the locations of
- /// the square brackets. For a field or identifier node, the source range
- /// contains the location of the period (if there is one) and the
- /// identifier.
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
-};
-
-/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
-/// offsetof(record-type, member-designator). For example, given:
-/// @code
-/// struct S {
-/// float f;
-/// double d;
-/// };
-/// struct T {
-/// int i;
-/// struct S s[10];
-/// };
-/// @endcode
-/// we can represent and evaluate the expression @c offsetof(struct T, s[2].d).
-
-class OffsetOfExpr final
- : public Expr,
- private llvm::TrailingObjects<OffsetOfExpr, OffsetOfNode, Expr *> {
- SourceLocation OperatorLoc, RParenLoc;
- // Base type;
- TypeSourceInfo *TSInfo;
- // Number of sub-components (i.e. instances of OffsetOfNode).
- unsigned NumComps;
- // Number of sub-expressions (i.e. array subscript expressions).
- unsigned NumExprs;
-
- size_t numTrailingObjects(OverloadToken<OffsetOfNode>) const {
- return NumComps;
- }
-
- OffsetOfExpr(const ASTContext &C, QualType type,
- SourceLocation OperatorLoc, TypeSourceInfo *tsi,
- ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
- SourceLocation RParenLoc);
-
- explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
- : Expr(OffsetOfExprClass, EmptyShell()),
- TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
-
-public:
-
- static OffsetOfExpr *Create(const ASTContext &C, QualType type,
- SourceLocation OperatorLoc, TypeSourceInfo *tsi,
- ArrayRef<OffsetOfNode> comps,
- ArrayRef<Expr*> exprs, SourceLocation RParenLoc);
-
- static OffsetOfExpr *CreateEmpty(const ASTContext &C,
- unsigned NumComps, unsigned NumExprs);
-
- /// getOperatorLoc - Return the location of the operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
- void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
-
- /// \brief Return the location of the right parentheses.
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation R) { RParenLoc = R; }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return TSInfo;
- }
- void setTypeSourceInfo(TypeSourceInfo *tsi) {
- TSInfo = tsi;
- }
-
- const OffsetOfNode &getComponent(unsigned Idx) const {
- assert(Idx < NumComps && "Subscript out of range");
- return getTrailingObjects<OffsetOfNode>()[Idx];
- }
-
- void setComponent(unsigned Idx, OffsetOfNode ON) {
- assert(Idx < NumComps && "Subscript out of range");
- getTrailingObjects<OffsetOfNode>()[Idx] = ON;
- }
-
- unsigned getNumComponents() const {
- return NumComps;
- }
-
- Expr* getIndexExpr(unsigned Idx) {
- assert(Idx < NumExprs && "Subscript out of range");
- return getTrailingObjects<Expr *>()[Idx];
- }
-
- const Expr *getIndexExpr(unsigned Idx) const {
- assert(Idx < NumExprs && "Subscript out of range");
- return getTrailingObjects<Expr *>()[Idx];
- }
-
- void setIndexExpr(unsigned Idx, Expr* E) {
- assert(Idx < NumComps && "Subscript out of range");
- getTrailingObjects<Expr *>()[Idx] = E;
- }
-
- unsigned getNumExpressions() const {
- return NumExprs;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OffsetOfExprClass;
- }
-
- // Iterators
- child_range children() {
- Stmt **begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
- return child_range(begin, begin + NumExprs);
- }
- friend TrailingObjects;
-};
-
-/// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
-/// expression operand. Used for sizeof/alignof (C99 6.5.3.4) and
-/// vec_step (OpenCL 1.1 6.11.12).
-class UnaryExprOrTypeTraitExpr : public Expr {
- union {
- TypeSourceInfo *Ty;
- Stmt *Ex;
- } Argument;
- SourceLocation OpLoc, RParenLoc;
-
-public:
- UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo,
- QualType resultType, SourceLocation op,
- SourceLocation rp) :
- Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Never type-dependent (C++ [temp.dep.expr]p3).
- // Value-dependent if the argument is type-dependent.
- TInfo->getType()->isDependentType(),
- TInfo->getType()->isInstantiationDependentType(),
- TInfo->getType()->containsUnexpandedParameterPack()),
- OpLoc(op), RParenLoc(rp) {
- UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
- UnaryExprOrTypeTraitExprBits.IsType = true;
- Argument.Ty = TInfo;
- }
-
- UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E,
- QualType resultType, SourceLocation op,
- SourceLocation rp);
-
- /// \brief Construct an empty sizeof/alignof expression.
- explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty)
- : Expr(UnaryExprOrTypeTraitExprClass, Empty) { }
-
- UnaryExprOrTypeTrait getKind() const {
- return static_cast<UnaryExprOrTypeTrait>(UnaryExprOrTypeTraitExprBits.Kind);
- }
- void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;}
-
- bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; }
- QualType getArgumentType() const {
- return getArgumentTypeInfo()->getType();
- }
- TypeSourceInfo *getArgumentTypeInfo() const {
- assert(isArgumentType() && "calling getArgumentType() when arg is expr");
- return Argument.Ty;
- }
- Expr *getArgumentExpr() {
- assert(!isArgumentType() && "calling getArgumentExpr() when arg is type");
- return static_cast<Expr*>(Argument.Ex);
- }
- const Expr *getArgumentExpr() const {
- return const_cast<UnaryExprOrTypeTraitExpr*>(this)->getArgumentExpr();
- }
-
- void setArgument(Expr *E) {
- Argument.Ex = E;
- UnaryExprOrTypeTraitExprBits.IsType = false;
- }
- void setArgument(TypeSourceInfo *TInfo) {
- Argument.Ty = TInfo;
- UnaryExprOrTypeTraitExprBits.IsType = true;
- }
-
- /// Gets the argument type, or the type of the argument expression, whichever
- /// is appropriate.
- QualType getTypeOfArgument() const {
- return isArgumentType() ? getArgumentType() : getArgumentExpr()->getType();
- }
-
- SourceLocation getOperatorLoc() const { return OpLoc; }
- void setOperatorLoc(SourceLocation L) { OpLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return OpLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
- }
-
- // Iterators
- child_range children();
-};
-
-//===----------------------------------------------------------------------===//
-// Postfix Operators.
-//===----------------------------------------------------------------------===//
-
-/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
-class ArraySubscriptExpr : public Expr {
- enum { LHS, RHS, END_EXPR=2 };
- Stmt* SubExprs[END_EXPR];
- SourceLocation RBracketLoc;
-public:
- ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation rbracketloc)
- : Expr(ArraySubscriptExprClass, t, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- RBracketLoc(rbracketloc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- /// \brief Create an empty array subscript expression.
- explicit ArraySubscriptExpr(EmptyShell Shell)
- : Expr(ArraySubscriptExprClass, Shell) { }
-
- /// An array access can be written A[4] or 4[A] (both are equivalent).
- /// - getBase() and getIdx() always present the normalized view: A[4].
- /// In this case getBase() returns "A" and getIdx() returns "4".
- /// - getLHS() and getRHS() present the syntactic view. e.g. for
- /// 4[A] getLHS() returns "4".
- /// Note: Because vector element access is also written A[4] we must
- /// predicate the format conversion in getBase and getIdx only on the
- /// the type of the RHS, as it is possible for the LHS to be a vector of
- /// integer type
- Expr *getLHS() { return cast<Expr>(SubExprs[LHS]); }
- const Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- void setLHS(Expr *E) { SubExprs[LHS] = E; }
-
- Expr *getRHS() { return cast<Expr>(SubExprs[RHS]); }
- const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- void setRHS(Expr *E) { SubExprs[RHS] = E; }
-
- Expr *getBase() {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
- }
-
- const Expr *getBase() const {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
- }
-
- Expr *getIdx() {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
- }
-
- const Expr *getIdx() const {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getLHS()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getBase()->getExprLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ArraySubscriptExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
-/// CallExpr itself represents a normal function call, e.g., "f(x, 2)",
-/// while its subclasses may represent alternative syntax that (semantically)
-/// results in a function call. For example, CXXOperatorCallExpr is
-/// a subclass for overloaded operator calls that use operator syntax, e.g.,
-/// "str1 + str2" to resolve to a function call.
-class CallExpr : public Expr {
- enum { FN=0, PREARGS_START=1 };
- Stmt **SubExprs;
- unsigned NumArgs;
- SourceLocation RParenLoc;
-
-protected:
- // These versions of the constructor are for derived classes.
- CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation rparenloc);
- CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
- EmptyShell Empty);
-
- Stmt *getPreArg(unsigned i) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
- }
- const Stmt *getPreArg(unsigned i) const {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
- }
- void setPreArg(unsigned i, Stmt *PreArg) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- SubExprs[PREARGS_START+i] = PreArg;
- }
-
- unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
-
-public:
- CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc);
-
- /// \brief Build an empty call expression.
- CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty);
-
- const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
- Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
- void setCallee(Expr *F) { SubExprs[FN] = F; }
-
- Decl *getCalleeDecl();
- const Decl *getCalleeDecl() const {
- return const_cast<CallExpr*>(this)->getCalleeDecl();
- }
-
- /// \brief If the callee is a FunctionDecl, return it. Otherwise return 0.
- FunctionDecl *getDirectCallee();
- const FunctionDecl *getDirectCallee() const {
- return const_cast<CallExpr*>(this)->getDirectCallee();
- }
-
- /// getNumArgs - Return the number of actual arguments to this call.
- ///
- unsigned getNumArgs() const { return NumArgs; }
-
- /// \brief Retrieve the call arguments.
- Expr **getArgs() {
- return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START);
- }
- const Expr *const *getArgs() const {
- return reinterpret_cast<Expr **>(SubExprs + getNumPreArgs() +
- PREARGS_START);
- }
-
- /// getArg - Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
- }
-
- /// setArg - Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
- }
-
- /// setNumArgs - This changes the number of arguments present in this call.
- /// Any orphaned expressions are deleted by this, and any new operands are set
- /// to null.
- void setNumArgs(const ASTContext& C, unsigned NumArgs);
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
- typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
-
- arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
- }
-
- arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
- arg_iterator arg_end() {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
- }
- const_arg_iterator arg_begin() const {
- return SubExprs+PREARGS_START+getNumPreArgs();
- }
- const_arg_iterator arg_end() const {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
- }
-
- /// This method provides fast access to all the subexpressions of
- /// a CallExpr without going through the slower virtual child_iterator
- /// interface. This provides efficient reverse iteration of the
- /// subexpressions. This is currently used for CFG construction.
- ArrayRef<Stmt*> getRawSubExprs() {
- return llvm::makeArrayRef(SubExprs,
- getNumPreArgs() + PREARGS_START + getNumArgs());
- }
-
- /// getNumCommas - Return the number of commas that must have been present in
- /// this function call.
- unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
-
- /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
- /// of the callee. If not, return 0.
- unsigned getBuiltinCallee() const;
-
- /// \brief Returns \c true if this is a call to a builtin which does not
- /// evaluate side-effects within its arguments.
- bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const;
-
- /// getCallReturnType - Get the return type of the call expr. This is not
- /// always the type of the expr itself, if the return type is a reference
- /// type.
- QualType getCallReturnType(const ASTContext &Ctx) const;
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstCallExprConstant &&
- T->getStmtClass() <= lastCallExprConstant;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0],
- &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
- }
-};
-
-/// Extra data stored in some MemberExpr objects.
-struct MemberExprNameQualifier {
- /// \brief 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
- /// name qualifiers.
- DeclAccessPair FoundDecl;
-};
-
-/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F.
-///
-class MemberExpr final
- : public Expr,
- private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// Base - the expression for the base pointer or structure references. In
- /// X.F, this is "X".
- Stmt *Base;
-
- /// MemberDecl - This is the decl being referenced by the field/member name.
- /// In X.F, this is the decl referenced by F.
- ValueDecl *MemberDecl;
-
- /// MemberDNLoc - Provides source/type location info for the
- /// declaration name embedded in MemberDecl.
- DeclarationNameLoc MemberDNLoc;
-
- /// MemberLoc - This is the location of the member name.
- SourceLocation MemberLoc;
-
- /// This is the location of the -> or . in the expression.
- SourceLocation OperatorLoc;
-
- /// 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
- /// 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
- /// 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
- /// was resolved from an overloaded set having size greater than 1.
- bool HadMultipleCandidates : 1;
-
- size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const {
- return HasQualifierOrFoundDecl ? 1 : 0;
- }
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
-public:
- MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc,
- ValueDecl *memberdecl, const DeclarationNameInfo &NameInfo,
- QualType ty, ExprValueKind VK, ExprObjectKind OK)
- : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(),
- base->isValueDependent(), base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()),
- MemberLoc(NameInfo.getLoc()), OperatorLoc(operatorloc),
- IsArrow(isarrow), HasQualifierOrFoundDecl(false),
- HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) {
- assert(memberdecl->getDeclName() == NameInfo.getName());
- }
-
- // NOTE: this constructor should be used only when it is known that
- // the member name can not provide additional syntactic info
- // (i.e., source locations for C++ operator names or type source info
- // for constructors, destructors and conversion operators).
- MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc,
- ValueDecl *memberdecl, SourceLocation l, QualType ty,
- ExprValueKind VK, ExprObjectKind OK)
- : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(),
- base->isValueDependent(), base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l),
- OperatorLoc(operatorloc), IsArrow(isarrow),
- HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false),
- HadMultipleCandidates(false) {}
-
- static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *memberdecl,
- DeclAccessPair founddecl,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *targs, QualType ty,
- ExprValueKind VK, ExprObjectKind OK);
-
- void setBase(Expr *E) { Base = E; }
- Expr *getBase() const { return cast<Expr>(Base); }
-
- /// \brief Retrieve the member declaration to which this expression refers.
- ///
- /// The returned declaration will either be a FieldDecl or (in C++)
- /// a CXXMethodDecl.
- ValueDecl *getMemberDecl() const { return MemberDecl; }
- void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
-
- /// \brief Retrieves the declaration found by lookup.
- DeclAccessPair getFoundDecl() const {
- if (!HasQualifierOrFoundDecl)
- return DeclAccessPair::make(getMemberDecl(),
- getMemberDecl()->getAccess());
- return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
- }
-
- /// \brief Determines whether this member expression actually had
- /// a C++ nested-name-specifier prior to the name of the member, e.g.,
- /// x->Base::foo.
- bool hasQualifier() const { return getQualifier() != nullptr; }
-
- /// \brief If the member name was qualified, retrieves the
- /// nested-name-specifier that precedes the member name, with source-location
- /// information.
- NestedNameSpecifierLoc getQualifierLoc() const {
- if (!HasQualifierOrFoundDecl)
- return NestedNameSpecifierLoc();
-
- return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
- }
-
- /// \brief 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
- /// 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
- /// 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
- /// explicit template argument list following the member name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// 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
- /// explicit template argument list.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- /// \brief Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- /// \brief Retrieve the member declaration name info.
- DeclarationNameInfo getMemberNameInfo() const {
- return DeclarationNameInfo(MemberDecl->getDeclName(),
- MemberLoc, MemberDNLoc);
- }
-
- SourceLocation getOperatorLoc() const LLVM_READONLY { return OperatorLoc; }
-
- bool isArrow() const { return IsArrow; }
- void setArrow(bool A) { IsArrow = A; }
-
- /// getMemberLoc - Return the location of the "member", in X->F, it is the
- /// location of 'F'.
- SourceLocation getMemberLoc() const { return MemberLoc; }
- void setMemberLoc(SourceLocation L) { MemberLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- SourceLocation getExprLoc() const LLVM_READONLY { return MemberLoc; }
-
- /// \brief 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
- /// 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
- /// 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.
- /// 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.
- bool performsVirtualDispatch(const LangOptions &LO) const {
- return LO.AppleKext || !hasQualifier();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MemberExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
-
- friend TrailingObjects;
- friend class ASTReader;
- friend class ASTStmtWriter;
-};
-
-/// CompoundLiteralExpr - [C99 6.5.2.5]
-///
-class CompoundLiteralExpr : public Expr {
- /// LParenLoc - If non-null, this is the location of the left paren in a
- /// compound literal like "(int){4}". This can be null if this is a
- /// synthesized compound expression.
- SourceLocation LParenLoc;
-
- /// The type as written. This can be an incomplete array type, in
- /// which case the actual expression type will be different.
- /// The int part of the pair stores whether this expr is file scope.
- llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfoAndScope;
- Stmt *Init;
-public:
- CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
- QualType T, ExprValueKind VK, Expr *init, bool fileScope)
- : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary,
- tinfo->getType()->isDependentType(),
- init->isValueDependent(),
- (init->isInstantiationDependent() ||
- tinfo->getType()->isInstantiationDependentType()),
- init->containsUnexpandedParameterPack()),
- LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {}
-
- /// \brief Construct an empty compound literal.
- explicit CompoundLiteralExpr(EmptyShell Empty)
- : Expr(CompoundLiteralExprClass, Empty) { }
-
- const Expr *getInitializer() const { return cast<Expr>(Init); }
- Expr *getInitializer() { return cast<Expr>(Init); }
- void setInitializer(Expr *E) { Init = E; }
-
- bool isFileScope() const { return TInfoAndScope.getInt(); }
- void setFileScope(bool FS) { TInfoAndScope.setInt(FS); }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return TInfoAndScope.getPointer();
- }
- void setTypeSourceInfo(TypeSourceInfo *tinfo) {
- TInfoAndScope.setPointer(tinfo);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- // FIXME: Init should never be null.
- if (!Init)
- return SourceLocation();
- if (LParenLoc.isInvalid())
- return Init->getLocStart();
- return LParenLoc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- // FIXME: Init should never be null.
- if (!Init)
- return SourceLocation();
- return Init->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CompoundLiteralExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Init, &Init+1); }
-};
-
-/// CastExpr - Base class for type casts, including both implicit
-/// casts (ImplicitCastExpr) and explicit casts that have some
-/// representation in the source code (ExplicitCastExpr's derived
-/// classes).
-class CastExpr : public Expr {
-private:
- Stmt *Op;
-
- bool CastConsistency() const;
-
- const CXXBaseSpecifier * const *path_buffer() const {
- return const_cast<CastExpr*>(this)->path_buffer();
- }
- CXXBaseSpecifier **path_buffer();
-
- void setBasePathSize(unsigned basePathSize) {
- CastExprBits.BasePathSize = basePathSize;
- assert(CastExprBits.BasePathSize == basePathSize &&
- "basePathSize doesn't fit in bits of CastExprBits.BasePathSize!");
- }
-
-protected:
- CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
- Expr *op, unsigned BasePathSize)
- : Expr(SC, ty, VK, OK_Ordinary,
- // Cast expressions are type-dependent if the type is
- // dependent (C++ [temp.dep.expr]p3).
- ty->isDependentType(),
- // Cast expressions are value-dependent if the type is
- // dependent or if the subexpression is value-dependent.
- ty->isDependentType() || (op && op->isValueDependent()),
- (ty->isInstantiationDependentType() ||
- (op && op->isInstantiationDependent())),
- // An implicit cast expression doesn't (lexically) contain an
- // unexpanded pack, even if its target type does.
- ((SC != ImplicitCastExprClass &&
- ty->containsUnexpandedParameterPack()) ||
- (op && op->containsUnexpandedParameterPack()))),
- Op(op) {
- assert(kind != CK_Invalid && "creating cast with invalid cast kind");
- CastExprBits.Kind = kind;
- setBasePathSize(BasePathSize);
- assert(CastConsistency());
- }
-
- /// \brief Construct an empty cast.
- CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
- : Expr(SC, Empty) {
- setBasePathSize(BasePathSize);
- }
-
-public:
- CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
- void setCastKind(CastKind K) { CastExprBits.Kind = K; }
- const char *getCastKindName() const;
-
- 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
- /// code, looking through any implicit casts or other intermediate nodes
- /// introduced by semantic analysis.
- Expr *getSubExprAsWritten();
- const Expr *getSubExprAsWritten() const {
- return const_cast<CastExpr *>(this)->getSubExprAsWritten();
- }
-
- typedef CXXBaseSpecifier **path_iterator;
- typedef const CXXBaseSpecifier * const *path_const_iterator;
- bool path_empty() const { return CastExprBits.BasePathSize == 0; }
- unsigned path_size() const { return CastExprBits.BasePathSize; }
- path_iterator path_begin() { return path_buffer(); }
- path_iterator path_end() { return path_buffer() + path_size(); }
- path_const_iterator path_begin() const { return path_buffer(); }
- path_const_iterator path_end() const { return path_buffer() + path_size(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstCastExprConstant &&
- T->getStmtClass() <= lastCastExprConstant;
- }
-
- // Iterators
- child_range children() { return child_range(&Op, &Op+1); }
-};
-
-/// ImplicitCastExpr - Allows us to explicitly represent implicit type
-/// conversions, which have no direct representation in the original
-/// source code. For example: converting T[]->T*, void f()->void
-/// (*f)(), float->double, short->int, etc.
-///
-/// In C, implicit casts always produce rvalues. However, in C++, an
-/// implicit cast whose result is being bound to a reference will be
-/// an lvalue or xvalue. For example:
-///
-/// @code
-/// class Base { };
-/// class Derived : public Base { };
-/// Derived &&ref();
-/// void f(Derived d) {
-/// Base& b = d; // initializer is an ImplicitCastExpr
-/// // to an lvalue of type Base
-/// Base&& r = ref(); // initializer is an ImplicitCastExpr
-/// // to an xvalue of type Base
-/// }
-/// @endcode
-class ImplicitCastExpr final
- : public CastExpr,
- private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> {
-private:
- ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
- unsigned BasePathLength, ExprValueKind VK)
- : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) {
- }
-
- /// \brief Construct an empty implicit cast.
- explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
- : CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
-
-public:
- enum OnStack_t { OnStack };
- ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
- ExprValueKind VK)
- : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) {
- }
-
- static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
- CastKind Kind, Expr *Operand,
- const CXXCastPath *BasePath,
- ExprValueKind Cat);
-
- static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSubExpr()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImplicitCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-inline Expr *Expr::IgnoreImpCasts() {
- Expr *e = this;
- while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
- e = ice->getSubExpr();
- return e;
-}
-
-/// ExplicitCastExpr - An explicit cast written in the source
-/// code.
-///
-/// This class is effectively an abstract class, because it provides
-/// the basic representation of an explicitly-written cast without
-/// specifying which kind of cast (C cast, functional cast, static
-/// cast, etc.) was written; specific derived classes represent the
-/// particular style of cast and its location information.
-///
-/// Unlike implicit casts, explicit cast nodes have two different
-/// types: the type that was written into the source code, and the
-/// actual type of the expression as determined by semantic
-/// analysis. These types may differ slightly. For example, in C++ one
-/// can cast to a reference type, which indicates that the resulting
-/// expression will be an lvalue or xvalue. The reference type, however,
-/// will not be used as the type of the expression.
-class ExplicitCastExpr : public CastExpr {
- /// TInfo - Source type info for the (written) type
- /// this expression is casting to.
- TypeSourceInfo *TInfo;
-
-protected:
- ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK,
- CastKind kind, Expr *op, unsigned PathSize,
- TypeSourceInfo *writtenTy)
- : CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {}
-
- /// \brief Construct an empty explicit cast.
- ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
- : CastExpr(SC, Shell, PathSize) { }
-
-public:
- /// getTypeInfoAsWritten - Returns the type source info for the type
- /// that this expression is casting to.
- TypeSourceInfo *getTypeInfoAsWritten() const { return TInfo; }
- void setTypeInfoAsWritten(TypeSourceInfo *writtenTy) { TInfo = writtenTy; }
-
- /// getTypeAsWritten - Returns the type that this expression is
- /// casting to, as written in the source code.
- QualType getTypeAsWritten() const { return TInfo->getType(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstExplicitCastExprConstant &&
- T->getStmtClass() <= lastExplicitCastExprConstant;
- }
-};
-
-/// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style
-/// cast in C++ (C++ [expr.cast]), which uses the syntax
-/// (Type)expr. For example: @c (int)f.
-class CStyleCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> {
- SourceLocation LPLoc; // the location of the left paren
- SourceLocation RPLoc; // the location of the right paren
-
- CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op,
- unsigned PathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation r)
- : ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
- writtenTy), LPLoc(l), RPLoc(r) {}
-
- /// \brief Construct an empty C-style explicit cast.
- explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
-
-public:
- static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind K,
- Expr *Op, const CXXCastPath *BasePath,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation R);
-
- static CStyleCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- SourceLocation getLParenLoc() const { return LPLoc; }
- void setLParenLoc(SourceLocation L) { LPLoc = L; }
-
- SourceLocation getRParenLoc() const { return RPLoc; }
- void setRParenLoc(SourceLocation L) { RPLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LPLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CStyleCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief 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
-/// already have been converted to appropriate types (e.g., by
-/// performing promotions or conversions).
-///
-/// In C++, where operators may be overloaded, a different kind of
-/// expression node (CXXOperatorCallExpr) is used to express the
-/// invocation of an overloaded operator with operator syntax. Within
-/// a C++ template, whether BinaryOperator or CXXOperatorCallExpr is
-/// used to store an expression "x + y" depends on the subexpressions
-/// for x and y. If neither x or y is type-dependent, and the "+"
-/// operator resolves to a built-in operation, BinaryOperator will be
-/// used to express the computation (x and y may still be
-/// value-dependent). If either x or y is type-dependent, or if the
-/// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
-/// be used to express the computation.
-class BinaryOperator : public Expr {
-public:
- typedef BinaryOperatorKind Opcode;
-
-private:
- unsigned Opc : 6;
-
- // Records the FP_CONTRACT pragma status at the point that this binary
- // operator was parsed. This bit is only meaningful for operations on
- // floating point types. For all other types it should default to
- // false.
- unsigned FPContractable : 1;
- SourceLocation OpLoc;
-
- enum { LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR];
-public:
-
- BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, bool fpContractable)
- : Expr(BinaryOperatorClass, ResTy, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- assert(!isCompoundAssignmentOp() &&
- "Use CompoundAssignOperator for compound assignments");
- }
-
- /// \brief Construct an empty binary operator.
- explicit BinaryOperator(EmptyShell Empty)
- : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
-
- SourceLocation getExprLoc() const LLVM_READONLY { return OpLoc; }
- SourceLocation getOperatorLoc() const { return OpLoc; }
- void setOperatorLoc(SourceLocation L) { OpLoc = L; }
-
- Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
- void setOpcode(Opcode O) { Opc = O; }
-
- Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- void setLHS(Expr *E) { SubExprs[LHS] = E; }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- void setRHS(Expr *E) { SubExprs[RHS] = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getLHS()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getRHS()->getLocEnd();
- }
-
- /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
- /// corresponds to, e.g. "<<=".
- static StringRef getOpcodeStr(Opcode Op);
-
- StringRef getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
-
- /// \brief 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
- /// the given binary opcode.
- static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
-
- /// predicates to categorize the respective opcodes.
- bool isPtrMemOp() const { return Opc == BO_PtrMemD || Opc == BO_PtrMemI; }
- static bool isMultiplicativeOp(Opcode Opc) {
- return Opc >= BO_Mul && Opc <= BO_Rem;
- }
- bool isMultiplicativeOp() const { return isMultiplicativeOp(getOpcode()); }
- static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; }
- bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); }
- static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; }
- bool isShiftOp() const { return isShiftOp(getOpcode()); }
-
- static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; }
- bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); }
-
- static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; }
- bool isRelationalOp() const { return isRelationalOp(getOpcode()); }
-
- static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
- bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
-
- static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
- bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
-
- static Opcode negateComparisonOp(Opcode Opc) {
- switch (Opc) {
- default:
- llvm_unreachable("Not a comparsion operator.");
- case BO_LT: return BO_GE;
- case BO_GT: return BO_LE;
- case BO_LE: return BO_GT;
- case BO_GE: return BO_LT;
- case BO_EQ: return BO_NE;
- case BO_NE: return BO_EQ;
- }
- }
-
- static Opcode reverseComparisonOp(Opcode Opc) {
- switch (Opc) {
- default:
- llvm_unreachable("Not a comparsion operator.");
- case BO_LT: return BO_GT;
- case BO_GT: return BO_LT;
- case BO_LE: return BO_GE;
- case BO_GE: return BO_LE;
- case BO_EQ:
- case BO_NE:
- return Opc;
- }
- }
-
- static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; }
- bool isLogicalOp() const { return isLogicalOp(getOpcode()); }
-
- static bool isAssignmentOp(Opcode Opc) {
- return Opc >= BO_Assign && Opc <= BO_OrAssign;
- }
- bool isAssignmentOp() const { return isAssignmentOp(getOpcode()); }
-
- static bool isCompoundAssignmentOp(Opcode Opc) {
- return Opc > BO_Assign && Opc <= BO_OrAssign;
- }
- bool isCompoundAssignmentOp() const {
- return isCompoundAssignmentOp(getOpcode());
- }
- static Opcode getOpForCompoundAssignment(Opcode Opc) {
- assert(isCompoundAssignmentOp(Opc));
- if (Opc >= BO_AndAssign)
- return Opcode(unsigned(Opc) - BO_AndAssign + BO_And);
- else
- return Opcode(unsigned(Opc) - BO_MulAssign + BO_Mul);
- }
-
- static bool isShiftAssignOp(Opcode Opc) {
- return Opc == BO_ShlAssign || Opc == BO_ShrAssign;
- }
- bool isShiftAssignOp() const {
- return isShiftAssignOp(getOpcode());
- }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() >= firstBinaryOperatorConstant &&
- S->getStmtClass() <= lastBinaryOperatorConstant;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-
- // Set the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- void setFPContractable(bool FPC) { FPContractable = FPC; }
-
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- bool isFPContractable() const { return FPContractable; }
-
-protected:
- BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, bool fpContractable, bool dead2)
- : Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- BinaryOperator(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Opc(BO_MulAssign) { }
-};
-
-/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
-/// track of the type the operation is performed in. Due to the semantics of
-/// these operators, the operands are promoted, the arithmetic performed, an
-/// implicit conversion back to the result type done, then the assignment takes
-/// place. This captures the intermediate type which the computation is done
-/// in.
-class CompoundAssignOperator : public BinaryOperator {
- QualType ComputationLHSType;
- QualType ComputationResultType;
-public:
- CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
- ExprValueKind VK, ExprObjectKind OK,
- QualType CompLHSType, QualType CompResultType,
- SourceLocation OpLoc, bool fpContractable)
- : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable,
- true),
- ComputationLHSType(CompLHSType),
- ComputationResultType(CompResultType) {
- assert(isCompoundAssignmentOp() &&
- "Only should be used for compound assignments");
- }
-
- /// \brief Build an empty compound assignment operator expression.
- explicit CompoundAssignOperator(EmptyShell Empty)
- : BinaryOperator(CompoundAssignOperatorClass, Empty) { }
-
- // The two computation types are the type the LHS is converted
- // to for the computation and the type of the result; the two are
- // distinct in a few cases (specifically, int+=ptr and ptr-=ptr).
- QualType getComputationLHSType() const { return ComputationLHSType; }
- void setComputationLHSType(QualType T) { ComputationLHSType = T; }
-
- QualType getComputationResultType() const { return ComputationResultType; }
- void setComputationResultType(QualType T) { ComputationResultType = T; }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == CompoundAssignOperatorClass;
- }
-};
-
-/// AbstractConditionalOperator - An abstract base class for
-/// ConditionalOperator and BinaryConditionalOperator.
-class AbstractConditionalOperator : public Expr {
- SourceLocation QuestionLoc, ColonLoc;
- friend class ASTStmtReader;
-
-protected:
- AbstractConditionalOperator(StmtClass SC, QualType T,
- ExprValueKind VK, ExprObjectKind OK,
- bool TD, bool VD, bool ID,
- bool ContainsUnexpandedParameterPack,
- SourceLocation qloc,
- SourceLocation cloc)
- : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack),
- QuestionLoc(qloc), ColonLoc(cloc) {}
-
- AbstractConditionalOperator(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty) { }
-
-public:
- // getCond - Return the expression representing the condition for
- // the ?: operator.
- Expr *getCond() const;
-
- // getTrueExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to true.
- Expr *getTrueExpr() const;
-
- // getFalseExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to false. This is
- // the same as getRHS.
- Expr *getFalseExpr() const;
-
- SourceLocation getQuestionLoc() const { return QuestionLoc; }
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConditionalOperatorClass ||
- T->getStmtClass() == BinaryConditionalOperatorClass;
- }
-};
-
-/// ConditionalOperator - The ?: ternary operator. The GNU "missing
-/// middle" extension is a BinaryConditionalOperator.
-class ConditionalOperator : public AbstractConditionalOperator {
- enum { COND, LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
-
- friend class ASTStmtReader;
-public:
- ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
- SourceLocation CLoc, Expr *rhs,
- QualType t, ExprValueKind VK, ExprObjectKind OK)
- : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK,
- // FIXME: the type of the conditional operator doesn't
- // depend on the type of the conditional, but the standard
- // seems to imply that it could. File a bug!
- (lhs->isTypeDependent() || rhs->isTypeDependent()),
- (cond->isValueDependent() || lhs->isValueDependent() ||
- rhs->isValueDependent()),
- (cond->isInstantiationDependent() ||
- lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (cond->containsUnexpandedParameterPack() ||
- lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack()),
- QLoc, CLoc) {
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- /// \brief Build an empty conditional operator.
- explicit ConditionalOperator(EmptyShell Empty)
- : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { }
-
- // getCond - Return the expression representing the condition for
- // the ?: operator.
- Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
-
- // getTrueExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to true.
- Expr *getTrueExpr() const { return cast<Expr>(SubExprs[LHS]); }
-
- // getFalseExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to false. This is
- // the same as getRHS.
- Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
-
- Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCond()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getRHS()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConditionalOperatorClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// BinaryConditionalOperator - The GNU extension to the conditional
-/// operator which allows the middle operand to be omitted.
-///
-/// This is a different expression kind on the assumption that almost
-/// every client ends up needing to know that these are different.
-class BinaryConditionalOperator : public AbstractConditionalOperator {
- enum { COMMON, COND, LHS, RHS, NUM_SUBEXPRS };
-
- /// - the common condition/left-hand-side expression, which will be
- /// evaluated as the opaque value
- /// - the condition, expressed in terms of the opaque value
- /// - the left-hand-side, expressed in terms of the opaque value
- /// - the right-hand-side
- Stmt *SubExprs[NUM_SUBEXPRS];
- OpaqueValueExpr *OpaqueValue;
-
- friend class ASTStmtReader;
-public:
- BinaryConditionalOperator(Expr *common, OpaqueValueExpr *opaqueValue,
- Expr *cond, Expr *lhs, Expr *rhs,
- SourceLocation qloc, SourceLocation cloc,
- QualType t, ExprValueKind VK, ExprObjectKind OK)
- : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
- (common->isTypeDependent() || rhs->isTypeDependent()),
- (common->isValueDependent() || rhs->isValueDependent()),
- (common->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (common->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack()),
- qloc, cloc),
- OpaqueValue(opaqueValue) {
- SubExprs[COMMON] = common;
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- assert(OpaqueValue->getSourceExpr() == common && "Wrong opaque value");
- }
-
- /// \brief Build an empty conditional operator.
- explicit BinaryConditionalOperator(EmptyShell Empty)
- : AbstractConditionalOperator(BinaryConditionalOperatorClass, Empty) { }
-
- /// \brief 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.
- OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
-
- /// \brief 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
- /// 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
- /// evaluated if the condnition evaluates to false; this is
- /// defined in terms of the opaque value.
- Expr *getFalseExpr() const {
- return cast<Expr>(SubExprs[RHS]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCommon()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getFalseExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BinaryConditionalOperatorClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
- }
-};
-
-inline Expr *AbstractConditionalOperator::getCond() const {
- if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
- return co->getCond();
- return cast<BinaryConditionalOperator>(this)->getCond();
-}
-
-inline Expr *AbstractConditionalOperator::getTrueExpr() const {
- if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
- return co->getTrueExpr();
- return cast<BinaryConditionalOperator>(this)->getTrueExpr();
-}
-
-inline Expr *AbstractConditionalOperator::getFalseExpr() const {
- if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
- return co->getFalseExpr();
- return cast<BinaryConditionalOperator>(this)->getFalseExpr();
-}
-
-/// AddrLabelExpr - The GNU address of label extension, representing &&label.
-class AddrLabelExpr : public Expr {
- SourceLocation AmpAmpLoc, LabelLoc;
- LabelDecl *Label;
-public:
- AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
- QualType t)
- : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false,
- false),
- AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
-
- /// \brief Build an empty address of a label expression.
- explicit AddrLabelExpr(EmptyShell Empty)
- : Expr(AddrLabelExprClass, Empty) { }
-
- SourceLocation getAmpAmpLoc() const { return AmpAmpLoc; }
- void setAmpAmpLoc(SourceLocation L) { AmpAmpLoc = L; }
- SourceLocation getLabelLoc() const { return LabelLoc; }
- void setLabelLoc(SourceLocation L) { LabelLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AmpAmpLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
-
- LabelDecl *getLabel() const { return Label; }
- void setLabel(LabelDecl *L) { Label = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AddrLabelExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
-/// The StmtExpr contains a single CompoundStmt node, which it evaluates and
-/// takes the value of the last subexpression.
-///
-/// A StmtExpr is always an r-value; values "returned" out of a
-/// StmtExpr will be copied.
-class StmtExpr : public Expr {
- Stmt *SubStmt;
- SourceLocation LParenLoc, RParenLoc;
-public:
- // FIXME: Does type-dependence need to be computed differently?
- // FIXME: Do we need to compute instantiation instantiation-dependence for
- // statements? (ugh!)
- StmtExpr(CompoundStmt *substmt, QualType T,
- SourceLocation lp, SourceLocation rp) :
- Expr(StmtExprClass, T, VK_RValue, OK_Ordinary,
- T->isDependentType(), false, false, false),
- SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
-
- /// \brief Build an empty statement expression.
- explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { }
-
- CompoundStmt *getSubStmt() { return cast<CompoundStmt>(SubStmt); }
- const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
- void setSubStmt(CompoundStmt *S) { SubStmt = S; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == StmtExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubStmt, &SubStmt+1); }
-};
-
-/// ShuffleVectorExpr - clang-specific builtin-in function
-/// __builtin_shufflevector.
-/// This AST node represents a operator that does a constant
-/// shuffle, similar to LLVM's shufflevector instruction. It takes
-/// two vectors and a variable number of constant indices,
-/// and returns the appropriately shuffled vector.
-class ShuffleVectorExpr : public Expr {
- SourceLocation BuiltinLoc, RParenLoc;
-
- // SubExprs - the list of values passed to the __builtin_shufflevector
- // function. The first two are vectors, and the rest are constant
- // indices. The number of values in this list is always
- // 2+the number of indices in the vector type.
- Stmt **SubExprs;
- unsigned NumExprs;
-
-public:
- ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type,
- SourceLocation BLoc, SourceLocation RP);
-
- /// \brief Build an empty vector-shuffle expression.
- explicit ShuffleVectorExpr(EmptyShell Empty)
- : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
-
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
- void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ShuffleVectorExprClass;
- }
-
- /// getNumSubExprs - Return the size of the SubExprs array. This includes the
- /// constant expression, the actual arguments passed in, and the function
- /// pointers.
- unsigned getNumSubExprs() const { return NumExprs; }
-
- /// \brief Retrieve the array of expressions.
- Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
-
- /// getExpr - Return the Expr at the specified index.
- Expr *getExpr(unsigned Index) {
- assert((Index < NumExprs) && "Arg access out of range!");
- return cast<Expr>(SubExprs[Index]);
- }
- const Expr *getExpr(unsigned Index) const {
- assert((Index < NumExprs) && "Arg access out of range!");
- return cast<Expr>(SubExprs[Index]);
- }
-
- void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs);
-
- llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const {
- assert((N < NumExprs - 2) && "Shuffle idx out of range!");
- return getExpr(N+2)->EvaluateKnownConstInt(Ctx);
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+NumExprs);
- }
-};
-
-/// ConvertVectorExpr - Clang builtin function __builtin_convertvector
-/// This AST node provides support for converting a vector type to another
-/// vector type of the same arity.
-class ConvertVectorExpr : public Expr {
-private:
- Stmt *SrcExpr;
- TypeSourceInfo *TInfo;
- SourceLocation BuiltinLoc, RParenLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {}
-
-public:
- ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation BuiltinLoc, SourceLocation RParenLoc)
- : Expr(ConvertVectorExprClass, DstType, VK, OK,
- DstType->isDependentType(),
- DstType->isDependentType() || SrcExpr->isValueDependent(),
- (DstType->isInstantiationDependentType() ||
- SrcExpr->isInstantiationDependent()),
- (DstType->containsUnexpandedParameterPack() ||
- SrcExpr->containsUnexpandedParameterPack())),
- SrcExpr(SrcExpr), TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
-
- /// getSrcExpr - Return the Expr to be converted.
- Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
-
- /// getTypeSourceInfo - Return the destination type.
- TypeSourceInfo *getTypeSourceInfo() const {
- return TInfo;
- }
- void setTypeSourceInfo(TypeSourceInfo *ti) {
- TInfo = ti;
- }
-
- /// getBuiltinLoc - Return the location of the __builtin_convertvector token.
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
-
- /// getRParenLoc - Return the location of final right parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConvertVectorExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
-};
-
-/// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
-/// This AST node is similar to the conditional operator (?:) in C, with
-/// the following exceptions:
-/// - the test expression must be a integer constant expression.
-/// - the expression returned acts like the chosen subexpression in every
-/// visible way: the type is the same as that of the chosen subexpression,
-/// and all predicates (whether it's an l-value, whether it's an integer
-/// constant expression, etc.) return the same result as for the chosen
-/// sub-expression.
-class ChooseExpr : public Expr {
- enum { COND, LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
- SourceLocation BuiltinLoc, RParenLoc;
- bool CondIsTrue;
-public:
- ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs,
- QualType t, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation RP, bool condIsTrue,
- bool TypeDependent, bool ValueDependent)
- : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent,
- (cond->isInstantiationDependent() ||
- lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (cond->containsUnexpandedParameterPack() ||
- lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- BuiltinLoc(BLoc), RParenLoc(RP), CondIsTrue(condIsTrue) {
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- /// \brief Build an empty __builtin_choose_expr.
- explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { }
-
- /// isConditionTrue - Return whether the condition is true (i.e. not
- /// equal to zero).
- bool isConditionTrue() const {
- assert(!isConditionDependent() &&
- "Dependent condition isn't true or false");
- return CondIsTrue;
- }
- void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; }
-
- bool isConditionDependent() const {
- return getCond()->isTypeDependent() || getCond()->isValueDependent();
- }
-
- /// getChosenSubExpr - Return the subexpression chosen according to the
- /// condition.
- Expr *getChosenSubExpr() const {
- return isConditionTrue() ? getLHS() : getRHS();
- }
-
- Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
- void setCond(Expr *E) { SubExprs[COND] = E; }
- Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- void setLHS(Expr *E) { SubExprs[LHS] = E; }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- void setRHS(Expr *E) { SubExprs[RHS] = E; }
-
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
- void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ChooseExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// GNUNullExpr - Implements the GNU __null extension, which is a name
-/// for a null pointer constant that has integral type (e.g., int or
-/// long) and is the same size and alignment as a pointer. The __null
-/// extension is typically only used by system headers, which define
-/// NULL as __null in C++ rather than using 0 (which is an integer
-/// that may not match the size of a pointer).
-class GNUNullExpr : public Expr {
- /// TokenLoc - The location of the __null keyword.
- SourceLocation TokenLoc;
-
-public:
- GNUNullExpr(QualType Ty, SourceLocation Loc)
- : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false,
- false),
- TokenLoc(Loc) { }
-
- /// \brief Build an empty GNU __null expression.
- explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { }
-
- /// getTokenLocation - The location of the __null token.
- SourceLocation getTokenLocation() const { return TokenLoc; }
- void setTokenLocation(SourceLocation L) { TokenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return TokenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return TokenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GNUNullExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// Represents a call to the builtin function \c __builtin_va_arg.
-class VAArgExpr : public Expr {
- Stmt *Val;
- llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfo;
- SourceLocation BuiltinLoc, RParenLoc;
-public:
- VAArgExpr(SourceLocation BLoc, Expr *e, TypeSourceInfo *TInfo,
- SourceLocation RPLoc, QualType t, bool IsMS)
- : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, t->isDependentType(),
- false, (TInfo->getType()->isInstantiationDependentType() ||
- e->isInstantiationDependent()),
- (TInfo->getType()->containsUnexpandedParameterPack() ||
- e->containsUnexpandedParameterPack())),
- Val(e), TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) {}
-
- /// Create an empty __builtin_va_arg expression.
- explicit VAArgExpr(EmptyShell Empty)
- : Expr(VAArgExprClass, Empty), Val(nullptr), TInfo(nullptr, false) {}
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
- void setSubExpr(Expr *E) { Val = E; }
-
- /// Returns whether this is really a Win64 ABI va_arg expression.
- bool isMicrosoftABI() const { return TInfo.getInt(); }
- void setIsMicrosoftABI(bool IsMS) { TInfo.setInt(IsMS); }
-
- TypeSourceInfo *getWrittenTypeInfo() const { return TInfo.getPointer(); }
- void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo.setPointer(TI); }
-
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
- void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == VAArgExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Val, &Val+1); }
-};
-
-/// @brief Describes an C or C++ initializer list.
-///
-/// InitListExpr describes an initializer list, which can be used to
-/// initialize objects of different types, including
-/// struct/class/union types, arrays, and vectors. For example:
-///
-/// @code
-/// struct foo x = { 1, { 2, 3 } };
-/// @endcode
-///
-/// Prior to semantic analysis, an initializer list will represent the
-/// initializer list as written by the user, but will have the
-/// placeholder type "void". This initializer list is called the
-/// syntactic form of the initializer, and may contain C99 designated
-/// initializers (represented as DesignatedInitExprs), initializations
-/// of subobject members without explicit braces, and so on. Clients
-/// interested in the original syntax of the initializer list should
-/// use the syntactic form of the initializer list.
-///
-/// After semantic analysis, the initializer list will represent the
-/// semantic form of the initializer, where the initializations of all
-/// subobjects are made explicit with nested InitListExpr nodes and
-/// C99 designators have been eliminated by placing the designated
-/// initializations into the subobject they initialize. Additionally,
-/// any "holes" in the initialization, where no initializer has been
-/// specified for a particular subobject, will be replaced with
-/// implicitly-generated ImplicitValueInitExpr expressions that
-/// value-initialize the subobjects. Note, however, that the
-/// initializer lists may still have fewer initializers than there are
-/// elements to initialize within the object.
-///
-/// After semantic analysis has completed, given an initializer list,
-/// method isSemanticForm() returns true if and only if this is the
-/// semantic form of the initializer list (note: the same AST node
-/// may at the same time be the syntactic form).
-/// Given the semantic form of the initializer list, one can retrieve
-/// the syntactic form of that initializer list (when different)
-/// using method getSyntacticForm(); the method returns null if applied
-/// to a initializer list which is already in syntactic form.
-/// Similarly, given the syntactic form (i.e., an initializer list such
-/// that isSemanticForm() returns false), one can retrieve the semantic
-/// form using method getSemanticForm().
-/// Since many initializer lists have the same syntactic and semantic forms,
-/// getSyntacticForm() may return NULL, indicating that the current
-/// semantic initializer list also serves as its syntactic form.
-class InitListExpr : public Expr {
- // FIXME: Eliminate this vector in favor of ASTContext allocation
- typedef ASTVector<Stmt *> InitExprsTy;
- InitExprsTy InitExprs;
- SourceLocation LBraceLoc, RBraceLoc;
-
- /// The alternative form of the initializer list (if it exists).
- /// The int part of the pair stores whether this initializer list is
- /// in semantic form. If not null, the pointer points to:
- /// - the syntactic form, if this is in semantic form;
- /// - the semantic form, if this is in syntactic form.
- llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm;
-
- /// \brief 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.
- /// Or
- /// If this initializer list initializes a union, specifies which
- /// field within the union will be initialized.
- llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
-
-public:
- InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
- ArrayRef<Expr*> initExprs, SourceLocation rbraceloc);
-
- /// \brief Build an empty initializer list.
- explicit InitListExpr(EmptyShell Empty)
- : Expr(InitListExprClass, Empty) { }
-
- unsigned getNumInits() const { return InitExprs.size(); }
-
- /// \brief Retrieve the set of initializers.
- Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
-
- ArrayRef<Expr *> inits() {
- return llvm::makeArrayRef(getInits(), getNumInits());
- }
-
- const Expr *getInit(unsigned Init) const {
- assert(Init < getNumInits() && "Initializer access out of range!");
- return cast_or_null<Expr>(InitExprs[Init]);
- }
-
- Expr *getInit(unsigned Init) {
- assert(Init < getNumInits() && "Initializer access out of range!");
- return cast_or_null<Expr>(InitExprs[Init]);
- }
-
- void setInit(unsigned Init, Expr *expr) {
- assert(Init < getNumInits() && "Initializer access out of range!");
- InitExprs[Init] = expr;
-
- if (expr) {
- ExprBits.TypeDependent |= expr->isTypeDependent();
- ExprBits.ValueDependent |= expr->isValueDependent();
- ExprBits.InstantiationDependent |= expr->isInstantiationDependent();
- ExprBits.ContainsUnexpandedParameterPack |=
- expr->containsUnexpandedParameterPack();
- }
- }
-
- /// \brief Reserve space for some number of initializers.
- void reserveInits(const ASTContext &C, unsigned NumInits);
-
- /// @brief 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
- /// NumInits initializers, NULL expressions will be added for the
- /// unknown initializers.
- void resizeInits(const ASTContext &Context, unsigned NumInits);
-
- /// @brief Updates the initializer at index @p Init with the new
- /// expression @p expr, and returns the old expression at that
- /// location.
- ///
- /// When @p Init is out of range for this initializer list, the
- /// initializer list will be extended with NULL expressions to
- /// accommodate the new entry.
- Expr *updateInit(const ASTContext &C, unsigned Init, Expr *expr);
-
- /// \brief 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() {
- return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
- }
- const Expr *getArrayFiller() const {
- return const_cast<InitListExpr *>(this)->getArrayFiller();
- }
- void setArrayFiller(Expr *filler);
-
- /// \brief 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
- /// union to initialize.
- ///
- /// Typically, this field is the first named field within the
- /// union. However, a designated initializer can specify the
- /// initialization of a different field within the union.
- FieldDecl *getInitializedFieldInUnion() {
- return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
- }
- const FieldDecl *getInitializedFieldInUnion() const {
- return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
- }
- void setInitializedFieldInUnion(FieldDecl *FD) {
- assert((FD == nullptr
- || getInitializedFieldInUnion() == nullptr
- || getInitializedFieldInUnion() == FD)
- && "Only one field of a union may be initialized at a time!");
- ArrayFillerOrUnionFieldInit = FD;
- }
-
- // Explicit InitListExpr's originate from source code (and have valid source
- // locations). Implicit InitListExpr's are created by the semantic analyzer.
- bool isExplicit() {
- return LBraceLoc.isValid() && RBraceLoc.isValid();
- }
-
- // Is this an initializer for an array of characters, initialized by a string
- // literal or an @encode?
- bool isStringLiteralInit() const;
-
- SourceLocation getLBraceLoc() const { return LBraceLoc; }
- void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
- SourceLocation getRBraceLoc() const { return RBraceLoc; }
- void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
-
- bool isSemanticForm() const { return AltForm.getInt(); }
- InitListExpr *getSemanticForm() const {
- return isSemanticForm() ? nullptr : AltForm.getPointer();
- }
- InitListExpr *getSyntacticForm() const {
- return isSemanticForm() ? AltForm.getPointer() : nullptr;
- }
-
- void setSyntacticForm(InitListExpr *Init) {
- AltForm.setPointer(Init);
- AltForm.setInt(true);
- Init->AltForm.setPointer(this);
- Init->AltForm.setInt(false);
- }
-
- bool hadArrayRangeDesignator() const {
- return InitListExprBits.HadArrayRangeDesignator != 0;
- }
- void sawArrayRangeDesignator(bool ARD = true) {
- InitListExprBits.HadArrayRangeDesignator = ARD;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == InitListExprClass;
- }
-
- // Iterators
- child_range children() {
- // FIXME: This does not include the array filler expression.
- if (InitExprs.empty())
- return child_range(child_iterator(), child_iterator());
- return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
- }
-
- typedef InitExprsTy::iterator iterator;
- typedef InitExprsTy::const_iterator const_iterator;
- typedef InitExprsTy::reverse_iterator reverse_iterator;
- typedef InitExprsTy::const_reverse_iterator const_reverse_iterator;
-
- iterator begin() { return InitExprs.begin(); }
- const_iterator begin() const { return InitExprs.begin(); }
- iterator end() { return InitExprs.end(); }
- const_iterator end() const { return InitExprs.end(); }
- reverse_iterator rbegin() { return InitExprs.rbegin(); }
- const_reverse_iterator rbegin() const { return InitExprs.rbegin(); }
- reverse_iterator rend() { return InitExprs.rend(); }
- const_reverse_iterator rend() const { return InitExprs.rend(); }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// @brief 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
-/// designators, or GNU array-range designators) followed by an
-/// expression that initializes the field or element(s) that the
-/// designators refer to. For example, given:
-///
-/// @code
-/// struct point {
-/// double x;
-/// double y;
-/// };
-/// struct point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
-/// @endcode
-///
-/// The InitListExpr contains three DesignatedInitExprs, the first of
-/// which covers @c [2].y=1.0. This DesignatedInitExpr will have two
-/// designators, one array designator for @c [2] followed by one field
-/// designator for @c .y. The initialization expression will be 1.0.
-class DesignatedInitExpr final
- : public Expr,
- private llvm::TrailingObjects<DesignatedInitExpr, Stmt *> {
-public:
- /// \brief Forward declaration of the Designator class.
- class Designator;
-
-private:
- /// The location of the '=' or ':' prior to the actual initializer
- /// expression.
- SourceLocation EqualOrColonLoc;
-
- /// Whether this designated initializer used the GNU deprecated
- /// syntax rather than the C99 '=' syntax.
- bool GNUSyntax : 1;
-
- /// The number of designators in this initializer expression.
- unsigned NumDesignators : 15;
-
- /// The number of subexpressions of this initializer expression,
- /// which contains both the initializer and any additional
- /// expressions used by array and array-range designators.
- unsigned NumSubExprs : 16;
-
- /// \brief The designators in this designated initialization
- /// expression.
- Designator *Designators;
-
-
- DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators,
- const Designator *Designators,
- SourceLocation EqualOrColonLoc, bool GNUSyntax,
- ArrayRef<Expr*> IndexExprs, Expr *Init);
-
- explicit DesignatedInitExpr(unsigned NumSubExprs)
- : Expr(DesignatedInitExprClass, EmptyShell()),
- NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
-
-public:
- /// A field designator, e.g., ".x".
- struct FieldDesignator {
- /// Refers to the field that is being initialized. The low bit
- /// of this field determines whether this is actually a pointer
- /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
- /// initially constructed, a field designator will store an
- /// IdentifierInfo*. After semantic analysis has resolved that
- /// name, the field designator will instead store a FieldDecl*.
- uintptr_t NameOrField;
-
- /// The location of the '.' in the designated initializer.
- unsigned DotLoc;
-
- /// The location of the field name in the designated initializer.
- unsigned FieldLoc;
- };
-
- /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
- struct ArrayOrRangeDesignator {
- /// Location of the first index expression within the designated
- /// initializer expression's list of subexpressions.
- unsigned Index;
- /// The location of the '[' starting the array range designator.
- unsigned LBracketLoc;
- /// The location of the ellipsis separating the start and end
- /// indices. Only valid for GNU array-range designators.
- unsigned EllipsisLoc;
- /// The location of the ']' terminating the array range designator.
- unsigned RBracketLoc;
- };
-
- /// @brief 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.
- enum {
- FieldDesignator,
- ArrayDesignator,
- ArrayRangeDesignator
- } Kind;
-
- union {
- /// A field designator, e.g., ".x".
- struct FieldDesignator Field;
- /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
- struct ArrayOrRangeDesignator ArrayOrRange;
- };
- friend class DesignatedInitExpr;
-
- public:
- Designator() {}
-
- /// @brief Initializes a field designator.
- Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
- SourceLocation FieldLoc)
- : Kind(FieldDesignator) {
- Field.NameOrField = reinterpret_cast<uintptr_t>(FieldName) | 0x01;
- Field.DotLoc = DotLoc.getRawEncoding();
- Field.FieldLoc = FieldLoc.getRawEncoding();
- }
-
- /// @brief Initializes an array designator.
- Designator(unsigned Index, SourceLocation LBracketLoc,
- SourceLocation RBracketLoc)
- : Kind(ArrayDesignator) {
- ArrayOrRange.Index = Index;
- ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
- ArrayOrRange.EllipsisLoc = SourceLocation().getRawEncoding();
- ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
- }
-
- /// @brief Initializes a GNU array-range designator.
- Designator(unsigned Index, SourceLocation LBracketLoc,
- SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
- : Kind(ArrayRangeDesignator) {
- ArrayOrRange.Index = Index;
- ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
- ArrayOrRange.EllipsisLoc = EllipsisLoc.getRawEncoding();
- ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
- }
-
- bool isFieldDesignator() const { return Kind == FieldDesignator; }
- bool isArrayDesignator() const { return Kind == ArrayDesignator; }
- bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
-
- IdentifierInfo *getFieldName() const;
-
- FieldDecl *getField() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- if (Field.NameOrField & 0x01)
- return nullptr;
- else
- return reinterpret_cast<FieldDecl *>(Field.NameOrField);
- }
-
- void setField(FieldDecl *FD) {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- Field.NameOrField = reinterpret_cast<uintptr_t>(FD);
- }
-
- SourceLocation getDotLoc() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- return SourceLocation::getFromRawEncoding(Field.DotLoc);
- }
-
- SourceLocation getFieldLoc() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- return SourceLocation::getFromRawEncoding(Field.FieldLoc);
- }
-
- SourceLocation getLBracketLoc() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
- "Only valid on an array or array-range designator");
- return SourceLocation::getFromRawEncoding(ArrayOrRange.LBracketLoc);
- }
-
- SourceLocation getRBracketLoc() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
- "Only valid on an array or array-range designator");
- return SourceLocation::getFromRawEncoding(ArrayOrRange.RBracketLoc);
- }
-
- SourceLocation getEllipsisLoc() const {
- assert(Kind == ArrayRangeDesignator &&
- "Only valid on an array-range designator");
- return SourceLocation::getFromRawEncoding(ArrayOrRange.EllipsisLoc);
- }
-
- unsigned getFirstExprIndex() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
- "Only valid on an array or array-range designator");
- return ArrayOrRange.Index;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (Kind == FieldDesignator)
- return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
- else
- return getLBracketLoc();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
- }
- };
-
- static DesignatedInitExpr *Create(const ASTContext &C,
- Designator *Designators,
- unsigned NumDesignators,
- ArrayRef<Expr*> IndexExprs,
- SourceLocation EqualOrColonLoc,
- bool GNUSyntax, Expr *Init);
-
- static DesignatedInitExpr *CreateEmpty(const ASTContext &C,
- unsigned NumIndexExprs);
-
- /// @brief Returns the number of designators in this initializer.
- unsigned size() const { return NumDesignators; }
-
- // Iterator access to the designators.
- typedef Designator *designators_iterator;
- designators_iterator designators_begin() { return Designators; }
- designators_iterator designators_end() {
- return Designators + NumDesignators;
- }
-
- typedef const Designator *const_designators_iterator;
- const_designators_iterator designators_begin() const { return Designators; }
- const_designators_iterator designators_end() const {
- return Designators + NumDesignators;
- }
-
- typedef llvm::iterator_range<designators_iterator> designators_range;
- designators_range designators() {
- return designators_range(designators_begin(), designators_end());
- }
-
- typedef llvm::iterator_range<const_designators_iterator>
- designators_const_range;
- designators_const_range designators() const {
- return designators_const_range(designators_begin(), designators_end());
- }
-
- typedef std::reverse_iterator<designators_iterator>
- reverse_designators_iterator;
- reverse_designators_iterator designators_rbegin() {
- return reverse_designators_iterator(designators_end());
- }
- reverse_designators_iterator designators_rend() {
- return reverse_designators_iterator(designators_begin());
- }
-
- typedef std::reverse_iterator<const_designators_iterator>
- const_reverse_designators_iterator;
- const_reverse_designators_iterator designators_rbegin() const {
- return const_reverse_designators_iterator(designators_end());
- }
- const_reverse_designators_iterator designators_rend() const {
- return const_reverse_designators_iterator(designators_begin());
- }
-
- Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
-
- void setDesignators(const ASTContext &C, const Designator *Desigs,
- unsigned NumDesigs);
-
- Expr *getArrayIndex(const Designator &D) const;
- Expr *getArrayRangeStart(const Designator &D) const;
- Expr *getArrayRangeEnd(const Designator &D) const;
-
- /// @brief 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
- /// deprecated GNU syntax for designated initializers.
- bool usesGNUSyntax() const { return GNUSyntax; }
- void setGNUSyntax(bool GNU) { GNUSyntax = GNU; }
-
- /// @brief Retrieve the initializer value.
- Expr *getInit() const {
- return cast<Expr>(*const_cast<DesignatedInitExpr*>(this)->child_begin());
- }
-
- void setInit(Expr *init) {
- *child_begin() = init;
- }
-
- /// \brief 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.
- unsigned getNumSubExprs() const { return NumSubExprs; }
-
- Expr *getSubExpr(unsigned Idx) const {
- assert(Idx < NumSubExprs && "Subscript out of range");
- return cast<Expr>(getTrailingObjects<Stmt *>()[Idx]);
- }
-
- void setSubExpr(unsigned Idx, Expr *E) {
- assert(Idx < NumSubExprs && "Subscript out of range");
- getTrailingObjects<Stmt *>()[Idx] = E;
- }
-
- /// \brief 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);
-
- SourceRange getDesignatorsSourceRange() const;
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DesignatedInitExprClass;
- }
-
- // Iterators
- child_range children() {
- Stmt **begin = getTrailingObjects<Stmt *>();
- return child_range(begin, begin + NumSubExprs);
- }
-
- friend TrailingObjects;
-};
-
-/// \brief 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
-/// DesignatedInitUpdateExpr (see below). The base expression of a DIUE
-/// initializes a big object, and the NoInitExpr's mark the spots within the
-/// big object not to be overwritten by the updater.
-///
-/// \see DesignatedInitUpdateExpr
-class NoInitExpr : public Expr {
-public:
- explicit NoInitExpr(QualType ty)
- : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary,
- false, false, ty->isInstantiationDependentType(), false) { }
-
- explicit NoInitExpr(EmptyShell Empty)
- : Expr(NoInitExprClass, Empty) { }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == NoInitExprClass;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-// In cases like:
-// struct Q { int a, b, c; };
-// Q *getQ();
-// void foo() {
-// struct A { Q q; } a = { *getQ(), .q.b = 3 };
-// }
-//
-// We will have an InitListExpr for a, with type A, and then a
-// DesignatedInitUpdateExpr for "a.q" with type Q. The "base" for this DIUE
-// is the call expression *getQ(); the "updater" for the DIUE is ".q.b = 3"
-//
-class DesignatedInitUpdateExpr : public Expr {
- // BaseAndUpdaterExprs[0] is the base expression;
- // BaseAndUpdaterExprs[1] is an InitListExpr overwriting part of the base.
- Stmt *BaseAndUpdaterExprs[2];
-
-public:
- DesignatedInitUpdateExpr(const ASTContext &C, SourceLocation lBraceLoc,
- Expr *baseExprs, SourceLocation rBraceLoc);
-
- explicit DesignatedInitUpdateExpr(EmptyShell Empty)
- : Expr(DesignatedInitUpdateExprClass, Empty) { }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DesignatedInitUpdateExprClass;
- }
-
- Expr *getBase() const { return cast<Expr>(BaseAndUpdaterExprs[0]); }
- void setBase(Expr *Base) { BaseAndUpdaterExprs[0] = Base; }
-
- InitListExpr *getUpdater() const {
- return cast<InitListExpr>(BaseAndUpdaterExprs[1]);
- }
- void setUpdater(Expr *Updater) { BaseAndUpdaterExprs[1] = Updater; }
-
- // Iterators
- // children = the base and the updater
- child_range children() {
- return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2);
- }
-};
-
-/// \brief Represents an implicitly-generated value initialization of
-/// an object of a given type.
-///
-/// Implicit value initializations occur within semantic initializer
-/// list expressions (InitListExpr) as placeholders for subobject
-/// initializations not explicitly specified by the user.
-///
-/// \see InitListExpr
-class ImplicitValueInitExpr : public Expr {
-public:
- explicit ImplicitValueInitExpr(QualType ty)
- : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary,
- false, false, ty->isInstantiationDependentType(), false) { }
-
- /// \brief Construct an empty implicit value initialization.
- explicit ImplicitValueInitExpr(EmptyShell Empty)
- : Expr(ImplicitValueInitExprClass, Empty) { }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImplicitValueInitExprClass;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-class ParenListExpr : public Expr {
- Stmt **Exprs;
- unsigned NumExprs;
- SourceLocation LParenLoc, RParenLoc;
-
-public:
- ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
- ArrayRef<Expr*> exprs, SourceLocation rparenloc);
-
- /// \brief Build an empty paren list.
- explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
-
- unsigned getNumExprs() const { return NumExprs; }
-
- const Expr* getExpr(unsigned Init) const {
- assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
- }
-
- Expr* getExpr(unsigned Init) {
- assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
- }
-
- Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); }
-
- ArrayRef<Expr *> exprs() {
- return llvm::makeArrayRef(getExprs(), getNumExprs());
- }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ParenListExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Exprs[0], &Exprs[0]+NumExprs);
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief 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
-/// association specifies a type name and an expression, or "default" and an
-/// expression (in which case it is known as a default generic association).
-/// The type and value of the generic selection are identical to those of its
-/// result expression, which is defined as the expression in the generic
-/// association with a type name that is compatible with the type of the
-/// controlling expression, or the expression in the default generic association
-/// if no types are compatible. For example:
-///
-/// @code
-/// _Generic(X, double: 1, float: 2, default: 3)
-/// @endcode
-///
-/// The above expression evaluates to 1 if 1.0 is substituted for X, 2 if 1.0f
-/// or 3 if "hello".
-///
-/// As an extension, generic selections are allowed in C++, where the following
-/// additional semantics apply:
-///
-/// Any generic selection whose controlling expression is type-dependent or
-/// which names a dependent type in its association list is result-dependent,
-/// which means that the choice of result expression is dependent.
-/// Result-dependent generic associations are both type- and value-dependent.
-class GenericSelectionExpr : public Expr {
- enum { CONTROLLING, END_EXPR };
- TypeSourceInfo **AssocTypes;
- Stmt **SubExprs;
- unsigned NumAssocs, ResultIndex;
- SourceLocation GenericLoc, DefaultLoc, RParenLoc;
-
-public:
- GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc, SourceLocation RParenLoc,
- bool ContainsUnexpandedParameterPack,
- unsigned ResultIndex);
-
- /// This constructor is used in the result-dependent case.
- GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc, SourceLocation RParenLoc,
- bool ContainsUnexpandedParameterPack);
-
- explicit GenericSelectionExpr(EmptyShell Empty)
- : Expr(GenericSelectionExprClass, Empty) { }
-
- unsigned getNumAssocs() const { return NumAssocs; }
-
- SourceLocation getGenericLoc() const { return GenericLoc; }
- SourceLocation getDefaultLoc() const { return DefaultLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- const Expr *getAssocExpr(unsigned i) const {
- return cast<Expr>(SubExprs[END_EXPR+i]);
- }
- Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
-
- const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
- return AssocTypes[i];
- }
- TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
-
- QualType getAssocType(unsigned i) const {
- if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))
- return TS->getType();
- else
- return QualType();
- }
-
- const Expr *getControllingExpr() const {
- return cast<Expr>(SubExprs[CONTROLLING]);
- }
- Expr *getControllingExpr() { return cast<Expr>(SubExprs[CONTROLLING]); }
-
- /// Whether this generic selection is result-dependent.
- bool isResultDependent() const { return ResultIndex == -1U; }
-
- /// The zero-based index of the result expression's generic association in
- /// the generic selection's association list. Defined only if the
- /// generic selection is not result-dependent.
- unsigned getResultIndex() const {
- assert(!isResultDependent() && "Generic selection is result-dependent");
- return ResultIndex;
- }
-
- /// The generic selection's result expression. Defined only if the
- /// generic selection is not result-dependent.
- const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
- Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return GenericLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GenericSelectionExprClass;
- }
-
- child_range children() {
- return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
- }
-
- friend class ASTStmtReader;
-};
-
-//===----------------------------------------------------------------------===//
-// Clang Extensions
-//===----------------------------------------------------------------------===//
-
-/// ExtVectorElementExpr - This represents access to specific elements of a
-/// vector, and may occur on the left hand side or right hand side. For example
-/// the following is legal: "V.xy = V.zw" if V is a 4 element extended vector.
-///
-/// Note that the base may have either vector or pointer to vector type, just
-/// like a struct field reference.
-///
-class ExtVectorElementExpr : public Expr {
- Stmt *Base;
- IdentifierInfo *Accessor;
- SourceLocation AccessorLoc;
-public:
- ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base,
- IdentifierInfo &accessor, SourceLocation loc)
- : Expr(ExtVectorElementExprClass, ty, VK,
- (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent),
- base->isTypeDependent(), base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- Base(base), Accessor(&accessor), AccessorLoc(loc) {}
-
- /// \brief Build an empty vector element expression.
- explicit ExtVectorElementExpr(EmptyShell Empty)
- : Expr(ExtVectorElementExprClass, Empty) { }
-
- const Expr *getBase() const { return cast<Expr>(Base); }
- Expr *getBase() { return cast<Expr>(Base); }
- void setBase(Expr *E) { Base = E; }
-
- IdentifierInfo &getAccessor() const { return *Accessor; }
- void setAccessor(IdentifierInfo *II) { Accessor = II; }
-
- SourceLocation getAccessorLoc() const { return AccessorLoc; }
- void setAccessorLoc(SourceLocation L) { AccessorLoc = L; }
-
- /// getNumElements - Get the number of components being selected.
- unsigned getNumElements() const;
-
- /// containsDuplicateElements - Return true if any element access is
- /// repeated.
- bool containsDuplicateElements() const;
-
- /// getEncodedElementAccess - Encode the elements accessed into an llvm
- /// aggregate Constant of ConstantInt(s).
- void getEncodedElementAccess(SmallVectorImpl<uint32_t> &Elts) const;
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return AccessorLoc; }
-
- /// isArrow - Return true if the base expression is a pointer to vector,
- /// return false if the base expression is a vector.
- bool isArrow() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExtVectorElementExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
-};
-
-/// BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
-/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
-class BlockExpr : public Expr {
-protected:
- BlockDecl *TheBlock;
-public:
- BlockExpr(BlockDecl *BD, QualType ty)
- : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary,
- ty->isDependentType(), ty->isDependentType(),
- ty->isInstantiationDependentType() || BD->isDependentContext(),
- false),
- TheBlock(BD) {}
-
- /// \brief Build an empty block expression.
- explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { }
-
- const BlockDecl *getBlockDecl() const { return TheBlock; }
- BlockDecl *getBlockDecl() { return TheBlock; }
- void setBlockDecl(BlockDecl *BD) { TheBlock = BD; }
-
- // Convenience functions for probing the underlying BlockDecl.
- SourceLocation getCaretLocation() const;
- const Stmt *getBody() const;
- Stmt *getBody();
-
- SourceLocation getLocStart() const LLVM_READONLY { return getCaretLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getBody()->getLocEnd(); }
-
- /// getFunctionType - Return the underlying function type for this block.
- const FunctionProtoType *getFunctionType() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BlockExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
-/// This AST node provides support for reinterpreting a type to another
-/// type of the same size.
-class AsTypeExpr : public Expr {
-private:
- Stmt *SrcExpr;
- SourceLocation BuiltinLoc, RParenLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
-
-public:
- AsTypeExpr(Expr* SrcExpr, QualType DstType,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation BuiltinLoc, SourceLocation RParenLoc)
- : Expr(AsTypeExprClass, DstType, VK, OK,
- DstType->isDependentType(),
- DstType->isDependentType() || SrcExpr->isValueDependent(),
- (DstType->isInstantiationDependentType() ||
- SrcExpr->isInstantiationDependent()),
- (DstType->containsUnexpandedParameterPack() ||
- SrcExpr->containsUnexpandedParameterPack())),
- SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
-
- /// getSrcExpr - Return the Expr to be converted.
- Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
-
- /// getBuiltinLoc - Return the location of the __builtin_astype token.
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
-
- /// getRParenLoc - Return the location of final right parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AsTypeExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
-};
-
-/// PseudoObjectExpr - An expression which accesses a pseudo-object
-/// l-value. A pseudo-object is an abstract object, accesses to which
-/// are translated to calls. The pseudo-object expression has a
-/// syntactic form, which shows how the expression was actually
-/// written in the source code, and a semantic form, which is a series
-/// of expressions to be executed in order which detail how the
-/// operation is actually evaluated. Optionally, one of the semantic
-/// forms may also provide a result value for the expression.
-///
-/// If any of the semantic-form expressions is an OpaqueValueExpr,
-/// that OVE is required to have a source expression, and it is bound
-/// to the result of that source expression. Such OVEs may appear
-/// only in subsequent semantic-form expressions and as
-/// sub-expressions of the syntactic form.
-///
-/// PseudoObjectExpr should be used only when an operation can be
-/// usefully described in terms of fairly simple rewrite rules on
-/// objects and functions that are meant to be used by end-developers.
-/// For example, under the Itanium ABI, dynamic casts are implemented
-/// as a call to a runtime function called __dynamic_cast; using this
-/// class to describe that would be inappropriate because that call is
-/// not really part of the user-visible semantics, and instead the
-/// cast is properly reflected in the AST and IR-generation has been
-/// taught to generate the call as necessary. In contrast, an
-/// Objective-C property access is semantically defined to be
-/// equivalent to a particular message send, and this is very much
-/// part of the user model. The name of this class encourages this
-/// modelling design.
-class PseudoObjectExpr final
- : public Expr,
- private llvm::TrailingObjects<PseudoObjectExpr, Expr *> {
- // PseudoObjectExprBits.NumSubExprs - The number of sub-expressions.
- // Always at least two, because the first sub-expression is the
- // syntactic form.
-
- // PseudoObjectExprBits.ResultIndex - The index of the
- // sub-expression holding the result. 0 means the result is void,
- // which is unambiguous because it's the index of the syntactic
- // form. Note that this is therefore 1 higher than the value passed
- // in to Create, which is an index within the semantic forms.
- // Note also that ASTStmtWriter assumes this encoding.
-
- Expr **getSubExprsBuffer() { return getTrailingObjects<Expr *>(); }
- const Expr * const *getSubExprsBuffer() const {
- return getTrailingObjects<Expr *>();
- }
-
- PseudoObjectExpr(QualType type, ExprValueKind VK,
- Expr *syntactic, ArrayRef<Expr*> semantic,
- unsigned resultIndex);
-
- PseudoObjectExpr(EmptyShell shell, unsigned numSemanticExprs);
-
- unsigned getNumSubExprs() const {
- return PseudoObjectExprBits.NumSubExprs;
- }
-
-public:
- /// NoResult - A value for the result index indicating that there is
- /// no semantic result.
- enum : unsigned { NoResult = ~0U };
-
- static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic,
- ArrayRef<Expr*> semantic,
- unsigned resultIndex);
-
- static PseudoObjectExpr *Create(const ASTContext &Context, EmptyShell shell,
- unsigned numSemanticExprs);
-
- /// Return the syntactic form of this expression, i.e. the
- /// expression it actually looks like. Likely to be expressed in
- /// terms of OpaqueValueExprs bound in the semantic form.
- Expr *getSyntacticForm() { return getSubExprsBuffer()[0]; }
- const Expr *getSyntacticForm() const { return getSubExprsBuffer()[0]; }
-
- /// Return the index of the result-bearing expression into the semantics
- /// expressions, or PseudoObjectExpr::NoResult if there is none.
- unsigned getResultExprIndex() const {
- if (PseudoObjectExprBits.ResultIndex == 0) return NoResult;
- return PseudoObjectExprBits.ResultIndex - 1;
- }
-
- /// Return the result-bearing expression, or null if there is none.
- Expr *getResultExpr() {
- if (PseudoObjectExprBits.ResultIndex == 0)
- return nullptr;
- return getSubExprsBuffer()[PseudoObjectExprBits.ResultIndex];
- }
- const Expr *getResultExpr() const {
- return const_cast<PseudoObjectExpr*>(this)->getResultExpr();
- }
-
- unsigned getNumSemanticExprs() const { return getNumSubExprs() - 1; }
-
- typedef Expr * const *semantics_iterator;
- typedef const Expr * const *const_semantics_iterator;
- semantics_iterator semantics_begin() {
- return getSubExprsBuffer() + 1;
- }
- const_semantics_iterator semantics_begin() const {
- return getSubExprsBuffer() + 1;
- }
- semantics_iterator semantics_end() {
- return getSubExprsBuffer() + getNumSubExprs();
- }
- const_semantics_iterator semantics_end() const {
- return getSubExprsBuffer() + getNumSubExprs();
- }
-
- llvm::iterator_range<semantics_iterator> semantics() {
- return llvm::make_range(semantics_begin(), semantics_end());
- }
- llvm::iterator_range<const_semantics_iterator> semantics() const {
- return llvm::make_range(semantics_begin(), semantics_end());
- }
-
- Expr *getSemanticExpr(unsigned index) {
- assert(index + 1 < getNumSubExprs());
- return getSubExprsBuffer()[index + 1];
- }
- const Expr *getSemanticExpr(unsigned index) const {
- return const_cast<PseudoObjectExpr*>(this)->getSemanticExpr(index);
- }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getSyntacticForm()->getExprLoc();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSyntacticForm()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSyntacticForm()->getLocEnd();
- }
-
- child_range children() {
- Stmt **cs = reinterpret_cast<Stmt**>(getSubExprsBuffer());
- return child_range(cs, cs + getNumSubExprs());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PseudoObjectExprClass;
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-};
-
-/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
-/// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the
-/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>.
-/// All of these instructions take one primary pointer and at least one memory
-/// order.
-class AtomicExpr : public Expr {
-public:
- enum AtomicOp {
-#define BUILTIN(ID, TYPE, ATTRS)
-#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) AO ## ID,
-#include "clang/Basic/Builtins.def"
- // Avoid trailing comma
- BI_First = 0
- };
-
- // The ABI values for various atomic memory orderings.
- enum AtomicOrderingKind {
- AO_ABI_memory_order_relaxed = 0,
- AO_ABI_memory_order_consume = 1,
- AO_ABI_memory_order_acquire = 2,
- AO_ABI_memory_order_release = 3,
- AO_ABI_memory_order_acq_rel = 4,
- AO_ABI_memory_order_seq_cst = 5
- };
-
-private:
- enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- unsigned NumSubExprs;
- SourceLocation BuiltinLoc, RParenLoc;
- AtomicOp Op;
-
- friend class ASTStmtReader;
-
-public:
- AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
- AtomicOp op, SourceLocation RP);
-
- /// \brief Determine the number of arguments the specified atomic builtin
- /// should have.
- static unsigned getNumSubExprs(AtomicOp Op);
-
- /// \brief Build an empty AtomicExpr.
- explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { }
-
- Expr *getPtr() const {
- return cast<Expr>(SubExprs[PTR]);
- }
- Expr *getOrder() const {
- return cast<Expr>(SubExprs[ORDER]);
- }
- Expr *getVal1() const {
- if (Op == AO__c11_atomic_init)
- return cast<Expr>(SubExprs[ORDER]);
- assert(NumSubExprs > VAL1);
- return cast<Expr>(SubExprs[VAL1]);
- }
- Expr *getOrderFail() const {
- assert(NumSubExprs > ORDER_FAIL);
- return cast<Expr>(SubExprs[ORDER_FAIL]);
- }
- Expr *getVal2() const {
- if (Op == AO__atomic_exchange)
- return cast<Expr>(SubExprs[ORDER_FAIL]);
- assert(NumSubExprs > VAL2);
- return cast<Expr>(SubExprs[VAL2]);
- }
- Expr *getWeak() const {
- assert(NumSubExprs > WEAK);
- return cast<Expr>(SubExprs[WEAK]);
- }
-
- AtomicOp getOp() const { return Op; }
- unsigned getNumSubExprs() { return NumSubExprs; }
-
- Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
-
- bool isVolatile() const {
- return getPtr()->getType()->getPointeeType().isVolatileQualified();
- }
-
- bool isCmpXChg() const {
- return getOp() == AO__c11_atomic_compare_exchange_strong ||
- getOp() == AO__c11_atomic_compare_exchange_weak ||
- getOp() == AO__atomic_compare_exchange ||
- getOp() == AO__atomic_compare_exchange_n;
- }
-
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AtomicExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(SubExprs, SubExprs+NumSubExprs);
- }
-};
-
-/// TypoExpr - Internal placeholder for expressions where typo correction
-/// still needs to be performed and/or an error diagnostic emitted.
-class TypoExpr : public Expr {
-public:
- TypoExpr(QualType T)
- : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary,
- /*isTypeDependent*/ true,
- /*isValueDependent*/ true,
- /*isInstantiationDependent*/ true,
- /*containsUnexpandedParameterPack*/ false) {
- assert(T->isDependentType() && "TypoExpr given a non-dependent type");
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == TypoExprClass;
- }
-
-};
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_EXPR_H
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
deleted file mode 100644
index 0608aba..0000000
--- a/include/clang/AST/ExprCXX.h
+++ /dev/null
@@ -1,4179 +0,0 @@
-//===--- ExprCXX.h - Classes for representing expressions -------*- 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::Expr interface and subclasses for C++ expressions.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPRCXX_H
-#define LLVM_CLANG_AST_EXPRCXX_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/LambdaCapture.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/TypeTraits.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class CXXConstructorDecl;
-class CXXDestructorDecl;
-class CXXMethodDecl;
-class CXXTemporary;
-class MSPropertyDecl;
-class TemplateArgumentListInfo;
-class UuidAttr;
-
-//===--------------------------------------------------------------------===//
-// C++ Expressions.
-//===--------------------------------------------------------------------===//
-
-/// \brief A call to an overloaded operator written using operator
-/// syntax.
-///
-/// Represents a call to an overloaded operator written using operator
-/// syntax, e.g., "x + y" or "*p". While semantically equivalent to a
-/// normal call, this AST node provides better information about the
-/// syntactic representation of the call.
-///
-/// In a C++ template, this expression node kind will be used whenever
-/// any of the arguments are type-dependent. In this case, the
-/// function itself will be a (possibly empty) set of functions and
-/// function templates that were found by name lookup at template
-/// definition time.
-class CXXOperatorCallExpr : public CallExpr {
- /// \brief The overloaded operator.
- OverloadedOperatorKind Operator;
- SourceRange Range;
-
- // Record the FP_CONTRACT state that applies to this operator call. Only
- // meaningful for floating point types. For other types this value can be
- // set to false.
- unsigned FPContractable : 1;
-
- SourceRange getSourceRangeImpl() const LLVM_READONLY;
-public:
- CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation operatorloc, bool fpContractable)
- : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK,
- operatorloc),
- Operator(Op), FPContractable(fpContractable) {
- Range = getSourceRangeImpl();
- }
- explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
- CallExpr(C, CXXOperatorCallExprClass, Empty) { }
-
-
- /// \brief Returns the kind of overloaded operator that this
- /// expression refers to.
- OverloadedOperatorKind getOperator() const { return Operator; }
-
- /// \brief 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
- /// of the right bracket.
- SourceLocation getOperatorLoc() const { return getRParenLoc(); }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return (Operator < OO_Plus || Operator >= OO_Arrow ||
- Operator == OO_PlusPlus || Operator == OO_MinusMinus)
- ? getLocStart()
- : getOperatorLoc();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const { return Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXOperatorCallExprClass;
- }
-
- // Set the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- void setFPContractable(bool FPC) { FPContractable = FPC; }
-
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- bool isFPContractable() const { return FPContractable; }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// Represents a call to a member function that
-/// may be written either with member call syntax (e.g., "obj.func()"
-/// or "objptr->func()") or with normal function-call syntax
-/// ("func()") within a member function that ends up calling a member
-/// function. The callee in either case is a MemberExpr that contains
-/// both the object argument and the member function, while the
-/// arguments are the arguments within the parentheses (not including
-/// the object argument).
-class CXXMemberCallExpr : public CallExpr {
-public:
- CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
- QualType t, ExprValueKind VK, SourceLocation RP)
- : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {}
-
- CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CXXMemberCallExprClass, Empty) { }
-
- /// \brief 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.
- CXXMethodDecl *getMethodDecl() const;
-
- /// \brief 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
- /// context of the CXXMethodDecl which this function is calling.
- /// FIXME: Returns 0 for member pointer call exprs.
- CXXRecordDecl *getRecordDecl() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXMemberCallExprClass;
- }
-};
-
-/// \brief Represents a call to a CUDA kernel function.
-class CUDAKernelCallExpr : public CallExpr {
-private:
- enum { CONFIG, END_PREARG };
-
-public:
- CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation RP)
- : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) {
- setConfig(Config);
- }
-
- CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { }
-
- const CallExpr *getConfig() const {
- return cast_or_null<CallExpr>(getPreArg(CONFIG));
- }
- CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); }
- void setConfig(CallExpr *E) { setPreArg(CONFIG, E); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CUDAKernelCallExprClass;
- }
-};
-
-/// \brief 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,
-/// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for
-/// reinterpret_cast, and CXXConstCastExpr for \c const_cast.
-class CXXNamedCastExpr : public ExplicitCastExpr {
-private:
- SourceLocation Loc; // the location of the casting op
- SourceLocation RParenLoc; // the location of the right parenthesis
- SourceRange AngleBrackets; // range for '<' '>'
-
-protected:
- CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
- CastKind kind, Expr *op, unsigned PathSize,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
- RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
-
- explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(SC, Shell, PathSize) { }
-
- friend class ASTStmtReader;
-
-public:
- const char *getCastName() const;
-
- /// \brief 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.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
- SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; }
-
- static bool classof(const Stmt *T) {
- switch (T->getStmtClass()) {
- case CXXStaticCastExprClass:
- case CXXDynamicCastExprClass:
- case CXXReinterpretCastExprClass:
- case CXXConstCastExprClass:
- return true;
- default:
- return false;
- }
- }
-};
-
-/// \brief 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).
-class CXXStaticCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> {
- CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
- unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
- writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
- : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
-
-public:
- static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind K, Expr *Op,
- const CXXCastPath *Path,
- TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXStaticCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief 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
-/// check to determine how to perform the type conversion.
-class CXXDynamicCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
- CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
- Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
- writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
-
-public:
- static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind Kind, Expr *Op,
- const CXXCastPath *Path,
- TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
-
- static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned pathSize);
-
- bool isAlwaysNull() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDynamicCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
-///
-/// This expression node represents a reinterpret cast, e.g.,
-/// @c reinterpret_cast<int>(VoidPtr).
-///
-/// A reinterpret_cast provides a differently-typed view of a value but
-/// (in Clang, as in most C++ implementations) performs no actual work at
-/// run time.
-class CXXReinterpretCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXReinterpretCastExpr,
- CXXBaseSpecifier *> {
- CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
- Expr *op, unsigned pathSize,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
- pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
-
- CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
-
-public:
- static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind Kind,
- Expr *Op, const CXXCastPath *Path,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned pathSize);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXReinterpretCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A C++ \c const_cast expression (C++ [expr.const.cast]).
-///
-/// This expression node represents a const cast, e.g.,
-/// \c const_cast<char*>(PtrToConstChar).
-///
-/// A const_cast can remove type qualifiers but does not change the underlying
-/// value.
-class CXXConstCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> {
- CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc, SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
- 0, writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXConstCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
-
-public:
- static CXXConstCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, Expr *Op,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXConstCastExpr *CreateEmpty(const ASTContext &Context);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConstCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief 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
-/// is semantically equivalent to a normal call, this AST node provides better
-/// information about the syntactic representation of the literal.
-///
-/// 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.
- SourceLocation UDSuffixLoc;
-
-public:
- UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args,
- QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
- SourceLocation SuffixLoc)
- : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc),
- UDSuffixLoc(SuffixLoc) {}
- explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty)
- : CallExpr(C, UserDefinedLiteralClass, Empty) {}
-
- /// The kind of literal operator which is invoked.
- enum LiteralOperatorKind {
- LOK_Raw, ///< Raw form: operator "" X (const char *)
- LOK_Template, ///< Raw form: operator "" X<cs...> ()
- LOK_Integer, ///< operator "" X (unsigned long long)
- LOK_Floating, ///< operator "" X (long double)
- LOK_String, ///< operator "" X (const CharT *, size_t)
- LOK_Character ///< operator "" X (CharT)
- };
-
- /// \brief 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
- /// underlying cooked literal (representing the literal with the suffix
- /// removed).
- Expr *getCookedLiteral();
- const Expr *getCookedLiteral() const {
- return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral();
- }
-
- SourceLocation getLocStart() const {
- if (getLiteralOperatorKind() == LOK_Template)
- return getRParenLoc();
- return getArg(0)->getLocStart();
- }
- SourceLocation getLocEnd() const { return getRParenLoc(); }
-
-
- /// \brief 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.
- const IdentifierInfo *getUDSuffix() const;
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == UserDefinedLiteralClass;
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief A boolean literal, per ([C++ lex.bool] Boolean literals).
-///
-class CXXBoolLiteralExpr : public Expr {
- bool Value;
- SourceLocation Loc;
-public:
- CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
- Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(val), Loc(l) {}
-
- explicit CXXBoolLiteralExpr(EmptyShell Empty)
- : Expr(CXXBoolLiteralExprClass, Empty) { }
-
- bool getValue() const { return Value; }
- void setValue(bool V) { Value = V; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBoolLiteralExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief 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 {
- SourceLocation Loc;
-public:
- CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
- Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Loc(l) {}
-
- explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
- : Expr(CXXNullPtrLiteralExprClass, Empty) { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNullPtrLiteralExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief 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;
-
- CXXStdInitializerListExpr(EmptyShell Empty)
- : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
-
-public:
- CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
- : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
- Ty->isDependentType(), SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- SubExpr(SubExpr) {}
-
- Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
- const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExpr->getLocEnd();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SubExpr->getSourceRange();
- }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == CXXStdInitializerListExprClass;
- }
-
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-
- friend class ASTReader;
- friend class ASTStmtReader;
-};
-
-/// A C++ \c typeid expression (C++ [expr.typeid]), which gets
-/// the \c type_info that corresponds to the supplied type, or the (possibly
-/// dynamic) type of the supplied expression.
-///
-/// This represents code like \c typeid(int) or \c typeid(*objPtr)
-class CXXTypeidExpr : public Expr {
-private:
- llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- SourceRange Range;
-
-public:
- CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are dependent
- Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are dependent
- Operand->isTypeDependent() || Operand->isValueDependent(),
- Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXTypeidExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXTypeidExprClass, Empty) {
- if (isExpr)
- Operand = (Expr*)nullptr;
- else
- Operand = (TypeSourceInfo*)nullptr;
- }
-
- /// Determine whether this typeid has a type operand which is potentially
- /// evaluated, per C++11 [expr.typeid]p3.
- bool isPotentiallyEvaluated() const;
-
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
-
- /// \brief 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.
- TypeSourceInfo *getTypeOperandSourceInfo() const {
- assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- return Operand.get<TypeSourceInfo *>();
- }
-
- void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
- assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- Operand = TSI;
- }
-
- Expr *getExprOperand() const {
- assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
- }
-
- void setExprOperand(Expr *E) {
- assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- Operand = E;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- void setSourceRange(SourceRange R) { Range = R; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTypeidExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isTypeOperand())
- return child_range(child_iterator(), child_iterator());
- Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
- return child_range(begin, begin + 1);
- }
-};
-
-/// \brief 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
-/// within the syntactic form of a PseudoObjectExpr.
-class MSPropertyRefExpr : public Expr {
- Expr *BaseExpr;
- MSPropertyDecl *TheDecl;
- SourceLocation MemberLoc;
- bool IsArrow;
- NestedNameSpecifierLoc QualifierLoc;
-
-public:
- MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
- QualType ty, ExprValueKind VK,
- NestedNameSpecifierLoc qualifierLoc,
- SourceLocation nameLoc)
- : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
- /*type-dependent*/ false, baseExpr->isValueDependent(),
- baseExpr->isInstantiationDependent(),
- baseExpr->containsUnexpandedParameterPack()),
- BaseExpr(baseExpr), TheDecl(decl),
- MemberLoc(nameLoc), IsArrow(isArrow),
- QualifierLoc(qualifierLoc) {}
-
- MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
- }
- bool isImplicitAccess() const {
- return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
- }
- SourceLocation getLocStart() const {
- if (!isImplicitAccess())
- return BaseExpr->getLocStart();
- else if (QualifierLoc)
- return QualifierLoc.getBeginLoc();
- else
- return MemberLoc;
- }
- SourceLocation getLocEnd() const { return getMemberLoc(); }
-
- child_range children() {
- return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSPropertyRefExprClass;
- }
-
- Expr *getBaseExpr() const { return BaseExpr; }
- MSPropertyDecl *getPropertyDecl() const { return TheDecl; }
- bool isArrow() const { return IsArrow; }
- SourceLocation getMemberLoc() const { return MemberLoc; }
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- friend class ASTStmtReader;
-};
-
-/// MS property subscript expression.
-/// MSVC supports 'property' attribute and allows to apply it to the
-/// declaration of an empty array in a class or structure definition.
-/// For example:
-/// \code
-/// __declspec(property(get=GetX, put=PutX)) int x[];
-/// \endcode
-/// The above statement indicates that x[] can be used with one or more array
-/// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and
-/// p->x[a][b] = i will be turned into p->PutX(a, b, i).
-/// This is a syntactic pseudo-object expression.
-class MSPropertySubscriptExpr : public Expr {
- friend class ASTStmtReader;
- enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 };
- Stmt *SubExprs[NUM_SUBEXPRS];
- SourceLocation RBracketLoc;
-
- void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; }
- void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; }
-
-public:
- MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK,
- ExprObjectKind OK, SourceLocation RBracketLoc)
- : Expr(MSPropertySubscriptExprClass, Ty, VK, OK, Idx->isTypeDependent(),
- Idx->isValueDependent(), Idx->isInstantiationDependent(),
- Idx->containsUnexpandedParameterPack()),
- RBracketLoc(RBracketLoc) {
- SubExprs[BASE_EXPR] = Base;
- SubExprs[IDX_EXPR] = Idx;
- }
-
- /// \brief Create an empty array subscript expression.
- explicit MSPropertySubscriptExpr(EmptyShell Shell)
- : Expr(MSPropertySubscriptExprClass, Shell) {}
-
- Expr *getBase() { return cast<Expr>(SubExprs[BASE_EXPR]); }
- const Expr *getBase() const { return cast<Expr>(SubExprs[BASE_EXPR]); }
-
- Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); }
- const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getBase()->getExprLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSPropertySubscriptExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
- }
-};
-
-/// A Microsoft C++ @c __uuidof expression, which gets
-/// the _GUID that corresponds to the supplied type or expression.
-///
-/// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
-class CXXUuidofExpr : public Expr {
-private:
- llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- SourceRange Range;
-
-public:
- CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
- false, Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
- false, Operand->isTypeDependent(),
- Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXUuidofExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXUuidofExprClass, Empty) {
- if (isExpr)
- Operand = (Expr*)nullptr;
- else
- Operand = (TypeSourceInfo*)nullptr;
- }
-
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
-
- /// \brief 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.
- TypeSourceInfo *getTypeOperandSourceInfo() const {
- assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- return Operand.get<TypeSourceInfo *>();
- }
-
- void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
- assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- Operand = TSI;
- }
-
- Expr *getExprOperand() const {
- assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
- }
-
- void setExprOperand(Expr *E) {
- assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- Operand = E;
- }
-
- StringRef getUuidAsStringRef(ASTContext &Context) const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- void setSourceRange(SourceRange R) { Range = R; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUuidofExprClass;
- }
-
- /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
- /// a single GUID.
- static const UuidAttr *GetUuidAttrOfType(QualType QT,
- bool *HasMultipleGUIDsPtr = nullptr);
-
- // Iterators
- child_range children() {
- if (isTypeOperand())
- return child_range(child_iterator(), child_iterator());
- Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
- return child_range(begin, begin + 1);
- }
-};
-
-/// \brief 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:
-///
-/// \code
-/// class Foo {
-/// public:
-/// void bar();
-/// void test() { this->bar(); }
-/// };
-/// \endcode
-class CXXThisExpr : public Expr {
- SourceLocation Loc;
- bool Implicit : 1;
-
-public:
- CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit)
- : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary,
- // 'this' is type-dependent if the class type of the enclosing
- // member function is dependent (C++ [temp.dep.expr]p2)
- Type->isDependentType(), Type->isDependentType(),
- Type->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(L), Implicit(isImplicit) { }
-
- CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I) { Implicit = I; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThisExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief 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
-/// present, Op will be null.
-class CXXThrowExpr : public Expr {
- Stmt *Op;
- SourceLocation ThrowLoc;
- /// \brief Whether the thrown variable (if any) is in scope.
- unsigned IsThrownVariableInScope : 1;
-
- friend class ASTStmtReader;
-
-public:
- // \p Ty is the void type which is used as the result type of the
- // expression. The \p l is the location of the throw keyword. \p expr
- // can by null, if the optional expression to throw isn't present.
- CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l,
- bool IsThrownVariableInScope) :
- Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- expr && expr->isInstantiationDependent(),
- expr && expr->containsUnexpandedParameterPack()),
- Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {}
- CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
-
- const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
- Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
-
- SourceLocation getThrowLoc() const { return ThrowLoc; }
-
- /// \brief 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
- /// this variable.
- bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (!getSubExpr())
- return ThrowLoc;
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThrowExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Op, Op ? &Op+1 : &Op);
- }
-};
-
-/// \brief 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,
- private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
- /// \brief The parameter whose default is being used.
- ///
- /// When the bit is set, the subexpression is stored after the
- /// CXXDefaultArgExpr itself. When the bit is clear, the parameter's
- /// actual default expression is the subexpression.
- llvm::PointerIntPair<ParmVarDecl *, 1, bool> Param;
-
- /// \brief The location where the default argument expression was used.
- SourceLocation Loc;
-
- CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
- : Expr(SC,
- param->hasUnparsedDefaultArg()
- ? param->getType().getNonReferenceType()
- : param->getDefaultArg()->getType(),
- param->getDefaultArg()->getValueKind(),
- param->getDefaultArg()->getObjectKind(), false, false, false, false),
- Param(param, false), Loc(Loc) { }
-
- CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
- Expr *SubExpr)
- : Expr(SC, SubExpr->getType(),
- SubExpr->getValueKind(), SubExpr->getObjectKind(),
- false, false, false, false),
- Param(param, true), Loc(Loc) {
- *getTrailingObjects<Expr *>() = SubExpr;
- }
-
-public:
- CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
-
- // \p Param is the parameter whose default argument is used by this
- // expression.
- static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param) {
- return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param);
- }
-
- // \p Param is the parameter whose default argument is used by this
- // expression, and \p SubExpr is the expression that will actually be used.
- static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param, Expr *SubExpr);
-
- // Retrieve the parameter that the argument was created from.
- const ParmVarDecl *getParam() const { return Param.getPointer(); }
- ParmVarDecl *getParam() { return Param.getPointer(); }
-
- // Retrieve the actual argument to the function call.
- const Expr *getExpr() const {
- if (Param.getInt())
- return *getTrailingObjects<Expr *>();
- return getParam()->getDefaultArg();
- }
- Expr *getExpr() {
- if (Param.getInt())
- return *getTrailingObjects<Expr *>();
- return getParam()->getDefaultArg();
- }
-
- /// \brief Retrieve the location where this default argument was actually
- /// used.
- SourceLocation getUsedLocation() const { return Loc; }
-
- /// Default argument expressions have no representation in the
- /// source, so they have an empty source range.
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultArgExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief A use of a default initializer in a constructor or in aggregate
-/// initialization.
-///
-/// This wraps a use of a C++ default initializer (technically,
-/// a brace-or-equal-initializer for a non-static data member) when it
-/// is implicitly used in a mem-initializer-list in a constructor
-/// (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.
- FieldDecl *Field;
-
- /// \brief The location where the default initializer expression was used.
- SourceLocation Loc;
-
- CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field,
- QualType T);
-
- CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
-
-public:
- /// \p Field is the non-static data member whose default initializer is used
- /// by this expression.
- static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc,
- FieldDecl *Field) {
- return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType());
- }
-
- /// \brief 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.
- const Expr *getExpr() const {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
- }
- Expr *getExpr() {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultInitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTReader;
- friend class ASTStmtReader;
-};
-
-/// \brief Represents a C++ temporary.
-class CXXTemporary {
- /// \brief The destructor that needs to be called.
- const CXXDestructorDecl *Destructor;
-
- explicit CXXTemporary(const CXXDestructorDecl *destructor)
- : Destructor(destructor) { }
-
-public:
- static CXXTemporary *Create(const ASTContext &C,
- const CXXDestructorDecl *Destructor);
-
- const CXXDestructorDecl *getDestructor() const { return Destructor; }
- void setDestructor(const CXXDestructorDecl *Dtor) {
- Destructor = Dtor;
- }
-};
-
-/// \brief 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:
-///
-/// \code
-/// struct S {
-/// S() { } // User defined constructor makes S non-POD.
-/// ~S() { } // User defined destructor makes it non-trivial.
-/// };
-/// void test() {
-/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
-/// }
-/// \endcode
-class CXXBindTemporaryExpr : public Expr {
- CXXTemporary *Temp;
-
- Stmt *SubExpr;
-
- CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr)
- : Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
- VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
- SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- Temp(temp), SubExpr(SubExpr) { }
-
-public:
- CXXBindTemporaryExpr(EmptyShell Empty)
- : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
-
- static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
- Expr* SubExpr);
-
- CXXTemporary *getTemporary() { return Temp; }
- const CXXTemporary *getTemporary() const { return Temp; }
- void setTemporary(CXXTemporary *T) { Temp = T; }
-
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- void setSubExpr(Expr *E) { SubExpr = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBindTemporaryExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-};
-
-/// \brief Represents a call to a C++ constructor.
-class CXXConstructExpr : public Expr {
-public:
- enum ConstructionKind {
- CK_Complete,
- CK_NonVirtualBase,
- CK_VirtualBase,
- CK_Delegating
- };
-
-private:
- CXXConstructorDecl *Constructor;
-
- SourceLocation Loc;
- SourceRange ParenOrBraceRange;
- unsigned NumArgs : 16;
- bool Elidable : 1;
- bool HadMultipleCandidates : 1;
- bool ListInitialization : 1;
- bool StdInitListInitialization : 1;
- bool ZeroInitialization : 1;
- unsigned ConstructKind : 2;
- Stmt **Args;
-
-protected:
- CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *d, bool elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
-
- /// \brief Construct an empty C++ construction expression.
- CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
- HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0), Args(nullptr)
- { }
-
-public:
- /// \brief Construct an empty C++ construction expression.
- explicit CXXConstructExpr(EmptyShell Empty)
- : Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
- NumArgs(0), Elidable(false), HadMultipleCandidates(false),
- ListInitialization(false), ZeroInitialization(false),
- ConstructKind(0), Args(nullptr)
- { }
-
- static CXXConstructExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *D, bool Elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
-
- CXXConstructorDecl *getConstructor() const { return Constructor; }
- void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation Loc) { this->Loc = Loc; }
-
- /// \brief Whether this construction is elidable.
- bool isElidable() const { return Elidable; }
- void setElidable(bool E) { Elidable = E; }
-
- /// \brief 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.
- bool isListInitialization() const { return ListInitialization; }
- void setListInitialization(bool V) { ListInitialization = V; }
-
- /// \brief Whether this constructor call was written as list-initialization,
- /// but was interpreted as forming a std::initializer_list<T> from the list
- /// and passing that as a single constructor argument.
- /// See C++11 [over.match.list]p1 bullet 1.
- bool isStdInitListInitialization() const { return StdInitListInitialization; }
- void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
-
- /// \brief Whether this construction first requires
- /// zero-initialization before the initializer is called.
- bool requiresZeroInitialization() const { return ZeroInitialization; }
- void setRequiresZeroInitialization(bool ZeroInit) {
- ZeroInitialization = ZeroInit;
- }
-
- /// \brief Determine whether this constructor is actually constructing
- /// a base class (rather than a complete object).
- ConstructionKind getConstructionKind() const {
- return (ConstructionKind)ConstructKind;
- }
- void setConstructionKind(ConstructionKind CK) {
- ConstructKind = CK;
- }
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
- typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
-
- arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
- }
-
- arg_iterator arg_begin() { return Args; }
- arg_iterator arg_end() { return Args + NumArgs; }
- const_arg_iterator arg_begin() const { return Args; }
- const_arg_iterator arg_end() const { return Args + NumArgs; }
-
- Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
- const Expr *const *getArgs() const {
- return const_cast<CXXConstructExpr *>(this)->getArgs();
- }
- unsigned getNumArgs() const { return NumArgs; }
-
- /// \brief Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
- }
-
- /// \brief Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- Args[Arg] = ArgExpr;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
- SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
- void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConstructExprClass ||
- T->getStmtClass() == CXXTemporaryObjectExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Args[0], &Args[0]+NumArgs);
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Represents an explicit C++ type conversion that uses "functional"
-/// notation (C++ [expr.type.conv]).
-///
-/// Example:
-/// \code
-/// x = int(0.5);
-/// \endcode
-class CXXFunctionalCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> {
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
-
- CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
- TypeSourceInfo *writtenTy,
- CastKind kind, Expr *castExpr, unsigned pathSize,
- SourceLocation lParenLoc, SourceLocation rParenLoc)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
- castExpr, pathSize, writtenTy),
- LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
-
- explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
-
-public:
- static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- TypeSourceInfo *Written,
- CastKind Kind, Expr *Op,
- const CXXCastPath *Path,
- SourceLocation LPLoc,
- SourceLocation RPLoc);
- static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFunctionalCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// @brief Represents a C++ functional cast expression that builds a
-/// temporary object.
-///
-/// This expression type represents a C++ "functional" cast
-/// (C++[expr.type.conv]) with N != 1 arguments that invokes a
-/// constructor to build a temporary object. With N == 1 arguments the
-/// functional cast expression will be represented by CXXFunctionalCastExpr.
-/// Example:
-/// \code
-/// struct X { X(int, float); }
-///
-/// X create_X() {
-/// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
-/// };
-/// \endcode
-class CXXTemporaryObjectExpr : public CXXConstructExpr {
- TypeSourceInfo *Type;
-
-public:
- CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons,
- TypeSourceInfo *Type,
- ArrayRef<Expr *> Args,
- SourceRange ParenOrBraceRange,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization);
- explicit CXXTemporaryObjectExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
-
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTemporaryObjectExprClass;
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief A C++ lambda expression, which produces a function object
-/// (of unspecified type) that can be invoked later.
-///
-/// Example:
-/// \code
-/// void low_pass_filter(std::vector<double> &values, double cutoff) {
-/// values.erase(std::remove_if(values.begin(), values.end(),
-/// [=](double value) { return value > cutoff; });
-/// }
-/// \endcode
-///
-/// C++11 lambda expressions can capture local variables, either by copying
-/// the values of those local variables at the time the function
-/// object is constructed (not when it is called!) or by holding a
-/// reference to the local variable. These captures can occur either
-/// implicitly or can be written explicitly between the square
-/// brackets ([...]) that start the lambda expression.
-///
-/// C++1y introduces a new form of "capture" called an init-capture that
-/// includes an initializing expression (rather than capturing a variable),
-/// and which can never occur implicitly.
-class LambdaExpr final
- : public Expr,
- private llvm::TrailingObjects<LambdaExpr, Stmt *, unsigned, VarDecl *> {
- /// \brief The source range that covers the lambda introducer ([...]).
- SourceRange IntroducerRange;
-
- /// \brief The source location of this lambda's capture-default ('=' or '&').
- SourceLocation CaptureDefaultLoc;
-
- /// \brief The number of captures.
- unsigned NumCaptures : 16;
-
- /// \brief 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
- /// implicit (and empty) parameter list.
- unsigned ExplicitParams : 1;
-
- /// \brief Whether this lambda had the result type explicitly specified.
- unsigned ExplicitResultType : 1;
-
- /// \brief Whether there are any array index variables stored at the end of
- /// this lambda expression.
- unsigned HasArrayIndexVars : 1;
-
- /// \brief The location of the closing brace ('}') that completes
- /// the lambda.
- ///
- /// The location of the brace is also available by looking up the
- /// function call operator in the lambda class. However, it is
- /// stored here to improve the performance of getSourceRange(), and
- /// to avoid having to deserialize the function call operator from a
- /// module file just to determine the source range.
- SourceLocation ClosingBrace;
-
- size_t numTrailingObjects(OverloadToken<Stmt *>) const {
- return NumCaptures + 1;
- }
-
- size_t numTrailingObjects(OverloadToken<unsigned>) const {
- return HasArrayIndexVars ? NumCaptures + 1 : 0;
- }
-
- /// \brief Construct a lambda expression.
- LambdaExpr(QualType T, SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
- bool ExplicitParams, bool ExplicitResultType,
- ArrayRef<Expr *> CaptureInits, ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
-
- /// \brief Construct an empty lambda expression.
- LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
- : Expr(LambdaExprClass, Empty),
- NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
- ExplicitResultType(false), HasArrayIndexVars(true) {
- getStoredStmts()[NumCaptures] = nullptr;
- }
-
- Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
-
- Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
-
- /// \brief Retrieve the mapping from captures to the first array index
- /// variable.
- unsigned *getArrayIndexStarts() { return getTrailingObjects<unsigned>(); }
-
- const unsigned *getArrayIndexStarts() const {
- return getTrailingObjects<unsigned>();
- }
-
- /// \brief Retrieve the complete set of array-index variables.
- VarDecl **getArrayIndexVars() { return getTrailingObjects<VarDecl *>(); }
-
- VarDecl *const *getArrayIndexVars() const {
- return getTrailingObjects<VarDecl *>();
- }
-
-public:
- /// \brief Construct a new lambda expression.
- static LambdaExpr *
- Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
- ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
- bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
- ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
-
- /// \brief Construct a new lambda expression that will be deserialized from
- /// an external source.
- static LambdaExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumCaptures,
- unsigned NumArrayIndexVars);
-
- /// \brief 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.
- SourceLocation getCaptureDefaultLoc() const {
- return CaptureDefaultLoc;
- }
-
- /// \brief 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,
- /// both implicit and explicit.
- typedef const LambdaCapture *capture_iterator;
-
- /// \brief An iterator over a range of lambda captures.
- typedef llvm::iterator_range<capture_iterator> capture_range;
-
- /// \brief Retrieve this lambda's captures.
- capture_range captures() const;
-
- /// \brief Retrieve an iterator pointing to the first lambda capture.
- capture_iterator capture_begin() const;
-
- /// \brief 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.
- unsigned capture_size() const { return NumCaptures; }
-
- /// \brief Retrieve this lambda's explicit captures.
- capture_range explicit_captures() const;
-
- /// \brief Retrieve an iterator pointing to the first explicit
- /// lambda capture.
- capture_iterator explicit_capture_begin() const;
-
- /// \brief 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.
- capture_range implicit_captures() const;
-
- /// \brief 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
- /// implicit lambda captures.
- capture_iterator implicit_capture_end() const;
-
- /// \brief Iterator that walks over the capture initialization
- /// arguments.
- typedef Expr **capture_init_iterator;
-
- /// \brief Const iterator that walks over the capture initialization
- /// arguments.
- typedef Expr *const *const_capture_init_iterator;
-
- /// \brief 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.
- 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
- /// 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
- /// 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
- /// 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
- /// initialization argument for this lambda expression.
- const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
- }
-
- /// \brief Retrieve the set of index variables used in the capture
- /// initializer of an array captured by copy.
- ///
- /// \param Iter The iterator that points at the capture initializer for
- /// which we are extracting the corresponding index variables.
- ArrayRef<VarDecl *>
- getCaptureInitIndexVars(const_capture_init_iterator Iter) const;
-
- /// \brief 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.
- ///
- /// 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
- /// lambda expression.
- CXXMethodDecl *getCallOperator() const;
-
- /// \brief 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.
- bool isGenericLambda() const { return getTemplateParameterList(); }
-
- /// \brief Retrieve the body of the lambda.
- CompoundStmt *getBody() const;
-
- /// \brief 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
- /// list vs. an implicit (empty) parameter list.
- bool hasExplicitParameters() const { return ExplicitParams; }
-
- /// \brief Whether this lambda had its result type explicitly specified.
- bool hasExplicitResultType() const { return ExplicitResultType; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == LambdaExprClass;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return IntroducerRange.getBegin();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; }
-
- child_range children() {
- // Includes initialization exprs plus body stmt
- return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// An expression "T()" which creates a value-initialized rvalue of type
-/// T, which is a non-class type. See (C++98 [5.2.3p2]).
-class CXXScalarValueInitExpr : public Expr {
- SourceLocation RParenLoc;
- TypeSourceInfo *TypeInfo;
-
- friend class ASTStmtReader;
-
-public:
- /// \brief Create an explicitly-written scalar-value initialization
- /// expression.
- CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
- SourceLocation rParenLoc)
- : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
- false, false, Type->isInstantiationDependentType(),
- Type->containsUnexpandedParameterPack()),
- RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
-
- explicit CXXScalarValueInitExpr(EmptyShell Shell)
- : Expr(CXXScalarValueInitExprClass, Shell) { }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return TypeInfo;
- }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXScalarValueInitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a new-expression for memory allocation and constructor
-/// calls, e.g: "new CXXNewExpr(foo)".
-class CXXNewExpr : public Expr {
- /// Contains an optional array size expression, an optional initialization
- /// expression, and any number of optional placement arguments, in that order.
- Stmt **SubExprs;
- /// \brief Points to the allocation function used.
- FunctionDecl *OperatorNew;
- /// \brief 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.
- TypeSourceInfo *AllocatedTypeInfo;
-
- /// \brief 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.
- SourceRange Range;
-
- /// \brief Source-range of a paren-delimited initializer.
- SourceRange DirectInitRange;
-
- /// Was the usage ::new, i.e. is the global new to be used?
- bool GlobalNew : 1;
- /// Do we allocate an array? If so, the first SubExpr is the size expression.
- bool Array : 1;
- /// If this is an array allocation, does the usual deallocation
- /// function for the allocated type want to know the allocated size?
- bool UsualArrayDeleteWantsSize : 1;
- /// The number of placement new arguments.
- unsigned NumPlacementArgs : 13;
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
- unsigned StoredInitializationStyle : 2;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-public:
- enum InitializationStyle {
- NoInit, ///< New-expression has no initializer as written.
- CallInit, ///< New-expression has a C++98 paren-delimited initializer.
- ListInit ///< New-expression has a C++11 list-initializer.
- };
-
- CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
- FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
- ArrayRef<Expr*> placementArgs,
- SourceRange typeIdParens, Expr *arraySize,
- InitializationStyle initializationStyle, Expr *initializer,
- QualType ty, TypeSourceInfo *AllocatedTypeInfo,
- SourceRange Range, SourceRange directInitRange);
- explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
-
- void AllocateArgsArray(const ASTContext &C, bool isArray,
- unsigned numPlaceArgs, bool hasInitializer);
-
- QualType getAllocatedType() const {
- assert(getType()->isPointerType());
- return getType()->getAs<PointerType>()->getPointeeType();
- }
-
- TypeSourceInfo *getAllocatedTypeSourceInfo() const {
- return AllocatedTypeInfo;
- }
-
- /// \brief True if the allocation result needs to be null-checked.
- ///
- /// C++11 [expr.new]p13:
- /// If the allocation function returns null, initialization shall
- /// not be done, the deallocation function shall not be called,
- /// and the value of the new-expression shall be null.
- ///
- /// C++ DR1748:
- /// If the allocation function is a reserved placement allocation
- /// function that returns null, the behavior is undefined.
- ///
- /// An allocation function is not allowed to return null unless it
- /// has a non-throwing exception-specification. The '03 rule is
- /// identical except that the definition of a non-throwing
- /// exception specification is just "is it throw()?".
- bool shouldNullCheckAllocation(const ASTContext &Ctx) const;
-
- FunctionDecl *getOperatorNew() const { return OperatorNew; }
- void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
- FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
- void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
-
- bool isArray() const { return Array; }
- Expr *getArraySize() {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
- }
- const Expr *getArraySize() const {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
- }
-
- unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
- Expr **getPlacementArgs() {
- return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
- }
-
- Expr *getPlacementArg(unsigned i) {
- assert(i < NumPlacementArgs && "Index out of range");
- return getPlacementArgs()[i];
- }
- const Expr *getPlacementArg(unsigned i) const {
- assert(i < NumPlacementArgs && "Index out of range");
- return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
- }
-
- bool isParenTypeId() const { return TypeIdParens.isValid(); }
- SourceRange getTypeIdParens() const { return TypeIdParens; }
-
- bool isGlobalNew() const { return GlobalNew; }
-
- /// \brief Whether this new-expression has any initializer at all.
- bool hasInitializer() const { return StoredInitializationStyle > 0; }
-
- /// \brief 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.
- Expr *getInitializer() {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
- }
- const Expr *getInitializer() const {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
- }
-
- /// \brief Returns the CXXConstructExpr from this new-expression, or null.
- const CXXConstructExpr* getConstructExpr() const {
- return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
- }
-
- /// Answers whether the usual array deallocation function for the
- /// allocated type expects the size of the allocation as a
- /// parameter.
- bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
- }
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
-
- llvm::iterator_range<arg_iterator> placement_arguments() {
- return llvm::make_range(placement_arg_begin(), placement_arg_end());
- }
-
- llvm::iterator_range<const_arg_iterator> placement_arguments() const {
- return llvm::make_range(placement_arg_begin(), placement_arg_end());
- }
-
- arg_iterator placement_arg_begin() {
- return SubExprs + Array + hasInitializer();
- }
- arg_iterator placement_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
- const_arg_iterator placement_arg_begin() const {
- return SubExprs + Array + hasInitializer();
- }
- const_arg_iterator placement_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
-
- typedef Stmt **raw_arg_iterator;
- raw_arg_iterator raw_arg_begin() { return SubExprs; }
- raw_arg_iterator raw_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
- const_arg_iterator raw_arg_begin() const { return SubExprs; }
- const_arg_iterator raw_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
-
- SourceLocation getStartLoc() const { return Range.getBegin(); }
- SourceLocation getEndLoc() const { return Range.getEnd(); }
-
- SourceRange getDirectInitRange() const { return DirectInitRange; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return Range;
- }
- SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNewExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(raw_arg_begin(), raw_arg_end());
- }
-};
-
-/// \brief 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.
- FunctionDecl *OperatorDelete;
- /// The pointer expression to be deleted.
- Stmt *Argument;
- /// Location of the expression.
- SourceLocation Loc;
- /// Is this a forced global delete, i.e. "::delete"?
- bool GlobalDelete : 1;
- /// Is this the array form of delete, i.e. "delete[]"?
- bool ArrayForm : 1;
- /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied
- /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm
- /// will be true).
- bool ArrayFormAsWritten : 1;
- /// Does the usual deallocation function for the element type require
- /// a size_t argument?
- bool UsualArrayDeleteWantsSize : 1;
-public:
- CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm,
- bool arrayFormAsWritten, bool usualArrayDeleteWantsSize,
- FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
- : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false,
- arg->isInstantiationDependent(),
- arg->containsUnexpandedParameterPack()),
- OperatorDelete(operatorDelete), Argument(arg), Loc(loc),
- GlobalDelete(globalDelete),
- ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
- UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
- explicit CXXDeleteExpr(EmptyShell Shell)
- : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
- Argument(nullptr) {}
-
- bool isGlobalDelete() const { return GlobalDelete; }
- bool isArrayForm() const { return ArrayForm; }
- bool isArrayFormAsWritten() const { return ArrayFormAsWritten; }
-
- /// Answers whether the usual array deallocation function for the
- /// allocated type expects the size of the allocation as a
- /// parameter. This can be true even if the actual deallocation
- /// function that we're using doesn't want a size.
- bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
- }
-
- FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
-
- Expr *getArgument() { return cast<Expr>(Argument); }
- const Expr *getArgument() const { return cast<Expr>(Argument); }
-
- /// \brief 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.
- QualType getDestroyedType() const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY {return Argument->getLocEnd();}
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDeleteExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Argument, &Argument+1); }
-
- friend class ASTStmtReader;
-};
-
-/// \brief 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
- /// it couldn't be resolved due to type-dependence.
- llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
-
- /// \brief The starting source location of the pseudo-destructor type.
- SourceLocation Location;
-
-public:
- PseudoDestructorTypeStorage() { }
-
- PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
- : Type(II), Location(Loc) { }
-
- PseudoDestructorTypeStorage(TypeSourceInfo *Info);
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return Type.dyn_cast<TypeSourceInfo *>();
- }
-
- IdentifierInfo *getIdentifier() const {
- return Type.dyn_cast<IdentifierInfo *>();
- }
-
- SourceLocation getLocation() const { return Location; }
-};
-
-/// \brief 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
-/// destructors. For example:
-///
-/// \code
-/// typedef int T;
-/// void f(int *p) {
-/// p->T::~T();
-/// }
-/// \endcode
-///
-/// Pseudo-destructors typically occur when instantiating templates such as:
-///
-/// \code
-/// template<typename T>
-/// void destroy(T* ptr) {
-/// ptr->T::~T();
-/// }
-/// \endcode
-///
-/// for scalar types. A pseudo-destructor expression has no run-time semantics
-/// beyond evaluating the base expression.
-class CXXPseudoDestructorExpr : public Expr {
- /// \brief The base expression (that is being destroyed).
- Stmt *Base;
-
- /// \brief Whether the operator was an arrow ('->'); otherwise, it was a
- /// period ('.').
- bool IsArrow : 1;
-
- /// \brief The location of the '.' or '->' operator.
- SourceLocation OperatorLoc;
-
- /// \brief The nested-name-specifier that follows the operator, if present.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The type that precedes the '::' in a qualified pseudo-destructor
- /// expression.
- TypeSourceInfo *ScopeType;
-
- /// \brief The location of the '::' in a qualified pseudo-destructor
- /// expression.
- SourceLocation ColonColonLoc;
-
- /// \brief The location of the '~'.
- SourceLocation TildeLoc;
-
- /// \brief The type being destroyed, or its name if we were unable to
- /// resolve the name.
- PseudoDestructorTypeStorage DestroyedType;
-
- friend class ASTStmtReader;
-
-public:
- CXXPseudoDestructorExpr(const ASTContext &Context,
- Expr *Base, bool isArrow, SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- TypeSourceInfo *ScopeType,
- SourceLocation ColonColonLoc,
- SourceLocation TildeLoc,
- PseudoDestructorTypeStorage DestroyedType);
-
- explicit CXXPseudoDestructorExpr(EmptyShell Shell)
- : Expr(CXXPseudoDestructorExprClass, Shell),
- Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
-
- Expr *getBase() const { return cast<Expr>(Base); }
-
- /// \brief Determines whether this member expression actually had
- /// a C++ nested-name-specifier prior to the name of the member, e.g.,
- /// x->Base::foo.
- bool hasQualifier() const { return QualifierLoc.hasQualifier(); }
-
- /// \brief 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
- /// 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
- /// using an '->' (otherwise, it used a '.').
- bool isArrow() const { return IsArrow; }
-
- /// \brief Retrieve the location of the '.' or '->' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Retrieve the scope type in a qualified pseudo-destructor
- /// expression.
- ///
- /// Pseudo-destructor expressions can have extra qualification within them
- /// that is not part of the nested-name-specifier, e.g., \c p->T::~T().
- /// Here, if the object type of the expression is (or may be) a scalar type,
- /// \p T may also be a scalar type and, therefore, cannot be part of a
- /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
- /// destructor expression.
- TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
-
- /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
- /// expression.
- SourceLocation getColonColonLoc() const { return ColonColonLoc; }
-
- /// \brief Retrieve the location of the '~'.
- SourceLocation getTildeLoc() const { return TildeLoc; }
-
- /// \brief Retrieve the source location information for the type
- /// being destroyed.
- ///
- /// This type-source information is available for non-dependent
- /// pseudo-destructor expressions and some dependent pseudo-destructor
- /// expressions. Returns null if we only have the identifier for a
- /// dependent pseudo-destructor expression.
- TypeSourceInfo *getDestroyedTypeInfo() const {
- return DestroyedType.getTypeSourceInfo();
- }
-
- /// \brief 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.
- QualType getDestroyedType() const;
-
- /// \brief 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
- /// expression.
- void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
- DestroyedType = PseudoDestructorTypeStorage(II, Loc);
- }
-
- /// \brief Set the destroyed type.
- void setDestroyedType(TypeSourceInfo *Info) {
- DestroyedType = PseudoDestructorTypeStorage(Info);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {return Base->getLocStart();}
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXPseudoDestructorExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base + 1); }
-};
-
-/// \brief A type trait used in the implementation of various C++11 and
-/// Library TR1 trait templates.
-///
-/// \code
-/// __is_pod(int) == true
-/// __is_enum(std::string) == false
-/// __is_trivially_constructible(vector<int>, int*, int*)
-/// \endcode
-class TypeTraitExpr final
- : public Expr,
- private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> {
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing parenthesis.
- SourceLocation RParenLoc;
-
- // Note: The TypeSourceInfos for the arguments are allocated after the
- // TypeTraitExpr.
-
- TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc,
- bool Value);
-
- TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) { }
-
- size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
- return getNumArgs();
- }
-
-public:
- /// \brief Create a new type trait expression.
- static TypeTraitExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc, TypeTrait Kind,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc,
- bool Value);
-
- static TypeTraitExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumArgs);
-
- /// \brief Determine which type trait this expression uses.
- TypeTrait getTrait() const {
- return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
- }
-
- bool getValue() const {
- assert(!isValueDependent());
- return TypeTraitExprBits.Value;
- }
-
- /// \brief Determine the number of arguments to this type trait.
- unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
-
- /// \brief Retrieve the Ith argument.
- TypeSourceInfo *getArg(unsigned I) const {
- assert(I < getNumArgs() && "Argument out-of-range");
- return getArgs()[I];
- }
-
- /// \brief Retrieve the argument types.
- ArrayRef<TypeSourceInfo *> getArgs() const {
- return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(),
- getNumArgs());
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == TypeTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief An Embarcadero array type trait, as used in the implementation of
-/// __array_rank and __array_extent.
-///
-/// Example:
-/// \code
-/// __array_rank(int[10][20]) == 2
-/// __array_extent(int, 1) == 20
-/// \endcode
-class ArrayTypeTraitExpr : public Expr {
- virtual void anchor();
-
- /// \brief The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
- unsigned ATT : 2;
-
- /// \brief The value of the type trait. Unspecified if dependent.
- uint64_t Value;
-
- /// \brief The array dimension being queried, or -1 if not used.
- Expr *Dimension;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The type being queried.
- TypeSourceInfo *QueriedType;
-
-public:
- ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
- TypeSourceInfo *queried, uint64_t value,
- Expr *dimension, SourceLocation rparen, QualType ty)
- : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
- false, queried->getType()->isDependentType(),
- (queried->getType()->isInstantiationDependentType() ||
- (dimension && dimension->isInstantiationDependent())),
- queried->getType()->containsUnexpandedParameterPack()),
- ATT(att), Value(value), Dimension(dimension),
- Loc(loc), RParen(rparen), QueriedType(queried) { }
-
-
- explicit ArrayTypeTraitExpr(EmptyShell Empty)
- : Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
- QueriedType() { }
-
- virtual ~ArrayTypeTraitExpr() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
-
- QualType getQueriedType() const { return QueriedType->getType(); }
-
- TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
-
- uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
-
- Expr *getDimensionExpression() const { return Dimension; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ArrayTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief An expression trait intrinsic.
-///
-/// Example:
-/// \code
-/// __is_lvalue_expr(std::cout) == true
-/// __is_lvalue_expr(1) == false
-/// \endcode
-class ExpressionTraitExpr : public Expr {
- /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned.
- unsigned ET : 31;
- /// \brief The value of the type trait. Unspecified if dependent.
- bool Value : 1;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The expression being queried.
- Expr* QueriedExpression;
-public:
- ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et,
- Expr *queried, bool value,
- SourceLocation rparen, QualType resultType)
- : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Not type-dependent
- // Value-dependent if the argument is type-dependent.
- queried->isTypeDependent(),
- queried->isInstantiationDependent(),
- queried->containsUnexpandedParameterPack()),
- ET(et), Value(value), Loc(loc), RParen(rparen),
- QueriedExpression(queried) { }
-
- explicit ExpressionTraitExpr(EmptyShell Empty)
- : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
- QueriedExpression() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
-
- Expr *getQueriedExpression() const { return QueriedExpression; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExpressionTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
-};
-
-
-/// \brief 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.
- DeclarationNameInfo NameInfo;
-
- /// \brief The nested-name-specifier that qualifies the name, if any.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls. Access is relative to the naming
- /// class.
- // FIXME: Allocate this data after the OverloadExpr subclass.
- DeclAccessPair *Results;
- unsigned NumResults;
-
-protected:
- /// \brief Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
-
- /// \brief Return the optional template keyword and arguments info.
- ASTTemplateKWAndArgsInfo *
- getTrailingASTTemplateKWAndArgsInfo(); // defined far below.
-
- /// \brief Return the optional template keyword and arguments info.
- const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
- return const_cast<OverloadExpr *>(this)
- ->getTrailingASTTemplateKWAndArgsInfo();
- }
-
- /// Return the optional template arguments.
- TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
-
- OverloadExpr(StmtClass K, const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool KnownDependent,
- bool KnownInstantiationDependent,
- bool KnownContainsUnexpandedParameterPack);
-
- OverloadExpr(StmtClass K, EmptyShell Empty)
- : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
- HasTemplateKWAndArgsInfo(false) { }
-
- void initializeResults(const ASTContext &C,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
-
-public:
- struct FindResult {
- OverloadExpr *Expression;
- bool IsAddressOfOperand;
- bool HasFormOfMemberPointer;
- };
-
- /// \brief Finds the overloaded expression in the given expression \p E of
- /// OverloadTy.
- ///
- /// \return the expression (which must be there) and true if it has
- /// the particular form of a member pointer expression
- static FindResult find(Expr *E) {
- assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
-
- FindResult Result;
-
- E = E->IgnoreParens();
- if (isa<UnaryOperator>(E)) {
- assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
- E = cast<UnaryOperator>(E)->getSubExpr();
- OverloadExpr *Ovl = cast<OverloadExpr>(E->IgnoreParens());
-
- Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
- Result.IsAddressOfOperand = true;
- Result.Expression = Ovl;
- } else {
- Result.HasFormOfMemberPointer = false;
- Result.IsAddressOfOperand = false;
- Result.Expression = cast<OverloadExpr>(E);
- }
-
- return Result;
- }
-
- /// \brief Gets the naming class of this lookup, if any.
- CXXRecordDecl *getNamingClass() const;
-
- typedef UnresolvedSetImpl::iterator decls_iterator;
- decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
- decls_iterator decls_end() const {
- return UnresolvedSetIterator(Results + NumResults);
- }
- llvm::iterator_range<decls_iterator> decls() const {
- return llvm::make_range(decls_begin(), decls_end());
- }
-
- /// \brief Gets the number of declarations in the unresolved set.
- unsigned getNumDecls() const { return NumResults; }
-
- /// \brief Gets the full name info.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
-
- /// \brief Gets the name looked up.
- DeclarationName getName() const { return NameInfo.getName(); }
-
- /// \brief Gets the location of the name.
- SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
-
- /// \brief Fetches the nested-name qualifier, if one was given.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief 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
- /// 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
- /// 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
- /// 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.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// \brief Determines whether this expression had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- TemplateArgumentLoc const *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
- return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
- }
-
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs;
- }
-
- /// \brief Copies the template arguments into the given structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedLookupExprClass ||
- T->getStmtClass() == UnresolvedMemberExprClass;
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief 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:
-/// * we might be waiting for argument-dependent lookup;
-/// * the name might resolve to an overloaded function;
-/// and eventually:
-/// * the lookup might have included a function template.
-///
-/// These never include UnresolvedUsingValueDecls, which are always class
-/// members and therefore appear only in UnresolvedMemberLookupExprs.
-class UnresolvedLookupExpr final
- : public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
- /// True if these lookup results should be extended by
- /// argument-dependent lookup if this is the operand of a function
- /// call.
- bool RequiresADL;
-
- /// True if these lookup results are overloaded. This is pretty
- /// trivially rederivable if we urgently need to kill this field.
- bool Overloaded;
-
- /// The naming class (C++ [class.access.base]p5) of the lookup, if
- /// any. This can generally be recalculated from the context chain,
- /// but that can be fairly expensive for unqualified lookups. If we
- /// want to improve memory use here, this could go in a union
- /// against the qualified-lookup bits.
- CXXRecordDecl *NamingClass;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- UnresolvedLookupExpr(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool RequiresADL, bool Overloaded,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End)
- : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
- NameInfo, TemplateArgs, Begin, End, false, false, false),
- RequiresADL(RequiresADL),
- Overloaded(Overloaded), NamingClass(NamingClass)
- {}
-
- UnresolvedLookupExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), Overloaded(false), NamingClass(nullptr)
- {}
-
- friend TrailingObjects;
- friend class OverloadExpr;
- friend class ASTStmtReader;
-
-public:
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL, bool Overloaded,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
- return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
- SourceLocation(), NameInfo,
- ADL, Overloaded, nullptr, Begin, End);
- }
-
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL,
- const TemplateArgumentListInfo *Args,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
-
- static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// True if this declaration should be extended by
- /// argument-dependent lookup.
- bool requiresADL() const { return RequiresADL; }
-
- /// True if this lookup is overloaded.
- bool isOverloaded() const { return Overloaded; }
-
- /// Gets the 'naming class' (in the sense of C++0x
- /// [class.access.base]p5) of the lookup. This is the scope
- /// that was looked in to find these results.
- CXXRecordDecl *getNamingClass() const { return NamingClass; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (NestedNameSpecifierLoc l = getQualifierLoc())
- return l.getBeginLoc();
- return getNameInfo().getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getNameInfo().getLocEnd();
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedLookupExprClass;
- }
-};
-
-/// \brief A qualified reference to a name whose declaration cannot
-/// yet be resolved.
-///
-/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
-/// it expresses a reference to a declaration such as
-/// X<T>::value. The difference, however, is that an
-/// DependentScopeDeclRefExpr node is used only within C++ templates when
-/// the qualification (e.g., X<T>::) refers to a dependent type. In
-/// this case, X<T>::value cannot resolve to a declaration because the
-/// declaration will differ from one instantiation of X<T> to the
-/// next. Therefore, DependentScopeDeclRefExpr keeps track of the
-/// qualifier (X<T>::) and the name of the entity being referenced
-/// ("value"). Such expressions will instantiate to a DeclRefExpr once the
-/// declaration can be found.
-class DependentScopeDeclRefExpr final
- : public Expr,
- private llvm::TrailingObjects<DependentScopeDeclRefExpr,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// \brief The nested-name-specifier that qualifies this unresolved
- /// declaration name.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The name of the entity we will be referencing.
- DeclarationNameInfo NameInfo;
-
- /// \brief Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- DependentScopeDeclRefExpr(QualType T,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *Args);
-
-public:
- static DependentScopeDeclRefExpr *Create(const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief Retrieve the name that this expression refers to.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
-
- /// \brief Retrieve the name that this expression refers to.
- DeclarationName getDeclName() const { return NameInfo.getName(); }
-
- /// \brief 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
- /// name, with source location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies this
- /// declaration.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief 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
- /// 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
- /// explicit template argument list following the name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// Determines whether the name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// Determines whether this lookup had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- /// \brief Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- TemplateArgumentLoc const *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr,
- /// and differs from getLocation().getStart().
- SourceLocation getLocStart() const LLVM_READONLY {
- return QualifierLoc.getBeginLoc();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getLocation();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DependentScopeDeclRefExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// Represents an expression -- generally a full-expression -- that
-/// introduces cleanups to be run at the end of the sub-expression's
-/// evaluation. The most common source of expression-introduced
-/// cleanups is temporary objects in C++, but several other kinds of
-/// expressions can create cleanups, including basically every
-/// call in ARC that returns an Objective-C pointer.
-///
-/// This expression also tracks whether the sub-expression contains a
-/// potentially-evaluated block literal. The lifetime of a block
-/// literal is the extent of the enclosing scope.
-class ExprWithCleanups final
- : public Expr,
- private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
-public:
- /// The type of objects that are kept in the cleanup.
- /// It's useful to remember the set of blocks; we could also
- /// remember the set of temporaries, but there's currently
- /// no need.
- typedef BlockDecl *CleanupObject;
-
-private:
- Stmt *SubExpr;
-
- ExprWithCleanups(EmptyShell, unsigned NumObjects);
- ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects);
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-
-public:
- static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty,
- unsigned numObjects);
-
- static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
- ArrayRef<CleanupObject> objects);
-
- ArrayRef<CleanupObject> getObjects() const {
- return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(),
- getNumObjects());
- }
-
- unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
-
- CleanupObject getObject(unsigned i) const {
- assert(i < getNumObjects() && "Index out of range");
- return getObjects()[i];
- }
-
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
-
- /// As with any mutator of the AST, be very careful
- /// when modifying an existing AST to preserve its invariants.
- void setSubExpr(Expr *E) { SubExpr = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExprWithCleanupsClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-};
-
-/// \brief Describes an explicit type conversion that uses functional
-/// notion but could not be resolved because one or more arguments are
-/// type-dependent.
-///
-/// The explicit type conversions expressed by
-/// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>,
-/// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and
-/// either \c T is a dependent type or one or more of the <tt>a</tt>'s is
-/// type-dependent. For example, this would occur in a template such
-/// as:
-///
-/// \code
-/// template<typename T, typename A1>
-/// inline T make_a(const A1& a1) {
-/// return T(a1);
-/// }
-/// \endcode
-///
-/// When the returned expression is instantiated, it may resolve to a
-/// constructor call, conversion function call, or some kind of type
-/// conversion.
-class CXXUnresolvedConstructExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> {
- /// \brief The type being constructed.
- TypeSourceInfo *Type;
-
- /// \brief The location of the left parentheses ('(').
- SourceLocation LParenLoc;
-
- /// \brief The location of the right parentheses (')').
- SourceLocation RParenLoc;
-
- /// \brief The number of arguments used to construct the type.
- unsigned NumArgs;
-
- CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
- SourceLocation RParenLoc);
-
- CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), Type(), NumArgs(NumArgs) { }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-
-public:
- static CXXUnresolvedConstructExpr *Create(const ASTContext &C,
- TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
- SourceLocation RParenLoc);
-
- static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C,
- unsigned NumArgs);
-
- /// \brief 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
- /// constructed.
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
-
- /// \brief 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
- /// follows the argument list.
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- /// \brief Retrieve the number of arguments.
- unsigned arg_size() const { return NumArgs; }
-
- typedef Expr** arg_iterator;
- arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
- arg_iterator arg_end() { return arg_begin() + NumArgs; }
-
- typedef const Expr* const * const_arg_iterator;
- const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
- const_arg_iterator arg_end() const {
- return arg_begin() + NumArgs;
- }
-
- Expr *getArg(unsigned I) {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
- }
-
- const Expr *getArg(unsigned I) const {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
- }
-
- void setArg(unsigned I, Expr *E) {
- assert(I < NumArgs && "Argument index out-of-range");
- *(arg_begin() + I) = E;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (!RParenLoc.isValid() && NumArgs > 0)
- return getArg(NumArgs - 1)->getLocEnd();
- return RParenLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUnresolvedConstructExprClass;
- }
-
- // Iterators
- child_range children() {
- Stmt **begin = reinterpret_cast<Stmt **>(arg_begin());
- return child_range(begin, begin + NumArgs);
- }
-};
-
-/// \brief 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.
-///
-/// Like UnresolvedMemberExprs, these can be either implicit or
-/// explicit accesses. It is only possible to get one of these with
-/// an implicit access if a qualifier is provided.
-class CXXDependentScopeMemberExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// \brief 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
- /// implicit accesses.
- QualType BaseType;
-
- /// \brief Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// \brief Whether this member expression has info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo : 1;
-
- /// \brief The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
-
- /// \brief 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
- /// member stores the resolves of name lookup in the context of the member
- /// access expression, to be used at instantiation time.
- ///
- /// FIXME: This member, along with the QualifierLoc, could
- /// be stuck into a structure that is optionally allocated at the end of
- /// the CXXDependentScopeMemberExpr, to save space in the common case.
- NamedDecl *FirstQualifierFoundInScope;
-
- /// \brief The member to which this member expression refers, which
- /// can be name, overloaded operator, or destructor.
- ///
- /// FIXME: could also be a template-id
- DeclarationNameInfo MemberNameInfo;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
-public:
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo);
-
- static CXXDependentScopeMemberExpr *
- Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- static CXXDependentScopeMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief 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,
- /// e.g., the \c x in \c x.m.
- Expr *getBase() const {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
-
- QualType getBaseType() const { return BaseType; }
-
- /// \brief 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.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief 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
- /// name, with source location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
-
- /// \brief 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.
- ///
- /// This function only returns a useful result when member access expression
- /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration
- /// returned by this function describes what was found by unqualified name
- /// lookup for the identifier "Base" within the scope of the member access
- /// expression itself. At template instantiation time, this information is
- /// combined with the results of name lookup into the type of the object
- /// expression itself (the class type of x).
- NamedDecl *getFirstQualifierFoundInScope() const {
- return FirstQualifierFoundInScope;
- }
-
- /// \brief 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
- /// refers to.
- DeclarationName getMember() const { return MemberNameInfo.getName(); }
-
- // \brief 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
- /// 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
- /// 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
- /// explicit template argument list following the member name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// 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++
- /// 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
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (!isImplicitAccess())
- return Base->getLocStart();
- if (getQualifier())
- return getQualifierLoc().getBeginLoc();
- return MemberNameInfo.getBeginLoc();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return MemberNameInfo.getEndLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDependentScopeMemberExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isImplicitAccess())
- return child_range(child_iterator(), child_iterator());
- return child_range(&Base, &Base + 1);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief Represents a C++ member access expression for which lookup
-/// produced a set of overloaded functions.
-///
-/// The member access may be explicit or implicit:
-/// \code
-/// struct A {
-/// int a, b;
-/// int explicitAccess() { return this->a + this->A::b; }
-/// int implicitAccess() { return a + A::b; }
-/// };
-/// \endcode
-///
-/// In the final AST, an explicit access always becomes a MemberExpr.
-/// An implicit access may become either a MemberExpr or a
-/// DeclRefExpr, depending on whether the member is static.
-class UnresolvedMemberExpr final
- : public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
- /// \brief Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// \brief Whether the lookup results contain an unresolved using
- /// declaration.
- bool HasUnresolvedUsing : 1;
-
- /// \brief 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;
-
- /// \brief The type of the base expression; never null.
- QualType BaseType;
-
- /// \brief The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
-
- UnresolvedMemberExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false), Base(nullptr) { }
-
- friend TrailingObjects;
- friend class OverloadExpr;
- friend class ASTStmtReader;
-
-public:
- static UnresolvedMemberExpr *
- Create(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
-
- static UnresolvedMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief 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,
- /// e.g., the \c x in \c x.m.
- Expr *getBase() {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
- const Expr *getBase() const {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
-
- QualType getBaseType() const { return BaseType; }
-
- /// \brief Determine whether the lookup results contain an unresolved using
- /// declaration.
- bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
-
- /// \brief 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.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Retrieve the naming class of this lookup.
- CXXRecordDecl *getNamingClass() const;
-
- /// \brief 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
- /// refers to.
- DeclarationName getMemberName() const { return getName(); }
-
- // \brief 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
- // diagnosing a problem with this expression.
- SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (!isImplicitAccess())
- return Base->getLocStart();
- if (NestedNameSpecifierLoc l = getQualifierLoc())
- return l.getBeginLoc();
- return getMemberNameInfo().getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getMemberNameInfo().getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedMemberExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isImplicitAccess())
- return child_range(child_iterator(), child_iterator());
- return child_range(&Base, &Base + 1);
- }
-};
-
-inline ASTTemplateKWAndArgsInfo *
-OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo)
- return nullptr;
-
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
-}
-
-inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
-}
-
-/// \brief 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.
-class CXXNoexceptExpr : public Expr {
- bool Value : 1;
- Stmt *Operand;
- SourceRange Range;
-
- friend class ASTStmtReader;
-
-public:
- CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
- SourceLocation Keyword, SourceLocation RParen)
- : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
- /*TypeDependent*/false,
- /*ValueDependent*/Val == CT_Dependent,
- Val == CT_Dependent || Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen)
- { }
-
- CXXNoexceptExpr(EmptyShell Empty)
- : Expr(CXXNoexceptExprClass, Empty)
- { }
-
- Expr *getOperand() const { return static_cast<Expr*>(Operand); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNoexceptExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Operand, &Operand + 1); }
-};
-
-/// \brief Represents a C++11 pack expansion that produces a sequence of
-/// expressions.
-///
-/// A pack expansion expression contains a pattern (which itself is an
-/// expression) followed by an ellipsis. For example:
-///
-/// \code
-/// template<typename F, typename ...Types>
-/// void forward(F f, Types &&...args) {
-/// f(static_cast<Types&&>(args)...);
-/// }
-/// \endcode
-///
-/// Here, the argument to the function object \c f is a pack expansion whose
-/// pattern is \c static_cast<Types&&>(args). When the \c forward function
-/// template is instantiated, the pack expansion will instantiate to zero or
-/// or more function arguments to the function object \c f.
-class PackExpansionExpr : public Expr {
- SourceLocation EllipsisLoc;
-
- /// \brief 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
- /// is the number of expansions + 1.
- unsigned NumExpansions;
-
- Stmt *Pattern;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions)
- : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
- Pattern->getObjectKind(), /*TypeDependent=*/true,
- /*ValueDependent=*/true, /*InstantiationDependent=*/true,
- /*ContainsUnexpandedParameterPack=*/false),
- EllipsisLoc(EllipsisLoc),
- NumExpansions(NumExpansions? *NumExpansions + 1 : 0),
- Pattern(Pattern) { }
-
- PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) { }
-
- /// \brief Retrieve the pattern of the pack expansion.
- Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); }
-
- /// \brief 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
- /// expansion.
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
-
- /// \brief Determine the number of expansions that will be produced when
- /// this pack expansion is instantiated, if already known.
- Optional<unsigned> getNumExpansions() const {
- if (NumExpansions)
- return NumExpansions - 1;
-
- return None;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return Pattern->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PackExpansionExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Pattern, &Pattern + 1);
- }
-};
-
-
-/// \brief Represents an expression that computes the length of a parameter
-/// pack.
-///
-/// \code
-/// template<typename ...Types>
-/// struct count {
-/// static const unsigned value = sizeof...(Types);
-/// };
-/// \endcode
-class SizeOfPackExpr final
- : public Expr,
- private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> {
- /// \brief The location of the \c sizeof keyword.
- SourceLocation OperatorLoc;
-
- /// \brief The location of the name of the parameter pack.
- SourceLocation PackLoc;
-
- /// \brief The location of the closing parenthesis.
- SourceLocation RParenLoc;
-
- /// \brief 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
- /// (and thus is value-dependent), this is zero.
- ///
- /// After partial substitution into a sizeof...(X) expression (for instance,
- /// within an alias template or during function template argument deduction),
- /// we store a trailing array of partially-substituted TemplateArguments,
- /// and this is the length of that array.
- unsigned Length;
-
- /// \brief The parameter pack.
- NamedDecl *Pack;
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- /// \brief Create an expression that computes the length of
- /// the given parameter pack.
- SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
- SourceLocation PackLoc, SourceLocation RParenLoc,
- Optional<unsigned> Length, ArrayRef<TemplateArgument> PartialArgs)
- : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
- /*TypeDependent=*/false, /*ValueDependent=*/!Length,
- /*InstantiationDependent=*/!Length,
- /*ContainsUnexpandedParameterPack=*/false),
- OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
- Length(Length ? *Length : PartialArgs.size()), Pack(Pack) {
- assert((!Length || PartialArgs.empty()) &&
- "have partial args for non-dependent sizeof... expression");
- TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
- std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
- }
-
- /// \brief Create an empty expression.
- SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs)
- : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs), Pack() {}
-
-public:
- static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc,
- NamedDecl *Pack, SourceLocation PackLoc,
- SourceLocation RParenLoc,
- Optional<unsigned> Length = None,
- ArrayRef<TemplateArgument> PartialArgs = None);
- static SizeOfPackExpr *CreateDeserialized(ASTContext &Context,
- unsigned NumPartialArgs);
-
- /// \brief Determine the location of the 'sizeof' keyword.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Determine the location of the parameter pack.
- SourceLocation getPackLoc() const { return PackLoc; }
-
- /// \brief Determine the location of the right parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- /// \brief Retrieve the parameter pack.
- NamedDecl *getPack() const { return Pack; }
-
- /// \brief Retrieve the length of the parameter pack.
- ///
- /// This routine may only be invoked when the expression is not
- /// value-dependent.
- unsigned getPackLength() const {
- assert(!isValueDependent() &&
- "Cannot get the length of a value-dependent pack size expression");
- return Length;
- }
-
- /// \brief Determine whether this represents a partially-substituted sizeof...
- /// expression, such as is produced for:
- ///
- /// template<typename ...Ts> using X = int[sizeof...(Ts)];
- /// template<typename ...Us> void f(X<Us..., 1, 2, 3, Us...>);
- bool isPartiallySubstituted() const {
- return isValueDependent() && Length;
- }
-
- /// \brief Get
- ArrayRef<TemplateArgument> getPartialArguments() const {
- assert(isPartiallySubstituted());
- const TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
- return llvm::makeArrayRef(Args, Args + Length);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SizeOfPackExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a reference to a non-type template parameter
-/// that has been substituted with a template argument.
-class SubstNonTypeTemplateParmExpr : public Expr {
- /// \brief The replaced parameter.
- NonTypeTemplateParmDecl *Param;
-
- /// \brief The replacement expression.
- Stmt *Replacement;
-
- /// \brief The location of the non-type template parameter reference.
- SourceLocation NameLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmExprClass, Empty) { }
-
-public:
- SubstNonTypeTemplateParmExpr(QualType type,
- ExprValueKind valueKind,
- SourceLocation loc,
- NonTypeTemplateParmDecl *param,
- Expr *replacement)
- : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
- replacement->isTypeDependent(), replacement->isValueDependent(),
- replacement->isInstantiationDependent(),
- replacement->containsUnexpandedParameterPack()),
- Param(param), Replacement(replacement), NameLoc(loc) {}
-
- SourceLocation getNameLoc() const { return NameLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- Expr *getReplacement() const { return cast<Expr>(Replacement); }
-
- NonTypeTemplateParmDecl *getParameter() const { return Param; }
-
- static bool classof(const Stmt *s) {
- return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Replacement, &Replacement+1); }
-};
-
-/// \brief 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
-/// and those parameter packs correspond to different levels of template
-/// parameter lists, this node is used to represent a non-type template
-/// parameter pack from an outer level, which has already had its argument pack
-/// substituted but that still lives within a pack expansion that itself
-/// could not be instantiated. When actually performing a substitution into
-/// that pack expansion (e.g., when all template parameters have corresponding
-/// arguments), this type will be replaced with the appropriate underlying
-/// expression at the current pack substitution index.
-class SubstNonTypeTemplateParmPackExpr : public Expr {
- /// \brief The non-type template parameter pack itself.
- NonTypeTemplateParmDecl *Param;
-
- /// \brief 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.
- unsigned NumArguments;
-
- /// \brief The location of the non-type template parameter pack reference.
- SourceLocation NameLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
-
-public:
- SubstNonTypeTemplateParmPackExpr(QualType T,
- NonTypeTemplateParmDecl *Param,
- SourceLocation NameLoc,
- const TemplateArgument &ArgPack);
-
- /// \brief Retrieve the non-type template parameter pack being substituted.
- NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
-
- /// \brief Retrieve the location of the parameter pack name.
- SourceLocation getParameterPackLocation() const { return NameLoc; }
-
- /// \brief Retrieve the template argument pack containing the substituted
- /// template arguments.
- TemplateArgument getArgumentPack() const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief 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,
-/// this node is used to represent a function parameter pack at an outer level
-/// which we have already substituted to refer to expanded parameters, but where
-/// the containing pack expansion cannot yet be expanded.
-///
-/// \code
-/// template<typename...Ts> struct S {
-/// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...));
-/// };
-/// template struct S<int, int>;
-/// \endcode
-class FunctionParmPackExpr final
- : public Expr,
- private llvm::TrailingObjects<FunctionParmPackExpr, ParmVarDecl *> {
- /// \brief The function parameter pack which was referenced.
- ParmVarDecl *ParamPack;
-
- /// \brief The location of the function parameter pack reference.
- SourceLocation NameLoc;
-
- /// \brief The number of expansions of this pack.
- unsigned NumParameters;
-
- FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
- SourceLocation NameLoc, unsigned NumParams,
- ParmVarDecl *const *Params);
-
- friend TrailingObjects;
- friend class ASTReader;
- friend class ASTStmtReader;
-
-public:
- static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T,
- ParmVarDecl *ParamPack,
- SourceLocation NameLoc,
- ArrayRef<ParmVarDecl *> Params);
- static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumParams);
-
- /// \brief Get the parameter pack which this expression refers to.
- ParmVarDecl *getParameterPack() const { return ParamPack; }
-
- /// \brief Get the location of the parameter pack.
- SourceLocation getParameterPackLocation() const { return NameLoc; }
-
- /// \brief Iterators over the parameters which the parameter pack expanded
- /// into.
- typedef ParmVarDecl * const *iterator;
- iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); }
- iterator end() const { return begin() + NumParameters; }
-
- /// \brief Get the number of parameters in this parameter pack.
- unsigned getNumExpansions() const { return NumParameters; }
-
- /// \brief Get an expansion of the parameter pack by index.
- ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == FunctionParmPackExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief 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
-/// in memory for a reference to bind to. This happens when binding a
-/// reference to the result of a conversion, e.g.,
-///
-/// \code
-/// const int &r = 1.0;
-/// \endcode
-///
-/// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is
-/// then materialized via a \c MaterializeTemporaryExpr, and the reference
-/// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues
-/// (either an lvalue or an xvalue, depending on the kind of reference binding
-/// to it), maintaining the invariant that references always bind to glvalues.
-///
-/// Reference binding and copy-elision can both extend the lifetime of a
-/// temporary. When either happens, the expression will also track the
-/// declaration which is responsible for the lifetime extension.
-class MaterializeTemporaryExpr : public Expr {
-private:
- struct ExtraState {
- /// \brief The temporary-generating expression whose value will be
- /// materialized.
- Stmt *Temporary;
-
- /// \brief The declaration which lifetime-extended this reference, if any.
- /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
- const ValueDecl *ExtendingDecl;
-
- unsigned ManglingNumber;
- };
- llvm::PointerUnion<Stmt *, ExtraState *> State;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- void initializeExtraState(const ValueDecl *ExtendedBy,
- unsigned ManglingNumber);
-
-public:
- MaterializeTemporaryExpr(QualType T, Expr *Temporary,
- bool BoundToLvalueReference)
- : Expr(MaterializeTemporaryExprClass, T,
- BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
- Temporary->isTypeDependent(), Temporary->isValueDependent(),
- Temporary->isInstantiationDependent(),
- Temporary->containsUnexpandedParameterPack()),
- State(Temporary) {}
-
- MaterializeTemporaryExpr(EmptyShell Empty)
- : Expr(MaterializeTemporaryExprClass, Empty) { }
-
- Stmt *getTemporary() const {
- return State.is<Stmt *>() ? State.get<Stmt *>()
- : State.get<ExtraState *>()->Temporary;
- }
-
- /// \brief Retrieve the temporary-generating subexpression whose value will
- /// be materialized into a glvalue.
- Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
-
- /// \brief Retrieve the storage duration for the materialized temporary.
- StorageDuration getStorageDuration() const {
- const ValueDecl *ExtendingDecl = getExtendingDecl();
- if (!ExtendingDecl)
- return SD_FullExpression;
- // FIXME: This is not necessarily correct for a temporary materialized
- // within a default initializer.
- if (isa<FieldDecl>(ExtendingDecl))
- return SD_Automatic;
- return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
- }
-
- /// \brief Get the declaration which triggered the lifetime-extension of this
- /// temporary, if any.
- const ValueDecl *getExtendingDecl() const {
- return State.is<Stmt *>() ? nullptr
- : State.get<ExtraState *>()->ExtendingDecl;
- }
-
- void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
-
- unsigned getManglingNumber() const {
- return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
- }
-
- /// \brief 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;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getTemporary()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getTemporary()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MaterializeTemporaryExprClass;
- }
-
- // Iterators
- child_range children() {
- if (State.is<Stmt *>())
- return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
-
- auto ES = State.get<ExtraState *>();
- return child_range(&ES->Temporary, &ES->Temporary + 1);
- }
-};
-
-/// \brief Represents a folding of a pack over an operator.
-///
-/// This expression is always dependent and represents a pack expansion of the
-/// forms:
-///
-/// ( expr op ... )
-/// ( ... op expr )
-/// ( expr op ... op expr )
-class CXXFoldExpr : public Expr {
- SourceLocation LParenLoc;
- SourceLocation EllipsisLoc;
- SourceLocation RParenLoc;
- Stmt *SubExprs[2];
- BinaryOperatorKind Opcode;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-public:
- CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
- BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc)
- : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary,
- /*Dependent*/ true, true, true,
- /*ContainsUnexpandedParameterPack*/ false),
- LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
- Opcode(Opcode) {
- SubExprs[0] = LHS;
- SubExprs[1] = RHS;
- }
- CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
-
- Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); }
- Expr *getRHS() const { return static_cast<Expr*>(SubExprs[1]); }
-
- /// Does this produce a right-associated sequence of operators?
- bool isRightFold() const {
- return getLHS() && getLHS()->containsUnexpandedParameterPack();
- }
- /// Does this produce a left-associated sequence of operators?
- bool isLeftFold() const { return !isRightFold(); }
- /// Get the pattern, that is, the operand that contains an unexpanded pack.
- Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); }
- /// Get the operand that doesn't contain a pack, for a binary fold.
- Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
-
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- BinaryOperatorKind getOperator() const { return Opcode; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return LParenLoc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return RParenLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFoldExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(SubExprs, SubExprs + 2); }
-};
-
-/// \brief 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
-/// that returns 'false':
-/// -- execution of the coroutine is suspended
-/// -- the 'suspend' expression is evaluated
-/// -- if the 'suspend' expression returns 'false', the coroutine is
-/// resumed
-/// -- otherwise, control passes back to the resumer.
-/// If the coroutine is not suspended, or when it is resumed, the 'resume'
-/// expression is evaluated, and its result is the result of the overall
-/// expression.
-class CoroutineSuspendExpr : public Expr {
- SourceLocation KeywordLoc;
-
- enum SubExpr { Common, Ready, Suspend, Resume, Count };
- Stmt *SubExprs[SubExpr::Count];
-
- friend class ASTStmtReader;
-public:
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
- Expr *Ready, Expr *Suspend, Expr *Resume)
- : Expr(SC, Resume->getType(), Resume->getValueKind(),
- Resume->getObjectKind(), Resume->isTypeDependent(),
- Resume->isValueDependent(), Common->isInstantiationDependent(),
- Common->containsUnexpandedParameterPack()),
- KeywordLoc(KeywordLoc) {
- SubExprs[SubExpr::Common] = Common;
- SubExprs[SubExpr::Ready] = Ready;
- SubExprs[SubExpr::Suspend] = Suspend;
- SubExprs[SubExpr::Resume] = Resume;
- }
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
- Expr *Common)
- : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true,
- Common->containsUnexpandedParameterPack()),
- KeywordLoc(KeywordLoc) {
- assert(Common->isTypeDependent() && Ty->isDependentType() &&
- "wrong constructor for non-dependent co_await/co_yield expression");
- SubExprs[SubExpr::Common] = Common;
- SubExprs[SubExpr::Ready] = nullptr;
- SubExprs[SubExpr::Suspend] = nullptr;
- SubExprs[SubExpr::Resume] = nullptr;
- }
- CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
- SubExprs[SubExpr::Common] = nullptr;
- SubExprs[SubExpr::Ready] = nullptr;
- SubExprs[SubExpr::Suspend] = nullptr;
- SubExprs[SubExpr::Resume] = nullptr;
- }
-
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
- Expr *getCommonExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Common]);
- }
-
- Expr *getReadyExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
- }
- Expr *getSuspendExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Suspend]);
- }
- Expr *getResumeExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return KeywordLoc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCommonExpr()->getLocEnd();
- }
-
- child_range children() {
- return child_range(SubExprs, SubExprs + SubExpr::Count);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoawaitExprClass ||
- T->getStmtClass() == CoyieldExprClass;
- }
-};
-
-/// \brief Represents a 'co_await' expression.
-class CoawaitExpr : public CoroutineSuspendExpr {
- friend class ASTStmtReader;
-public:
- CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
- Suspend, Resume) {}
- CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {}
- CoawaitExpr(EmptyShell Empty)
- : CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
-
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoawaitExprClass;
- }
-};
-
-/// \brief Represents a 'co_yield' expression.
-class CoyieldExpr : public CoroutineSuspendExpr {
- friend class ASTStmtReader;
-public:
- CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
- Suspend, Resume) {}
- CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
- CoyieldExpr(EmptyShell Empty)
- : CoroutineSuspendExpr(CoyieldExprClass, Empty) {}
-
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoyieldExprClass;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
deleted file mode 100644
index 61e6383..0000000
--- a/include/clang/AST/ExprObjC.h
+++ /dev/null
@@ -1,1568 +0,0 @@
-//===--- ExprObjC.h - Classes for representing ObjC expressions -*- 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 ExprObjC interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPROBJC_H
-#define LLVM_CLANG_AST_EXPROBJC_H
-
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/SelectorLocationsKind.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
- class IdentifierInfo;
- class ASTContext;
-
-/// ObjCStringLiteral, used for Objective-C string literals
-/// i.e. @"foo".
-class ObjCStringLiteral : public Expr {
- Stmt *String;
- SourceLocation AtLoc;
-public:
- ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
- : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- String(SL), AtLoc(L) {}
- explicit ObjCStringLiteral(EmptyShell Empty)
- : Expr(ObjCStringLiteralClass, Empty) {}
-
- StringLiteral *getString() { return cast<StringLiteral>(String); }
- const StringLiteral *getString() const { return cast<StringLiteral>(String); }
- void setString(StringLiteral *S) { String = S; }
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCStringLiteralClass;
- }
-
- // Iterators
- child_range children() { return child_range(&String, &String+1); }
-};
-
-/// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
-///
-class ObjCBoolLiteralExpr : public Expr {
- bool Value;
- SourceLocation Loc;
-public:
- ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
- Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false), Value(val), Loc(l) {}
-
- explicit ObjCBoolLiteralExpr(EmptyShell Empty)
- : Expr(ObjCBoolLiteralExprClass, Empty) { }
-
- bool getValue() const { return Value; }
- void setValue(bool V) { Value = V; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCBoolLiteralExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ObjCBoxedExpr - used for generalized expression boxing.
-/// as in: @(strdup("hello world")), @(random()) or @(view.frame)
-/// Also used for boxing non-parenthesized numeric literals;
-/// as in: @42 or \@true (c++/objc++) or \@__yes (c/objc).
-class ObjCBoxedExpr : public Expr {
- Stmt *SubExpr;
- ObjCMethodDecl *BoxingMethod;
- SourceRange Range;
-public:
- ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
- SourceRange R)
- : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
- E->isTypeDependent(), E->isValueDependent(),
- E->isInstantiationDependent(), E->containsUnexpandedParameterPack()),
- SubExpr(E), BoxingMethod(method), Range(R) {}
- explicit ObjCBoxedExpr(EmptyShell Empty)
- : Expr(ObjCBoxedExprClass, Empty) {}
-
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
-
- ObjCMethodDecl *getBoxingMethod() const {
- return BoxingMethod;
- }
-
- SourceLocation getAtLoc() const { return Range.getBegin(); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY {
- return Range;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCBoxedExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr+1); }
-
- typedef ConstExprIterator const_arg_iterator;
-
- const_arg_iterator arg_begin() const {
- return reinterpret_cast<Stmt const * const*>(&SubExpr);
- }
- const_arg_iterator arg_end() const {
- return reinterpret_cast<Stmt const * const*>(&SubExpr + 1);
- }
-
- friend class ASTStmtReader;
-};
-
-/// ObjCArrayLiteral - used for objective-c array containers; as in:
-/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
-class ObjCArrayLiteral final
- : public Expr,
- private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> {
- unsigned NumElements;
- SourceRange Range;
- ObjCMethodDecl *ArrayWithObjectsMethod;
-
- ObjCArrayLiteral(ArrayRef<Expr *> Elements,
- QualType T, ObjCMethodDecl * Method,
- SourceRange SR);
-
- explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
- : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
-
-public:
- static ObjCArrayLiteral *Create(const ASTContext &C,
- ArrayRef<Expr *> Elements,
- QualType T, ObjCMethodDecl * Method,
- SourceRange SR);
-
- static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
- unsigned NumElements);
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCArrayLiteralClass;
- }
-
- /// \brief Retrieve elements of array of literals.
- Expr **getElements() { return getTrailingObjects<Expr *>(); }
-
- /// \brief Retrieve elements of array of literals.
- const Expr * const *getElements() const {
- return getTrailingObjects<Expr *>();
- }
-
- /// getNumElements - Return number of elements of objective-c array literal.
- unsigned getNumElements() const { return NumElements; }
-
- /// getExpr - Return the Expr at the specified index.
- Expr *getElement(unsigned Index) {
- assert((Index < NumElements) && "Arg access out of range!");
- return cast<Expr>(getElements()[Index]);
- }
- const Expr *getElement(unsigned Index) const {
- assert((Index < NumElements) && "Arg access out of range!");
- return cast<Expr>(getElements()[Index]);
- }
-
- ObjCMethodDecl *getArrayWithObjectsMethod() const {
- return ArrayWithObjectsMethod;
- }
-
- // Iterators
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(getElements()),
- reinterpret_cast<Stmt **>(getElements()) + NumElements);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-};
-
-/// \brief An element in an Objective-C dictionary literal.
-///
-struct ObjCDictionaryElement {
- /// \brief The key for the dictionary element.
- Expr *Key;
-
- /// \brief The value of the dictionary element.
- Expr *Value;
-
- /// \brief 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
- /// this is a pack expansion and is known.
- Optional<unsigned> NumExpansions;
-
- /// \brief Determines whether this dictionary element is a pack expansion.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-};
-} // end namespace clang
-
-namespace llvm {
-template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
-}
-
-namespace clang {
-/// \brief 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
-/// 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
- /// expansion.
- SourceLocation EllipsisLoc;
-
- /// \brief If non-zero, the number of elements that this pack
- /// expansion will expand to (+1).
- unsigned NumExpansionsPlusOne;
-};
-
-/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
-/// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
-class ObjCDictionaryLiteral final
- : public Expr,
- private llvm::TrailingObjects<ObjCDictionaryLiteral,
- ObjCDictionaryLiteral_KeyValuePair,
- ObjCDictionaryLiteral_ExpansionData> {
- /// \brief The number of elements in this dictionary literal.
- unsigned NumElements : 31;
-
- /// \brief 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
- /// key/value pairs, which provide the locations of the ellipses (if
- /// any) and number of elements in the expansion (if known). If
- /// there are no pack expansions, we optimize away this storage.
- unsigned HasPackExpansions : 1;
-
- SourceRange Range;
- ObjCMethodDecl *DictWithObjectsMethod;
-
- typedef ObjCDictionaryLiteral_KeyValuePair KeyValuePair;
- typedef ObjCDictionaryLiteral_ExpansionData ExpansionData;
-
- size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
- return NumElements;
- }
-
- ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
- bool HasPackExpansions,
- QualType T, ObjCMethodDecl *method,
- SourceRange SR);
-
- explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
- bool HasPackExpansions)
- : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
- HasPackExpansions(HasPackExpansions) {}
-
-public:
- static ObjCDictionaryLiteral *Create(const ASTContext &C,
- ArrayRef<ObjCDictionaryElement> VK,
- bool HasPackExpansions,
- QualType T, ObjCMethodDecl *method,
- SourceRange SR);
-
- static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
- unsigned NumElements,
- bool HasPackExpansions);
-
- /// getNumElements - Return number of elements of objective-c dictionary
- /// literal.
- unsigned getNumElements() const { return NumElements; }
-
- ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
- assert((Index < NumElements) && "Arg access out of range!");
- const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
- ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
- if (HasPackExpansions) {
- const ExpansionData &Expansion =
- getTrailingObjects<ExpansionData>()[Index];
- Result.EllipsisLoc = Expansion.EllipsisLoc;
- if (Expansion.NumExpansionsPlusOne > 0)
- Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
- }
- return Result;
- }
-
- ObjCMethodDecl *getDictWithObjectsMethod() const
- { return DictWithObjectsMethod; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCDictionaryLiteralClass;
- }
-
- // Iterators
- child_range children() {
- // Note: we're taking advantage of the layout of the KeyValuePair struct
- // here. If that struct changes, this code will need to change as well.
- static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2,
- "KeyValuePair is expected size");
- return child_range(
- reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()),
- reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) +
- NumElements * 2);
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
-};
-
-
-/// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
-/// type and behavior as StringLiteral except that the string initializer is
-/// obtained from ASTContext with the encoding type as an argument.
-class ObjCEncodeExpr : public Expr {
- TypeSourceInfo *EncodedType;
- SourceLocation AtLoc, RParenLoc;
-public:
- ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
- EncodedType->getType()->isDependentType(),
- EncodedType->getType()->isDependentType(),
- EncodedType->getType()->isInstantiationDependentType(),
- EncodedType->getType()->containsUnexpandedParameterPack()),
- EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
-
- explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
-
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- QualType getEncodedType() const { return EncodedType->getType(); }
-
- TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
- void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
- EncodedType = EncType;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCEncodeExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ObjCSelectorExpr used for \@selector in Objective-C.
-class ObjCSelectorExpr : public Expr {
- Selector SelName;
- SourceLocation AtLoc, RParenLoc;
-public:
- ObjCSelectorExpr(QualType T, Selector selInfo,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- SelName(selInfo), AtLoc(at), RParenLoc(rp){}
- explicit ObjCSelectorExpr(EmptyShell Empty)
- : Expr(ObjCSelectorExprClass, Empty) {}
-
- Selector getSelector() const { return SelName; }
- void setSelector(Selector S) { SelName = S; }
-
- SourceLocation getAtLoc() const { return AtLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- /// getNumArgs - Return the number of actual arguments to this call.
- unsigned getNumArgs() const { return SelName.getNumArgs(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCSelectorExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ObjCProtocolExpr used for protocol expression in Objective-C.
-///
-/// This is used as: \@protocol(foo), as in:
-/// \code
-/// [obj conformsToProtocol:@protocol(foo)]
-/// \endcode
-///
-/// The return type is "Protocol*".
-class ObjCProtocolExpr : public Expr {
- ObjCProtocolDecl *TheProtocol;
- SourceLocation AtLoc, ProtoLoc, RParenLoc;
-public:
- ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
- SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
- : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
- explicit ObjCProtocolExpr(EmptyShell Empty)
- : Expr(ObjCProtocolExprClass, Empty) {}
-
- ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
- void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
-
- SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
- SourceLocation getAtLoc() const { return AtLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCProtocolExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
-class ObjCIvarRefExpr : public Expr {
- ObjCIvarDecl *D;
- Stmt *Base;
- SourceLocation Loc;
- /// OpLoc - This is the location of '.' or '->'
- SourceLocation OpLoc;
-
- bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
- bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
-
-public:
- ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
- SourceLocation l, SourceLocation oploc,
- Expr *base,
- bool arrow = false, bool freeIvar = false) :
- Expr(ObjCIvarRefExprClass, t, VK_LValue,
- d->isBitField() ? OK_BitField : OK_Ordinary,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- D(d), Base(base), Loc(l), OpLoc(oploc),
- IsArrow(arrow), IsFreeIvar(freeIvar) {}
-
- explicit ObjCIvarRefExpr(EmptyShell Empty)
- : Expr(ObjCIvarRefExprClass, Empty) {}
-
- ObjCIvarDecl *getDecl() { return D; }
- const ObjCIvarDecl *getDecl() const { return D; }
- void setDecl(ObjCIvarDecl *d) { D = d; }
-
- const Expr *getBase() const { return cast<Expr>(Base); }
- Expr *getBase() { return cast<Expr>(Base); }
- void setBase(Expr * base) { Base = base; }
-
- bool isArrow() const { return IsArrow; }
- bool isFreeIvar() const { return IsFreeIvar; }
- void setIsArrow(bool A) { IsArrow = A; }
- void setIsFreeIvar(bool A) { IsFreeIvar = A; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return isFreeIvar() ? Loc : getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getOpLoc() const { return OpLoc; }
- void setOpLoc(SourceLocation L) { OpLoc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCIvarRefExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
-};
-
-/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
-/// property.
-class ObjCPropertyRefExpr : public Expr {
-private:
- /// If the bool is true, this is an implicit property reference; the
- /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
- /// if the bool is false, this is an explicit property reference;
- /// 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
- /// to the getter, the setter, or both.
- /// This applies to both implicit and explicit property references.
- enum MethodRefFlags {
- MethodRef_None = 0,
- MethodRef_Getter = 0x1,
- MethodRef_Setter = 0x2
- };
-
- /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
- llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
-
- // FIXME: Maybe we should store the property identifier here,
- // because it's not rederivable from the other data when there's an
- // implicit property with no getter (because the 'foo' -> 'setFoo:'
- // transformation is lossy on the first character).
-
- SourceLocation IdLoc;
-
- /// \brief 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;
- llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
-
-public:
- ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation l, Expr *base)
- : Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
- IdLoc(l), ReceiverLoc(), Receiver(base) {
- assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation l, SourceLocation sl, QualType st)
- : Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
- st->containsUnexpandedParameterPack()),
- PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
- IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
- assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- QualType T, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation IdLoc, Expr *Base)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
- Base->isValueDependent(), Base->isInstantiationDependent(),
- Base->containsUnexpandedParameterPack()),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
- assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- QualType T, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation IdLoc,
- SourceLocation SuperLoc, QualType SuperTy)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
- assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- QualType T, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation IdLoc,
- SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
- assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- explicit ObjCPropertyRefExpr(EmptyShell Empty)
- : Expr(ObjCPropertyRefExprClass, Empty) {}
-
- bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
- bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
-
- ObjCPropertyDecl *getExplicitProperty() const {
- assert(!isImplicitProperty());
- return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
- }
-
- ObjCMethodDecl *getImplicitPropertyGetter() const {
- assert(isImplicitProperty());
- return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
- }
-
- ObjCMethodDecl *getImplicitPropertySetter() const {
- assert(isImplicitProperty());
- return SetterAndMethodRefFlags.getPointer();
- }
-
- Selector getGetterSelector() const {
- if (isImplicitProperty())
- return getImplicitPropertyGetter()->getSelector();
- return getExplicitProperty()->getGetterName();
- }
-
- Selector getSetterSelector() const {
- if (isImplicitProperty())
- return getImplicitPropertySetter()->getSelector();
- return getExplicitProperty()->getSetterName();
- }
-
- /// \brief 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
- /// setter.
- /// This applies to both implicit and explicit property references.
- bool isMessagingSetter() const {
- return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
- }
-
- void setIsMessagingGetter(bool val = true) {
- setMethodRefFlag(MethodRef_Getter, val);
- }
-
- void setIsMessagingSetter(bool val = true) {
- setMethodRefFlag(MethodRef_Setter, val);
- }
-
- const Expr *getBase() const {
- return cast<Expr>(Receiver.get<Stmt*>());
- }
- Expr *getBase() {
- return cast<Expr>(Receiver.get<Stmt*>());
- }
-
- SourceLocation getLocation() const { return IdLoc; }
-
- SourceLocation getReceiverLocation() const { return ReceiverLoc; }
- QualType getSuperReceiverType() const {
- return QualType(Receiver.get<const Type*>(), 0);
- }
-
- ObjCInterfaceDecl *getClassReceiver() const {
- return Receiver.get<ObjCInterfaceDecl*>();
- }
- bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
- bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
- bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
-
- /// Determine the type of the base, regardless of the kind of receiver.
- QualType getReceiverType(const ASTContext &ctx) const;
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCPropertyRefExprClass;
- }
-
- // Iterators
- child_range children() {
- if (Receiver.is<Stmt*>()) {
- Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
- return child_range(begin, begin+1);
- }
- return child_range(child_iterator(), child_iterator());
- }
-
-private:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
- PropertyOrGetter.setPointer(D);
- PropertyOrGetter.setInt(false);
- SetterAndMethodRefFlags.setPointer(nullptr);
- SetterAndMethodRefFlags.setInt(methRefFlags);
- }
- void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- unsigned methRefFlags) {
- PropertyOrGetter.setPointer(Getter);
- PropertyOrGetter.setInt(true);
- SetterAndMethodRefFlags.setPointer(Setter);
- SetterAndMethodRefFlags.setInt(methRefFlags);
- }
- void setBase(Expr *Base) { Receiver = Base; }
- void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
- void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
-
- void setLocation(SourceLocation L) { IdLoc = L; }
- void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
-
- void setMethodRefFlag(MethodRefFlags flag, bool val) {
- unsigned f = SetterAndMethodRefFlags.getInt();
- if (val)
- f |= flag;
- else
- f &= ~flag;
- SetterAndMethodRefFlags.setInt(f);
- }
-};
-
-/// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
-/// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
-///
-class ObjCSubscriptRefExpr : public Expr {
- // Location of ']' in an indexing expression.
- SourceLocation RBracket;
- // array/dictionary base expression.
- // for arrays, this is a numeric expression. For dictionaries, this is
- // an objective-c object pointer expression.
- enum { BASE, KEY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
-
- ObjCMethodDecl *GetAtIndexMethodDecl;
-
- // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
- // an indexed object this is null too.
- ObjCMethodDecl *SetAtIndexMethodDecl;
-
-public:
-
- ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
- ExprValueKind VK, ExprObjectKind OK,
- ObjCMethodDecl *getMethod,
- ObjCMethodDecl *setMethod, SourceLocation RB)
- : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
- base->isTypeDependent() || key->isTypeDependent(),
- base->isValueDependent() || key->isValueDependent(),
- base->isInstantiationDependent() || key->isInstantiationDependent(),
- (base->containsUnexpandedParameterPack() ||
- key->containsUnexpandedParameterPack())),
- RBracket(RB),
- GetAtIndexMethodDecl(getMethod),
- SetAtIndexMethodDecl(setMethod)
- {SubExprs[BASE] = base; SubExprs[KEY] = key;}
-
- explicit ObjCSubscriptRefExpr(EmptyShell Empty)
- : Expr(ObjCSubscriptRefExprClass, Empty) {}
-
- SourceLocation getRBracket() const { return RBracket; }
- void setRBracket(SourceLocation RB) { RBracket = RB; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExprs[BASE]->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCSubscriptRefExprClass;
- }
-
- Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
- void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
-
- Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
- void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
-
- ObjCMethodDecl *getAtIndexMethodDecl() const {
- return GetAtIndexMethodDecl;
- }
-
- ObjCMethodDecl *setAtIndexMethodDecl() const {
- return SetAtIndexMethodDecl;
- }
-
- bool isArraySubscriptRefExpr() const {
- return getKeyExpr()->getType()->isIntegralOrEnumerationType();
- }
-
- child_range children() {
- return child_range(SubExprs, SubExprs+END_EXPR);
- }
-private:
- friend class ASTStmtReader;
-};
-
-
-/// \brief An expression that sends a message to the given Objective-C
-/// object or class.
-///
-/// The following contains two message send expressions:
-///
-/// \code
-/// [[NSString alloc] initWithString:@"Hello"]
-/// \endcode
-///
-/// The innermost message send invokes the "alloc" class method on the
-/// NSString class, while the outermost message send invokes the
-/// "initWithString" instance method on the object returned from
-/// NSString's "alloc". In all, an Objective-C message send can take
-/// on four different (although related) forms:
-///
-/// 1. Send to an object instance.
-/// 2. Send to a class.
-/// 3. Send to the superclass instance of the current class.
-/// 4. Send to the superclass of the current class.
-///
-/// All four kinds of message sends are modeled by the ObjCMessageExpr
-/// class, and can be distinguished via \c getReceiverKind(). Example:
-///
-/// The "void *" trailing objects are actually ONE void * (the
-/// receiver pointer), and NumArgs Expr *. But due to the
-/// implementation of children(), these must be together contiguously.
-
-class ObjCMessageExpr final
- : public Expr,
- private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
- /// \brief 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;
-
- enum { NumArgsBitWidth = 16 };
-
- /// \brief 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
- /// 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
- /// 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",
- /// 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
- /// the implementation rather than explicitly written by the user.
- unsigned IsImplicit : 1;
-
- /// \brief 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
- /// the location of the 'super' keyword.
- SourceLocation SuperLoc;
-
- /// \brief The source locations of the open and close square
- /// brackets ('[' and ']', respectively).
- SourceLocation LBracLoc, RBracLoc;
-
- size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
-
- void setNumArgs(unsigned Num) {
- assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
- NumArgs = Num;
- }
-
- ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0),
- HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
- setNumArgs(NumArgs);
- }
-
- ObjCMessageExpr(QualType T, ExprValueKind VK,
- SourceLocation LBracLoc,
- SourceLocation SuperLoc,
- bool IsInstanceSuper,
- QualType SuperType,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
- ObjCMessageExpr(QualType T, ExprValueKind VK,
- SourceLocation LBracLoc,
- TypeSourceInfo *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
- ObjCMessageExpr(QualType T, ExprValueKind VK,
- SourceLocation LBracLoc,
- Expr *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
-
- void initArgsAndSelLocs(ArrayRef<Expr *> Args,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK);
-
- /// \brief Retrieve the pointer value of the message receiver.
- void *getReceiverPointer() const { return *getTrailingObjects<void *>(); }
-
- /// \brief Set the pointer value of the message receiver.
- void setReceiverPointer(void *Value) {
- *getTrailingObjects<void *>() = Value;
- }
-
- SelectorLocationsKind getSelLocsKind() const {
- return (SelectorLocationsKind)SelLocsKind;
- }
- bool hasStandardSelLocs() const {
- return getSelLocsKind() != SelLoc_NonStandard;
- }
-
- /// \brief Get a pointer to the stored selector identifiers locations array.
- /// No locations will be stored if HasStandardSelLocs is true.
- SourceLocation *getStoredSelLocs() {
- return getTrailingObjects<SourceLocation>();
- }
- const SourceLocation *getStoredSelLocs() const {
- return getTrailingObjects<SourceLocation>();
- }
-
- /// \brief Get the number of stored selector identifiers locations.
- /// No locations will be stored if HasStandardSelLocs is true.
- unsigned getNumStoredSelLocs() const {
- if (hasStandardSelLocs())
- return 0;
- return getNumSelectorLocs();
- }
-
- static ObjCMessageExpr *alloc(const ASTContext &C,
- ArrayRef<Expr *> Args,
- SourceLocation RBraceLoc,
- ArrayRef<SourceLocation> SelLocs,
- Selector Sel,
- SelectorLocationsKind &SelLocsK);
- static ObjCMessageExpr *alloc(const ASTContext &C,
- unsigned NumArgs,
- unsigned NumStoredSelLocs);
-
-public:
- /// \brief The kind of receiver this message is sending to.
- enum ReceiverKind {
- /// \brief The receiver is a class.
- Class = 0,
- /// \brief The receiver is an object instance.
- Instance,
- /// \brief The receiver is a superclass.
- SuperClass,
- /// \brief The receiver is the instance of the superclass object.
- SuperInstance
- };
-
- /// \brief Create a message send to super.
- ///
- /// \param Context The ASTContext in which this expression will be created.
- ///
- /// \param T The result type of this message.
- ///
- /// \param VK The value kind of this message. A message returning
- /// a l-value or r-value reference will be an l-value or x-value,
- /// respectively.
- ///
- /// \param LBracLoc The location of the open square bracket '['.
- ///
- /// \param SuperLoc The location of the "super" keyword.
- ///
- /// \param IsInstanceSuper Whether this is an instance "super"
- /// message (otherwise, it's a class "super" message).
- ///
- /// \param Sel The selector used to determine which method gets called.
- ///
- /// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
- ///
- /// \param Args The message send arguments.
- ///
- /// \param RBracLoc The location of the closing square bracket ']'.
- static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- SourceLocation SuperLoc,
- bool IsInstanceSuper,
- QualType SuperType,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
-
- /// \brief Create a class message send.
- ///
- /// \param Context The ASTContext in which this expression will be created.
- ///
- /// \param T The result type of this message.
- ///
- /// \param VK The value kind of this message. A message returning
- /// a l-value or r-value reference will be an l-value or x-value,
- /// respectively.
- ///
- /// \param LBracLoc The location of the open square bracket '['.
- ///
- /// \param Receiver The type of the receiver, including
- /// source-location information.
- ///
- /// \param Sel The selector used to determine which method gets called.
- ///
- /// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
- ///
- /// \param Args The message send arguments.
- ///
- /// \param RBracLoc The location of the closing square bracket ']'.
- static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- TypeSourceInfo *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
-
- /// \brief Create an instance message send.
- ///
- /// \param Context The ASTContext in which this expression will be created.
- ///
- /// \param T The result type of this message.
- ///
- /// \param VK The value kind of this message. A message returning
- /// a l-value or r-value reference will be an l-value or x-value,
- /// respectively.
- ///
- /// \param LBracLoc The location of the open square bracket '['.
- ///
- /// \param Receiver The expression used to produce the object that
- /// will receive this message.
- ///
- /// \param Sel The selector used to determine which method gets called.
- ///
- /// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
- ///
- /// \param Args The message send arguments.
- ///
- /// \param RBracLoc The location of the closing square bracket ']'.
- static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- Expr *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SeLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
-
- /// \brief 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.
- ///
- /// \param NumArgs The number of message arguments, not including
- /// the receiver.
- static ObjCMessageExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumArgs,
- unsigned NumStoredSelLocs);
-
- /// \brief 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
- /// sent to.
- ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
-
- /// \brief Source range of the receiver.
- SourceRange getReceiverRange() const;
-
- /// \brief 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
- /// specified class or to super.
- bool isClassMessage() const {
- return getReceiverKind() == Class || getReceiverKind() == SuperClass;
- }
-
- /// \brief 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)
- return static_cast<Expr *>(getReceiverPointer());
-
- return nullptr;
- }
- const Expr *getInstanceReceiver() const {
- return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
- }
-
- /// \brief 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
- /// message is not a class message.
- QualType getClassReceiver() const {
- if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
- return TSInfo->getType();
-
- return QualType();
- }
-
- /// \brief Returns a type-source information of a class message
- /// send, or NULL if the message is not a class message.
- TypeSourceInfo *getClassReceiverTypeInfo() const {
- if (getReceiverKind() == Class)
- return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
- return nullptr;
- }
-
- void setClassReceiver(TypeSourceInfo *TSInfo) {
- Kind = Class;
- setReceiverPointer(TSInfo);
- }
-
- /// \brief 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)
- return SuperLoc;
-
- return SourceLocation();
- }
-
- /// \brief 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
- /// of the receiver will be; use \c getReceiverKind() to determine
- /// whether the message is a class or an instance method, whether it
- /// is a send to super or not, etc.
- ///
- /// \returns The type of the receiver.
- QualType getReceiverType() const;
-
- /// \brief 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
- /// sends to determine what the underlying (statically known) type
- /// of the receiver will be; use \c getReceiverKind() to determine
- /// whether the message is a class or an instance method, whether it
- /// is a send to super or not, etc.
- ///
- /// \returns The Objective-C interface if known, otherwise NULL.
- ObjCInterfaceDecl *getReceiverInterface() const;
-
- /// \brief 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
- /// to a class (for an instance message to super);
- QualType getSuperType() const {
- if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
- return QualType::getFromOpaquePtr(getReceiverPointer());
-
- return QualType();
- }
-
- void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
- Kind = IsInstanceSuper? SuperInstance : SuperClass;
- SuperLoc = Loc;
- setReceiverPointer(T.getAsOpaquePtr());
- }
-
- Selector getSelector() const;
-
- void setSelector(Selector S) {
- HasMethod = false;
- SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
- }
-
- const ObjCMethodDecl *getMethodDecl() const {
- if (HasMethod)
- return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
-
- return nullptr;
- }
-
- ObjCMethodDecl *getMethodDecl() {
- if (HasMethod)
- return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
-
- return nullptr;
- }
-
- void setMethodDecl(ObjCMethodDecl *MD) {
- HasMethod = true;
- SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
- }
-
- ObjCMethodFamily getMethodFamily() const {
- if (HasMethod) return getMethodDecl()->getMethodFamily();
- return getSelector().getMethodFamily();
- }
-
- /// \brief 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
- /// receiver.
- Expr **getArgs() {
- return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1);
- }
- const Expr * const *getArgs() const {
- return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() +
- 1);
- }
-
- /// getArg - Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return getArgs()[Arg];
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return getArgs()[Arg];
- }
- /// setArg - Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- getArgs()[Arg] = ArgExpr;
- }
-
- /// isDelegateInitCall - Answers whether this message send has been
- /// tagged as a "delegate init call", i.e. a call to a method in the
- /// -init family on self from within an -init method implementation.
- bool isDelegateInitCall() const { return IsDelegateInitCall; }
- void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
-
- SourceLocation getLeftLoc() const { return LBracLoc; }
- SourceLocation getRightLoc() const { return RBracLoc; }
-
- SourceLocation getSelectorStartLoc() const {
- if (isImplicit())
- return getLocStart();
- return getSelectorLoc(0);
- }
- SourceLocation getSelectorLoc(unsigned Index) const {
- assert(Index < getNumSelectorLocs() && "Index out of range!");
- if (hasStandardSelLocs())
- return getStandardSelectorLoc(Index, getSelector(),
- getSelLocsKind() == SelLoc_StandardWithSpace,
- llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
- getNumArgs()),
- RBracLoc);
- return getStoredSelLocs()[Index];
- }
-
- void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
-
- unsigned getNumSelectorLocs() const {
- if (isImplicit())
- return 0;
- Selector Sel = getSelector();
- if (Sel.isUnarySelector())
- return 1;
- return Sel.getNumArgs();
- }
-
- void setSourceRange(SourceRange R) {
- LBracLoc = R.getBegin();
- RBracLoc = R.getEnd();
- }
- SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCMessageExprClass;
- }
-
- // Iterators
- child_range children();
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
-
- llvm::iterator_range<arg_iterator> arguments() {
- return llvm::make_range(arg_begin(), arg_end());
- }
-
- llvm::iterator_range<const_arg_iterator> arguments() const {
- return llvm::make_range(arg_begin(), arg_end());
- }
-
- arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
- arg_iterator arg_end() {
- return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
- }
- const_arg_iterator arg_begin() const {
- return reinterpret_cast<Stmt const * const*>(getArgs());
- }
- const_arg_iterator arg_end() const {
- return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
-/// (similar in spirit to MemberExpr).
-class ObjCIsaExpr : public Expr {
- /// Base - the expression for the base object pointer.
- Stmt *Base;
-
- /// IsaMemberLoc - This is the location of the 'isa'.
- SourceLocation IsaMemberLoc;
-
- /// OpLoc - This is the location of '.' or '->'
- SourceLocation OpLoc;
-
- /// IsArrow - True if this is "X->F", false if this is "X.F".
- bool IsArrow;
-public:
- ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
- QualType ty)
- : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- /*ContainsUnexpandedParameterPack=*/false),
- Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
-
- /// \brief Build an empty expression.
- explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
-
- void setBase(Expr *E) { Base = E; }
- Expr *getBase() const { return cast<Expr>(Base); }
-
- bool isArrow() const { return IsArrow; }
- void setArrow(bool A) { IsArrow = A; }
-
- /// getMemberLoc - Return the location of the "member", in X->F, it is the
- /// location of 'F'.
- SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
- void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
-
- SourceLocation getOpLoc() const { return OpLoc; }
- void setOpLoc(SourceLocation L) { OpLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
-
- SourceLocation getBaseLocEnd() const LLVM_READONLY {
- return getBase()->getLocEnd();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; }
-
- SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCIsaExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
-};
-
-
-/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
-/// argument by indirect copy-restore in ARC. This is used to support
-/// passing indirect arguments with the wrong lifetime, e.g. when
-/// passing the address of a __strong local variable to an 'out'
-/// parameter. This expression kind is only valid in an "argument"
-/// position to some sort of call expression.
-///
-/// The parameter must have type 'pointer to T', and the argument must
-/// have type 'pointer to U', where T and U agree except possibly in
-/// qualification. If the argument value is null, then a null pointer
-/// is passed; otherwise it points to an object A, and:
-/// 1. A temporary object B of type T is initialized, either by
-/// zero-initialization (used when initializing an 'out' parameter)
-/// or copy-initialization (used when initializing an 'inout'
-/// parameter).
-/// 2. The address of the temporary is passed to the function.
-/// 3. If the call completes normally, A is move-assigned from B.
-/// 4. Finally, A is destroyed immediately.
-///
-/// Currently 'T' must be a retainable object lifetime and must be
-/// __autoreleasing; this qualifier is ignored when initializing
-/// the value.
-class ObjCIndirectCopyRestoreExpr : public Expr {
- Stmt *Operand;
-
- // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
-
- friend class ASTReader;
- friend class ASTStmtReader;
-
- void setShouldCopy(bool shouldCopy) {
- ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
- }
-
- explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
- : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
-
-public:
- ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
- : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
- operand->isTypeDependent(), operand->isValueDependent(),
- operand->isInstantiationDependent(),
- operand->containsUnexpandedParameterPack()),
- Operand(operand) {
- setShouldCopy(shouldCopy);
- }
-
- Expr *getSubExpr() { return cast<Expr>(Operand); }
- const Expr *getSubExpr() const { return cast<Expr>(Operand); }
-
- /// shouldCopy - True if we should do the 'copy' part of the
- /// copy-restore. If false, the temporary will be zero-initialized.
- bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
-
- child_range children() { return child_range(&Operand, &Operand+1); }
-
- // Source locations are determined by the subexpression.
- SourceLocation getLocStart() const LLVM_READONLY {
- return Operand->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();}
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getSubExpr()->getExprLoc();
- }
-
- static bool classof(const Stmt *s) {
- return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
- }
-};
-
-/// \brief An Objective-C "bridged" cast expression, which casts between
-/// Objective-C pointers and C pointers, transferring ownership in the process.
-///
-/// \code
-/// NSString *str = (__bridge_transfer NSString *)CFCreateString();
-/// \endcode
-class ObjCBridgedCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
- SourceLocation LParenLoc;
- SourceLocation BridgeKeywordLoc;
- unsigned Kind : 2;
-
- friend TrailingObjects;
- friend class CastExpr;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
- CastKind CK, SourceLocation BridgeKeywordLoc,
- TypeSourceInfo *TSInfo, Expr *Operand)
- : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
- CK, Operand, 0, TSInfo),
- LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
-
- /// \brief 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.
- ObjCBridgeCastKind getBridgeKind() const {
- return static_cast<ObjCBridgeCastKind>(Kind);
- }
-
- /// \brief Retrieve the kind of bridge being performed as a string.
- StringRef getBridgeKindName() const;
-
- /// \brief The location of the bridge keyword.
- SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCBridgedCastExprClass;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h
deleted file mode 100644
index 2d71a3a..0000000
--- a/include/clang/AST/ExprOpenMP.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- ExprOpenMP.h - Classes for representing expressions ----*- 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 Expr interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPROPENMP_H
-#define LLVM_CLANG_AST_EXPROPENMP_H
-
-#include "clang/AST/Expr.h"
-
-namespace clang {
-/// \brief 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
-/// [ lower-bound : length ]
-/// [ lower-bound : ]
-/// [ : length ]
-/// [ : ]
-/// \endcode
-/// The array section must be a subset of the original array.
-/// Array sections are allowed on multidimensional arrays. Base language array
-/// subscript expressions can be used to specify length-one dimensions of
-/// multidimensional array sections.
-/// The lower-bound and length are integral type expressions. When evaluated
-/// they represent a set of integer values as follows:
-/// \code
-/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length -
-/// 1 }
-/// \endcode
-/// The lower-bound and length must evaluate to non-negative integers.
-/// When the size of the array dimension is not known, the length must be
-/// specified explicitly.
-/// When the length is absent, it defaults to the size of the array dimension
-/// minus the lower-bound.
-/// When the lower-bound is absent it defaults to 0.
-class OMPArraySectionExpr : public Expr {
- enum { BASE, LOWER_BOUND, LENGTH, END_EXPR };
- Stmt *SubExprs[END_EXPR];
- SourceLocation ColonLoc;
- SourceLocation RBracketLoc;
-
-public:
- OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation ColonLoc, SourceLocation RBracketLoc)
- : Expr(
- OMPArraySectionExprClass, Type, VK, OK,
- Base->isTypeDependent() ||
- (LowerBound && LowerBound->isTypeDependent()) ||
- (Length && Length->isTypeDependent()),
- Base->isValueDependent() ||
- (LowerBound && LowerBound->isValueDependent()) ||
- (Length && Length->isValueDependent()),
- Base->isInstantiationDependent() ||
- (LowerBound && LowerBound->isInstantiationDependent()) ||
- (Length && Length->isInstantiationDependent()),
- Base->containsUnexpandedParameterPack() ||
- (LowerBound && LowerBound->containsUnexpandedParameterPack()) ||
- (Length && Length->containsUnexpandedParameterPack())),
- ColonLoc(ColonLoc), RBracketLoc(RBracketLoc) {
- SubExprs[BASE] = Base;
- SubExprs[LOWER_BOUND] = LowerBound;
- SubExprs[LENGTH] = Length;
- }
-
- /// \brief 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.
- Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
- const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
- /// \brief Set base of the array section.
- void setBase(Expr *E) { SubExprs[BASE] = E; }
-
- /// \brief Return original type of the base expression for array section.
- static QualType getBaseOriginalType(Expr *Base);
-
- /// \brief 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.
- void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
-
- /// \brief 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.
- void setLength(Expr *E) { SubExprs[LENGTH] = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getBase()->getExprLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPArraySectionExprClass;
- }
-
- child_range children() {
- return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
- }
-};
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
deleted file mode 100644
index 81cf631..0000000
--- a/include/clang/AST/ExternalASTSource.h
+++ /dev/null
@@ -1,578 +0,0 @@
-//===--- ExternalASTSource.h - Abstract External AST Interface --*- 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 ExternalASTSource interface, which enables
-// construction of AST nodes from some external source.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
-#define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
-
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclBase.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-
-class ASTConsumer;
-class CXXBaseSpecifier;
-class CXXCtorInitializer;
-class DeclarationName;
-class ExternalSemaSource; // layering violation required for downcasting
-class FieldDecl;
-class Module;
-class NamedDecl;
-class RecordDecl;
-class Selector;
-class Stmt;
-class TagDecl;
-
-/// \brief 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
-/// sources can resolve types and declarations from abstract IDs into
-/// actual type and declaration nodes, and read parts of declaration
-/// contexts.
-class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
- /// Generation number for this external AST source. Must be increased
- /// whenever we might have added new redeclarations for existing decls.
- uint32_t CurrentGeneration;
-
- /// \brief Whether this AST source also provides information for
- /// semantic analysis.
- bool SemaSource;
-
- friend class ExternalSemaSource;
-
-public:
- ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
-
- virtual ~ExternalASTSource();
-
- /// \brief RAII class for safely pairing a StartedDeserializing call
- /// with FinishedDeserializing.
- class Deserializing {
- ExternalASTSource *Source;
- public:
- explicit Deserializing(ExternalASTSource *source) : Source(source) {
- assert(Source);
- Source->StartedDeserializing();
- }
- ~Deserializing() {
- Source->FinishedDeserializing();
- }
- };
-
- /// \brief Get the current generation of this AST source. This number
- /// is incremented each time the AST source lazily extends an existing
- /// entity.
- uint32_t getGeneration() const { return CurrentGeneration; }
-
- /// \brief Resolve a declaration ID into a declaration, potentially
- /// building a new declaration.
- ///
- /// This method only needs to be implemented if the AST source ever
- /// passes back decl sets as VisibleDeclaration objects.
- ///
- /// The default implementation of this method is a no-op.
- virtual Decl *GetExternalDecl(uint32_t ID);
-
- /// \brief Resolve a selector ID into a selector.
- ///
- /// This operation only needs to be implemented if the AST source
- /// returns non-zero for GetNumKnownSelectors().
- ///
- /// 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
- /// 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
- /// a statement.
- ///
- /// This operation is meant to be used via a LazyOffsetPtr. It only
- /// needs to be implemented if the AST source uses methods like
- /// FunctionDecl::setLazyBody when building decls.
- ///
- /// 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
- /// 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
- /// 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.
- virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { }
-
- /// \brief 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
- /// we definitely have no declarations with tbis name.
- ///
- /// The default implementation of this method is a no-op returning \c false.
- virtual bool
- FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
-
- /// \brief 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.
- virtual Module *getModule(unsigned ID) { return nullptr; }
-
- /// Abstracts clang modules and precompiled header files and holds
- /// everything needed to generate debug info for an imported module
- /// or PCH.
- class ASTSourceDescriptor {
- StringRef PCHModuleName;
- StringRef Path;
- StringRef ASTFile;
- uint64_t Signature = 0;
- const Module *ClangModule = nullptr;
-
- public:
- ASTSourceDescriptor(){};
- ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
- uint64_t Signature)
- : PCHModuleName(std::move(Name)), Path(std::move(Path)),
- ASTFile(std::move(ASTFile)), Signature(Signature){};
- ASTSourceDescriptor(const Module &M);
- std::string getModuleName() const;
- StringRef getPath() const { return Path; }
- StringRef getASTFile() const { return ASTFile; }
- uint64_t getSignature() const { return Signature; }
- const Module *getModuleOrNull() const { return ClangModule; }
- };
-
- /// Return a descriptor for the corresponding module, if one exists.
- virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
-
- /// \brief 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
- /// declaration kind is one we are looking for.
- ///
- /// The default implementation of this method is a no-op.
- virtual void
- FindExternalLexicalDecls(const DeclContext *DC,
- llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
- SmallVectorImpl<Decl *> &Result);
-
- /// \brief 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
- /// 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
- /// the redeclaration chain for a declaration. Called each time we
- /// need the most recent declaration of a declaration after the
- /// generation count is incremented.
- virtual void CompleteRedeclChain(const Decl *D);
-
- /// \brief Gives the external AST source an opportunity to complete
- /// an incomplete type.
- virtual void CompleteType(TagDecl *Tag);
-
- /// \brief Gives the external AST source an opportunity to complete an
- /// incomplete Objective-C class.
- ///
- /// This routine will only be invoked if the "externally completed" bit is
- /// set on the ObjCInterfaceDecl via the function
- /// \c ObjCInterfaceDecl::setExternallyCompleted().
- virtual void CompleteType(ObjCInterfaceDecl *Class);
-
- /// \brief Loads comment ranges.
- virtual void ReadComments();
-
- /// \brief Notify ExternalASTSource that we started deserialization of
- /// a decl or type so until FinishedDeserializing is called there may be
- /// decls that are initializing. Must be paired with FinishedDeserializing.
- ///
- /// The default implementation of this method is a no-op.
- virtual void StartedDeserializing();
-
- /// \brief Notify ExternalASTSource that we finished the deserialization of
- /// a decl or type. Must be paired with StartedDeserializing.
- ///
- /// The default implementation of this method is a no-op.
- virtual void FinishedDeserializing();
-
- /// \brief Function that will be invoked when we begin parsing a new
- /// translation unit involving this external AST source.
- ///
- /// The default implementation of this method is a no-op.
- virtual void StartTranslationUnit(ASTConsumer *Consumer);
-
- /// \brief 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.
- ///
- /// This routine allows the external AST source to provide an specific
- /// layout for a record, overriding the layout that would normally be
- /// constructed. It is intended for clients who receive specific layout
- /// details rather than source code (such as LLDB). The client is expected
- /// to fill in the field offsets, base offsets, virtual base offsets, and
- /// complete object size.
- ///
- /// \param Record The record whose layout is being requested.
- ///
- /// \param Size The final size of the record, in bits.
- ///
- /// \param Alignment The final alignment of the record, in bits.
- ///
- /// \param FieldOffsets The offset of each of the fields within the record,
- /// expressed in bits. All of the fields must be provided with offsets.
- ///
- /// \param BaseOffsets The offset of each of the direct, non-virtual base
- /// classes. If any bases are not given offsets, the bases will be laid
- /// out according to the ABI.
- ///
- /// \param VirtualBaseOffsets The offset of each of the virtual base classes
- /// (either direct or not). If any bases are not given offsets, the bases will be laid
- /// out according to the ABI.
- ///
- /// \returns true if the record layout was provided, false otherwise.
- virtual bool layoutRecordType(
- const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
-
- //===--------------------------------------------------------------------===//
- // Queries for performance analysis.
- //===--------------------------------------------------------------------===//
-
- struct MemoryBufferSizes {
- size_t malloc_bytes;
- size_t mmap_bytes;
-
- MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
- : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
- };
-
- /// Return the amount of memory used by memory buffers, breaking down
- /// by heap-backed versus mmap'ed memory.
- MemoryBufferSizes getMemoryBufferSizes() const {
- MemoryBufferSizes sizes(0, 0);
- getMemoryBufferSizes(sizes);
- return sizes;
- }
-
- virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
-
-protected:
- static DeclContextLookupResult
- SetExternalVisibleDeclsForName(const DeclContext *DC,
- DeclarationName Name,
- ArrayRef<NamedDecl*> Decls);
-
- static DeclContextLookupResult
- SetNoExternalVisibleDeclsForName(const DeclContext *DC,
- DeclarationName Name);
-
- /// \brief Increment the current generation.
- uint32_t incrementGeneration(ASTContext &C);
-};
-
-/// \brief A lazy pointer to an AST node (of base type T) that resides
-/// within an external AST source.
-///
-/// The AST node is identified within the external AST source by a
-/// 63-bit offset, and can be retrieved via an operation on the
-/// 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
- /// 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
- /// bit is set, the upper 63 bits are the offset.
- mutable uint64_t Ptr;
-
-public:
- LazyOffsetPtr() : Ptr(0) { }
-
- explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
- explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
- assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
- if (Offset == 0)
- Ptr = 0;
- }
-
- LazyOffsetPtr &operator=(T *Ptr) {
- this->Ptr = reinterpret_cast<uint64_t>(Ptr);
- return *this;
- }
-
- LazyOffsetPtr &operator=(uint64_t Offset) {
- assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
- if (Offset == 0)
- Ptr = 0;
- else
- Ptr = (Offset << 1) | 0x01;
-
- return *this;
- }
-
- /// \brief 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.
- ///
- /// 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.
- bool isOffset() const { return Ptr & 0x01; }
-
- /// \brief Retrieve the pointer to the AST node that this lazy pointer
- ///
- /// \param Source the external AST source.
- ///
- /// \returns a pointer to the AST node.
- T* get(ExternalASTSource *Source) const {
- if (isOffset()) {
- assert(Source &&
- "Cannot deserialize a lazy pointer without an AST source");
- Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
- }
- return reinterpret_cast<T*>(Ptr);
- }
-};
-
-/// \brief A lazy value (of type T) that is within an AST node of type Owner,
-/// where the value might change in later generations of the external AST
-/// source.
-template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
-struct LazyGenerationalUpdatePtr {
- /// A cache of the value of this pointer, in the most recent generation in
- /// which we queried it.
- struct LazyData {
- LazyData(ExternalASTSource *Source, T Value)
- : ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
- ExternalASTSource *ExternalSource;
- uint32_t LastGeneration;
- T LastValue;
- };
-
- // Our value is represented as simply T if there is no external AST source.
- typedef llvm::PointerUnion<T, LazyData*> ValueType;
- ValueType Value;
-
- LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
-
- // Defined in ASTContext.h
- static ValueType makeValue(const ASTContext &Ctx, T Value);
-
-public:
- explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
- : Value(makeValue(Ctx, Value)) {}
-
- /// Create a pointer that is not potentially updated by later generations of
- /// the external AST source.
- enum NotUpdatedTag { NotUpdated };
- LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
- : Value(Value) {}
-
- /// Forcibly set this pointer (which must be lazy) as needing updates.
- void markIncomplete() {
- Value.template get<LazyData *>()->LastGeneration = 0;
- }
-
- /// Set the value of this pointer, in the current generation.
- void set(T NewValue) {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
- LazyVal->LastValue = NewValue;
- return;
- }
- Value = NewValue;
- }
-
- /// Set the value of this pointer, for this and all future generations.
- void setNotUpdated(T NewValue) { Value = NewValue; }
-
- /// Get the value of this pointer, updating its owner if necessary.
- T get(Owner O) {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
- if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
- LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
- (LazyVal->ExternalSource->*Update)(O);
- }
- return LazyVal->LastValue;
- }
- return Value.template get<T>();
- }
-
- /// Get the most recently computed value of this pointer without updating it.
- T getNotUpdated() const {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
- return LazyVal->LastValue;
- return Value.template get<T>();
- }
-
- void *getOpaqueValue() { return Value.getOpaqueValue(); }
- static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
- return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
- }
-};
-} // end namespace clang
-
-/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
-/// placed into a PointerUnion.
-namespace llvm {
-template<typename Owner, typename T,
- void (clang::ExternalASTSource::*Update)(Owner)>
-struct PointerLikeTypeTraits<
- clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
- typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
- static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
- static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
- enum {
- NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
- };
-};
-}
-
-namespace clang {
-/// \brief Represents a lazily-loaded vector of data.
-///
-/// The lazily-loaded vector of data contains data that is partially loaded
-/// from an external source and partially added by local translation. The
-/// items loaded from the external source are loaded lazily, when needed for
-/// iteration over the complete vector.
-template<typename T, typename Source,
- void (Source::*Loader)(SmallVectorImpl<T>&),
- unsigned LoadedStorage = 2, unsigned LocalStorage = 4>
-class LazyVector {
- SmallVector<T, LoadedStorage> Loaded;
- SmallVector<T, LocalStorage> Local;
-
-public:
- /// Iteration over the elements in the vector.
- ///
- /// In a complete iteration, the iterator walks the range [-M, N),
- /// where negative values are used to indicate elements
- /// loaded from the external source while non-negative values are used to
- /// indicate elements added via \c push_back().
- /// However, to provide iteration in source order (for, e.g., chained
- /// precompiled headers), dereferencing the iterator flips the negative
- /// values (corresponding to loaded entities), so that position -M
- /// corresponds to element 0 in the loaded entities vector, position -M+1
- /// corresponds to element 1 in the loaded entities vector, etc. This
- /// gives us a reasonably efficient, source-order walk.
- ///
- /// We define this as a wrapping iterator around an int. The
- /// iterator_adaptor_base class forwards the iterator methods to basic integer
- /// arithmetic.
- class iterator : public llvm::iterator_adaptor_base<
- iterator, int, std::random_access_iterator_tag, T, int> {
- LazyVector *Self;
-
- iterator(LazyVector *Self, int Position)
- : iterator::iterator_adaptor_base(Position), Self(Self) {}
-
- bool isLoaded() const { return this->I < 0; }
- friend class LazyVector;
-
- public:
- iterator() : iterator(nullptr, 0) {}
-
- typename iterator::reference operator*() const {
- if (isLoaded())
- return Self->Loaded.end()[this->I];
- return Self->Local.begin()[this->I];
- }
- };
-
- iterator begin(Source *source, bool LocalOnly = false) {
- if (LocalOnly)
- return iterator(this, 0);
-
- if (source)
- (source->*Loader)(Loaded);
- return iterator(this, -(int)Loaded.size());
- }
-
- iterator end() {
- return iterator(this, Local.size());
- }
-
- void push_back(const T& LocalValue) {
- Local.push_back(LocalValue);
- }
-
- void erase(iterator From, iterator To) {
- if (From.isLoaded() && To.isLoaded()) {
- Loaded.erase(&*From, &*To);
- return;
- }
-
- if (From.isLoaded()) {
- Loaded.erase(&*From, Loaded.end());
- From = begin(nullptr, true);
- }
-
- Local.erase(&*From, &*To);
- }
-};
-
-/// \brief A lazy pointer to a statement.
-typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
- LazyDeclStmtPtr;
-
-/// \brief A lazy pointer to a declaration.
-typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
- LazyDeclPtr;
-
-/// \brief A lazy pointer to a set of CXXCtorInitializers.
-typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
- &ExternalASTSource::GetExternalCXXCtorInitializers>
- LazyCXXCtorInitializersPtr;
-
-/// \brief A lazy pointer to a set of CXXBaseSpecifiers.
-typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
- &ExternalASTSource::GetExternalCXXBaseSpecifiers>
- LazyCXXBaseSpecifiersPtr;
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h
deleted file mode 100644
index 54c9d88..0000000
--- a/include/clang/AST/GlobalDecl.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
-// together with its type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_GLOBALDECL_H
-#define LLVM_CLANG_AST_GLOBALDECL_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/ABI.h"
-
-namespace clang {
-
-/// GlobalDecl - represents a global declaration. This can either be a
-/// CXXConstructorDecl and the constructor type (Base, Complete).
-/// a CXXDestructorDecl and the destructor type (Base, Complete) or
-/// a VarDecl, a FunctionDecl or a BlockDecl.
-class GlobalDecl {
- llvm::PointerIntPair<const Decl*, 2> Value;
-
- void Init(const Decl *D) {
- assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
- assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
-
- Value.setPointer(D);
- }
-
-public:
- GlobalDecl() {}
-
- GlobalDecl(const VarDecl *D) { Init(D);}
- GlobalDecl(const FunctionDecl *D) { Init(D); }
- GlobalDecl(const BlockDecl *D) { Init(D); }
- GlobalDecl(const CapturedDecl *D) { Init(D); }
- GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
-
- GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
- : Value(D, Type) {}
- GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
- : Value(D, Type) {}
-
- GlobalDecl getCanonicalDecl() const {
- GlobalDecl CanonGD;
- CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
- CanonGD.Value.setInt(Value.getInt());
-
- return CanonGD;
- }
-
- const Decl *getDecl() const { return Value.getPointer(); }
-
- CXXCtorType getCtorType() const {
- assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
- return static_cast<CXXCtorType>(Value.getInt());
- }
-
- CXXDtorType getDtorType() const {
- assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
- return static_cast<CXXDtorType>(Value.getInt());
- }
-
- friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
- return LHS.Value == RHS.Value;
- }
-
- void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
-
- static GlobalDecl getFromOpaquePtr(void *P) {
- GlobalDecl GD;
- GD.Value.setFromOpaqueValue(P);
- return GD;
- }
-
- GlobalDecl getWithDecl(const Decl *D) {
- GlobalDecl Result(*this);
- Result.Value.setPointer(D);
- return Result;
- }
-};
-
-} // end namespace clang
-
-namespace llvm {
- template<class> struct DenseMapInfo;
-
- template<> struct DenseMapInfo<clang::GlobalDecl> {
- static inline clang::GlobalDecl getEmptyKey() {
- return clang::GlobalDecl();
- }
-
- static inline clang::GlobalDecl getTombstoneKey() {
- return clang::GlobalDecl::
- getFromOpaquePtr(reinterpret_cast<void*>(-1));
- }
-
- static unsigned getHashValue(clang::GlobalDecl GD) {
- return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
- }
-
- static bool isEqual(clang::GlobalDecl LHS,
- clang::GlobalDecl RHS) {
- return LHS == RHS;
- }
-
- };
-
- // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
- // copy assignment operator, and destructor are all trivial.
- template <>
- struct isPodLike<clang::GlobalDecl> {
- static const bool value = true;
- };
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
deleted file mode 100644
index ddefa88..0000000
--- a/include/clang/AST/LambdaCapture.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the LambdaCapture class.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H
-#define LLVM_CLANG_AST_LAMBDACAPTURE_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Basic/Lambda.h"
-#include "llvm/ADT/PointerIntPair.h"
-
-namespace clang {
-
-/// \brief Describes the capture of a variable or of \c this, or of a
-/// C++1y init-capture.
-class LambdaCapture {
- enum {
- /// \brief Flag used by the Capture class to indicate that the given
- /// capture was implicit.
- Capture_Implicit = 0x01,
-
- /// \brief Flag used by the Capture class to indicate that the
- /// given capture was by-copy.
- ///
- /// This includes the case of a non-reference init-capture.
- Capture_ByCopy = 0x02
- };
-
- llvm::PointerIntPair<Decl *, 2> DeclAndBits;
- SourceLocation Loc;
- SourceLocation EllipsisLoc;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- /// \brief Create a new capture of a variable or of \c this.
- ///
- /// \param Loc The source location associated with this capture.
- ///
- /// \param Kind The kind of capture (this, byref, bycopy), which must
- /// not be init-capture.
- ///
- /// \param Implicit Whether the capture was implicit or explicit.
- ///
- /// \param Var The local variable being captured, or null if capturing
- /// \c this.
- ///
- /// \param EllipsisLoc The location of the ellipsis (...) for a
- /// capture that is a pack expansion, or an invalid source
- /// location to indicate that this is not a pack expansion.
- LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
- VarDecl *Var = nullptr,
- SourceLocation EllipsisLoc = SourceLocation());
-
- /// \brief Determine the kind of capture.
- LambdaCaptureKind getCaptureKind() const;
-
- /// \brief Determine whether this capture handles the C++ \c this
- /// pointer.
- bool capturesThis() const {
- return (DeclAndBits.getPointer() == nullptr) &&
- !(DeclAndBits.getInt() & Capture_ByCopy);
- }
-
- /// \brief 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
- /// expression.
- bool capturesVLAType() const {
- return (DeclAndBits.getPointer() == nullptr) &&
- (DeclAndBits.getInt() & Capture_ByCopy);
- }
-
- /// \brief Retrieve the declaration of the local variable being
- /// captured.
- ///
- /// This operation is only valid if this capture is a variable capture
- /// (other than a capture of \c this).
- VarDecl *getCapturedVar() const {
- assert(capturesVariable() && "No variable available for 'this' capture");
- return cast<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this was an implicit capture (not
- /// written between the square brackets introducing the lambda).
- bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
-
- /// \brief Determine whether this was an explicit capture (written
- /// between the square brackets introducing the lambda).
- bool isExplicit() const { return !isImplicit(); }
-
- /// \brief Retrieve the source location of the capture.
- ///
- /// For an explicit capture, this returns the location of the
- /// explicit capture in the source. For an implicit capture, this
- /// returns the location at which the variable or \c this was first
- /// used.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Determine whether this capture is a pack expansion,
- /// which captures a function parameter pack.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-
- /// \brief Retrieve the location of the ellipsis for a capture
- /// that is a pack expansion.
- SourceLocation getEllipsisLoc() const {
- assert(isPackExpansion() && "No ellipsis location for a non-expansion");
- return EllipsisLoc;
- }
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
deleted file mode 100644
index 85e6449..0000000
--- a/include/clang/AST/Makefile
+++ /dev/null
@@ -1,79 +0,0 @@
-CLANG_LEVEL := ../../..
-TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc AttrVisitor.inc \
- StmtNodes.inc DeclNodes.inc \
- CommentNodes.inc CommentHTMLTags.inc \
- CommentHTMLTagsProperties.inc \
- CommentHTMLNamedCharacterReferences.inc \
- CommentCommandInfo.inc \
- CommentCommandList.inc
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute classes with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute implementations with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute dumper with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrVisitor.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute AST visitor with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-ast-visitor -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang statement node tables with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/DeclNodes.inc.tmp : $(TD_SRC_DIR)/DeclNodes.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang declaration node tables with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-decl-nodes -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentNodes.inc.tmp : $(TD_SRC_DIR)/CommentNodes.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang comment node tables with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-nodes -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentHTMLTags.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang comment HTML tag matchers with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang comment HTML tag properties with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentHTMLNamedCharacterReferences.inc.tmp : \
- $(PROJ_SRC_DIR)/CommentHTMLNamedCharacterReferences.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang named character reference translation function with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-html-named-character-references -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentCommandInfo.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang comment command info with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-command-info -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentCommandList.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang list of comment commands with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-command-list -o $(call SYSPATH, $@) $<
-
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
deleted file mode 100644
index 4872738..0000000
--- a/include/clang/AST/Mangle.h
+++ /dev/null
@@ -1,243 +0,0 @@
-//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines the C++ name mangling interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_MANGLE_H
-#define LLVM_CLANG_AST_MANGLE_H
-
-#include "clang/AST/Type.h"
-#include "clang/Basic/ABI.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
- class ASTContext;
- class BlockDecl;
- class CXXConstructorDecl;
- class CXXDestructorDecl;
- class CXXMethodDecl;
- class FunctionDecl;
- class NamedDecl;
- class ObjCMethodDecl;
- class StringLiteral;
- struct ThisAdjustment;
- struct ThunkInfo;
- class VarDecl;
-
-/// MangleContext - Context for tracking state which persists across multiple
-/// calls to the C++ name mangler.
-class MangleContext {
-public:
- enum ManglerKind {
- MK_Itanium,
- MK_Microsoft
- };
-
-private:
- virtual void anchor();
-
- ASTContext &Context;
- DiagnosticsEngine &Diags;
- const ManglerKind Kind;
-
- llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
- llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
- llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
-
-public:
- ManglerKind getKind() const { return Kind; }
-
- explicit MangleContext(ASTContext &Context,
- DiagnosticsEngine &Diags,
- ManglerKind Kind)
- : Context(Context), Diags(Diags), Kind(Kind) {}
-
- virtual ~MangleContext() { }
-
- ASTContext &getASTContext() const { return Context; }
-
- DiagnosticsEngine &getDiags() const { return Diags; }
-
- virtual void startNewFunction() { LocalBlockIds.clear(); }
-
- unsigned getBlockId(const BlockDecl *BD, bool Local) {
- llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
- = Local? LocalBlockIds : GlobalBlockIds;
- std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
- Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
- return Result.first->second;
- }
-
- uint64_t getAnonymousStructId(const TagDecl *TD) {
- std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
- Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
- return Result.first->second;
- }
-
- /// @name Mangler Entry Points
- /// @{
-
- bool shouldMangleDeclName(const NamedDecl *D);
- virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
- virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
-
- // FIXME: consider replacing raw_ostream & with something like SmallString &.
- void mangleName(const NamedDecl *D, raw_ostream &);
- virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
- virtual void mangleThunk(const CXXMethodDecl *MD,
- const ThunkInfo &Thunk,
- raw_ostream &) = 0;
- virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
- const ThisAdjustment &ThisAdjustment,
- raw_ostream &) = 0;
- virtual void mangleReferenceTemporary(const VarDecl *D,
- unsigned ManglingNumber,
- raw_ostream &) = 0;
- virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
- raw_ostream &) = 0;
- virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
- raw_ostream &) = 0;
- virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
-
- void mangleGlobalBlock(const BlockDecl *BD,
- const NamedDecl *ID,
- raw_ostream &Out);
- void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
- const BlockDecl *BD, raw_ostream &Out);
- void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
- const BlockDecl *BD, raw_ostream &Out);
- void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
- raw_ostream &Out);
-
- void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
-
- virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
-
- virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
-
- virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
- raw_ostream &) = 0;
-
- virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
- raw_ostream &Out) = 0;
-
- virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
- raw_ostream &Out) = 0;
-
- /// Generates a unique string for an externally visible type for use with TBAA
- /// or type uniquing.
- /// TODO: Extend this to internal types by generating names that are unique
- /// across translation units so it can be used with LTO.
- virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
-
- /// @}
-};
-
-class ItaniumMangleContext : public MangleContext {
-public:
- explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Itanium) {}
-
- virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
- virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
- virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
- const CXXRecordDecl *Type,
- raw_ostream &) = 0;
- virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
- raw_ostream &) = 0;
- virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
- raw_ostream &) = 0;
-
- virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
- raw_ostream &) = 0;
- virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
- raw_ostream &) = 0;
-
- static bool classof(const MangleContext *C) {
- return C->getKind() == MK_Itanium;
- }
-
- static ItaniumMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
-};
-
-class MicrosoftMangleContext : public MangleContext {
-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
- /// 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
- /// to the vbtable are included in the name. It's up to the caller to pick
- /// them correctly.
- virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out) = 0;
-
- virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
- unsigned GuardNum,
- raw_ostream &Out) = 0;
-
- virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
- raw_ostream &) = 0;
-
- virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
- const CXXRecordDecl *DstRD,
- raw_ostream &Out) = 0;
-
- virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
- uint32_t NumEntries, raw_ostream &Out) = 0;
-
- virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
- raw_ostream &Out) = 0;
-
- virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
- CXXCtorType CT, uint32_t Size,
- uint32_t NVOffset, int32_t VBPtrOffset,
- uint32_t VBIndex, raw_ostream &Out) = 0;
-
- virtual void mangleCXXRTTIBaseClassDescriptor(
- const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
- uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
-
- virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
- raw_ostream &Out) = 0;
- virtual void
- mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
- raw_ostream &Out) = 0;
-
- virtual void
- mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out) = 0;
-
- static bool classof(const MangleContext *C) {
- return C->getKind() == MK_Microsoft;
- }
-
- static MicrosoftMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
-};
-}
-
-#endif
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
deleted file mode 100644
index 7a81855..0000000
--- a/include/clang/AST/MangleNumberingContext.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//=== MangleNumberingContext.h - Context for mangling numbers ---*- 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 LambdaBlockMangleContext interface, which keeps track
-// of the Itanium C++ ABI mangling numbers for lambda expressions and block
-// literals.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
-#define LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-
-namespace clang {
-
-class BlockDecl;
-class CXXMethodDecl;
-class IdentifierInfo;
-class TagDecl;
-class Type;
-class VarDecl;
-
-/// \brief Keeps track of the mangled names of lambda expressions and block
-/// literals within a particular context.
-class MangleNumberingContext : public RefCountedBase<MangleNumberingContext> {
-public:
- virtual ~MangleNumberingContext() {}
-
- /// \brief 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
- /// 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
- /// this context.
- virtual unsigned getManglingNumber(const VarDecl *VD,
- unsigned MSLocalManglingNumber) = 0;
-
- /// \brief Retrieve the mangling number of a static local variable within
- /// this context.
- virtual unsigned getManglingNumber(const TagDecl *TD,
- unsigned MSLocalManglingNumber) = 0;
-};
-
-} // end namespace clang
-#endif
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
deleted file mode 100644
index 583f9d9..0000000
--- a/include/clang/AST/NSAPI.h
+++ /dev/null
@@ -1,262 +0,0 @@
-//===--- NSAPI.h - NSFoundation APIs ----------------------------*- 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_AST_NSAPI_H
-#define LLVM_CLANG_AST_NSAPI_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-
-namespace clang {
- class ASTContext;
- class ObjCInterfaceDecl;
- class QualType;
- class Expr;
-
-// \brief Provides info and caches identifiers/selectors for NSFoundation API.
-class NSAPI {
-public:
- explicit NSAPI(ASTContext &Ctx);
-
- ASTContext &getASTContext() const { return Ctx; }
-
- enum NSClassIdKindKind {
- ClassId_NSObject,
- ClassId_NSString,
- ClassId_NSArray,
- ClassId_NSMutableArray,
- ClassId_NSDictionary,
- ClassId_NSMutableDictionary,
- ClassId_NSNumber,
- ClassId_NSMutableSet,
- ClassId_NSMutableOrderedSet,
- ClassId_NSValue
- };
- static const unsigned NumClassIds = 10;
-
- enum NSStringMethodKind {
- NSStr_stringWithString,
- NSStr_stringWithUTF8String,
- NSStr_stringWithCStringEncoding,
- NSStr_stringWithCString,
- NSStr_initWithString,
- NSStr_initWithUTF8String
- };
- static const unsigned NumNSStringMethods = 5;
-
- IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
-
- /// \brief The Objective-C NSString selectors.
- Selector getNSStringSelector(NSStringMethodKind MK) const;
-
- /// \brief 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
- /// "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
- /// "NSASCIIStringEncoding" enum constant.
- bool isNSASCIIStringEncodingConstant(const Expr *E) const {
- return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId);
- }
-
- /// \brief Enumerates the NSArray/NSMutableArray methods used to generate
- /// literals and to apply some checks.
- enum NSArrayMethodKind {
- NSArr_array,
- NSArr_arrayWithArray,
- NSArr_arrayWithObject,
- NSArr_arrayWithObjects,
- NSArr_arrayWithObjectsCount,
- NSArr_initWithArray,
- NSArr_initWithObjects,
- NSArr_objectAtIndex,
- NSMutableArr_replaceObjectAtIndex,
- NSMutableArr_addObject,
- NSMutableArr_insertObjectAtIndex,
- NSMutableArr_setObjectAtIndexedSubscript
- };
- static const unsigned NumNSArrayMethods = 12;
-
- /// \brief The Objective-C NSArray selectors.
- Selector getNSArraySelector(NSArrayMethodKind MK) const;
-
- /// \brief Return NSArrayMethodKind if \p Sel is such a selector.
- Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
-
- /// \brief Enumerates the NSDictionary/NSMutableDictionary methods used
- /// to generate literals and to apply some checks.
- enum NSDictionaryMethodKind {
- NSDict_dictionary,
- NSDict_dictionaryWithDictionary,
- NSDict_dictionaryWithObjectForKey,
- NSDict_dictionaryWithObjectsForKeys,
- NSDict_dictionaryWithObjectsForKeysCount,
- NSDict_dictionaryWithObjectsAndKeys,
- NSDict_initWithDictionary,
- NSDict_initWithObjectsAndKeys,
- NSDict_initWithObjectsForKeys,
- NSDict_objectForKey,
- NSMutableDict_setObjectForKey,
- NSMutableDict_setObjectForKeyedSubscript,
- NSMutableDict_setValueForKey
- };
- static const unsigned NumNSDictionaryMethods = 14;
-
- /// \brief The Objective-C NSDictionary selectors.
- Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
-
- /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector.
- Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
-
- /// \brief Enumerates the NSMutableSet/NSOrderedSet methods used
- /// to apply some checks.
- enum NSSetMethodKind {
- NSMutableSet_addObject,
- NSOrderedSet_insertObjectAtIndex,
- NSOrderedSet_setObjectAtIndex,
- NSOrderedSet_setObjectAtIndexedSubscript,
- NSOrderedSet_replaceObjectAtIndexWithObject
- };
- static const unsigned NumNSSetMethods = 5;
-
- /// \brief The Objective-C NSSet selectors.
- Selector getNSSetSelector(NSSetMethodKind MK) const;
-
- /// \brief Return NSSetMethodKind if \p Sel is such a selector.
- Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
-
- /// \brief Returns selector for "objectForKeyedSubscript:".
- Selector getObjectForKeyedSubscriptSelector() const {
- return getOrInitSelector(StringRef("objectForKeyedSubscript"),
- objectForKeyedSubscriptSel);
- }
-
- /// \brief Returns selector for "objectAtIndexedSubscript:".
- Selector getObjectAtIndexedSubscriptSelector() const {
- return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
- objectAtIndexedSubscriptSel);
- }
-
- /// \brief Returns selector for "setObject:forKeyedSubscript".
- Selector getSetObjectForKeyedSubscriptSelector() const {
- StringRef Ids[] = { "setObject", "forKeyedSubscript" };
- return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
- }
-
- /// \brief Returns selector for "setObject:atIndexedSubscript".
- Selector getSetObjectAtIndexedSubscriptSelector() const {
- StringRef Ids[] = { "setObject", "atIndexedSubscript" };
- return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
- }
-
- /// \brief Returns selector for "isEqual:".
- Selector getIsEqualSelector() const {
- return getOrInitSelector(StringRef("isEqual"), isEqualSel);
- }
-
- /// \brief Enumerates the NSNumber methods used to generate literals.
- enum NSNumberLiteralMethodKind {
- NSNumberWithChar,
- NSNumberWithUnsignedChar,
- NSNumberWithShort,
- NSNumberWithUnsignedShort,
- NSNumberWithInt,
- NSNumberWithUnsignedInt,
- NSNumberWithLong,
- NSNumberWithUnsignedLong,
- NSNumberWithLongLong,
- NSNumberWithUnsignedLongLong,
- NSNumberWithFloat,
- NSNumberWithDouble,
- NSNumberWithBool,
- NSNumberWithInteger,
- NSNumberWithUnsignedInteger
- };
- static const unsigned NumNSNumberLiteralMethods = 15;
-
- /// \brief 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,
- bool Instance) const;
-
- bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
- Selector Sel) const {
- return Sel == getNSNumberLiteralSelector(MK, false) ||
- Sel == getNSNumberLiteralSelector(MK, true);
- }
-
- /// \brief 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
- /// 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.
- bool isObjCBOOLType(QualType T) const;
- /// \brief 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.
- bool isObjCNSUIntegerType(QualType T) const;
- /// \brief 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.
- bool isMacroDefined(StringRef Id) const;
-
- /// \brief Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind
- bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
- NSClassIdKindKind NSClassKind) const;
-
-private:
- bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
- bool isObjCEnumerator(const Expr *E,
- StringRef name, IdentifierInfo *&II) const;
- Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
-
- ASTContext &Ctx;
-
- mutable IdentifierInfo *ClassIds[NumClassIds];
-
- mutable Selector NSStringSelectors[NumNSStringMethods];
-
- /// \brief The selectors for Objective-C NSArray methods.
- mutable Selector NSArraySelectors[NumNSArrayMethods];
-
- /// \brief The selectors for Objective-C NSDictionary methods.
- mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
-
- /// \brief The selectors for Objective-C NSSet methods.
- mutable Selector NSSetSelectors[NumNSSetMethods];
-
- /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
- mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
- mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
-
- mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
- setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
- isEqualSel;
-
- mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
- mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_NSAPI_H
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
deleted file mode 100644
index b1ff9bd..0000000
--- a/include/clang/AST/NestedNameSpecifier.h
+++ /dev/null
@@ -1,516 +0,0 @@
-//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- 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 NestedNameSpecifier class, which represents
-// a C++ nested-name-specifier.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
-#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class ASTContext;
-class CXXRecordDecl;
-class NamespaceAliasDecl;
-class NamespaceDecl;
-class IdentifierInfo;
-struct PrintingPolicy;
-class Type;
-class TypeLoc;
-class LangOptions;
-
-/// \brief Represents a C++ nested name specifier, such as
-/// "\::std::vector<int>::".
-///
-/// C++ nested name specifiers are the prefixes to qualified
-/// namespaces. For example, "foo::" in "foo::x" is a nested name
-/// specifier. Nested name specifiers are made up of a sequence of
-/// specifiers, each of which can be a namespace, type, identifier
-/// (for dependent names), decltype specifier, or the global specifier ('::').
-/// The last two specifiers can only appear at the start of a
-/// nested-namespace-specifier.
-class NestedNameSpecifier : public llvm::FoldingSetNode {
-
- /// \brief Enumeration describing
- enum StoredSpecifierKind {
- StoredIdentifier = 0,
- StoredDecl = 1,
- StoredTypeSpec = 2,
- StoredTypeSpecWithTemplate = 3
- };
-
- /// \brief The nested name specifier that precedes this nested name
- /// specifier.
- ///
- /// The pointer is the nested-name-specifier that precedes this
- /// one. The integer stores one of the first four values of type
- /// SpecifierKind.
- llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
-
- /// \brief 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
- /// specifier '::'. Otherwise, the pointer is one of
- /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
- /// specifier as encoded within the prefix.
- void* Specifier;
-
-public:
- /// \brief The kind of specifier that completes this nested name
- /// specifier.
- enum SpecifierKind {
- /// \brief An identifier, stored as an IdentifierInfo*.
- Identifier,
- /// \brief A namespace, stored as a NamespaceDecl*.
- Namespace,
- /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
- NamespaceAlias,
- /// \brief A type, stored as a Type*.
- TypeSpec,
- /// \brief A type that was preceded by the 'template' keyword,
- /// stored as a Type*.
- TypeSpecWithTemplate,
- /// \brief The global specifier '::'. There is no stored value.
- Global,
- /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
- /// the class it appeared in.
- Super
- };
-
-private:
- /// \brief Builds the global specifier.
- NestedNameSpecifier()
- : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
-
- /// \brief Copy constructor used internally to clone nested name
- /// specifiers.
- NestedNameSpecifier(const NestedNameSpecifier &Other)
- : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
- Specifier(Other.Specifier) {
- }
-
- void operator=(const NestedNameSpecifier &) = delete;
-
- /// \brief Either find or insert the given nested name specifier
- /// mockup in the given context.
- static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
- const NestedNameSpecifier &Mockup);
-
-public:
- /// \brief 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
- /// cannot be resolved.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- IdentifierInfo *II);
-
- /// \brief 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.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- NamespaceAliasDecl *Alias);
-
- /// \brief 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.
- ///
- /// The nested-name-specifier is assumed to be dependent, but has no
- /// prefix because the prefix is implied by something outside of the
- /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
- /// type.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- IdentifierInfo *II);
-
- /// \brief 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
- /// for the given CXXRecordDecl.
- static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
- CXXRecordDecl *RD);
-
- /// \brief 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
- /// nested name specifier that represents "foo::bar::", the current
- /// specifier will contain "bar::" and the prefix will contain
- /// "foo::".
- NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
-
- /// \brief Determine what kind of nested name specifier is stored.
- SpecifierKind getKind() const;
-
- /// \brief Retrieve the identifier stored in this nested name
- /// specifier.
- IdentifierInfo *getAsIdentifier() const {
- if (Prefix.getInt() == StoredIdentifier)
- return (IdentifierInfo *)Specifier;
-
- return nullptr;
- }
-
- /// \brief Retrieve the namespace stored in this nested name
- /// specifier.
- NamespaceDecl *getAsNamespace() const;
-
- /// \brief Retrieve the namespace alias stored in this nested name
- /// specifier.
- NamespaceAliasDecl *getAsNamespaceAlias() const;
-
- /// \brief Retrieve the record declaration stored in this nested name
- /// specifier.
- CXXRecordDecl *getAsRecordDecl() const;
-
- /// \brief Retrieve the type stored in this nested name specifier.
- const Type *getAsType() const {
- if (Prefix.getInt() == StoredTypeSpec ||
- Prefix.getInt() == StoredTypeSpecWithTemplate)
- return (const Type *)Specifier;
-
- return nullptr;
- }
-
- /// \brief Whether this nested name specifier refers to a dependent
- /// type or not.
- bool isDependent() const;
-
- /// \brief Whether this nested name specifier involves a template
- /// parameter.
- bool isInstantiationDependent() const;
-
- /// \brief 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
- /// stream.
- void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddPointer(Prefix.getOpaqueValue());
- ID.AddPointer(Specifier);
- }
-
- /// \brief 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
-/// information.
-class NestedNameSpecifierLoc {
- NestedNameSpecifier *Qualifier;
- void *Data;
-
- /// \brief 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
- /// nested-name-specifier.
- static unsigned getDataLength(NestedNameSpecifier *Qualifier);
-
-public:
- /// \brief Construct an empty nested-name-specifier.
- NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
-
- /// \brief 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
- /// non-empty.
- explicit operator bool() const { return Qualifier; }
-
- /// \brief Evalutes true when this nested-name-specifier location is
- /// empty.
- bool hasQualifier() const { return Qualifier; }
-
- /// \brief 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.
- void *getOpaqueData() const { return Data; }
-
- /// \brief Retrieve the source range covering the entirety of this
- /// nested-name-specifier.
- ///
- /// For example, if this instance refers to a nested-name-specifier
- /// \c \::std::vector<int>::, the returned source range would cover
- /// from the initial '::' to the last '::'.
- SourceRange getSourceRange() const LLVM_READONLY;
-
- /// \brief 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
- /// \c \::std::vector<int>::, the returned source range would cover
- /// from "vector" to the last '::'.
- SourceRange getLocalSourceRange() const;
-
- /// \brief 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
- /// nested-name-specifier.
- SourceLocation getEndLoc() const {
- return getSourceRange().getEnd();
- }
-
- /// \brief 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
- /// nested-name-specifier.
- SourceLocation getLocalEndLoc() const {
- return getLocalSourceRange().getEnd();
- }
-
- /// \brief 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
- /// returned prefix may be empty, if this is the first component of
- /// the nested-name-specifier.
- NestedNameSpecifierLoc getPrefix() const {
- if (!Qualifier)
- return *this;
-
- return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
- }
-
- /// \brief 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
- /// nested-name-specifier.
- unsigned getDataLength() const { return getDataLength(Qualifier); }
-
- friend bool operator==(NestedNameSpecifierLoc X,
- NestedNameSpecifierLoc Y) {
- return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
- }
-
- friend bool operator!=(NestedNameSpecifierLoc X,
- NestedNameSpecifierLoc Y) {
- return !(X == Y);
- }
-};
-
-/// \brief 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
- /// building.
- NestedNameSpecifier *Representation;
-
- /// \brief Buffer used to store source-location information for the
- /// nested-name-specifier.
- ///
- /// Note that we explicitly manage the buffer (rather than using a
- /// SmallVector) because \c Declarator expects it to be possible to memcpy()
- /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
- char *Buffer;
-
- /// \brief The size of the buffer used to store source-location information
- /// for the nested-name-specifier.
- unsigned BufferSize;
-
- /// \brief The capacity of the buffer used to store source-location
- /// information for the nested-name-specifier.
- unsigned BufferCapacity;
-
-public:
- NestedNameSpecifierLocBuilder()
- : Representation(nullptr), Buffer(nullptr), BufferSize(0),
- BufferCapacity(0) {}
-
- NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
-
- NestedNameSpecifierLocBuilder &
- operator=(const NestedNameSpecifierLocBuilder &Other);
-
- ~NestedNameSpecifierLocBuilder() {
- if (BufferCapacity)
- free(Buffer);
- }
-
- /// \brief Retrieve the representation of the nested-name-specifier.
- NestedNameSpecifier *getRepresentation() const { return Representation; }
-
- /// \brief 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
- /// resides.
- ///
- /// \param TemplateKWLoc The location of the 'template' keyword, if present.
- ///
- /// \param TL The TypeLoc that describes the type preceding the '::'.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
- SourceLocation ColonColonLoc);
-
- /// \brief 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
- /// resides.
- ///
- /// \param Identifier The identifier.
- ///
- /// \param IdentifierLoc The location of the identifier.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, IdentifierInfo *Identifier,
- SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
-
- /// \brief 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
- /// resides.
- ///
- /// \param Namespace The namespace.
- ///
- /// \param NamespaceLoc The location of the namespace name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceDecl *Namespace,
- SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
-
- /// \brief 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
- /// resides.
- ///
- /// \param Alias The namespace alias.
- ///
- /// \param AliasLoc The location of the namespace alias
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc, SourceLocation ColonColonLoc);
-
- /// \brief 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'
- /// nested-name-specifier.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param RD The declaration of the class in which nested-name-specifier
- /// appeared.
- ///
- /// \param SuperLoc The location of the '__super' keyword.
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
- SourceLocation SuperLoc, SourceLocation ColonColonLoc);
- /// \brief Make a new nested-name-specifier from incomplete source-location
- /// information.
- ///
- /// This routine should be used very, very rarely, in cases where we
- /// need to synthesize a nested-name-specifier. Most code should instead use
- /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
- void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
- SourceRange R);
-
- /// \brief 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.
- SourceRange getSourceRange() const LLVM_READONLY {
- return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
- }
-
- /// \brief 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
- /// information based on the information in this builder.
- ///
- /// This loc will contain references to the builder's internal data and may
- /// be invalidated by any change to the builder.
- NestedNameSpecifierLoc getTemporary() const {
- return NestedNameSpecifierLoc(Representation, Buffer);
- }
-
- /// \brief 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.
- ///
- /// \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
- /// buffer.
- std::pair<char *, unsigned> getBuffer() const {
- return std::make_pair(Buffer, BufferSize);
- }
-};
-
-/// Insertion operator for diagnostics. This allows sending
-/// NestedNameSpecifiers into a diagnostic with <<.
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- NestedNameSpecifier *NNS) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
- DiagnosticsEngine::ak_nestednamespec);
- return DB;
-}
-
-}
-
-#endif
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
deleted file mode 100644
index 7632a4b..0000000
--- a/include/clang/AST/OpenMPClause.h
+++ /dev/null
@@ -1,3198 +0,0 @@
-//===- OpenMPClause.h - Classes for OpenMP clauses --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// \brief This file defines OpenMP AST classes for clauses.
-/// There are clauses for executable directives, clauses for declarative
-/// directives and clauses which can be used in both kinds of directives.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
-#define LLVM_CLANG_AST_OPENMPCLAUSE_H
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-// AST classes for clauses.
-//===----------------------------------------------------------------------===//
-
-/// \brief This is a basic class for representing single OpenMP clause.
-///
-class OMPClause {
- /// \brief Starting location of the clause (the clause keyword).
- SourceLocation StartLoc;
- /// \brief Ending location of the clause.
- SourceLocation EndLoc;
- /// \brief Kind of the clause.
- OpenMPClauseKind Kind;
-
-protected:
- OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
- : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
-
-public:
- /// \brief Returns the starting location of the clause.
- SourceLocation getLocStart() const { return StartLoc; }
- /// \brief Returns the ending location of the clause.
- SourceLocation getLocEnd() const { return EndLoc; }
-
- /// \brief Sets the starting location of the clause.
- void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
- /// \brief Sets the ending location of the clause.
- void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
-
- /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
- OpenMPClauseKind getClauseKind() const { return Kind; }
-
- bool isImplicit() const { return StartLoc.isInvalid(); }
-
- typedef StmtIterator child_iterator;
- typedef ConstStmtIterator const_child_iterator;
- typedef llvm::iterator_range<child_iterator> child_range;
- typedef llvm::iterator_range<const_child_iterator> const_child_range;
-
- child_range children();
- const_child_range children() const {
- auto Children = const_cast<OMPClause *>(this)->children();
- return const_child_range(Children.begin(), Children.end());
- }
- static bool classof(const OMPClause *) { return true; }
-};
-
-/// \brief This represents clauses with the list of variables like 'private',
-/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
-/// '#pragma omp ...' directives.
-template <class T> class OMPVarListClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Number of variables in the list.
- unsigned NumVars;
-
-protected:
- /// \brief Fetches list of variables associated with this clause.
- MutableArrayRef<Expr *> getVarRefs() {
- return MutableArrayRef<Expr *>(
- static_cast<T *>(this)->template getTrailingObjects<Expr *>(), NumVars);
- }
-
- /// \brief Sets the list of variables for this clause.
- void setVarRefs(ArrayRef<Expr *> VL) {
- assert(VL.size() == NumVars &&
- "Number of variables is not the same as the preallocated buffer");
- std::copy(VL.begin(), VL.end(),
- static_cast<T *>(this)->template getTrailingObjects<Expr *>());
- }
-
- /// \brief Build a clause with \a N variables
- ///
- /// \param K Kind of the clause.
- /// \param StartLoc Starting location of the clause (the clause keyword).
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
- : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
-
-public:
- typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
- typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
- typedef llvm::iterator_range<varlist_iterator> varlist_range;
- typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
-
- unsigned varlist_size() const { return NumVars; }
- bool varlist_empty() const { return NumVars == 0; }
-
- varlist_range varlists() {
- return varlist_range(varlist_begin(), varlist_end());
- }
- varlist_const_range varlists() const {
- return varlist_const_range(varlist_begin(), varlist_end());
- }
-
- varlist_iterator varlist_begin() { return getVarRefs().begin(); }
- varlist_iterator varlist_end() { return getVarRefs().end(); }
- varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
- varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Fetches list of all variables in the clause.
- ArrayRef<const Expr *> getVarRefs() const {
- return llvm::makeArrayRef(
- static_cast<const T *>(this)->template getTrailingObjects<Expr *>(),
- NumVars);
- }
-};
-
-/// \brief This represents 'if' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp parallel if(parallel:a > 5)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'if' clause with
-/// condition 'a > 5' and directive name modifier 'parallel'.
-///
-class OMPIfClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Condition of the 'if' clause.
- Stmt *Condition;
- /// \brief Location of ':' (if any).
- SourceLocation ColonLoc;
- /// \brief Directive name modifier for the clause.
- OpenMPDirectiveKind NameModifier;
- /// \brief Name modifier location.
- SourceLocation NameModifierLoc;
-
- /// \brief Set condition.
- ///
- void setCondition(Expr *Cond) { Condition = Cond; }
- /// \brief Set directive name modifier for the clause.
- ///
- void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; }
- /// \brief Set location of directive name modifier for the clause.
- ///
- void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; }
- /// \brief Set location of ':'.
- ///
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
-
-public:
- /// \brief Build 'if' clause with condition \a Cond.
- ///
- /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
- /// \param Cond Condition of the clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param NameModifierLoc Location of directive name modifier.
- /// \param ColonLoc [OpenMP 4.1] Location of ':'.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation NameModifierLoc, SourceLocation ColonLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier),
- NameModifierLoc(NameModifierLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPIfClause()
- : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(),
- Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown),
- NameModifierLoc() {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return the location of ':'.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- /// \brief Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
- /// \brief Return directive name modifier associated with the clause.
- OpenMPDirectiveKind getNameModifier() const { return NameModifier; }
-
- /// \brief Return the location of directive name modifier.
- SourceLocation getNameModifierLoc() const { return NameModifierLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_if;
- }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-};
-
-/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp task final(a > 5)
-/// \endcode
-/// In this example directive '#pragma omp task' has simple 'final'
-/// clause with condition 'a > 5'.
-///
-class OMPFinalClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Condition of the 'if' clause.
- Stmt *Condition;
-
- /// \brief Set condition.
- ///
- void setCondition(Expr *Cond) { Condition = Cond; }
-
-public:
- /// \brief Build 'final' clause with condition \a Cond.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param Cond Condition of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Condition(Cond) {}
-
- /// \brief Build an empty clause.
- ///
- OMPFinalClause()
- : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Condition(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_final;
- }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-};
-
-/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp parallel num_threads(6)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'num_threads'
-/// clause with number of threads '6'.
-///
-class OMPNumThreadsClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Condition of the 'num_threads' clause.
- Stmt *NumThreads;
-
- /// \brief Set condition.
- ///
- void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
-
-public:
- /// \brief Build 'num_threads' clause with condition \a NumThreads.
- ///
- /// \param NumThreads Number of threads for the construct.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumThreads(NumThreads) {}
-
- /// \brief Build an empty clause.
- ///
- OMPNumThreadsClause()
- : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumThreads(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns number of threads.
- Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_threads;
- }
-
- child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
-};
-
-/// \brief This represents 'safelen' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp simd safelen(4)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'safelen'
-/// with single expression '4'.
-/// If the safelen clause is used then no two iterations executed
-/// concurrently with SIMD instructions can have a greater distance
-/// in the logical iteration space than its value. The parameter of
-/// the safelen clause must be a constant positive integer expression.
-///
-class OMPSafelenClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
- Stmt *Safelen;
-
- /// \brief Set safelen.
- void setSafelen(Expr *Len) { Safelen = Len; }
-
-public:
- /// \brief Build 'safelen' clause.
- ///
- /// \param Len Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Safelen(Len) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPSafelenClause()
- : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Safelen(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return safe iteration space distance.
- Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_safelen;
- }
-
- child_range children() { return child_range(&Safelen, &Safelen + 1); }
-};
-
-/// \brief This represents 'simdlen' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp simd simdlen(4)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'simdlen'
-/// with single expression '4'.
-/// If the 'simdlen' clause is used then it specifies the preferred number of
-/// iterations to be executed concurrently. The parameter of the 'simdlen'
-/// clause must be a constant positive integer expression.
-///
-class OMPSimdlenClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
- Stmt *Simdlen;
-
- /// \brief Set simdlen.
- void setSimdlen(Expr *Len) { Simdlen = Len; }
-
-public:
- /// \brief Build 'simdlen' clause.
- ///
- /// \param Len Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Simdlen(Len) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPSimdlenClause()
- : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Simdlen(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return safe iteration space distance.
- Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_simdlen;
- }
-
- child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
-};
-
-/// \brief This represents 'collapse' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp simd collapse(3)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'collapse'
-/// with single expression '3'.
-/// The parameter must be a constant positive integer expression, it specifies
-/// the number of nested loops that should be collapsed into a single iteration
-/// space.
-///
-class OMPCollapseClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Number of for-loops.
- Stmt *NumForLoops;
-
- /// \brief Set the number of associated for-loops.
- void setNumForLoops(Expr *Num) { NumForLoops = Num; }
-
-public:
- /// \brief Build 'collapse' clause.
- ///
- /// \param Num Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumForLoops(Num) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPCollapseClause()
- : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return the number of associated for-loops.
- Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_collapse;
- }
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
-};
-
-/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp parallel default(shared)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'default'
-/// clause with kind 'shared'.
-///
-class OMPDefaultClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief A kind of the 'default' clause.
- OpenMPDefaultClauseKind Kind;
- /// \brief Start location of the kind in source code.
- SourceLocation KindKwLoc;
-
- /// \brief Set kind of the clauses.
- ///
- /// \param K Argument of clause.
- ///
- void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
-
- /// \brief Set argument location.
- ///
- /// \param KLoc Argument location.
- ///
- void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
-
-public:
- /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
- ///
- /// \param A Argument of the clause ('none' or 'shared').
- /// \param ALoc Starting location of the argument.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(A), KindKwLoc(ALoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPDefaultClause()
- : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
- KindKwLoc(SourceLocation()) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns kind of the clause.
- OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
-
- /// \brief Returns location of clause kind.
- SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_default;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp parallel proc_bind(master)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
-/// clause with kind 'master'.
-///
-class OMPProcBindClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief A kind of the 'proc_bind' clause.
- OpenMPProcBindClauseKind Kind;
- /// \brief Start location of the kind in source code.
- SourceLocation KindKwLoc;
-
- /// \brief Set kind of the clause.
- ///
- /// \param K Kind of clause.
- ///
- void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
-
- /// \brief Set clause kind location.
- ///
- /// \param KLoc Kind location.
- ///
- void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
-
-public:
- /// \brief Build 'proc_bind' clause with argument \a A ('master', 'close' or
- /// 'spread').
- ///
- /// \param A Argument of the clause ('master', 'close' or 'spread').
- /// \param ALoc Starting location of the argument.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(A), KindKwLoc(ALoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPProcBindClause()
- : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown),
- KindKwLoc(SourceLocation()) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns kind of the clause.
- OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
-
- /// \brief Returns location of clause kind.
- SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_proc_bind;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'schedule' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp for schedule(static, 3)
-/// \endcode
-/// In this example directive '#pragma omp for' has 'schedule' clause with
-/// arguments 'static' and '3'.
-///
-class OMPScheduleClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief A kind of the 'schedule' clause.
- OpenMPScheduleClauseKind Kind;
- /// \brief Modifiers for 'schedule' clause.
- enum {FIRST, SECOND, NUM_MODIFIERS};
- OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS];
- /// \brief Locations of modifiers.
- SourceLocation ModifiersLoc[NUM_MODIFIERS];
- /// \brief Start location of the schedule ind in source code.
- SourceLocation KindLoc;
- /// \brief Location of ',' (if any).
- SourceLocation CommaLoc;
- /// \brief Chunk size and a reference to pseudo variable for combined
- /// directives.
- enum { CHUNK_SIZE, HELPER_CHUNK_SIZE, NUM_EXPRS };
- Stmt *ChunkSizes[NUM_EXPRS];
-
- /// \brief Set schedule kind.
- ///
- /// \param K Schedule kind.
- ///
- void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }
- /// \brief Set the first schedule modifier.
- ///
- /// \param M Schedule modifier.
- ///
- void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) {
- Modifiers[FIRST] = M;
- }
- /// \brief Set the second schedule modifier.
- ///
- /// \param M Schedule modifier.
- ///
- void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) {
- Modifiers[SECOND] = M;
- }
- /// \brief Set location of the first schedule modifier.
- ///
- void setFirstScheduleModifierLoc(SourceLocation Loc) {
- ModifiersLoc[FIRST] = Loc;
- }
- /// \brief Set location of the second schedule modifier.
- ///
- void setSecondScheduleModifierLoc(SourceLocation Loc) {
- ModifiersLoc[SECOND] = Loc;
- }
- /// \brief Set schedule modifier location.
- ///
- /// \param M Schedule modifier location.
- ///
- void setScheduleModifer(OpenMPScheduleClauseModifier M) {
- if (Modifiers[FIRST] == OMPC_SCHEDULE_MODIFIER_unknown)
- Modifiers[FIRST] = M;
- else {
- assert(Modifiers[SECOND] == OMPC_SCHEDULE_MODIFIER_unknown);
- Modifiers[SECOND] = M;
- }
- }
- /// \brief Sets the location of '('.
- ///
- /// \param Loc Location of '('.
- ///
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Set schedule kind start location.
- ///
- /// \param KLoc Schedule kind location.
- ///
- void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
- /// \brief Set location of ','.
- ///
- /// \param Loc Location of ','.
- ///
- void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
- /// \brief Set chunk size.
- ///
- /// \param E Chunk size.
- ///
- void setChunkSize(Expr *E) { ChunkSizes[CHUNK_SIZE] = E; }
- /// \brief Set helper chunk size.
- ///
- /// \param E Helper chunk size.
- ///
- void setHelperChunkSize(Expr *E) { ChunkSizes[HELPER_CHUNK_SIZE] = E; }
-
-public:
- /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size
- /// expression \a ChunkSize.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param KLoc Starting location of the argument.
- /// \param CommaLoc Location of ','.
- /// \param EndLoc Ending location of the clause.
- /// \param Kind Schedule kind.
- /// \param ChunkSize Chunk size.
- /// \param HelperChunkSize Helper chunk size for combined directives.
- /// \param M1 The first modifier applied to 'schedule' clause.
- /// \param M1Loc Location of the first modifier
- /// \param M2 The second modifier applied to 'schedule' clause.
- /// \param M2Loc Location of the second modifier
- ///
- OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation KLoc, SourceLocation CommaLoc,
- SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
- Expr *ChunkSize, Expr *HelperChunkSize,
- OpenMPScheduleClauseModifier M1, SourceLocation M1Loc,
- OpenMPScheduleClauseModifier M2, SourceLocation M2Loc)
- : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) {
- ChunkSizes[CHUNK_SIZE] = ChunkSize;
- ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize;
- Modifiers[FIRST] = M1;
- Modifiers[SECOND] = M2;
- ModifiersLoc[FIRST] = M1Loc;
- ModifiersLoc[SECOND] = M2Loc;
- }
-
- /// \brief Build an empty clause.
- ///
- explicit OMPScheduleClause()
- : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
- Kind(OMPC_SCHEDULE_unknown) {
- ChunkSizes[CHUNK_SIZE] = nullptr;
- ChunkSizes[HELPER_CHUNK_SIZE] = nullptr;
- Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown;
- Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown;
- }
-
- /// \brief Get kind of the clause.
- ///
- OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }
- /// \brief Get the first modifier of the clause.
- ///
- OpenMPScheduleClauseModifier getFirstScheduleModifier() const {
- return Modifiers[FIRST];
- }
- /// \brief Get the second modifier of the clause.
- ///
- OpenMPScheduleClauseModifier getSecondScheduleModifier() const {
- return Modifiers[SECOND];
- }
- /// \brief Get location of '('.
- ///
- SourceLocation getLParenLoc() { return LParenLoc; }
- /// \brief Get kind location.
- ///
- SourceLocation getScheduleKindLoc() { return KindLoc; }
- /// \brief Get the first modifier location.
- ///
- SourceLocation getFirstScheduleModifierLoc() const {
- return ModifiersLoc[FIRST];
- }
- /// \brief Get the second modifier location.
- ///
- SourceLocation getSecondScheduleModifierLoc() const {
- return ModifiersLoc[SECOND];
- }
- /// \brief Get location of ','.
- ///
- SourceLocation getCommaLoc() { return CommaLoc; }
- /// \brief Get chunk size.
- ///
- Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]); }
- /// \brief Get chunk size.
- ///
- Expr *getChunkSize() const {
- return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]);
- }
- /// \brief Get helper chunk size.
- ///
- Expr *getHelperChunkSize() {
- return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]);
- }
- /// \brief Get helper chunk size.
- ///
- Expr *getHelperChunkSize() const {
- return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]);
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_schedule;
- }
-
- child_range children() {
- return child_range(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1);
- }
-};
-
-/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp for ordered (2)
-/// \endcode
-/// In this example directive '#pragma omp for' has 'ordered' clause with
-/// parameter 2.
-///
-class OMPOrderedClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Number of for-loops.
- Stmt *NumForLoops;
-
- /// \brief Set the number of associated for-loops.
- void setNumForLoops(Expr *Num) { NumForLoops = Num; }
-
-public:
- /// \brief Build 'ordered' clause.
- ///
- /// \param Num Expression, possibly associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPOrderedClause(Expr *Num, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumForLoops(Num) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPOrderedClause()
- : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return the number of associated for-loops.
- Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_ordered;
- }
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
-};
-
-/// \brief This represents 'nowait' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp for nowait
-/// \endcode
-/// In this example directive '#pragma omp for' has 'nowait' clause.
-///
-class OMPNowaitClause : public OMPClause {
-public:
- /// \brief Build 'nowait' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_nowait, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPNowaitClause()
- : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nowait;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp task untied
-/// \endcode
-/// In this example directive '#pragma omp task' has 'untied' clause.
-///
-class OMPUntiedClause : public OMPClause {
-public:
- /// \brief Build 'untied' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_untied, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPUntiedClause()
- : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_untied;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp task mergeable
-/// \endcode
-/// In this example directive '#pragma omp task' has 'mergeable' clause.
-///
-class OMPMergeableClause : public OMPClause {
-public:
- /// \brief Build 'mergeable' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPMergeableClause()
- : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_mergeable;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'read' clause in the '#pragma omp atomic' directive.
-///
-/// \code
-/// #pragma omp atomic read
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'read' clause.
-///
-class OMPReadClause : public OMPClause {
-public:
- /// \brief 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.
- ///
- OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_read;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'write' clause in the '#pragma omp atomic' directive.
-///
-/// \code
-/// #pragma omp atomic write
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'write' clause.
-///
-class OMPWriteClause : public OMPClause {
-public:
- /// \brief 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.
- ///
- OMPWriteClause()
- : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_write;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'update' clause in the '#pragma omp atomic'
-/// directive.
-///
-/// \code
-/// #pragma omp atomic update
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'update' clause.
-///
-class OMPUpdateClause : public OMPClause {
-public:
- /// \brief 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.
- ///
- OMPUpdateClause()
- : OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_update;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'capture' clause in the '#pragma omp atomic'
-/// directive.
-///
-/// \code
-/// #pragma omp atomic capture
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'capture' clause.
-///
-class OMPCaptureClause : public OMPClause {
-public:
- /// \brief 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.
- ///
- OMPCaptureClause()
- : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_capture;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'seq_cst' clause in the '#pragma omp atomic'
-/// directive.
-///
-/// \code
-/// #pragma omp atomic seq_cst
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'seq_cst' clause.
-///
-class OMPSeqCstClause : public OMPClause {
-public:
- /// \brief 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.
- ///
- OMPSeqCstClause()
- : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_seq_cst;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel private(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'private'
-/// with the variables 'a' and 'b'.
-///
-class OMPPrivateClause final
- : public OMPVarListClause<OMPPrivateClause>,
- private llvm::TrailingObjects<OMPPrivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
- EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPPrivateClause(unsigned N)
- : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N) {}
-
- /// \brief 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
- /// new private variables.
- MutableArrayRef<Expr *> getPrivateCopies() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param PrivateVL List of references to private copies with initializers.
- ///
- static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
- ArrayRef<Expr *> PrivateVL);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
- typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
- typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
- typedef llvm::iterator_range<private_copies_const_iterator>
- private_copies_const_range;
-
- private_copies_range private_copies() {
- return private_copies_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
- private_copies_const_range private_copies() const {
- return private_copies_const_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_private;
- }
-};
-
-/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp parallel firstprivate(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
-/// with the variables 'a' and 'b'.
-///
-class OMPFirstprivateClause final
- : public OMPVarListClause<OMPFirstprivateClause>,
- private llvm::TrailingObjects<OMPFirstprivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
- LParenLoc, EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPFirstprivateClause(unsigned N)
- : OMPVarListClause<OMPFirstprivateClause>(
- OMPC_firstprivate, SourceLocation(), SourceLocation(),
- SourceLocation(), N) {}
- /// \brief 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
- /// new private variables.
- MutableArrayRef<Expr *> getPrivateCopies() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief 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
- /// private variables.
- MutableArrayRef<Expr *> getInits() {
- return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
- }
- ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the original variables.
- /// \param PrivateVL List of references to private copies with initializers.
- /// \param InitVL List of references to auto generated variables used for
- /// initialization of a single array element. Used if firstprivate variable is
- /// of array type.
- ///
- static OMPFirstprivateClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
- ArrayRef<Expr *> InitVL);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
- typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
- typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
- typedef llvm::iterator_range<private_copies_const_iterator>
- private_copies_const_range;
-
- private_copies_range private_copies() {
- return private_copies_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
- private_copies_const_range private_copies() const {
- return private_copies_const_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
-
- typedef MutableArrayRef<Expr *>::iterator inits_iterator;
- typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
- typedef llvm::iterator_range<inits_iterator> inits_range;
- typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
-
- inits_range inits() {
- return inits_range(getInits().begin(), getInits().end());
- }
- inits_const_range inits() const {
- return inits_const_range(getInits().begin(), getInits().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_firstprivate;
- }
-};
-
-/// \brief This represents clause 'lastprivate' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp simd lastprivate(a,b)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'lastprivate'
-/// with the variables 'a' and 'b'.
-class OMPLastprivateClause final
- : public OMPVarListClause<OMPLastprivateClause>,
- private llvm::TrailingObjects<OMPLastprivateClause, Expr *> {
- // There are 4 additional tail-allocated arrays at the end of the class:
- // 1. Contains list of pseudo variables with the default initialization for
- // each non-firstprivate variables. Used in codegen for initialization of
- // lastprivate copies.
- // 2. List of helper expressions for proper generation of assignment operation
- // required for lastprivate clause. This list represents private variables
- // (for arrays, single array element).
- // 3. List of helper expressions for proper generation of assignment operation
- // required for lastprivate clause. This list represents original variables
- // (for arrays, single array element).
- // 4. List of helper expressions that represents assignment operation:
- // \code
- // DstExprs = SrcExprs;
- // \endcode
- // Required for proper codegen of final assignment performed by the
- // lastprivate clause.
- //
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
- LParenLoc, EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPLastprivateClause(unsigned N)
- : OMPVarListClause<OMPLastprivateClause>(
- OMPC_lastprivate, SourceLocation(), SourceLocation(),
- SourceLocation(), N) {}
-
- /// \brief Get the list of helper expressions for initialization of private
- /// copies for lastprivate variables.
- MutableArrayRef<Expr *> getPrivateCopies() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getSourceExprs() {
- return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
- }
- ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getDestinationExprs() {
- return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getAssignmentOps() {
- return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param SrcExprs List of helper expressions for proper generation of
- /// assignment operation required for lastprivate clause. This list represents
- /// private variables (for arrays, single array element).
- /// \param DstExprs List of helper expressions for proper generation of
- /// assignment operation required for lastprivate clause. This list represents
- /// original variables (for arrays, single array element).
- /// \param AssignmentOps List of helper expressions that represents assignment
- /// operation:
- /// \code
- /// DstExprs = SrcExprs;
- /// \endcode
- /// Required for proper codegen of final assignment performed by the
- /// lastprivate clause.
- ///
- ///
- static OMPLastprivateClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
-
- /// \brief Set list of helper expressions, required for generation of private
- /// copies of original lastprivate variables.
- void setPrivateCopies(ArrayRef<Expr *> PrivateCopies);
-
- helper_expr_const_range private_copies() const {
- return helper_expr_const_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
- helper_expr_range private_copies() {
- return helper_expr_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
- helper_expr_const_range source_exprs() const {
- return helper_expr_const_range(getSourceExprs().begin(),
- getSourceExprs().end());
- }
- helper_expr_range source_exprs() {
- return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
- }
- helper_expr_const_range destination_exprs() const {
- return helper_expr_const_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_range destination_exprs() {
- return helper_expr_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_const_range assignment_ops() const {
- return helper_expr_const_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
- helper_expr_range assignment_ops() {
- return helper_expr_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_lastprivate;
- }
-};
-
-/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel shared(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'shared'
-/// with the variables 'a' and 'b'.
-///
-class OMPSharedClause final
- : public OMPVarListClause<OMPSharedClause>,
- private llvm::TrailingObjects<OMPSharedClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
- EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPSharedClause(unsigned N)
- : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N) {}
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- ///
- static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_shared;
- }
-};
-
-/// \brief This represents clause 'reduction' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp parallel reduction(+:a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'reduction'
-/// with operator '+' and the variables 'a' and 'b'.
-///
-class OMPReductionClause final
- : public OMPVarListClause<OMPReductionClause>,
- private llvm::TrailingObjects<OMPReductionClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Location of ':'.
- SourceLocation ColonLoc;
- /// \brief Nested name specifier for C++.
- NestedNameSpecifierLoc QualifierLoc;
- /// \brief Name of custom operator.
- DeclarationNameInfo NameInfo;
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param ColonLoc Location of ':'.
- /// \param N Number of the variables in the clause.
- /// \param QualifierLoc The nested-name qualifier with location information
- /// \param NameInfo The full name info for reduction identifier.
- ///
- OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo)
- : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc,
- LParenLoc, EndLoc, N),
- ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPReductionClause(unsigned N)
- : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N),
- ColonLoc(), QualifierLoc(), NameInfo() {}
-
- /// \brief Sets location of ':' symbol in clause.
- void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
- /// \brief Sets the name info for specified reduction identifier.
- void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
- /// \brief Sets the nested name specifier.
- void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getPrivates() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getLHSExprs() {
- return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
- }
- ArrayRef<const Expr *> getLHSExprs() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getRHSExprs() {
- return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getRHSExprs() const {
- return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getReductionOps() {
- return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getReductionOps() const {
- return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param VL The variables in the clause.
- /// \param QualifierLoc The nested-name qualifier with location information
- /// \param NameInfo The full name info for reduction identifier.
- /// \param Privates List of helper expressions for proper generation of
- /// private copies.
- /// \param LHSExprs List of helper expressions for proper generation of
- /// assignment operation required for copyprivate clause. This list represents
- /// LHSs of the reduction expressions.
- /// \param RHSExprs List of helper expressions for proper generation of
- /// assignment operation required for copyprivate clause. This list represents
- /// RHSs of the reduction expressions.
- /// Also, variables in these expressions are used for proper initialization of
- /// reduction copies.
- /// \param ReductionOps List of helper expressions that represents reduction
- /// expressions:
- /// \code
- /// LHSExprs binop RHSExprs;
- /// operator binop(LHSExpr, RHSExpr);
- /// <CutomReduction>(LHSExpr, RHSExpr);
- /// \endcode
- /// Required for proper codegen of final reduction operation performed by the
- /// reduction clause.
- ///
- static OMPReductionClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
- ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
- ArrayRef<Expr *> ReductionOps);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- /// \brief Gets location of ':' symbol in clause.
- SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Gets the name info for specified reduction identifier.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
- /// \brief Gets the nested name specifier.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
-
- helper_expr_const_range privates() const {
- return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
- }
- helper_expr_range privates() {
- return helper_expr_range(getPrivates().begin(), getPrivates().end());
- }
- helper_expr_const_range lhs_exprs() const {
- return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
- }
- helper_expr_range lhs_exprs() {
- return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
- }
- helper_expr_const_range rhs_exprs() const {
- return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
- }
- helper_expr_range rhs_exprs() {
- return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
- }
- helper_expr_const_range reduction_ops() const {
- return helper_expr_const_range(getReductionOps().begin(),
- getReductionOps().end());
- }
- helper_expr_range reduction_ops() {
- return helper_expr_range(getReductionOps().begin(),
- getReductionOps().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_reduction;
- }
-};
-
-/// \brief This represents clause 'linear' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp simd linear(a,b : 2)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'linear'
-/// with variables 'a', 'b' and linear step '2'.
-///
-class OMPLinearClause final
- : public OMPVarListClause<OMPLinearClause>,
- private llvm::TrailingObjects<OMPLinearClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Modifier of 'linear' clause.
- OpenMPLinearClauseKind Modifier;
- /// \brief Location of linear modifier if any.
- SourceLocation ModifierLoc;
- /// \brief Location of ':'.
- SourceLocation ColonLoc;
-
- /// \brief Sets the linear step for clause.
- void setStep(Expr *Step) { *(getFinals().end()) = Step; }
-
- /// \brief 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.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of variables.
- ///
- OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc,
- unsigned NumVars)
- : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc,
- EndLoc, NumVars),
- Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param NumVars Number of variables.
- ///
- explicit OMPLinearClause(unsigned NumVars)
- : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
- SourceLocation(), SourceLocation(),
- NumVars),
- Modifier(OMPC_LINEAR_val), ModifierLoc(), ColonLoc() {}
-
- /// \brief 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
- /// the linear variable's value on current iteration) and they are followed by
- /// NumVars final expressions (used to calculate the linear variable's
- /// value after the loop body). After these lists, there are 2 helper
- /// expressions - linear step and a helper to calculate it before the
- /// loop body (used when the linear step is not constant):
- ///
- /// { Vars[] /* in OMPVarListClause */; Privates[]; Inits[]; Updates[];
- /// Finals[]; Step; CalcStep; }
- ///
- MutableArrayRef<Expr *> getPrivates() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- MutableArrayRef<Expr *> getInits() {
- return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
- }
- ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
- }
-
- /// \brief Sets the list of update expressions for linear variables.
- MutableArrayRef<Expr *> getUpdates() {
- return MutableArrayRef<Expr *>(getInits().end(), varlist_size());
- }
- ArrayRef<const Expr *> getUpdates() const {
- return llvm::makeArrayRef(getInits().end(), varlist_size());
- }
-
- /// \brief Sets the list of final update expressions for linear variables.
- MutableArrayRef<Expr *> getFinals() {
- return MutableArrayRef<Expr *>(getUpdates().end(), varlist_size());
- }
- ArrayRef<const Expr *> getFinals() const {
- return llvm::makeArrayRef(getUpdates().end(), varlist_size());
- }
-
- /// \brief 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.
- /// \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
- /// \a Step.
- ///
- /// \param C AST Context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param Modifier Modifier of 'linear' clause.
- /// \param ModifierLoc Modifier location.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param PL List of private copies of original variables.
- /// \param IL List of initial values for the variables.
- /// \param Step Linear step.
- /// \param CalcStep Calculation of the linear step.
- static OMPLinearClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
- ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep);
-
- /// \brief Creates an empty clause with the place for \a NumVars variables.
- ///
- /// \param C AST context.
- /// \param NumVars Number of variables.
- ///
- static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
-
- /// \brief Set modifier.
- void setModifier(OpenMPLinearClauseKind Kind) { Modifier = Kind; }
- /// \brief Return modifier.
- OpenMPLinearClauseKind getModifier() const { return Modifier; }
-
- /// \brief Set modifier location.
- void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
- /// \brief Return modifier location.
- SourceLocation getModifierLoc() const { return ModifierLoc; }
-
- /// \brief Sets the location of ':'.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
- /// \brief Returns the location of ':'.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- /// \brief Returns linear step.
- Expr *getStep() { return *(getFinals().end()); }
- /// \brief Returns linear step.
- const Expr *getStep() const { return *(getFinals().end()); }
- /// \brief Returns expression to calculate linear step.
- Expr *getCalcStep() { return *(getFinals().end() + 1); }
- /// \brief Returns expression to calculate linear step.
- const Expr *getCalcStep() const { return *(getFinals().end() + 1); }
-
- /// \brief 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.
- /// \param FL List of expressions.
- void setFinals(ArrayRef<Expr *> FL);
-
- typedef MutableArrayRef<Expr *>::iterator privates_iterator;
- typedef ArrayRef<const Expr *>::iterator privates_const_iterator;
- typedef llvm::iterator_range<privates_iterator> privates_range;
- typedef llvm::iterator_range<privates_const_iterator> privates_const_range;
-
- privates_range privates() {
- return privates_range(getPrivates().begin(), getPrivates().end());
- }
- privates_const_range privates() const {
- return privates_const_range(getPrivates().begin(), getPrivates().end());
- }
-
- typedef MutableArrayRef<Expr *>::iterator inits_iterator;
- typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
- typedef llvm::iterator_range<inits_iterator> inits_range;
- typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
-
- inits_range inits() {
- return inits_range(getInits().begin(), getInits().end());
- }
- inits_const_range inits() const {
- return inits_const_range(getInits().begin(), getInits().end());
- }
-
- typedef MutableArrayRef<Expr *>::iterator updates_iterator;
- typedef ArrayRef<const Expr *>::iterator updates_const_iterator;
- typedef llvm::iterator_range<updates_iterator> updates_range;
- typedef llvm::iterator_range<updates_const_iterator> updates_const_range;
-
- updates_range updates() {
- return updates_range(getUpdates().begin(), getUpdates().end());
- }
- updates_const_range updates() const {
- return updates_const_range(getUpdates().begin(), getUpdates().end());
- }
-
- typedef MutableArrayRef<Expr *>::iterator finals_iterator;
- typedef ArrayRef<const Expr *>::iterator finals_const_iterator;
- typedef llvm::iterator_range<finals_iterator> finals_range;
- typedef llvm::iterator_range<finals_const_iterator> finals_const_range;
-
- finals_range finals() {
- return finals_range(getFinals().begin(), getFinals().end());
- }
- finals_const_range finals() const {
- return finals_const_range(getFinals().begin(), getFinals().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_linear;
- }
-};
-
-/// \brief This represents clause 'aligned' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp simd aligned(a,b : 8)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'aligned'
-/// with variables 'a', 'b' and alignment '8'.
-///
-class OMPAlignedClause final
- : public OMPVarListClause<OMPAlignedClause>,
- private llvm::TrailingObjects<OMPAlignedClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Location of ':'.
- SourceLocation ColonLoc;
-
- /// \brief Sets the alignment for clause.
- void setAlignment(Expr *A) { *varlist_end() = A; }
-
- /// \brief Build 'aligned' clause with given number of variables \a NumVars.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of variables.
- ///
- OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc,
- unsigned NumVars)
- : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
- EndLoc, NumVars),
- ColonLoc(ColonLoc) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param NumVars Number of variables.
- ///
- explicit OMPAlignedClause(unsigned NumVars)
- : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
- SourceLocation(), SourceLocation(),
- NumVars),
- ColonLoc(SourceLocation()) {}
-
-public:
- /// \brief Creates clause with a list of variables \a VL and alignment \a A.
- ///
- /// \param C AST Context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param A Alignment.
- static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation ColonLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
- Expr *A);
-
- /// \brief Creates an empty clause with the place for \a NumVars variables.
- ///
- /// \param C AST context.
- /// \param NumVars Number of variables.
- ///
- static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
-
- /// \brief Sets the location of ':'.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
- /// \brief Returns the location of ':'.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- /// \brief Returns alignment.
- Expr *getAlignment() { return *varlist_end(); }
- /// \brief Returns alignment.
- const Expr *getAlignment() const { return *varlist_end(); }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_aligned;
- }
-};
-
-/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel copyin(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'copyin'
-/// with the variables 'a' and 'b'.
-///
-class OMPCopyinClause final
- : public OMPVarListClause<OMPCopyinClause>,
- private llvm::TrailingObjects<OMPCopyinClause, Expr *> {
- // Class has 3 additional tail allocated arrays:
- // 1. List of helper expressions for proper generation of assignment operation
- // required for copyin clause. This list represents sources.
- // 2. List of helper expressions for proper generation of assignment operation
- // required for copyin clause. This list represents destinations.
- // 3. List of helper expressions that represents assignment operation:
- // \code
- // DstExprs = SrcExprs;
- // \endcode
- // Required for proper codegen of propagation of master's thread values of
- // threadprivate variables to local instances of that variables in other
- // implicit threads.
-
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
- EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPCopyinClause(unsigned N)
- : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N) {}
-
- /// \brief 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.
- MutableArrayRef<Expr *> getSourceExprs() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getDestinationExprs() {
- return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getAssignmentOps() {
- return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param SrcExprs List of helper expressions for proper generation of
- /// assignment operation required for copyin clause. This list represents
- /// sources.
- /// \param DstExprs List of helper expressions for proper generation of
- /// assignment operation required for copyin clause. This list represents
- /// destinations.
- /// \param AssignmentOps List of helper expressions that represents assignment
- /// operation:
- /// \code
- /// DstExprs = SrcExprs;
- /// \endcode
- /// Required for proper codegen of propagation of master's thread values of
- /// threadprivate variables to local instances of that variables in other
- /// implicit threads.
- ///
- static OMPCopyinClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
-
- helper_expr_const_range source_exprs() const {
- return helper_expr_const_range(getSourceExprs().begin(),
- getSourceExprs().end());
- }
- helper_expr_range source_exprs() {
- return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
- }
- helper_expr_const_range destination_exprs() const {
- return helper_expr_const_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_range destination_exprs() {
- return helper_expr_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_const_range assignment_ops() const {
- return helper_expr_const_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
- helper_expr_range assignment_ops() {
- return helper_expr_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_copyin;
- }
-};
-
-/// \brief This represents clause 'copyprivate' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp single copyprivate(a,b)
-/// \endcode
-/// In this example directive '#pragma omp single' has clause 'copyprivate'
-/// with the variables 'a' and 'b'.
-///
-class OMPCopyprivateClause final
- : public OMPVarListClause<OMPCopyprivateClause>,
- private llvm::TrailingObjects<OMPCopyprivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
- LParenLoc, EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPCopyprivateClause(unsigned N)
- : OMPVarListClause<OMPCopyprivateClause>(
- OMPC_copyprivate, SourceLocation(), SourceLocation(),
- SourceLocation(), N) {}
-
- /// \brief 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.
- MutableArrayRef<Expr *> getSourceExprs() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getDestinationExprs() {
- return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
- }
-
- /// \brief 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.
- MutableArrayRef<Expr *> getAssignmentOps() {
- return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param SrcExprs List of helper expressions for proper generation of
- /// assignment operation required for copyprivate clause. This list represents
- /// sources.
- /// \param DstExprs List of helper expressions for proper generation of
- /// assignment operation required for copyprivate clause. This list represents
- /// destinations.
- /// \param AssignmentOps List of helper expressions that represents assignment
- /// operation:
- /// \code
- /// DstExprs = SrcExprs;
- /// \endcode
- /// Required for proper codegen of final assignment performed by the
- /// copyprivate clause.
- ///
- static OMPCopyprivateClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
-
- helper_expr_const_range source_exprs() const {
- return helper_expr_const_range(getSourceExprs().begin(),
- getSourceExprs().end());
- }
- helper_expr_range source_exprs() {
- return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
- }
- helper_expr_const_range destination_exprs() const {
- return helper_expr_const_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_range destination_exprs() {
- return helper_expr_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_const_range assignment_ops() const {
- return helper_expr_const_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
- helper_expr_range assignment_ops() {
- return helper_expr_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_copyprivate;
- }
-};
-
-/// \brief 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
-/// of \a OMPExecutableDirective class and its derivatives and to use the
-/// existing infrastructure of clauses with the list of variables.
-///
-/// \code
-/// #pragma omp flush(a,b)
-/// \endcode
-/// In this example directive '#pragma omp flush' has implicit clause 'flush'
-/// with the variables 'a' and 'b'.
-///
-class OMPFlushClause final
- : public OMPVarListClause<OMPFlushClause>,
- private llvm::TrailingObjects<OMPFlushClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
- EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPFlushClause(unsigned N)
- : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N) {}
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- ///
- static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_flush;
- }
-};
-
-/// \brief This represents implicit clause 'depend' for the '#pragma omp task'
-/// directive.
-///
-/// \code
-/// #pragma omp task depend(in:a,b)
-/// \endcode
-/// In this example directive '#pragma omp task' with clause 'depend' with the
-/// variables 'a' and 'b' with dependency 'in'.
-///
-class OMPDependClause final
- : public OMPVarListClause<OMPDependClause>,
- private llvm::TrailingObjects<OMPDependClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Dependency type (one of in, out, inout).
- OpenMPDependClauseKind DepKind;
- /// \brief Dependency type location.
- SourceLocation DepLoc;
- /// \brief Colon location.
- SourceLocation ColonLoc;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc,
- EndLoc, N),
- DepKind(OMPC_DEPEND_unknown) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPDependClause(unsigned N)
- : OMPVarListClause<OMPDependClause>(OMPC_depend, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N),
- DepKind(OMPC_DEPEND_unknown) {}
- /// \brief Set dependency kind.
- void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; }
-
- /// \brief Set dependency kind and its location.
- void setDependencyLoc(SourceLocation Loc) { DepLoc = Loc; }
-
- /// \brief Set colon location.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param DepKind Dependency type.
- /// \param DepLoc Location of the dependency type.
- /// \param ColonLoc Colon location.
- /// \param VL List of references to the variables.
- ///
- static OMPDependClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
- SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL);
- /// \brief 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.
- OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
- /// \brief Get dependency type location.
- SourceLocation getDependencyLoc() const { return DepLoc; }
- /// \brief Get colon location.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_depend;
- }
-};
-
-/// \brief This represents 'device' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp target device(a)
-/// \endcode
-/// In this example directive '#pragma omp target' has clause 'device'
-/// with single expression 'a'.
-///
-class OMPDeviceClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Device number.
- Stmt *Device;
- /// \brief Set the device number.
- ///
- /// \param E Device number.
- ///
- void setDevice(Expr *E) { Device = E; }
-
-public:
- /// \brief Build 'device' clause.
- ///
- /// \param E Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPDeviceClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_device, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Device(E) {}
-
- /// \brief Build an empty clause.
- ///
- OMPDeviceClause()
- : OMPClause(OMPC_device, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Device(nullptr) {}
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return device number.
- Expr *getDevice() { return cast<Expr>(Device); }
- /// \brief Return device number.
- Expr *getDevice() const { return cast<Expr>(Device); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_device;
- }
-
- child_range children() { return child_range(&Device, &Device + 1); }
-};
-
-/// \brief This represents 'threads' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp ordered threads
-/// \endcode
-/// In this example directive '#pragma omp ordered' has simple 'threads' clause.
-///
-class OMPThreadsClause : public OMPClause {
-public:
- /// \brief 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.
- ///
- OMPThreadsClause()
- : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_threads;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'simd' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp ordered simd
-/// \endcode
-/// In this example directive '#pragma omp ordered' has simple 'simd' clause.
-///
-class OMPSIMDClause : public OMPClause {
-public:
- /// \brief 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.
- ///
- OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_simd;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents clause 'map' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp target map(a,b)
-/// \endcode
-/// In this example directive '#pragma omp target' has clause 'map'
-/// with the variables 'a' and 'b'.
-///
-class OMPMapClause final : public OMPVarListClause<OMPMapClause>,
- private llvm::TrailingObjects<OMPMapClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
-
- /// \brief Map type modifier for the 'map' clause.
- OpenMPMapClauseKind MapTypeModifier;
- /// \brief Map type for the 'map' clause.
- OpenMPMapClauseKind MapType;
- /// \brief Location of the map type.
- SourceLocation MapLoc;
- /// \brief Colon location.
- SourceLocation ColonLoc;
-
- /// \brief 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.
- ///
- /// \param T Type for the clause.
- ///
- void setMapType(OpenMPMapClauseKind T) { MapType = T; }
-
- /// \brief Set type location.
- ///
- /// \param TLoc Type location.
- ///
- void setMapLoc(SourceLocation TLoc) { MapLoc = TLoc; }
-
- /// \brief Set colon location.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param MapTypeModifier Map type modifier.
- /// \param MapType Map type.
- /// \param MapLoc Location of the map type.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier,
- OpenMPMapClauseKind MapType, SourceLocation MapLoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPMapClause>(OMPC_map, StartLoc, LParenLoc, EndLoc, N),
- MapTypeModifier(MapTypeModifier), MapType(MapType), MapLoc(MapLoc) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPMapClause(unsigned N)
- : OMPVarListClause<OMPMapClause>(OMPC_map, SourceLocation(),
- SourceLocation(), SourceLocation(), N),
- MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), MapLoc() {}
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param TypeModifier Map type modifier.
- /// \param Type Map type.
- /// \param TypeLoc Location of the map type.
- ///
- static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
- OpenMPMapClauseKind TypeModifier,
- OpenMPMapClauseKind Type, SourceLocation TypeLoc);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- /// \brief Fetches mapping kind for the clause.
- OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; }
-
- /// \brief Fetches the map type modifier for the clause.
- OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY {
- return MapTypeModifier;
- }
-
- /// \brief Fetches location of clause mapping kind.
- SourceLocation getMapLoc() const LLVM_READONLY { return MapLoc; }
-
- /// \brief Get colon location.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_map;
- }
-
- child_range children() {
- return child_range(
- reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-};
-
-/// \brief This represents 'num_teams' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp teams num_teams(n)
-/// \endcode
-/// In this example directive '#pragma omp teams' has clause 'num_teams'
-/// with single expression 'n'.
-///
-class OMPNumTeamsClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief NumTeams number.
- Stmt *NumTeams;
- /// \brief Set the NumTeams number.
- ///
- /// \param E NumTeams number.
- ///
- void setNumTeams(Expr *E) { NumTeams = E; }
-
-public:
- /// \brief Build 'num_teams' clause.
- ///
- /// \param E Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNumTeamsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_num_teams, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumTeams(E) {}
-
- /// \brief Build an empty clause.
- ///
- OMPNumTeamsClause()
- : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumTeams(nullptr) {}
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return NumTeams number.
- Expr *getNumTeams() { return cast<Expr>(NumTeams); }
- /// \brief Return NumTeams number.
- Expr *getNumTeams() const { return cast<Expr>(NumTeams); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_teams;
- }
-
- child_range children() { return child_range(&NumTeams, &NumTeams + 1); }
-};
-
-/// \brief This represents 'thread_limit' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp teams thread_limit(n)
-/// \endcode
-/// In this example directive '#pragma omp teams' has clause 'thread_limit'
-/// with single expression 'n'.
-///
-class OMPThreadLimitClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief ThreadLimit number.
- Stmt *ThreadLimit;
- /// \brief Set the ThreadLimit number.
- ///
- /// \param E ThreadLimit number.
- ///
- void setThreadLimit(Expr *E) { ThreadLimit = E; }
-
-public:
- /// \brief Build 'thread_limit' clause.
- ///
- /// \param E Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPThreadLimitClause(Expr *E, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), LParenLoc(LParenLoc),
- ThreadLimit(E) {}
-
- /// \brief Build an empty clause.
- ///
- OMPThreadLimitClause()
- : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), ThreadLimit(nullptr) {}
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return ThreadLimit number.
- Expr *getThreadLimit() { return cast<Expr>(ThreadLimit); }
- /// \brief Return ThreadLimit number.
- Expr *getThreadLimit() const { return cast<Expr>(ThreadLimit); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_thread_limit;
- }
-
- child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); }
-};
-
-/// \brief This represents 'priority' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp task priority(n)
-/// \endcode
-/// In this example directive '#pragma omp teams' has clause 'priority' with
-/// single expression 'n'.
-///
-class OMPPriorityClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Priority number.
- Stmt *Priority;
- /// \brief Set the Priority number.
- ///
- /// \param E Priority number.
- ///
- void setPriority(Expr *E) { Priority = E; }
-
-public:
- /// \brief Build 'priority' clause.
- ///
- /// \param E Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPPriorityClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_priority, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Priority(E) {}
-
- /// \brief Build an empty clause.
- ///
- OMPPriorityClause()
- : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Priority(nullptr) {}
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return Priority number.
- Expr *getPriority() { return cast<Expr>(Priority); }
- /// \brief Return Priority number.
- Expr *getPriority() const { return cast<Expr>(Priority); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_priority;
- }
-
- child_range children() { return child_range(&Priority, &Priority + 1); }
-};
-
-/// \brief This represents 'grainsize' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp taskloop grainsize(4)
-/// \endcode
-/// In this example directive '#pragma omp taskloop' has clause 'grainsize'
-/// with single expression '4'.
-///
-class OMPGrainsizeClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
- Stmt *Grainsize;
-
- /// \brief Set safelen.
- void setGrainsize(Expr *Size) { Grainsize = Size; }
-
-public:
- /// \brief Build 'grainsize' clause.
- ///
- /// \param Size Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPGrainsizeClause(Expr *Size, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_grainsize, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Grainsize(Size) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPGrainsizeClause()
- : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Grainsize(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return safe iteration space distance.
- Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_grainsize;
- }
-
- child_range children() { return child_range(&Grainsize, &Grainsize + 1); }
-};
-
-/// \brief This represents 'nogroup' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp taskloop nogroup
-/// \endcode
-/// In this example directive '#pragma omp taskloop' has 'nogroup' clause.
-///
-class OMPNogroupClause : public OMPClause {
-public:
- /// \brief 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.
- ///
- OMPNogroupClause()
- : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nogroup;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'num_tasks' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp taskloop num_tasks(4)
-/// \endcode
-/// In this example directive '#pragma omp taskloop' has clause 'num_tasks'
-/// with single expression '4'.
-///
-class OMPNumTasksClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
- Stmt *NumTasks;
-
- /// \brief Set safelen.
- void setNumTasks(Expr *Size) { NumTasks = Size; }
-
-public:
- /// \brief Build 'num_tasks' clause.
- ///
- /// \param Size Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNumTasksClause(Expr *Size, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumTasks(Size) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPNumTasksClause()
- : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumTasks(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return safe iteration space distance.
- Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_tasks;
- }
-
- child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
-};
-
-/// \brief This represents 'hint' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp critical (name) hint(6)
-/// \endcode
-/// In this example directive '#pragma omp critical' has name 'name' and clause
-/// 'hint' with argument '6'.
-///
-class OMPHintClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Hint expression of the 'hint' clause.
- Stmt *Hint;
-
- /// \brief Set hint expression.
- ///
- void setHint(Expr *H) { Hint = H; }
-
-public:
- /// \brief Build 'hint' clause with expression \a Hint.
- ///
- /// \param Hint Hint expression.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Hint(Hint) {}
-
- /// \brief Build an empty clause.
- ///
- OMPHintClause()
- : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Hint(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns number of threads.
- Expr *getHint() const { return cast_or_null<Expr>(Hint); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_hint;
- }
-
- child_range children() { return child_range(&Hint, &Hint + 1); }
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
deleted file mode 100644
index 2235c10..0000000
--- a/include/clang/AST/OperationKinds.h
+++ /dev/null
@@ -1,356 +0,0 @@
-//===- OperationKinds.h - Operation enums -----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file enumerates the different kinds of operations that can be
-// performed by various expressions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_OPERATIONKINDS_H
-#define LLVM_CLANG_AST_OPERATIONKINDS_H
-
-namespace clang {
-
-/// CastKind - The kind of operation required for a conversion.
-enum CastKind {
- /// CK_Dependent - A conversion which cannot yet be analyzed because
- /// either the expression or target type is dependent. These are
- /// created only for explicit casts; dependent ASTs aren't required
- /// to even approximately type-check.
- /// (T*) malloc(sizeof(T))
- /// reinterpret_cast<intptr_t>(A<T>::alloc());
- CK_Dependent,
-
- /// CK_BitCast - A conversion which causes a bit pattern of one type
- /// to be reinterpreted as a bit pattern of another type. Generally
- /// the operands must have equivalent size and unrelated types.
- ///
- /// The pointer conversion char* -> int* is a bitcast. A conversion
- /// from any pointer type to a C pointer type is a bitcast unless
- /// it's actually BaseToDerived or DerivedToBase. A conversion to a
- /// block pointer or ObjC pointer type is a bitcast only if the
- /// operand has the same type kind; otherwise, it's one of the
- /// specialized casts below.
- ///
- /// Vector coercions are bitcasts.
- CK_BitCast,
-
- /// CK_LValueBitCast - A conversion which reinterprets the address of
- /// an l-value as an l-value of a different kind. Used for
- /// reinterpret_casts of l-value expressions to reference types.
- /// bool b; reinterpret_cast<char&>(b) = 'a';
- CK_LValueBitCast,
-
- /// CK_LValueToRValue - A conversion which causes the extraction of
- /// an r-value from the operand gl-value. The result of an r-value
- /// conversion is always unqualified.
- CK_LValueToRValue,
-
- /// CK_NoOp - A conversion which does not affect the type other than
- /// (possibly) adding qualifiers.
- /// int -> int
- /// char** -> const char * const *
- CK_NoOp,
-
- /// CK_BaseToDerived - A conversion from a C++ class pointer/reference
- /// to a derived class pointer/reference.
- /// B *b = static_cast<B*>(a);
- CK_BaseToDerived,
-
- /// CK_DerivedToBase - A conversion from a C++ class pointer
- /// to a base class pointer.
- /// A *a = new B();
- CK_DerivedToBase,
-
- /// CK_UncheckedDerivedToBase - A conversion from a C++ class
- /// pointer/reference to a base class that can assume that the
- /// derived pointer is not null.
- /// const A &a = B();
- /// b->method_from_a();
- CK_UncheckedDerivedToBase,
-
- /// CK_Dynamic - A C++ dynamic_cast.
- CK_Dynamic,
-
- /// CK_ToUnion - The GCC cast-to-union extension.
- /// int -> union { int x; float y; }
- /// float -> union { int x; float y; }
- CK_ToUnion,
-
- /// CK_ArrayToPointerDecay - Array to pointer decay.
- /// int[10] -> int*
- /// char[5][6] -> char(*)[6]
- CK_ArrayToPointerDecay,
-
- /// CK_FunctionToPointerDecay - Function to pointer decay.
- /// void(int) -> void(*)(int)
- CK_FunctionToPointerDecay,
-
- /// CK_NullToPointer - Null pointer constant to pointer, ObjC
- /// pointer, or block pointer.
- /// (void*) 0
- /// void (^block)() = 0;
- CK_NullToPointer,
-
- /// CK_NullToMemberPointer - Null pointer constant to member pointer.
- /// int A::*mptr = 0;
- /// int (A::*fptr)(int) = nullptr;
- CK_NullToMemberPointer,
-
- /// CK_BaseToDerivedMemberPointer - Member pointer in base class to
- /// member pointer in derived class.
- /// int B::*mptr = &A::member;
- CK_BaseToDerivedMemberPointer,
-
- /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
- /// member pointer in base class.
- /// int A::*mptr = static_cast<int A::*>(&B::member);
- CK_DerivedToBaseMemberPointer,
-
- /// CK_MemberPointerToBoolean - Member pointer to boolean. A check
- /// against the null member pointer.
- CK_MemberPointerToBoolean,
-
- /// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a
- /// different kind of member pointer. C++ forbids this from
- /// crossing between function and object types, but otherwise does
- /// not restrict it. However, the only operation that is permitted
- /// on a "punned" member pointer is casting it back to the original
- /// type, which is required to be a lossless operation (although
- /// many ABIs do not guarantee this on all possible intermediate types).
- CK_ReinterpretMemberPointer,
-
- /// CK_UserDefinedConversion - Conversion using a user defined type
- /// conversion function.
- /// struct A { operator int(); }; int i = int(A());
- CK_UserDefinedConversion,
-
- /// CK_ConstructorConversion - Conversion by constructor.
- /// struct A { A(int); }; A a = A(10);
- CK_ConstructorConversion,
-
- /// CK_IntegralToPointer - Integral to pointer. A special kind of
- /// reinterpreting conversion. Applies to normal, ObjC, and block
- /// pointers.
- /// (char*) 0x1001aab0
- /// reinterpret_cast<int*>(0)
- CK_IntegralToPointer,
-
- /// CK_PointerToIntegral - Pointer to integral. A special kind of
- /// reinterpreting conversion. Applies to normal, ObjC, and block
- /// pointers.
- /// (intptr_t) "help!"
- CK_PointerToIntegral,
-
- /// CK_PointerToBoolean - Pointer to boolean conversion. A check
- /// against null. Applies to normal, ObjC, and block pointers.
- CK_PointerToBoolean,
-
- /// CK_ToVoid - Cast to void, discarding the computed value.
- /// (void) malloc(2048)
- CK_ToVoid,
-
- /// CK_VectorSplat - A conversion from an arithmetic type to a
- /// vector of that element type. Fills all elements ("splats") with
- /// the source value.
- /// __attribute__((ext_vector_type(4))) int v = 5;
- CK_VectorSplat,
-
- /// CK_IntegralCast - A cast between integral types (other than to
- /// boolean). Variously a bitcast, a truncation, a sign-extension,
- /// or a zero-extension.
- /// long l = 5;
- /// (unsigned) i
- CK_IntegralCast,
-
- /// CK_IntegralToBoolean - Integral to boolean. A check against zero.
- /// (bool) i
- CK_IntegralToBoolean,
-
- /// CK_IntegralToFloating - Integral to floating point.
- /// float f = i;
- CK_IntegralToFloating,
-
- /// CK_FloatingToIntegral - Floating point to integral. Rounds
- /// towards zero, discarding any fractional component.
- /// (int) f
- CK_FloatingToIntegral,
-
- /// CK_FloatingToBoolean - Floating point to boolean.
- /// (bool) f
- CK_FloatingToBoolean,
-
- /// CK_FloatingCast - Casting between floating types of different size.
- /// (double) f
- /// (float) ld
- CK_FloatingCast,
-
- /// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an
- /// Objective-C pointer.
- CK_CPointerToObjCPointerCast,
-
- /// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an
- /// ObjC pointer.
- CK_BlockPointerToObjCPointerCast,
-
- /// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer
- /// to a block pointer. Block-to-block casts are bitcasts.
- CK_AnyPointerToBlockPointerCast,
-
- /// \brief Converting between two Objective-C object types, which
- /// can occur when performing reference binding to an Objective-C
- /// object.
- CK_ObjCObjectLValueCast,
-
- /// \brief 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
- CK_FloatingRealToComplex,
-
- /// \brief 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
- CK_FloatingComplexToReal,
-
- /// \brief Converts a floating point complex to bool by comparing
- /// against 0+0i.
- CK_FloatingComplexToBoolean,
-
- /// \brief Converts between different floating point complex types.
- /// _Complex float -> _Complex double
- CK_FloatingComplexCast,
-
- /// \brief Converts from a floating complex to an integral complex.
- /// _Complex float -> _Complex int
- CK_FloatingComplexToIntegralComplex,
-
- /// \brief 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
- CK_IntegralRealToComplex,
-
- /// \brief Converts an integral complex to an integral real of the
- /// source's element type by discarding the imaginary component.
- /// _Complex short -> short
- CK_IntegralComplexToReal,
-
- /// \brief Converts an integral complex to bool by comparing against
- /// 0+0i.
- CK_IntegralComplexToBoolean,
-
- /// \brief Converts between different integral complex types.
- /// _Complex char -> _Complex long long
- /// _Complex unsigned int -> _Complex signed int
- CK_IntegralComplexCast,
-
- /// \brief Converts from an integral complex to a floating complex.
- /// _Complex unsigned -> _Complex float
- CK_IntegralComplexToFloatingComplex,
-
- /// \brief [ARC] Produces a retainable object pointer so that it may
- /// be consumed, e.g. by being passed to a consuming parameter.
- /// Calls objc_retain.
- CK_ARCProduceObject,
-
- /// \brief [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.
- CK_ARCConsumeObject,
-
- /// \brief [ARC] Reclaim a retainable object pointer object that may
- /// have been produced and autoreleased as part of a function return
- /// sequence.
- CK_ARCReclaimReturnedObject,
-
- /// \brief [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.
- CK_ARCExtendBlockObject,
-
- /// \brief Converts from _Atomic(T) to T.
- CK_AtomicToNonAtomic,
- /// \brief Converts from T to _Atomic(T).
- CK_NonAtomicToAtomic,
-
- /// \brief 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
- /// lambda expression to a block pointer.
- CK_CopyAndAutoreleaseBlockObject,
-
- // Convert a builtin function to a function pointer; only allowed in the
- // callee of a call expression.
- CK_BuiltinFnToFnPtr,
-
- // Convert a zero value for OpenCL event_t initialization.
- CK_ZeroToOCLEvent,
-
- // Convert a pointer to a different address space.
- CK_AddressSpaceConversion
-};
-
-static const CastKind CK_Invalid = static_cast<CastKind>(-1);
-
-enum BinaryOperatorKind {
- // Operators listed in order of precedence.
- // Note that additions to this should also update the StmtVisitor class.
- BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators.
- BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators.
- BO_Add, BO_Sub, // [C99 6.5.6] Additive operators.
- BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators.
- BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators.
- BO_EQ, BO_NE, // [C99 6.5.9] Equality operators.
- BO_And, // [C99 6.5.10] Bitwise AND operator.
- BO_Xor, // [C99 6.5.11] Bitwise XOR operator.
- BO_Or, // [C99 6.5.12] Bitwise OR operator.
- BO_LAnd, // [C99 6.5.13] Logical AND operator.
- BO_LOr, // [C99 6.5.14] Logical OR operator.
- BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators.
- BO_DivAssign, BO_RemAssign,
- BO_AddAssign, BO_SubAssign,
- BO_ShlAssign, BO_ShrAssign,
- BO_AndAssign, BO_XorAssign,
- BO_OrAssign,
- BO_Comma // [C99 6.5.17] Comma operator.
-};
-
-enum UnaryOperatorKind {
- // Note that additions to this should also update the StmtVisitor class.
- UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement
- UO_PreInc, UO_PreDec, // [C99 6.5.3.1] Prefix increment and decrement
- UO_AddrOf, UO_Deref, // [C99 6.5.3.2] Address and indirection
- UO_Plus, UO_Minus, // [C99 6.5.3.3] Unary arithmetic
- UO_Not, UO_LNot, // [C99 6.5.3.3] Unary arithmetic
- UO_Real, UO_Imag, // "__real expr"/"__imag expr" Extension.
- UO_Extension, // __extension__ marker.
- UO_Coawait // [C++ Coroutines] co_await operator
-};
-
-/// \brief The kind of bridging performed by the Objective-C bridge cast.
-enum ObjCBridgeCastKind {
- /// \brief Bridging via __bridge, which does nothing but reinterpret
- /// the bits.
- OBC_Bridge,
- /// \brief 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
- /// as a +1 C pointer.
- OBC_BridgeRetained
-};
-
-}
-
-#endif
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
deleted file mode 100644
index 8945c41..0000000
--- a/include/clang/AST/ParentMap.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===--- ParentMap.h - Mappings from Stmts to their Parents -----*- 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 ParentMap class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_PARENTMAP_H
-#define LLVM_CLANG_AST_PARENTMAP_H
-
-namespace clang {
-class Stmt;
-class Expr;
-
-class ParentMap {
- void* Impl;
-public:
- ParentMap(Stmt* ASTRoot);
- ~ParentMap();
-
- /// \brief 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);
-
- /// Manually sets the parent of \p S to \p Parent.
- ///
- /// If \p S is already in the map, this method will update the mapping.
- void setParent(const Stmt *S, const Stmt *Parent);
-
- Stmt *getParent(Stmt*) const;
- Stmt *getParentIgnoreParens(Stmt *) const;
- Stmt *getParentIgnoreParenCasts(Stmt *) const;
- Stmt *getParentIgnoreParenImpCasts(Stmt *) const;
- Stmt *getOuterParenParent(Stmt *) const;
-
- const Stmt *getParent(const Stmt* S) const {
- return getParent(const_cast<Stmt*>(S));
- }
-
- const Stmt *getParentIgnoreParens(const Stmt *S) const {
- return getParentIgnoreParens(const_cast<Stmt*>(S));
- }
-
- const Stmt *getParentIgnoreParenCasts(const Stmt *S) const {
- return getParentIgnoreParenCasts(const_cast<Stmt*>(S));
- }
-
- bool hasParent(Stmt* S) const {
- return getParent(S) != nullptr;
- }
-
- bool isConsumedExpr(Expr *E) const;
-
- bool isConsumedExpr(const Expr *E) const {
- return isConsumedExpr(const_cast<Expr*>(E));
- }
-};
-
-} // end clang namespace
-#endif
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
deleted file mode 100644
index 8ab3f617..0000000
--- a/include/clang/AST/PrettyPrinter.h
+++ /dev/null
@@ -1,175 +0,0 @@
-//===--- PrettyPrinter.h - Classes for aiding with AST printing -*- 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 PrinterHelper interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_PRETTYPRINTER_H
-#define LLVM_CLANG_AST_PRETTYPRINTER_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
-
-namespace clang {
-
-class LangOptions;
-class SourceManager;
-class Stmt;
-class TagDecl;
-
-class PrinterHelper {
-public:
- virtual ~PrinterHelper();
- virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0;
-};
-
-/// \brief Describes how types, statements, expressions, and
-/// declarations should be printed.
-struct PrintingPolicy {
- /// \brief Create a default printing policy for C.
- PrintingPolicy(const LangOptions &LO)
- : LangOpts(LO), Indentation(2), SuppressSpecifiers(false),
- SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
- SuppressUnwrittenScope(false), SuppressInitializers(false),
- ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
- SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
- Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false),
- Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
- IncludeNewlines(true), MSVCFormatting(false) { }
-
- /// \brief What language we're printing.
- LangOptions LangOpts;
-
- /// \brief The number of spaces to use to indent each line.
- unsigned Indentation : 8;
-
- /// \brief Whether we should suppress printing of the actual specifiers for
- /// the given type or declaration.
- ///
- /// This flag is only used when we are printing declarators beyond
- /// the first declarator within a declaration group. For example, given:
- ///
- /// \code
- /// const int *x, *y;
- /// \endcode
- ///
- /// SuppressSpecifiers will be false when printing the
- /// declaration for "x", so that we will print "int *x"; it will be
- /// \c true when we print "y", so that we suppress printing the
- /// "const int" type specifier and instead only print the "*y".
- bool SuppressSpecifiers : 1;
-
- /// \brief Whether type printing should skip printing the tag keyword.
- ///
- /// This is used when printing the inner type of elaborated types,
- /// (as the tag keyword is part of the elaborated type):
- ///
- /// \code
- /// struct Geometry::Point;
- /// \endcode
- bool SuppressTagKeyword : 1;
-
- /// \brief Whether type printing should skip printing the actual tag type.
- ///
- /// This is used when the caller needs to print a tag definition in front
- /// of the type, as in constructs like the following:
- ///
- /// \code
- /// typedef struct { int x, y; } Point;
- /// \endcode
- bool SuppressTag : 1;
-
- /// \brief Suppresses printing of scope specifiers.
- bool SuppressScope : 1;
-
- /// \brief Suppress printing parts of scope specifiers that don't need
- /// to be written, e.g., for inline or anonymous namespaces.
- bool SuppressUnwrittenScope : 1;
-
- /// \brief Suppress printing of variable initializers.
- ///
- /// This flag is used when printing the loop variable in a for-range
- /// statement. For example, given:
- ///
- /// \code
- /// for (auto x : coll)
- /// \endcode
- ///
- /// SuppressInitializers will be true when printing "auto x", so that the
- /// internal initializer constructed for x will not be printed.
- bool SuppressInitializers : 1;
-
- /// \brief Whether we should print the sizes of constant array expressions
- /// as written in the sources.
- ///
- /// This flag determines whether array types declared as
- ///
- /// \code
- /// int a[4+10*10];
- /// char a[] = "A string";
- /// \endcode
- ///
- /// will be printed as written or as follows:
- ///
- /// \code
- /// int a[104];
- /// char a[9] = "A string";
- /// \endcode
- bool ConstantArraySizeAsWritten : 1;
-
- /// \brief When printing an anonymous tag name, also print the location of
- /// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just
- /// prints "(anonymous)" for the name.
- bool AnonymousTagLocations : 1;
-
- /// \brief When true, suppress printing of the __strong lifetime qualifier in
- /// ARC.
- unsigned SuppressStrongLifetime : 1;
-
- /// \brief When true, suppress printing of lifetime qualifier in
- /// ARC.
- unsigned SuppressLifetimeQualifiers : 1;
-
- /// \brief Whether we can use 'bool' rather than '_Bool', even if the language
- /// doesn't actually have 'bool' (because, e.g., it is defined as a macro).
- unsigned Bool : 1;
-
- /// \brief Provide a 'terse' output.
- ///
- /// For example, in this mode we don't print function bodies, class members,
- /// declarations inside namespaces etc. Effectively, this should print
- /// only the requested declaration.
- unsigned TerseOutput : 1;
-
- /// \brief When true, do certain refinement needed for producing proper
- /// declaration tag; such as, do not print attributes attached to the declaration.
- ///
- unsigned PolishForDeclaration : 1;
-
- /// \brief When true, print the half-precision floating-point type as 'half'
- /// instead of '__fp16'
- unsigned Half : 1;
-
- /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in
- /// Microsoft mode when wchar_t is not available.
- unsigned MSWChar : 1;
-
- /// \brief When true, include newlines after statements like "break", etc.
- unsigned IncludeNewlines : 1;
-
- /// \brief Use whitespace and punctuation like MSVC does. In particular, this
- /// prints anonymous namespaces as `anonymous namespace' and does not insert
- /// spaces after template arguments.
- bool MSVCFormatting : 1;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
deleted file mode 100644
index 2e005dd..0000000
--- a/include/clang/AST/RawCommentList.h
+++ /dev/null
@@ -1,203 +0,0 @@
-//===--- RawCommentList.h - Classes for processing raw comments -*- 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_AST_RAWCOMMENTLIST_H
-#define LLVM_CLANG_AST_RAWCOMMENTLIST_H
-
-#include "clang/Basic/CommentOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/ArrayRef.h"
-
-namespace clang {
-
-class ASTContext;
-class ASTReader;
-class Decl;
-class Preprocessor;
-
-namespace comments {
- class FullComment;
-} // end namespace comments
-
-class RawComment {
-public:
- enum CommentKind {
- RCK_Invalid, ///< Invalid comment
- RCK_OrdinaryBCPL, ///< Any normal BCPL comments
- RCK_OrdinaryC, ///< Any normal C comment
- RCK_BCPLSlash, ///< \code /// stuff \endcode
- RCK_BCPLExcl, ///< \code //! stuff \endcode
- RCK_JavaDoc, ///< \code /** stuff */ \endcode
- RCK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc
- RCK_Merged ///< Two or more documentation comments merged together
- };
-
- RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { }
-
- RawComment(const SourceManager &SourceMgr, SourceRange SR,
- bool Merged, bool ParseAllComments);
-
- CommentKind getKind() const LLVM_READONLY {
- return (CommentKind) Kind;
- }
-
- bool isInvalid() const LLVM_READONLY {
- return Kind == RCK_Invalid;
- }
-
- bool isMerged() const LLVM_READONLY {
- return Kind == RCK_Merged;
- }
-
- /// Is this comment attached to any declaration?
- bool isAttached() const LLVM_READONLY {
- return IsAttached;
- }
-
- void setAttached() {
- IsAttached = true;
- }
-
- /// Returns true if it is a comment that should be put after a member:
- /// \code ///< stuff \endcode
- /// \code //!< stuff \endcode
- /// \code /**< stuff */ \endcode
- /// \code /*!< stuff */ \endcode
- bool isTrailingComment() const LLVM_READONLY {
- assert(isDocumentation());
- return IsTrailingComment;
- }
-
- /// Returns true if it is a probable typo:
- /// \code //< stuff \endcode
- /// \code /*< stuff */ \endcode
- bool isAlmostTrailingComment() const LLVM_READONLY {
- return IsAlmostTrailingComment;
- }
-
- /// Returns true if this comment is not a documentation comment.
- bool isOrdinary() const LLVM_READONLY {
- return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) &&
- !ParseAllComments;
- }
-
- /// Returns true if this comment any kind of a documentation comment.
- bool isDocumentation() const LLVM_READONLY {
- 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)
- return RawText;
-
- RawText = getRawTextSlow(SourceMgr);
- RawTextValid = true;
- return RawText;
- }
-
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
-
- const char *getBriefText(const ASTContext &Context) const {
- if (BriefTextValid)
- return BriefText;
-
- return extractBriefText(Context);
- }
-
- /// Parse the comment, assuming it is attached to decl \c D.
- comments::FullComment *parse(const ASTContext &Context,
- const Preprocessor *PP, const Decl *D) const;
-
-private:
- SourceRange Range;
-
- mutable StringRef RawText;
- mutable const char *BriefText;
-
- mutable bool RawTextValid : 1; ///< True if RawText is valid
- mutable bool BriefTextValid : 1; ///< True if BriefText is valid
-
- unsigned Kind : 3;
-
- /// True if comment is attached to a declaration in ASTContext.
- bool IsAttached : 1;
-
- 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.
- RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment,
- bool IsAlmostTrailingComment,
- bool ParseAllComments) :
- Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K),
- IsAttached(false), IsTrailingComment(IsTrailingComment),
- IsAlmostTrailingComment(IsAlmostTrailingComment),
- ParseAllComments(ParseAllComments)
- { }
-
- StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
-
- const char *extractBriefText(const ASTContext &Context) const;
-
- friend class ASTReader;
-};
-
-/// \brief Compare comments' source locations.
-template<>
-class BeforeThanCompare<RawComment> {
- const SourceManager &SM;
-
-public:
- explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
-
- bool operator()(const RawComment &LHS, const RawComment &RHS) {
- return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart());
- }
-
- bool operator()(const RawComment *LHS, const RawComment *RHS) {
- return operator()(*LHS, *RHS);
- }
-};
-
-/// \brief 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);
-
- ArrayRef<RawComment *> getComments() const {
- return Comments;
- }
-
-private:
- SourceManager &SourceMgr;
- std::vector<RawComment *> Comments;
-
- void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
-
- friend class ASTReader;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
deleted file mode 100644
index 667f235..0000000
--- a/include/clang/AST/RecordLayout.h
+++ /dev/null
@@ -1,315 +0,0 @@
-//===--- RecordLayout.h - Layout information for a struct/union -*- 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 RecordLayout interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_RECORDLAYOUT_H
-#define LLVM_CLANG_AST_RECORDLAYOUT_H
-
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclCXX.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
- class ASTContext;
- class FieldDecl;
- class RecordDecl;
- class CXXRecordDecl;
-
-/// ASTRecordLayout -
-/// This class contains layout information for one RecordDecl,
-/// which is a struct/union/class. The decl represented must be a definition,
-/// not a forward declaration.
-/// This class is also used to contain layout information for one
-/// ObjCInterfaceDecl. FIXME - Find appropriate name.
-/// These objects are managed by ASTContext.
-class ASTRecordLayout {
-public:
- struct VBaseInfo {
- /// The offset to this virtual base in the complete-object layout
- /// of this class.
- CharUnits VBaseOffset;
-
- private:
- /// Whether this virtual base requires a vtordisp field in the
- /// Microsoft ABI. These fields are required for certain operations
- /// in constructors and destructors.
- bool HasVtorDisp;
-
- public:
- bool hasVtorDisp() const { return HasVtorDisp; }
-
- VBaseInfo() : HasVtorDisp(false) {}
-
- VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) :
- VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
- };
-
- typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>
- VBaseOffsetsMapTy;
-
-private:
- /// Size - Size of record in characters.
- CharUnits Size;
-
- /// DataSize - Size of record in characters without tail padding.
- CharUnits DataSize;
-
- // Alignment - Alignment of record in characters.
- CharUnits Alignment;
-
- /// RequiredAlignment - The required alignment of the object. In the MS-ABI
- /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
- CharUnits RequiredAlignment;
-
- /// FieldOffsets - Array of field offsets in bits.
- uint64_t *FieldOffsets;
-
- // FieldCount - Number of fields.
- unsigned FieldCount;
-
- /// CXXRecordLayoutInfo - Contains C++ specific layout information.
- struct CXXRecordLayoutInfo {
- /// NonVirtualSize - The non-virtual size (in chars) of an object, which is
- /// the size of the object without virtual bases.
- CharUnits NonVirtualSize;
-
- /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
- /// which is the alignment of the object without virtual bases.
- CharUnits NonVirtualAlignment;
-
- /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
- /// (either a base or a member). Will be zero if the class doesn't contain
- /// any empty subobjects.
- CharUnits SizeOfLargestEmptySubobject;
-
- /// VBPtrOffset - Virtual base table offset (Microsoft-only).
- CharUnits VBPtrOffset;
-
- /// HasOwnVFPtr - Does this class provide a virtual function table
- /// (vtable in Itanium, vftbl in Microsoft) that is independent from
- /// its base classes?
- bool HasOwnVFPtr : 1;
-
- /// HasVFPtr - Does this class have a vftable that could be extended by
- /// a derived class. The class may have inherited this pointer from
- /// a primary base class.
- bool HasExtendableVFPtr : 1;
-
- /// HasZeroSizedSubObject - True if this class contains a zero sized member
- /// or base or a base with a zero sized member or base. Only used for
- /// MS-ABI.
- bool HasZeroSizedSubObject : 1;
-
- /// \brief True if this class is zero sized or first base is zero sized or
- /// has this property. Only used for MS-ABI.
- bool LeadsWithZeroSizedBase : 1;
-
- /// PrimaryBase - The primary base info for this record.
- llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
-
- /// BaseSharingVBPtr - The base we share vbptr with.
- const CXXRecordDecl *BaseSharingVBPtr;
-
- /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
- typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
-
- /// BaseOffsets - Contains a map from base classes to their offset.
- BaseOffsetsMapTy BaseOffsets;
-
- /// VBaseOffsets - Contains a map from vbase classes to their offset.
- VBaseOffsetsMapTy VBaseOffsets;
- };
-
- /// CXXInfo - If the record layout is for a C++ record, this will have
- /// C++ specific information about the record.
- CXXRecordLayoutInfo *CXXInfo;
-
- friend class ASTContext;
-
- ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
- CharUnits requiredAlignment,
- CharUnits datasize, const uint64_t *fieldoffsets,
- unsigned fieldcount);
-
- // Constructor for C++ records.
- typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
- ASTRecordLayout(const ASTContext &Ctx,
- CharUnits size, CharUnits alignment,
- CharUnits requiredAlignment,
- bool hasOwnVFPtr, bool hasExtendableVFPtr,
- CharUnits vbptroffset,
- CharUnits datasize,
- const uint64_t *fieldoffsets, unsigned fieldcount,
- CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
- CharUnits SizeOfLargestEmptySubobject,
- const CXXRecordDecl *PrimaryBase,
- bool IsPrimaryBaseVirtual,
- const CXXRecordDecl *BaseSharingVBPtr,
- bool HasZeroSizedSubObject,
- bool LeadsWithZeroSizedBase,
- const BaseOffsetsMapTy& BaseOffsets,
- const VBaseOffsetsMapTy& VBaseOffsets);
-
- ~ASTRecordLayout() = default;
-
- void Destroy(ASTContext &Ctx);
-
- ASTRecordLayout(const ASTRecordLayout &) = delete;
- void operator=(const ASTRecordLayout &) = delete;
-public:
-
- /// getAlignment - Get the record alignment in characters.
- CharUnits getAlignment() const { return Alignment; }
-
- /// getSize - Get the record size in characters.
- CharUnits getSize() const { return Size; }
-
- /// getFieldCount - Get the number of fields in the layout.
- unsigned getFieldCount() const { return FieldCount; }
-
- /// getFieldOffset - Get the offset of the given field index, in
- /// bits.
- uint64_t getFieldOffset(unsigned FieldNo) const {
- assert (FieldNo < FieldCount && "Invalid Field No");
- return FieldOffsets[FieldNo];
- }
-
- /// getDataSize() - Get the record data size, which is the record size
- /// without tail padding, in characters.
- CharUnits getDataSize() const {
- return DataSize;
- }
-
- /// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
- /// which is the size of the object without virtual bases.
- CharUnits getNonVirtualSize() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->NonVirtualSize;
- }
-
- /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
- /// which is the alignment of the object without virtual bases.
- CharUnits getNonVirtualAlignment() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->NonVirtualAlignment;
- }
-
- /// getPrimaryBase - Get the primary base for this record.
- const CXXRecordDecl *getPrimaryBase() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->PrimaryBase.getPointer();
- }
-
- /// isPrimaryBaseVirtual - Get whether the primary base for this record
- /// is virtual or not.
- bool isPrimaryBaseVirtual() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->PrimaryBase.getInt();
- }
-
- /// getBaseClassOffset - Get the offset, in chars, for the given base class.
- CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
-
- return CXXInfo->BaseOffsets[Base];
- }
-
- /// getVBaseClassOffset - Get the offset, in chars, for the given base class.
- CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
-
- return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
- }
-
- CharUnits getSizeOfLargestEmptySubobject() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->SizeOfLargestEmptySubobject;
- }
-
- /// hasOwnVFPtr - Does this class provide its own virtual-function
- /// table pointer, rather than inheriting one from a primary base
- /// class? If so, it is at offset zero.
- ///
- /// This implies that the ABI has no primary base class, meaning
- /// that it has no base classes that are suitable under the conditions
- /// of the ABI.
- bool hasOwnVFPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->HasOwnVFPtr;
- }
-
- /// hasVFPtr - Does this class have a virtual function table pointer
- /// that can be extended by a derived class? This is synonymous with
- /// this class having a VFPtr at offset zero.
- bool hasExtendableVFPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->HasExtendableVFPtr;
- }
-
- /// hasOwnVBPtr - Does this class provide its own virtual-base
- /// table pointer, rather than inheriting one from a primary base
- /// class?
- ///
- /// This implies that the ABI has no primary base class, meaning
- /// that it has no base classes that are suitable under the conditions
- /// of the ABI.
- bool hasOwnVBPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return hasVBPtr() && !CXXInfo->BaseSharingVBPtr;
- }
-
- /// hasVBPtr - Does this class have a virtual function table pointer.
- bool hasVBPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return !CXXInfo->VBPtrOffset.isNegative();
- }
-
- CharUnits getRequiredAlignment() const {
- return RequiredAlignment;
- }
-
- bool hasZeroSizedSubObject() const {
- return CXXInfo && CXXInfo->HasZeroSizedSubObject;
- }
-
- bool leadsWithZeroSizedBase() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->LeadsWithZeroSizedBase;
- }
-
- /// getVBPtrOffset - Get the offset for virtual base table pointer.
- /// This is only meaningful with the Microsoft ABI.
- CharUnits getVBPtrOffset() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->VBPtrOffset;
- }
-
- const CXXRecordDecl *getBaseSharingVBPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->BaseSharingVBPtr;
- }
-
- const VBaseOffsetsMapTy &getVBaseOffsetsMap() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->VBaseOffsets;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
deleted file mode 100644
index e6f7583..0000000
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ /dev/null
@@ -1,2805 +0,0 @@
-//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the RecursiveASTVisitor interface, which recursively
-// traverses the entire AST.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
-#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
-
-#include <type_traits>
-
-#include "clang/AST/Attr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprOpenMP.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-#include "clang/AST/StmtOpenMP.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeLoc.h"
-
-// The following three macros are used for meta programming. The code
-// using them is responsible for defining macro OPERATOR().
-
-// All unary operators.
-#define UNARYOP_LIST() \
- OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \
- OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \
- OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \
- OPERATOR(Extension) OPERATOR(Coawait)
-
-// All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
- OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
- OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
- OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
- OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \
- OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
-
-// All compound assign operators.
-#define CAO_LIST() \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
- OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
-
-namespace clang {
-
-// A helper macro to implement short-circuiting when recursing. It
-// invokes CALL_EXPR, which must be a method call, on the derived
-// object (s.t. a user of RecursiveASTVisitor can override the method
-// in CALL_EXPR).
-#define TRY_TO(CALL_EXPR) \
- do { \
- if (!getDerived().CALL_EXPR) \
- return false; \
- } while (0)
-
-/// \brief A class that does preorder depth-first traversal on the
-/// entire Clang AST and visits each node.
-///
-/// This class performs three distinct tasks:
-/// 1. traverse the AST (i.e. go to each node);
-/// 2. at a given node, walk up the class hierarchy, starting from
-/// the node's dynamic type, until the top-most class (e.g. Stmt,
-/// Decl, or Type) is reached.
-/// 3. given a (node, class) combination, where 'class' is some base
-/// class of the dynamic type of 'node', call a user-overridable
-/// function to actually visit the node.
-///
-/// These tasks are done by three groups of methods, respectively:
-/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
-/// for traversing an AST rooted at x. This method simply
-/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
-/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
-/// then recursively visits the child nodes of x.
-/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
-/// similarly.
-/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
-/// any child node of x. Instead, it first calls WalkUpFromBar(x)
-/// where Bar is the direct parent class of Foo (unless Foo has
-/// no parent), and then calls VisitFoo(x) (see the next list item).
-/// 3. VisitFoo(Foo *x) does task #3.
-///
-/// These three method groups are tiered (Traverse* > WalkUpFrom* >
-/// Visit*). A method (e.g. Traverse*) may call methods from the same
-/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
-/// It may not call methods from a higher tier.
-///
-/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
-/// is Foo's super class) before calling VisitFoo(), the result is
-/// that the Visit*() methods for a given node are called in the
-/// top-down order (e.g. for a node of type NamespaceDecl, the order will
-/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
-///
-/// This scheme guarantees that all Visit*() calls for the same AST
-/// node are grouped together. In other words, Visit*() methods for
-/// different nodes are never interleaved.
-///
-/// Clients of this visitor should subclass the visitor (providing
-/// themselves as the template argument, using the curiously recurring
-/// template pattern) and override any of the Traverse*, WalkUpFrom*,
-/// and Visit* methods for declarations, types, statements,
-/// expressions, or other AST nodes where the visitor should customize
-/// behavior. Most users only need to override Visit*. Advanced
-/// users may override Traverse* and WalkUpFrom* to implement custom
-/// traversal strategies. Returning false from one of these overridden
-/// functions will abort the entire traversal.
-///
-/// By default, this visitor tries to visit every part of the explicit
-/// source code exactly once. The default policy towards templates
-/// is to descend into the 'pattern' class or function body, not any
-/// explicit or implicit instantiations. Explicit specializations
-/// are still visited, and the patterns of partial specializations
-/// are visited separately. This behavior can be changed by
-/// overriding shouldVisitTemplateInstantiations() in the derived class
-/// to return true, in which case all known implicit and explicit
-/// instantiations will be visited at the same time as the pattern
-/// from which they were produced.
-template <typename Derived> class RecursiveASTVisitor {
-public:
- /// A queue used for performing data recursion over statements.
- /// Parameters involving this type are used to implement data
- /// recursion over Stmts and Exprs within this class, and should
- /// typically not be explicitly specified by derived classes.
- typedef SmallVectorImpl<Stmt *> DataRecursionQueue;
-
- /// \brief Return a reference to the derived class.
- Derived &getDerived() { return *static_cast<Derived *>(this); }
-
- /// \brief Return whether this visitor should recurse into
- /// template instantiations.
- bool shouldVisitTemplateInstantiations() const { return false; }
-
- /// \brief Return whether this visitor should recurse into the types of
- /// TypeLocs.
- bool shouldWalkTypesOfTypeLocs() const { return true; }
-
- /// \brief Return whether this visitor should recurse into implicit
- /// code, e.g., implicit constructors and destructors.
- bool shouldVisitImplicitCode() const { return false; }
-
- /// \brief Recursively visit a statement or expression, by
- /// dispatching to Traverse*() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is nullptr).
- bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
-
- /// \brief Recursively visit a type, by dispatching to
- /// Traverse*Type() based on the argument's getTypeClass() property.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type).
- bool TraverseType(QualType T);
-
- /// \brief Recursively visit a type with location, by dispatching to
- /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type location).
- bool TraverseTypeLoc(TypeLoc TL);
-
- /// \brief Recursively visit an attribute, by dispatching to
- /// Traverse*Attr() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type location).
- bool TraverseAttr(Attr *At);
-
- /// \brief Recursively visit a declaration, by dispatching to
- /// Traverse*Decl() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is NULL).
- bool TraverseDecl(Decl *D);
-
- /// \brief Recursively visit a C++ nested-name-specifier.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
-
- /// \brief Recursively visit a C++ nested-name-specifier with location
- /// information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
-
- /// \brief Recursively visit a name with its location information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
-
- /// \brief Recursively visit a template name and dispatch to the
- /// appropriate method.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseTemplateName(TemplateName Template);
-
- /// \brief Recursively visit a template argument and dispatch to the
- /// appropriate method for the argument type.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- // FIXME: migrate callers to TemplateArgumentLoc instead.
- bool TraverseTemplateArgument(const TemplateArgument &Arg);
-
- /// \brief Recursively visit a template argument location and dispatch to the
- /// appropriate method for the argument type.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
-
- /// \brief Recursively visit a set of template arguments.
- /// This can be overridden by a subclass, but it's not expected that
- /// will be needed -- this visitor always dispatches to another.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
- bool TraverseTemplateArguments(const TemplateArgument *Args,
- unsigned NumArgs);
-
- /// \brief Recursively visit a constructor initializer. This
- /// automatically dispatches to another visitor for the initializer
- /// expression, but not for the name of the initializer, so may
- /// be overridden for clients that need access to the name.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
-
- /// \brief Recursively visit a lambda capture.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
-
- /// \brief Recursively visit the body of a lambda expression.
- ///
- /// This provides a hook for visitors that need more context when visiting
- /// \c LE->getBody().
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaBody(LambdaExpr *LE, DataRecursionQueue *Queue = nullptr);
-
- /// \brief Recursively visit the syntactic or semantic form of an
- /// initialization list.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseSynOrSemInitListExpr(InitListExpr *S,
- DataRecursionQueue *Queue = nullptr);
-
- // ---- Methods on Attrs ----
-
- // \brief Visit an attribute.
- bool VisitAttr(Attr *A) { return true; }
-
-// Declare Traverse* and empty Visit* for all Attr classes.
-#define ATTR_VISITOR_DECLS_ONLY
-#include "clang/AST/AttrVisitor.inc"
-#undef ATTR_VISITOR_DECLS_ONLY
-
-// ---- Methods on Stmts ----
-
-private:
- template<typename T, typename U>
- struct has_same_member_pointer_type : std::false_type {};
- template<typename T, typename U, typename R, typename... P>
- struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
- : std::true_type {};
-
- // Traverse the given statement. If the most-derived traverse function takes a
- // data recursion queue, pass it on; otherwise, discard it. Note that the
- // first branch of this conditional must compile whether or not the derived
- // class can take a queue, so if we're taking the second arm, make the first
- // arm call our function rather than the derived class version.
-#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \
- (has_same_member_pointer_type<decltype( \
- &RecursiveASTVisitor::Traverse##NAME), \
- decltype(&Derived::Traverse##NAME)>::value \
- ? static_cast<typename std::conditional< \
- has_same_member_pointer_type< \
- decltype(&RecursiveASTVisitor::Traverse##NAME), \
- decltype(&Derived::Traverse##NAME)>::value, \
- Derived &, RecursiveASTVisitor &>::type>(*this) \
- .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \
- : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
-
-// Try to traverse the given statement, or enqueue it if we're performing data
-// recursion in the middle of traversing another statement. Can only be called
-// from within a DEF_TRAVERSE_STMT body or similar context.
-#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \
- do { \
- if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
- return false; \
- } while (0)
-
-public:
-// Declare Traverse*() for all concrete Stmt classes.
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr);
-#include "clang/AST/StmtNodes.inc"
- // The above header #undefs ABSTRACT_STMT and STMT upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
- bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
- bool VisitStmt(Stmt *S) { return true; }
-#define STMT(CLASS, PARENT) \
- bool WalkUpFrom##CLASS(CLASS *S) { \
- TRY_TO(WalkUpFrom##PARENT(S)); \
- TRY_TO(Visit##CLASS(S)); \
- return true; \
- } \
- bool Visit##CLASS(CLASS *S) { return true; }
-#include "clang/AST/StmtNodes.inc"
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
-// operator methods. Unary operators are not classes in themselves
-// (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME) \
- bool TraverseUnary##NAME(UnaryOperator *S, \
- DataRecursionQueue *Queue = nullptr) { \
- TRY_TO(WalkUpFromUnary##NAME(S)); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \
- return true; \
- } \
- bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnaryOperator(S)); \
- TRY_TO(VisitUnary##NAME(S)); \
- return true; \
- } \
- bool VisitUnary##NAME(UnaryOperator *S) { return true; }
-
- UNARYOP_LIST()
-#undef OPERATOR
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
-// operator methods. Binary operators are not classes in themselves
-// (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
- bool TraverseBin##NAME(BINOP_TYPE *S, DataRecursionQueue *Queue = nullptr) { \
- TRY_TO(WalkUpFromBin##NAME(S)); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \
- return true; \
- } \
- bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
- TRY_TO(VisitBin##NAME(S)); \
- return true; \
- } \
- bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
-
-#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
- BINOP_LIST()
-#undef OPERATOR
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
-// assignment methods. Compound assignment operators are not
-// classes in themselves (they're all opcodes in
-// CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
- GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
-
- CAO_LIST()
-#undef OPERATOR
-#undef GENERAL_BINOP_FALLBACK
-
-// ---- Methods on Types ----
-// FIXME: revamp to take TypeLoc's rather than Types.
-
-// Declare Traverse*() for all concrete Type classes.
-#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
-#include "clang/AST/TypeNodes.def"
- // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Type classes.
- bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
- bool VisitType(Type *T) { return true; }
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
- TRY_TO(WalkUpFrom##BASE(T)); \
- TRY_TO(Visit##CLASS##Type(T)); \
- return true; \
- } \
- bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
-#include "clang/AST/TypeNodes.def"
-
-// ---- Methods on TypeLocs ----
-// FIXME: this currently just calls the matching Type methods
-
-// Declare Traverse*() for all concrete TypeLoc classes.
-#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
-#include "clang/AST/TypeLocNodes.def"
- // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
- bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
- bool VisitTypeLoc(TypeLoc TL) { return true; }
-
- // QualifiedTypeLoc and UnqualTypeLoc are not declared in
- // TypeNodes.def and thus need to be handled specially.
- bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
- return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
- }
- bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
- bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
- return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
- }
- bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
-
-// Note that BASE includes trailing 'Type' which CLASS doesn't.
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
- TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
- TRY_TO(Visit##CLASS##TypeLoc(TL)); \
- return true; \
- } \
- bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
-#include "clang/AST/TypeNodes.def"
-
-// ---- Methods on Decls ----
-
-// Declare Traverse*() for all concrete Decl classes.
-#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
-#include "clang/AST/DeclNodes.inc"
- // The above header #undefs ABSTRACT_DECL and DECL upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
- bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
- bool VisitDecl(Decl *D) { return true; }
-#define DECL(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
- TRY_TO(WalkUpFrom##BASE(D)); \
- TRY_TO(Visit##CLASS##Decl(D)); \
- return true; \
- } \
- bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
-#include "clang/AST/DeclNodes.inc"
-
-private:
- // These are helper methods used by more than one Traverse* method.
- bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
-#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
- bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
- DEF_TRAVERSE_TMPL_INST(Class)
- DEF_TRAVERSE_TMPL_INST(Var)
- DEF_TRAVERSE_TMPL_INST(Function)
-#undef DEF_TRAVERSE_TMPL_INST
- bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
- unsigned Count);
- bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
- bool TraverseRecordHelper(RecordDecl *D);
- bool TraverseCXXRecordHelper(CXXRecordDecl *D);
- bool TraverseDeclaratorHelper(DeclaratorDecl *D);
- bool TraverseDeclContextHelper(DeclContext *DC);
- bool TraverseFunctionHelper(FunctionDecl *D);
- bool TraverseVarHelper(VarDecl *D);
- bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
- bool TraverseOMPLoopDirective(OMPLoopDirective *S);
- bool TraverseOMPClause(OMPClause *C);
-#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
-#include "clang/Basic/OpenMPKinds.def"
- /// \brief Process clauses with list of variables.
- template <typename T> bool VisitOMPClauseList(T *Node);
-
- bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
-};
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
- DataRecursionQueue *Queue) {
-#define DISPATCH_STMT(NAME, CLASS, VAR) \
- return TRAVERSE_STMT_BASE(NAME, CLASS, VAR, Queue);
-
- // If we have a binary expr, dispatch to the subcode of the binop. A smart
- // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
- // below.
- if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
- switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: \
- DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
-
- BINOP_LIST()
-#undef OPERATOR
-#undef BINOP_LIST
-
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
- DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
-
- CAO_LIST()
-#undef OPERATOR
-#undef CAO_LIST
- }
- } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
- switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: \
- DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
-
- UNARYOP_LIST()
-#undef OPERATOR
-#undef UNARYOP_LIST
- }
- }
-
- // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
- switch (S->getStmtClass()) {
- case Stmt::NoStmtClass:
- break;
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: \
- DISPATCH_STMT(CLASS, CLASS, S);
-#include "clang/AST/StmtNodes.inc"
- }
-
- return true;
-}
-
-#undef DISPATCH_STMT
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S,
- DataRecursionQueue *Queue) {
- if (!S)
- return true;
-
- if (Queue) {
- Queue->push_back(S);
- return true;
- }
-
- SmallVector<Stmt *, 8> LocalQueue;
- LocalQueue.push_back(S);
-
- while (!LocalQueue.empty()) {
- Stmt *CurrS = LocalQueue.pop_back_val();
-
- size_t N = LocalQueue.size();
- TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
- // Process new children in the order they were added.
- std::reverse(LocalQueue.begin() + N, LocalQueue.end());
- }
-
- return true;
-}
-
-#define DISPATCH(NAME, CLASS, VAR) \
- return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
- if (T.isNull())
- return true;
-
- switch (T->getTypeClass()) {
-#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- case Type::CLASS: \
- DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
-#include "clang/AST/TypeNodes.def"
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
- if (TL.isNull())
- return true;
-
- switch (TL.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- case TypeLoc::CLASS: \
- return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
-#include "clang/AST/TypeLocNodes.def"
- }
-
- return true;
-}
-
-// Define the Traverse*Attr(Attr* A) methods
-#define VISITORCLASS RecursiveASTVisitor
-#include "clang/AST/AttrVisitor.inc"
-#undef VISITORCLASS
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
- if (!D)
- return true;
-
- // As a syntax visitor, by default we want to ignore declarations for
- // implicit declarations (ones not typed explicitly by the user).
- if (!getDerived().shouldVisitImplicitCode() && D->isImplicit())
- return true;
-
- switch (D->getKind()) {
-#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- case Decl::CLASS: \
- if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
- return false; \
- break;
-#include "clang/AST/DeclNodes.inc"
- }
-
- // Visit any attributes attached to this declaration.
- for (auto *I : D->attrs()) {
- if (!getDerived().TraverseAttr(I))
- return false;
- }
- return true;
-}
-
-#undef DISPATCH
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
- if (!NNS)
- return true;
-
- if (NNS->getPrefix())
- TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- return true;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
- NestedNameSpecifierLoc NNS) {
- if (!NNS)
- return true;
-
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
-
- switch (NNS.getNestedNameSpecifier()->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- return true;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
- break;
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
- DeclarationNameInfo NameInfo) {
- switch (NameInfo.getName().getNameKind()) {
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
- TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
-
- break;
-
- case DeclarationName::Identifier:
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXOperatorName:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXUsingDirective:
- break;
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
- if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
- TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
- else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
- TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
- const TemplateArgument &Arg) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- return true;
-
- case TemplateArgument::Type:
- return getDerived().TraverseType(Arg.getAsType());
-
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
-
- case TemplateArgument::Expression:
- return getDerived().TraverseStmt(Arg.getAsExpr());
-
- case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
- }
-
- return true;
-}
-
-// FIXME: no template name location?
-// FIXME: no source locations for a template argument pack?
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
- const TemplateArgumentLoc &ArgLoc) {
- const TemplateArgument &Arg = ArgLoc.getArgument();
-
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- return true;
-
- case TemplateArgument::Type: {
- // FIXME: how can TSI ever be NULL?
- if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
- return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
- else
- return getDerived().TraverseType(Arg.getAsType());
- }
-
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- if (ArgLoc.getTemplateQualifierLoc())
- TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
- ArgLoc.getTemplateQualifierLoc()));
- return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
-
- case TemplateArgument::Expression:
- return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
-
- case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- const TemplateArgument *Args, unsigned NumArgs) {
- for (unsigned I = 0; I != NumArgs; ++I) {
- TRY_TO(TraverseTemplateArgument(Args[I]));
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
- CXXCtorInitializer *Init) {
- if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-
- if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
- TRY_TO(TraverseStmt(Init->getInit()));
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
- const LambdaCapture *C) {
- if (LE->isInitCapture(C))
- TRY_TO(TraverseDecl(C->getCapturedVar()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(
- LambdaExpr *LE, DataRecursionQueue *Queue) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(LE->getBody());
- return true;
-}
-
-// ----------------- Type traversal -----------------
-
-// This macro makes available a variable T, the passed-in type.
-#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
- TRY_TO(WalkUpFrom##TYPE(T)); \
- { CODE; } \
- return true; \
- }
-
-DEF_TRAVERSE_TYPE(BuiltinType, {})
-
-DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(BlockPointerType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(LValueReferenceType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(RValueReferenceType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseType(QualType(T->getClass(), 0)));
- TRY_TO(TraverseType(T->getPointeeType()));
-})
-
-DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-
-DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-
-DEF_TRAVERSE_TYPE(ConstantArrayType,
- { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(IncompleteArrayType,
- { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(VariableArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- TRY_TO(TraverseStmt(T->getSizeExpr()));
-})
-
-DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
-})
-
-DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- TRY_TO(TraverseType(T->getElementType()));
-})
-
-DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(FunctionNoProtoType,
- { TRY_TO(TraverseType(T->getReturnType())); })
-
-DEF_TRAVERSE_TYPE(FunctionProtoType, {
- TRY_TO(TraverseType(T->getReturnType()));
-
- for (const auto &A : T->param_types()) {
- TRY_TO(TraverseType(A));
- }
-
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
-
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO(TraverseStmt(NE));
-})
-
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
-DEF_TRAVERSE_TYPE(TypedefType, {})
-
-DEF_TRAVERSE_TYPE(TypeOfExprType,
- { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-
-DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
-
-DEF_TRAVERSE_TYPE(DecltypeType,
- { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-
-DEF_TRAVERSE_TYPE(UnaryTransformType, {
- TRY_TO(TraverseType(T->getBaseType()));
- TRY_TO(TraverseType(T->getUnderlyingType()));
-})
-
-DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
-
-DEF_TRAVERSE_TYPE(RecordType, {})
-DEF_TRAVERSE_TYPE(EnumType, {})
-DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
-
-DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-})
-
-DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
-
-DEF_TRAVERSE_TYPE(AttributedType,
- { TRY_TO(TraverseType(T->getModifiedType())); })
-
-DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
-
-DEF_TRAVERSE_TYPE(ElaboratedType, {
- if (T->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
- TRY_TO(TraverseType(T->getNamedType()));
-})
-
-DEF_TRAVERSE_TYPE(DependentNameType,
- { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
-
-DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-})
-
-DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
-
-DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
-
-DEF_TRAVERSE_TYPE(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (T->getBaseType().getTypePtr() != T)
- TRY_TO(TraverseType(T->getBaseType()));
- for (auto typeArg : T->getTypeArgsAsWritten()) {
- TRY_TO(TraverseType(typeArg));
- }
-})
-
-DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
-
-#undef DEF_TRAVERSE_TYPE
-
-// ----------------- TypeLoc traversal -----------------
-
-// This macro makes available a variable TL, the passed-in TypeLoc.
-// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
-// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
-// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
-// continue to work.
-#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
- { CODE; } \
- return true; \
- }
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
- // Move this over to the 'main' typeloc tree. Note that this is a
- // move -- we pretend that we were really looking at the unqualified
- // typeloc all along -- rather than a recursion, so we don't follow
- // the normal CRTP plan of going through
- // getDerived().TraverseTypeLoc. If we did, we'd be traversing
- // twice for the same type (once as a QualifiedTypeLoc version of
- // the type, once as an UnqualifiedTypeLoc version of the type),
- // which in effect means we'd call VisitTypeLoc twice with the
- // 'same' type. This solves that problem, at the cost of never
- // seeing the qualified version of the type (unless the client
- // subclasses TraverseQualifiedTypeLoc themselves). It's not a
- // perfect solution. A perfect solution probably requires making
- // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
- // wrapper around Type* -- rather than being its own class in the
- // type hierarchy.
- return TraverseTypeLoc(TL.getUnqualifiedLoc());
-}
-
-DEF_TRAVERSE_TYPELOC(BuiltinType, {})
-
-// FIXME: ComplexTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(ComplexType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-})
-
-DEF_TRAVERSE_TYPELOC(PointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-DEF_TRAVERSE_TYPELOC(BlockPointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-DEF_TRAVERSE_TYPELOC(LValueReferenceType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-DEF_TRAVERSE_TYPELOC(RValueReferenceType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-// FIXME: location of base class?
-// We traverse this in the type case as well, but how is it not reached through
-// the pointee type?
-DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(AdjustedType,
- { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-
-DEF_TRAVERSE_TYPELOC(DecayedType,
- { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
- // This isn't available for ArrayType, but is for the ArrayTypeLoc.
- TRY_TO(TraverseStmt(TL.getSizeExpr()));
- return true;
-}
-
-DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
-})
-
-DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
-})
-
-DEF_TRAVERSE_TYPELOC(VariableArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
-})
-
-DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
-})
-
-// FIXME: order? why not size expr first?
-// FIXME: base VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-})
-
-// FIXME: VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(VectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-})
-
-// FIXME: size and attributes
-// FIXME: base VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(ExtVectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-})
-
-DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
- { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
-
-// FIXME: location of exception specifications (attributes?)
-DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
-
- const FunctionProtoType *T = TL.getTypePtr();
-
- for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
- if (TL.getParam(I)) {
- TRY_TO(TraverseDecl(TL.getParam(I)));
- } else if (I < T->getNumParams()) {
- TRY_TO(TraverseType(T->getParamType(I)));
- }
- }
-
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
-
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO(TraverseStmt(NE));
-})
-
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
-DEF_TRAVERSE_TYPELOC(TypedefType, {})
-
-DEF_TRAVERSE_TYPELOC(TypeOfExprType,
- { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
-
-DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
-})
-
-// FIXME: location of underlying expr
-DEF_TRAVERSE_TYPELOC(DecltypeType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
-})
-
-DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(AutoType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
-})
-
-DEF_TRAVERSE_TYPELOC(RecordType, {})
-DEF_TRAVERSE_TYPELOC(EnumType, {})
-DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
-
-// FIXME: use the loc for the template name?
-DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
-})
-
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
-
-DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
-
-DEF_TRAVERSE_TYPELOC(AttributedType,
- { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
-
-DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
-
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
-})
-
-DEF_TRAVERSE_TYPELOC(PackExpansionType,
- { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
-
-DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
-
-DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
- TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
- for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
- TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
-
-#undef DEF_TRAVERSE_TYPELOC
-
-// ----------------- Decl traversal -----------------
-//
-// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
-// the children that come from the DeclContext associated with it.
-// Therefore each Traverse* only needs to worry about children other
-// than those.
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
- if (!DC)
- return true;
-
- for (auto *Child : DC->decls()) {
- // BlockDecls and CapturedDecls are traversed through BlockExprs and
- // CapturedStmts respectively.
- if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
- TRY_TO(TraverseDecl(Child));
- }
-
- return true;
-}
-
-// This macro makes available a variable D, the passed-in decl.
-#define DEF_TRAVERSE_DECL(DECL, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
- TRY_TO(WalkUpFrom##DECL(D)); \
- { CODE; } \
- TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
- return true; \
- }
-
-DEF_TRAVERSE_DECL(AccessSpecDecl, {})
-
-DEF_TRAVERSE_DECL(BlockDecl, {
- if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- TRY_TO(TraverseStmt(D->getBody()));
- for (const auto &I : D->captures()) {
- if (I.hasCopyExpr()) {
- TRY_TO(TraverseStmt(I.getCopyExpr()));
- }
- }
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
-})
-
-DEF_TRAVERSE_DECL(CapturedDecl, {
- TRY_TO(TraverseStmt(D->getBody()));
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
-})
-
-DEF_TRAVERSE_DECL(EmptyDecl, {})
-
-DEF_TRAVERSE_DECL(FileScopeAsmDecl,
- { TRY_TO(TraverseStmt(D->getAsmString())); })
-
-DEF_TRAVERSE_DECL(ImportDecl, {})
-
-DEF_TRAVERSE_DECL(FriendDecl, {
- // Friend is either decl or a type.
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
-})
-
-DEF_TRAVERSE_DECL(FriendTemplateDecl, {
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
- TemplateParameterList *TPL = D->getTemplateParameterList(I);
- for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
- ITPL != ETPL; ++ITPL) {
- TRY_TO(TraverseDecl(*ITPL));
- }
- }
-})
-
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
- TRY_TO(TraverseDecl(D->getSpecialization()));
-
- if (D->hasExplicitTemplateArgs()) {
- const TemplateArgumentListInfo &args = D->templateArgs();
- TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(),
- args.size()));
- }
-})
-
-DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
-
-DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
- })
-
-DEF_TRAVERSE_DECL(StaticAssertDecl, {
- TRY_TO(TraverseStmt(D->getAssertExpr()));
- TRY_TO(TraverseStmt(D->getMessage()));
-})
-
-DEF_TRAVERSE_DECL(
- TranslationUnitDecl,
- {// Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
-
-DEF_TRAVERSE_DECL(ExternCContextDecl, {})
-
-DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-
- // We shouldn't traverse an aliased namespace, since it will be
- // defined (and, therefore, traversed) somewhere else.
- //
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
-})
-
-DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
- })
-
-DEF_TRAVERSE_DECL(
- NamespaceDecl,
- {// Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
-
-DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
- if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
- for (auto typeParam : *typeParamList) {
- TRY_TO(TraverseObjCTypeParamDecl(typeParam));
- }
- }
-})
-
-DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
- if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
- for (auto typeParam : *typeParamList) {
- TRY_TO(TraverseObjCTypeParamDecl(typeParam));
- }
- }
-
- if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
- TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
- }
-})
-
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCMethodDecl, {
- if (D->getReturnTypeSourceInfo()) {
- TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
- }
- for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody()));
- }
- return true;
-})
-
-DEF_TRAVERSE_DECL(ObjCTypeParamDecl, {
- if (D->hasExplicitBound()) {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
- }
-})
-
-DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
- if (D->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- else
- TRY_TO(TraverseType(D->getType()));
- return true;
-})
-
-DEF_TRAVERSE_DECL(UsingDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-})
-
-DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-})
-
-DEF_TRAVERSE_DECL(UsingShadowDecl, {})
-
-DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
- for (auto *I : D->varlists()) {
- TRY_TO(TraverseStmt(I));
- }
-})
-
-// A helper method for TemplateDecl's children.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
- TemplateParameterList *TPL) {
- if (TPL) {
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- ClassTemplateDecl *D) {
- for (auto *SD : D->specializations()) {
- for (auto *RD : SD->redecls()) {
- // We don't want to visit injected-class-names in this traversal.
- if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
- continue;
-
- switch (
- cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
- // Visit the implicit instantiations with the requested pattern.
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- TRY_TO(TraverseDecl(RD));
- break;
-
- // We don't need to do anything on an explicit instantiation
- // or explicit specialization because there will be an explicit
- // node for it elsewhere.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- VarTemplateDecl *D) {
- for (auto *SD : D->specializations()) {
- for (auto *RD : SD->redecls()) {
- switch (
- cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- TRY_TO(TraverseDecl(RD));
- break;
-
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
-
- return true;
-}
-
-// A helper method for traversing the instantiations of a
-// function while skipping its specializations.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- FunctionTemplateDecl *D) {
- for (auto *FD : D->specializations()) {
- for (auto *RD : FD->redecls()) {
- switch (RD->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- // We don't know what kind of FunctionDecl this is.
- TRY_TO(TraverseDecl(RD));
- break;
-
- // FIXME: For now traverse explicit instantiations here. Change that
- // once they are represented as dedicated nodes in the AST.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- TRY_TO(TraverseDecl(RD));
- break;
-
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
-
- return true;
-}
-
-// This macro unifies the traversal of class, variable and function
-// template declarations.
-#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
- TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
- \
- /* By default, we do not traverse the instantiations of \
- class templates since they do not appear in the user code. The \
- following code optionally traverses them. \
- \
- We only traverse the class instantiations when we see the canonical \
- declaration of the template, to ensure we only visit them once. */ \
- if (getDerived().shouldVisitTemplateInstantiations() && \
- D == D->getCanonicalDecl()) \
- TRY_TO(TraverseTemplateInstantiations(D)); \
- \
- /* Note that getInstantiatedFromMemberTemplate() is just a link \
- from a template instantiation back to the template from which \
- it was instantiated, and thus should not be traversed. */ \
- })
-
-DEF_TRAVERSE_TMPL_DECL(Class)
-DEF_TRAVERSE_TMPL_DECL(Var)
-DEF_TRAVERSE_TMPL_DECL(Function)
-
-DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
- // D is the "T" in something like
- // template <template <typename> class T> class container { };
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
- TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
- }
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-})
-
-DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-})
-
-DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
- // D is the "T" in something like "template<typename T> class vector;"
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_DECL(TypedefDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the typedef, not something that was written in the
- // source.
-})
-
-DEF_TRAVERSE_DECL(TypeAliasDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
-})
-
-DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-})
-
-DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
- // A dependent using declaration which was marked with 'typename'.
- // template<class T> class A : public B<T> { using typename B<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the
- // source.
-})
-
-DEF_TRAVERSE_DECL(EnumDecl, {
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // The enumerators are already traversed by
- // decls_begin()/decls_end().
-})
-
-// Helper methods for RecordDecl and its children.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the source.
-
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
- if (!TraverseRecordHelper(D))
- return false;
- if (D->isCompleteDefinition()) {
- for (const auto &I : D->bases()) {
- TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
- }
- // We don't traverse the friends or the conversions, as they are
- // already in decls_begin()/decls_end().
- }
- return true;
-}
-
-DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
-
-DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
-
-#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
- /* For implicit instantiations ("set<int> x;"), we don't want to \
- recurse at all, since the instatiated template isn't written in \
- the source code anywhere. (Note the instatiated *type* -- \
- set<int> -- is written, and will still get a callback of \
- TemplateSpecializationType). For explicit instantiations \
- ("template set<int>;"), we do need a callback, since this \
- is the only callback that's made for this instantiation. \
- We use getTypeAsWritten() to distinguish. */ \
- if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
- \
- if (!getDerived().shouldVisitTemplateInstantiations() && \
- D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \
- /* Returning from here skips traversing the \
- declaration context of the *TemplateSpecializationDecl \
- (embedded in the DEF_TRAVERSE_DECL() macro) \
- which contains the instantiated members of the template. */ \
- return true; \
- })
-
-DEF_TRAVERSE_TMPL_SPEC_DECL(Class)
-DEF_TRAVERSE_TMPL_SPEC_DECL(Var)
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
- const TemplateArgumentLoc *TAL, unsigned Count) {
- for (unsigned I = 0; I < Count; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
- }
- return true;
-}
-
-#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
- /* The partial specialization. */ \
- if (TemplateParameterList *TPL = D->getTemplateParameters()) { \
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
- I != E; ++I) { \
- TRY_TO(TraverseDecl(*I)); \
- } \
- } \
- /* The args that remains unspecialized. */ \
- TRY_TO(TraverseTemplateArgumentLocsHelper( \
- D->getTemplateArgsAsWritten()->getTemplateArgs(), \
- D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
- \
- /* Don't need the *TemplatePartialSpecializationHelper, even \
- though that's our parent class -- we already visit all the \
- template args here. */ \
- TRY_TO(Traverse##DECLKIND##Helper(D)); \
- \
- /* Instantiations will have been visited with the primary template. */ \
- })
-
-DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
-DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)
-
-DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
-
-DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
- // Like UnresolvedUsingTypenameDecl, but without the 'typename':
- // template <class T> Class A : public Base<T> { using Base<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-})
-
-DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- if (D->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- else
- TRY_TO(TraverseType(D->getType()));
- return true;
-}
-
-DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
-
-DEF_TRAVERSE_DECL(FieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- else if (D->hasInClassInitializer())
- TRY_TO(TraverseStmt(D->getInClassInitializer()));
-})
-
-DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
-})
-
-DEF_TRAVERSE_DECL(ObjCIvarDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
-})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-
- // If we're an explicit template specialization, iterate over the
- // template args that were explicitly specified. If we were doing
- // this in typing order, we'd do it between the return type and
- // the function args, but both are handled by the FunctionTypeLoc
- // above, so we have to choose one side. I've decided to do before.
- if (const FunctionTemplateSpecializationInfo *FTSI =
- D->getTemplateSpecializationInfo()) {
- if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
- FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
- // A specialization might not have explicit template arguments if it has
- // a templated return type and concrete arguments.
- if (const ASTTemplateArgumentListInfo *TALI =
- FTSI->TemplateArgumentsAsWritten) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
- TALI->NumTemplateArgs));
- }
- }
- }
-
- // Visit the function type itself, which can be either
- // FunctionNoProtoType or FunctionProtoType, or a typedef. This
- // also covers the return type and the function parameters,
- // including exception specifications.
- if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
- } else if (getDerived().shouldVisitImplicitCode()) {
- // Visit parameter variable declarations of the implicit function
- // if the traverser is visiting implicit code. Parameter variable
- // declarations do not have valid TypeSourceInfo, so to visit them
- // we need to traverse the declarations explicitly.
- for (FunctionDecl::param_const_iterator I = D->param_begin(),
- E = D->param_end();
- I != E; ++I)
- TRY_TO(TraverseDecl(*I));
- }
-
- if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
- // Constructor initializers.
- for (auto *I : Ctor->inits()) {
- TRY_TO(TraverseConstructorInitializer(I));
- }
- }
-
- if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody())); // Function body.
- }
- return true;
-}
-
-DEF_TRAVERSE_DECL(FunctionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-DEF_TRAVERSE_DECL(CXXMethodDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-DEF_TRAVERSE_DECL(CXXConstructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-// CXXConversionDecl is the declaration of a type conversion operator.
-// It's not a cast expression.
-DEF_TRAVERSE_DECL(CXXConversionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-DEF_TRAVERSE_DECL(CXXDestructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
- TRY_TO(TraverseDeclaratorHelper(D));
- // Default params are taken care of when we traverse the ParmVarDecl.
- if (!isa<ParmVarDecl>(D) &&
- (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
- TRY_TO(TraverseStmt(D->getInit()));
- return true;
-}
-
-DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
-
-DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
-
-DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
- // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseStmt(D->getDefaultArgument()));
-})
-
-DEF_TRAVERSE_DECL(ParmVarDecl, {
- TRY_TO(TraverseVarHelper(D));
-
- if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
-
- if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getDefaultArg()));
-})
-
-#undef DEF_TRAVERSE_DECL
-
-// ----------------- Stmt traversal -----------------
-//
-// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
-// over the children defined in children() (every stmt defines these,
-// though sometimes the range is empty). Each individual Traverse*
-// method only needs to worry about children other than those. To see
-// what children() does for a given class, see, e.g.,
-// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
-
-// This macro makes available a variable S, the passed-in stmt.
-#define DEF_TRAVERSE_STMT(STMT, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##STMT( \
- STMT *S, DataRecursionQueue *Queue) { \
- TRY_TO(WalkUpFrom##STMT(S)); \
- { CODE; } \
- for (Stmt *SubStmt : S->children()) { \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
- } \
- return true; \
- }
-
-DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
- for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
- }
- // children() iterates over inputExpr and outputExpr.
-})
-
-DEF_TRAVERSE_STMT(
- MSAsmStmt,
- {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
- // added this needs to be implemented.
- })
-
-DEF_TRAVERSE_STMT(CXXCatchStmt, {
- TRY_TO(TraverseDecl(S->getExceptionDecl()));
- // children() iterates over the handler block.
-})
-
-DEF_TRAVERSE_STMT(DeclStmt, {
- for (auto *I : S->decls()) {
- TRY_TO(TraverseDecl(I));
- }
- // Suppress the default iteration over children() by
- // returning. Here's why: A DeclStmt looks like 'type var [=
- // initializer]'. The decls above already traverse over the
- // initializers, so we don't have to do it again (which
- // children() would do).
- return true;
-})
-
-// These non-expr stmts (most of them), do not need any action except
-// iterating over the children.
-DEF_TRAVERSE_STMT(BreakStmt, {})
-DEF_TRAVERSE_STMT(CXXTryStmt, {})
-DEF_TRAVERSE_STMT(CaseStmt, {})
-DEF_TRAVERSE_STMT(CompoundStmt, {})
-DEF_TRAVERSE_STMT(ContinueStmt, {})
-DEF_TRAVERSE_STMT(DefaultStmt, {})
-DEF_TRAVERSE_STMT(DoStmt, {})
-DEF_TRAVERSE_STMT(ForStmt, {})
-DEF_TRAVERSE_STMT(GotoStmt, {})
-DEF_TRAVERSE_STMT(IfStmt, {})
-DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
-DEF_TRAVERSE_STMT(LabelStmt, {})
-DEF_TRAVERSE_STMT(AttributedStmt, {})
-DEF_TRAVERSE_STMT(NullStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
-DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
-DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
-DEF_TRAVERSE_STMT(CXXForRangeStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
- // Visit everything else only if shouldVisitImplicitCode().
- return true;
- }
-})
-DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
-})
-DEF_TRAVERSE_STMT(ReturnStmt, {})
-DEF_TRAVERSE_STMT(SwitchStmt, {})
-DEF_TRAVERSE_STMT(WhileStmt, {})
-
-DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(DeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
-})
-
-DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(MemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
-})
-
-DEF_TRAVERSE_STMT(
- ImplicitCastExpr,
- {// We don't traverse the cast type, as it's not written in the
- // source code.
- })
-
-DEF_TRAVERSE_STMT(CStyleCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXConstCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
- InitListExpr *S, DataRecursionQueue *Queue) {
- if (S) {
- TRY_TO(WalkUpFromInitListExpr(S));
- // All we need are the default actions. FIXME: use a helper function.
- for (Stmt *SubStmt : S->children()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt);
- }
- }
- return true;
-}
-
-// This method is called once for each pair of syntactic and semantic
-// InitListExpr, and it traverses the subtrees defined by the two forms. This
-// may cause some of the children to be visited twice, if they appear both in
-// the syntactic and the semantic form.
-//
-// There is no guarantee about which form \p S takes when this method is called.
-DEF_TRAVERSE_STMT(InitListExpr, {
- TRY_TO(TraverseSynOrSemInitListExpr(
- S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
- TRY_TO(TraverseSynOrSemInitListExpr(
- S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
- return true;
-})
-
-// GenericSelectionExpr is a special case because the types and expressions
-// are interleaved. We also need to watch out for null types (default
-// generic associations).
-DEF_TRAVERSE_STMT(GenericSelectionExpr, {
- TRY_TO(TraverseStmt(S->getControllingExpr()));
- for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
- if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
- TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i));
- }
- return true;
-})
-
-// PseudoObjectExpr is a special case because of the weirdness with
-// syntactic expressions and opaque values.
-DEF_TRAVERSE_STMT(PseudoObjectExpr, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
- for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
- e = S->semantics_end();
- i != e; ++i) {
- Expr *sub = *i;
- if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
- sub = OVE->getSourceExpr();
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(sub);
- }
- return true;
-})
-
-DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
- // This is called for code like 'return T()' where T is a built-in
- // (i.e. non-class) type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXNewExpr, {
- // The child-iterator will pick up the other arguments.
- TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(OffsetOfExpr, {
- // The child-iterator will pick up the expression representing
- // the field.
- // FIMXE: for code like offsetof(Foo, a.b.c), should we get
- // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isArgumentType())
- TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXTypeidExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-})
-
-DEF_TRAVERSE_STMT(MSPropertySubscriptExpr, {})
-
-DEF_TRAVERSE_STMT(CXXUuidofExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(TypeTraitExpr, {
- for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
- TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(ExpressionTraitExpr,
- { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
-
-DEF_TRAVERSE_STMT(VAArgExpr, {
- // The child-iterator will pick up the expression argument.
- TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
- // This is called for code like 'return T()' where T is a class type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-
-// Walk only the visible parts of lambda expressions.
-DEF_TRAVERSE_STMT(LambdaExpr, {
- for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
- CEnd = S->explicit_capture_end();
- C != CEnd; ++C) {
- TRY_TO(TraverseLambdaCapture(S, C));
- }
-
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
-
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
- } else {
- if (S->hasExplicitParameters()) {
- // Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
- TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else if (S->hasExplicitResultType()) {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
- }
-
- auto *T = Proto.getTypePtr();
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
-
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
- }
-
- return TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue);
-})
-
-DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
- // This is called for code like 'T()', where T is a template argument.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-
-// These expressions all might take explicit template arguments.
-// We traverse those if so. FIXME: implement these.
-DEF_TRAVERSE_STMT(CXXConstructExpr, {})
-DEF_TRAVERSE_STMT(CallExpr, {})
-DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
-
-// These exprs (most of them), do not need any action except iterating
-// over the children.
-DEF_TRAVERSE_STMT(AddrLabelExpr, {})
-DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
-DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
-DEF_TRAVERSE_STMT(BlockExpr, {
- TRY_TO(TraverseDecl(S->getBlockDecl()));
- return true; // no child statements to loop through.
-})
-DEF_TRAVERSE_STMT(ChooseExpr, {})
-DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
-DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
-DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
-DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
-DEF_TRAVERSE_STMT(ExprWithCleanups, {})
-DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
-DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
-DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
- TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
- if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
- TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(CXXThisExpr, {})
-DEF_TRAVERSE_STMT(CXXThrowExpr, {})
-DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
-DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
-DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
-DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
-DEF_TRAVERSE_STMT(GNUNullExpr, {})
-DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
-DEF_TRAVERSE_STMT(NoInitExpr, {})
-DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
-DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
- if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
-DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
-DEF_TRAVERSE_STMT(ObjCMessageExpr, {
- if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
-DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
-DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
-DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
-DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
-DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ParenExpr, {})
-DEF_TRAVERSE_STMT(ParenListExpr, {})
-DEF_TRAVERSE_STMT(PredefinedExpr, {})
-DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
-DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
-DEF_TRAVERSE_STMT(StmtExpr, {})
-DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(SEHTryStmt, {})
-DEF_TRAVERSE_STMT(SEHExceptStmt, {})
-DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
-DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
-DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
-
-DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
-DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
-DEF_TRAVERSE_STMT(TypoExpr, {})
-DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
-
-// These operators (all of them) do not need any action except
-// iterating over the children.
-DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
-DEF_TRAVERSE_STMT(ConditionalOperator, {})
-DEF_TRAVERSE_STMT(UnaryOperator, {})
-DEF_TRAVERSE_STMT(BinaryOperator, {})
-DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
-DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
-DEF_TRAVERSE_STMT(PackExpansionExpr, {})
-DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
-DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
-DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
-DEF_TRAVERSE_STMT(CXXFoldExpr, {})
-DEF_TRAVERSE_STMT(AtomicExpr, {})
-
-// For coroutines expressions, traverse either the operand
-// as written or the implied calls, depending on what the
-// derived class requests.
-DEF_TRAVERSE_STMT(CoroutineBodyStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
- return true;
- }
-})
-DEF_TRAVERSE_STMT(CoreturnStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- return true;
- }
-})
-DEF_TRAVERSE_STMT(CoawaitExpr, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- return true;
- }
-})
-DEF_TRAVERSE_STMT(CoyieldExpr, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- return true;
- }
-})
-
-// These literals (all of them) do not need any action.
-DEF_TRAVERSE_STMT(IntegerLiteral, {})
-DEF_TRAVERSE_STMT(CharacterLiteral, {})
-DEF_TRAVERSE_STMT(FloatingLiteral, {})
-DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
-DEF_TRAVERSE_STMT(StringLiteral, {})
-DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
-DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
-DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
-DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
-
-// Traverse OpenCL: AsType, Convert.
-DEF_TRAVERSE_STMT(AsTypeExpr, {})
-
-// OpenMP directives.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
- OMPExecutableDirective *S) {
- for (auto *C : S->clauses()) {
- TRY_TO(TraverseOMPClause(C));
- }
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
- return TraverseOMPExecutableDirective(S);
-}
-
-DEF_TRAVERSE_STMT(OMPParallelDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPSectionsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPSectionDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPSingleDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPMasterDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPCriticalDirective, {
- TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
- TRY_TO(TraverseOMPExecutableDirective(S));
-})
-
-DEF_TRAVERSE_STMT(OMPParallelForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPBarrierDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPCancelDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPFlushDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPOrderedDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPAtomicDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTargetDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTargetDataDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTeamsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPDistributeDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-// OpenMP clauses.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
- if (!C)
- return true;
- switch (C->getClauseKind()) {
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_##Name: \
- TRY_TO(Visit##Class(static_cast<Class *>(C))); \
- break;
-#include "clang/Basic/OpenMPKinds.def"
- case OMPC_threadprivate:
- case OMPC_unknown:
- break;
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
- TRY_TO(TraverseStmt(C->getCondition()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
- TRY_TO(TraverseStmt(C->getCondition()));
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
- TRY_TO(TraverseStmt(C->getNumThreads()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
- TRY_TO(TraverseStmt(C->getSafelen()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
- TRY_TO(TraverseStmt(C->getSimdlen()));
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
- TRY_TO(TraverseStmt(C->getNumForLoops()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
- TRY_TO(TraverseStmt(C->getChunkSize()));
- TRY_TO(TraverseStmt(C->getHelperChunkSize()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) {
- TRY_TO(TraverseStmt(C->getNumForLoops()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) {
- return true;
-}
-
-template <typename Derived>
-template <typename T>
-bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
- for (auto *E : Node->varlists()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
- OMPFirstprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->inits()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
- OMPLastprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
- TRY_TO(TraverseStmt(C->getStep()));
- TRY_TO(TraverseStmt(C->getCalcStep()));
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->privates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->inits()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->updates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->finals()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
- TRY_TO(TraverseStmt(C->getAlignment()));
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
- OMPCopyprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
- TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->privates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->lhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->rhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->reduction_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) {
- TRY_TO(TraverseStmt(C->getDevice()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
- OMPNumTeamsClause *C) {
- TRY_TO(TraverseStmt(C->getNumTeams()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
- OMPThreadLimitClause *C) {
- TRY_TO(TraverseStmt(C->getThreadLimit()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause(
- OMPPriorityClause *C) {
- TRY_TO(TraverseStmt(C->getPriority()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause(
- OMPGrainsizeClause *C) {
- TRY_TO(TraverseStmt(C->getGrainsize()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause(
- OMPNumTasksClause *C) {
- TRY_TO(TraverseStmt(C->getNumTasks()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) {
- TRY_TO(TraverseStmt(C->getHint()));
- return true;
-}
-
-// FIXME: look at the following tricky-seeming exprs to see if we
-// need to recurse on anything. These are ones that have methods
-// returning decls or qualtypes or nestednamespecifier -- though I'm
-// not sure if they own them -- or just seemed very complicated, or
-// had lots of sub-types to explore.
-//
-// VisitOverloadExpr and its children: recurse on template args? etc?
-
-// FIXME: go through all the stmts and exprs again, and see which of them
-// create new types, and recurse on the types (TypeLocs?) of those.
-// Candidates:
-//
-// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
-// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
-// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
-// Every class that has getQualifier.
-
-#undef DEF_TRAVERSE_STMT
-#undef TRAVERSE_STMT
-#undef TRAVERSE_STMT_BASE
-
-#undef TRY_TO
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
deleted file mode 100644
index eaa22f8..0000000
--- a/include/clang/AST/Redeclarable.h
+++ /dev/null
@@ -1,285 +0,0 @@
-//===-- Redeclarable.h - Base for Decls that can be redeclared -*- 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 Redeclarable interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_REDECLARABLE_H
-#define LLVM_CLANG_AST_REDECLARABLE_H
-
-#include "clang/AST/ExternalASTSource.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Casting.h"
-#include <iterator>
-
-namespace clang {
-class ASTContext;
-
-/// \brief Provides common interface for the Decls that can be redeclared.
-template<typename decl_type>
-class Redeclarable {
-protected:
- class DeclLink {
- /// A pointer to a known latest declaration, either statically known or
- /// generationally updated as decls are added by an external source.
- typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
- &ExternalASTSource::CompleteRedeclChain>
- KnownLatest;
-
- /// We store a pointer to the ASTContext in the UninitializedLatest
- /// pointer, but to avoid circular type dependencies when we steal the low
- /// bits of this pointer, we use a raw void* here.
- typedef const void *UninitializedLatest;
-
- typedef Decl *Previous;
-
- /// A pointer to either an uninitialized latest declaration (where either
- /// we've not yet set the previous decl or there isn't one), or to a known
- /// previous declaration.
- typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
-
- mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
-
- 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))) {}
-
- bool NextIsPrevious() const {
- return Next.is<NotKnownLatest>() &&
- // FIXME: 'template' is required on the next line due to an
- // apparent clang bug.
- Next.get<NotKnownLatest>().template is<Previous>();
- }
-
- bool NextIsLatest() const { return !NextIsPrevious(); }
-
- decl_type *getNext(const decl_type *D) const {
- if (Next.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Next.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 *>(
- NKL.get<UninitializedLatest>()),
- const_cast<decl_type *>(D));
- }
-
- return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
- }
-
- void setPrevious(decl_type *D) {
- assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
- Next = 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 *>(
- NKL.get<UninitializedLatest>()),
- D);
- } else {
- auto Latest = Next.get<KnownLatest>();
- Latest.set(D);
- Next = Latest;
- }
- }
-
- void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
-
- Decl *getLatestNotUpdated() const {
- assert(NextIsLatest() && "expected a canonical decl");
- if (Next.is<NotKnownLatest>())
- return nullptr;
- return Next.get<KnownLatest>().getNotUpdated();
- }
- };
-
- static DeclLink PreviousDeclLink(decl_type *D) {
- return DeclLink(DeclLink::PreviousLink, D);
- }
-
- static DeclLink LatestDeclLink(const ASTContext &Ctx) {
- return DeclLink(DeclLink::LatestLink, Ctx);
- }
-
- /// \brief 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
- /// declaration and Link points to the latest declaration. For example:
- ///
- /// #1 int f(int x, int y = 1); // <pointer to #3, true>
- /// #2 int f(int x = 0, int y); // <pointer to #1, false>
- /// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
- ///
- /// If there is only one declaration, it is <pointer to self, true>
- DeclLink RedeclLink;
- decl_type *First;
-
- decl_type *getNextRedeclaration() const {
- return RedeclLink.getNext(static_cast<const decl_type *>(this));
- }
-
-public:
- Redeclarable(const ASTContext &Ctx)
- : RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {}
-
- /// \brief Return the previous declaration of this declaration or NULL if this
- /// is the first declaration.
- decl_type *getPreviousDecl() {
- if (RedeclLink.NextIsPrevious())
- return getNextRedeclaration();
- return nullptr;
- }
- const decl_type *getPreviousDecl() const {
- return const_cast<decl_type *>(
- static_cast<const decl_type*>(this))->getPreviousDecl();
- }
-
- /// \brief 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
- /// 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(); }
-
- /// \brief 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.
- const decl_type *getMostRecentDecl() const {
- return getFirstDecl()->getNextRedeclaration();
- }
-
- /// \brief 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.
- class redecl_iterator {
- /// Current - The current declaration.
- decl_type *Current;
- decl_type *Starter;
- bool PassedFirst;
-
- public:
- typedef decl_type* value_type;
- typedef decl_type* reference;
- typedef decl_type* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- redecl_iterator() : Current(nullptr) { }
- explicit redecl_iterator(decl_type *C)
- : Current(C), Starter(C), PassedFirst(false) { }
-
- reference operator*() const { return Current; }
- pointer operator->() const { return Current; }
-
- redecl_iterator& operator++() {
- assert(Current && "Advancing while iterator has reached end");
- // Sanity check to avoid infinite loop on invalid redecl chain.
- if (Current->isFirstDecl()) {
- if (PassedFirst) {
- assert(0 && "Passed first decl twice, invalid redecl chain!");
- Current = nullptr;
- return *this;
- }
- PassedFirst = true;
- }
-
- // Get either previous decl or latest decl.
- decl_type *Next = Current->getNextRedeclaration();
- Current = (Next != Starter) ? Next : nullptr;
- return *this;
- }
-
- redecl_iterator operator++(int) {
- redecl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(redecl_iterator x, redecl_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(redecl_iterator x, redecl_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<redecl_iterator> redecl_range;
-
- /// \brief Returns an iterator range for all the redeclarations of the same
- /// decl. It will iterate at least once (when this decl is the only one).
- redecl_range redecls() const {
- return redecl_range(redecl_iterator(const_cast<decl_type *>(
- static_cast<const decl_type *>(this))),
- redecl_iterator());
- }
-
- redecl_iterator redecls_begin() const { return redecls().begin(); }
- redecl_iterator redecls_end() const { return redecls().end(); }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief 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,
-/// but can be merged if the same declaration is brought in from multiple
-/// modules.
-template<typename decl_type>
-class Mergeable {
-public:
- Mergeable() {}
-
- /// \brief 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);
- 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
- /// is the only declaration.
- const decl_type *getFirstDecl() const {
- const decl_type *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.
- bool isFirstDecl() const { return getFirstDecl() == this; }
-};
-
-}
-
-#endif
diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h
deleted file mode 100644
index 6d903f8..0000000
--- a/include/clang/AST/SelectorLocationsKind.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===--- SelectorLocationsKind.h - Kind of selector locations ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Describes whether the identifier locations for a selector are "standard"
-// or not.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
-#define LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
-
-#include "clang/Basic/LLVM.h"
-
-namespace clang {
- class Selector;
- class SourceLocation;
- class Expr;
- class ParmVarDecl;
-
-/// \brief Whether all locations of the selector identifiers are in a
-/// "standard" position.
-enum SelectorLocationsKind {
- /// \brief Non-standard.
- SelLoc_NonStandard = 0,
-
- /// \brief 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:
- /// "[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.
-SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ArrayRef<Expr *> Args,
- SourceLocation EndLoc);
-
-/// \brief 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
-/// before arguments: "[foo first: 1 second: 2]"
-/// If false: "[foo first:1 second:2]"
-SourceLocation getStandardSelectorLoc(unsigned Index,
- Selector Sel,
- bool WithArgSpace,
- ArrayRef<Expr *> Args,
- SourceLocation EndLoc);
-
-/// \brief 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:
-/// For nullary selectors, immediately before ']': "[foo release]"
-///
-/// \param WithArgSpace if true the standard location is with a space apart
-/// before arguments: "-(id)first: (int)x second: (int)y;"
-/// If false: "-(id)first:(int)x second:(int)y;"
-SourceLocation getStandardSelectorLoc(unsigned Index,
- Selector Sel,
- bool WithArgSpace,
- ArrayRef<ParmVarDecl *> Args,
- SourceLocation EndLoc);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
deleted file mode 100644
index e48b7dc..0000000
--- a/include/clang/AST/Stmt.h
+++ /dev/null
@@ -1,2196 +0,0 @@
-//===--- Stmt.h - Classes for representing statements -----------*- 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 Stmt interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMT_H
-#define LLVM_CLANG_AST_STMT_H
-
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/StmtIterator.h"
-#include "clang/Basic/CapturedStmt.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <string>
-
-namespace llvm {
- class FoldingSetNodeID;
-}
-
-namespace clang {
- class ASTContext;
- class Attr;
- class CapturedDecl;
- class Decl;
- class Expr;
- class IdentifierInfo;
- class LabelDecl;
- class ParmVarDecl;
- class PrinterHelper;
- struct PrintingPolicy;
- class QualType;
- class RecordDecl;
- class SourceManager;
- class StringLiteral;
- class SwitchStmt;
- class Token;
- class VarDecl;
-
-//===----------------------------------------------------------------------===//
-// AST classes for statements.
-//===----------------------------------------------------------------------===//
-
-/// Stmt - This represents one statement.
-///
-class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
-public:
- enum StmtClass {
- NoStmtClass = 0,
-#define STMT(CLASS, PARENT) CLASS##Class,
-#define STMT_RANGE(BASE, FIRST, LAST) \
- first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
-#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
- first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
-#define ABSTRACT_STMT(STMT)
-#include "clang/AST/StmtNodes.inc"
- };
-
- // Make vanilla 'new' and 'delete' illegal for Stmts.
-protected:
- void *operator new(size_t bytes) LLVM_NOEXCEPT {
- llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
- }
- void operator delete(void *data) LLVM_NOEXCEPT {
- llvm_unreachable("Stmts cannot be released with regular 'delete'.");
- }
-
- class StmtBitfields {
- friend class Stmt;
-
- /// \brief The statement class.
- unsigned sClass : 8;
- };
- enum { NumStmtBits = 8 };
-
- class CompoundStmtBitfields {
- friend class CompoundStmt;
- unsigned : NumStmtBits;
-
- unsigned NumStmts : 32 - NumStmtBits;
- };
-
- class ExprBitfields {
- friend class Expr;
- friend class DeclRefExpr; // computeDependence
- friend class InitListExpr; // ctor
- friend class DesignatedInitExpr; // ctor
- friend class BlockDeclRefExpr; // ctor
- friend class ASTStmtReader; // deserialization
- friend class CXXNewExpr; // ctor
- friend class DependentScopeDeclRefExpr; // ctor
- friend class CXXConstructExpr; // ctor
- friend class CallExpr; // ctor
- friend class OffsetOfExpr; // ctor
- friend class ObjCMessageExpr; // ctor
- friend class ObjCArrayLiteral; // ctor
- friend class ObjCDictionaryLiteral; // ctor
- friend class ShuffleVectorExpr; // ctor
- friend class ParenListExpr; // ctor
- friend class CXXUnresolvedConstructExpr; // ctor
- friend class CXXDependentScopeMemberExpr; // ctor
- friend class OverloadExpr; // ctor
- friend class PseudoObjectExpr; // ctor
- friend class AtomicExpr; // ctor
- unsigned : NumStmtBits;
-
- unsigned ValueKind : 2;
- unsigned ObjectKind : 2;
- unsigned TypeDependent : 1;
- unsigned ValueDependent : 1;
- unsigned InstantiationDependent : 1;
- unsigned ContainsUnexpandedParameterPack : 1;
- };
- enum { NumExprBits = 16 };
-
- class CharacterLiteralBitfields {
- friend class CharacterLiteral;
- unsigned : NumExprBits;
-
- unsigned Kind : 2;
- };
-
- enum APFloatSemantics {
- IEEEhalf,
- IEEEsingle,
- IEEEdouble,
- x87DoubleExtended,
- IEEEquad,
- PPCDoubleDouble
- };
-
- class FloatingLiteralBitfields {
- friend class FloatingLiteral;
- unsigned : NumExprBits;
-
- unsigned Semantics : 3; // Provides semantics for APFloat construction
- unsigned IsExact : 1;
- };
-
- class UnaryExprOrTypeTraitExprBitfields {
- friend class UnaryExprOrTypeTraitExpr;
- unsigned : NumExprBits;
-
- unsigned Kind : 2;
- unsigned IsType : 1; // true if operand is a type, false if an expression.
- };
-
- class DeclRefExprBitfields {
- friend class DeclRefExpr;
- friend class ASTStmtReader; // deserialization
- unsigned : NumExprBits;
-
- unsigned HasQualifier : 1;
- unsigned HasTemplateKWAndArgsInfo : 1;
- unsigned HasFoundDecl : 1;
- unsigned HadMultipleCandidates : 1;
- unsigned RefersToEnclosingVariableOrCapture : 1;
- };
-
- class CastExprBitfields {
- friend class CastExpr;
- unsigned : NumExprBits;
-
- unsigned Kind : 6;
- unsigned BasePathSize : 32 - 6 - NumExprBits;
- };
-
- class CallExprBitfields {
- friend class CallExpr;
- unsigned : NumExprBits;
-
- unsigned NumPreArgs : 1;
- };
-
- class ExprWithCleanupsBitfields {
- friend class ExprWithCleanups;
- friend class ASTStmtReader; // deserialization
-
- unsigned : NumExprBits;
-
- unsigned NumObjects : 32 - NumExprBits;
- };
-
- class PseudoObjectExprBitfields {
- friend class PseudoObjectExpr;
- friend class ASTStmtReader; // deserialization
-
- unsigned : NumExprBits;
-
- // These don't need to be particularly wide, because they're
- // strictly limited by the forms of expressions we permit.
- unsigned NumSubExprs : 8;
- unsigned ResultIndex : 32 - 8 - NumExprBits;
- };
-
- class ObjCIndirectCopyRestoreExprBitfields {
- friend class ObjCIndirectCopyRestoreExpr;
- unsigned : NumExprBits;
-
- unsigned ShouldCopy : 1;
- };
-
- class InitListExprBitfields {
- friend class InitListExpr;
-
- unsigned : NumExprBits;
-
- /// Whether this initializer list originally had a GNU array-range
- /// designator in it. This is a temporary marker used by CodeGen.
- unsigned HadArrayRangeDesignator : 1;
- };
-
- class TypeTraitExprBitfields {
- friend class TypeTraitExpr;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- unsigned : NumExprBits;
-
- /// \brief 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
- /// the trait evaluated true or false.
- unsigned Value : 1;
-
- /// \brief The number of arguments to this type trait.
- unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
- };
-
- union {
- StmtBitfields StmtBits;
- CompoundStmtBitfields CompoundStmtBits;
- ExprBitfields ExprBits;
- CharacterLiteralBitfields CharacterLiteralBits;
- FloatingLiteralBitfields FloatingLiteralBits;
- UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
- DeclRefExprBitfields DeclRefExprBits;
- CastExprBitfields CastExprBits;
- CallExprBitfields CallExprBits;
- ExprWithCleanupsBitfields ExprWithCleanupsBits;
- PseudoObjectExprBitfields PseudoObjectExprBits;
- ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
- InitListExprBitfields InitListExprBits;
- TypeTraitExprBitfields TypeTraitExprBits;
- };
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- // Only allow allocation of Stmts using the allocator in ASTContext
- // or by doing a placement new.
- void* operator new(size_t bytes, const ASTContext& C,
- unsigned alignment = 8);
-
- void* operator new(size_t bytes, const ASTContext* C,
- unsigned alignment = 8) {
- return operator new(bytes, *C, alignment);
- }
-
- void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; }
-
- void operator delete(void *, const ASTContext &, unsigned) LLVM_NOEXCEPT {}
- void operator delete(void *, const ASTContext *, unsigned) LLVM_NOEXCEPT {}
- void operator delete(void *, size_t) LLVM_NOEXCEPT {}
- void operator delete(void *, void *) LLVM_NOEXCEPT {}
-
-public:
- /// \brief 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 { };
-
-protected:
- /// Iterator for iterating over Stmt * arrays that contain only Expr *
- ///
- /// This is needed because AST nodes use Stmt* arrays to store
- /// references to children (to be compatible with StmtIterator).
- struct ExprIterator
- : llvm::iterator_adaptor_base<ExprIterator, Stmt **,
- std::random_access_iterator_tag, Expr *> {
- ExprIterator() : iterator_adaptor_base(nullptr) {}
- ExprIterator(Stmt **I) : iterator_adaptor_base(I) {}
-
- reference operator*() const {
- assert((*I)->getStmtClass() >= firstExprConstant &&
- (*I)->getStmtClass() <= lastExprConstant);
- return *reinterpret_cast<Expr **>(I);
- }
- };
-
- /// Const iterator for iterating over Stmt * arrays that contain only Expr *
- struct ConstExprIterator
- : llvm::iterator_adaptor_base<ConstExprIterator, const Stmt *const *,
- std::random_access_iterator_tag,
- const Expr *const> {
- ConstExprIterator() : iterator_adaptor_base(nullptr) {}
- ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {}
-
- reference operator*() const {
- assert((*I)->getStmtClass() >= firstExprConstant &&
- (*I)->getStmtClass() <= lastExprConstant);
- return *reinterpret_cast<const Expr *const *>(I);
- }
- };
-
-private:
- /// \brief Whether statistic collection is enabled.
- static bool StatisticsEnabled;
-
-protected:
- /// \brief Construct an empty statement.
- explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {}
-
-public:
- Stmt(StmtClass SC) {
- static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0,
- "Insufficient alignment!");
- StmtBits.sClass = SC;
- if (StatisticsEnabled) Stmt::addStmtClass(SC);
- }
-
- StmtClass getStmtClass() const {
- return static_cast<StmtClass>(StmtBits.sClass);
- }
- const char *getStmtClassName() const;
-
- /// SourceLocation tokens are not useful in isolation - they are low level
- /// value objects created/interpreted by SourceManager. We assume AST
- /// clients will have a pointer to the respective SourceManager.
- SourceRange getSourceRange() const LLVM_READONLY;
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- // global temp stats (until we have a per-module visitor)
- static void addStmtClass(const StmtClass s);
- static void EnableStatistics();
- static void PrintStats();
-
- /// \brief Dumps the specified AST fragment and all subtrees to
- /// \c llvm::errs().
- void dump() const;
- void dump(SourceManager &SM) const;
- void dump(raw_ostream &OS, SourceManager &SM) const;
- void dump(raw_ostream &OS) const;
-
- /// dumpColor - same as dump(), but forces color highlighting.
- void dumpColor() const;
-
- /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
- /// back to its original source language syntax.
- void dumpPretty(const ASTContext &Context) const;
- void printPretty(raw_ostream &OS, PrinterHelper *Helper,
- const PrintingPolicy &Policy,
- unsigned Indentation = 0) const;
-
- /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
- /// works on systems with GraphViz (Mac OS X) or dot+gv installed.
- void viewAST() const;
-
- /// Skip past any implicit AST nodes which might surround this
- /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
- Stmt *IgnoreImplicit();
-
- /// \brief 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 *stripLabelLikeStatements() const;
- Stmt *stripLabelLikeStatements() {
- return const_cast<Stmt*>(
- const_cast<const Stmt*>(this)->stripLabelLikeStatements());
- }
-
- /// Child Iterators: All subclasses must implement 'children'
- /// to permit easy iteration over the substatements/subexpessions of an
- /// AST node. This permits easy iteration over all nodes in the AST.
- typedef StmtIterator child_iterator;
- typedef ConstStmtIterator const_child_iterator;
-
- typedef llvm::iterator_range<child_iterator> child_range;
- typedef llvm::iterator_range<const_child_iterator> const_child_range;
-
- child_range children();
- const_child_range children() const {
- auto Children = const_cast<Stmt *>(this)->children();
- return const_child_range(Children.begin(), Children.end());
- }
-
- child_iterator child_begin() { return children().begin(); }
- child_iterator child_end() { return children().end(); }
-
- 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.
- ///
- /// \param ID once the profiling operation is complete, will contain
- /// the unique representation of the given statement.
- ///
- /// \param Context the AST context in which the statement resides
- ///
- /// \param Canonical whether the profile should be based on the canonical
- /// representation of this statement (e.g., where non-type template
- /// parameters are identified by index/level rather than their
- /// declaration pointers) or the exact representation of the statement as
- /// written in the source.
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- bool Canonical) const;
-};
-
-/// DeclStmt - Adaptor class for mixing declarations with statements and
-/// expressions. For example, CompoundStmt mixes statements, expressions
-/// and declarations (variables, types). Another example is ForStmt, where
-/// the first statement can be an expression or a declaration.
-///
-class DeclStmt : public Stmt {
- DeclGroupRef DG;
- SourceLocation StartLoc, EndLoc;
-
-public:
- DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
- SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
- StartLoc(startLoc), EndLoc(endLoc) {}
-
- /// \brief Build an empty declaration statement.
- explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
-
- /// isSingleDecl - This method returns true if this DeclStmt refers
- /// to a single Decl.
- bool isSingleDecl() const {
- return DG.isSingleDecl();
- }
-
- const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
- Decl *getSingleDecl() { return DG.getSingleDecl(); }
-
- const DeclGroupRef getDeclGroup() const { return DG; }
- DeclGroupRef getDeclGroup() { return DG; }
- void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
-
- SourceLocation getStartLoc() const { return StartLoc; }
- void setStartLoc(SourceLocation L) { StartLoc = L; }
- SourceLocation getEndLoc() const { return EndLoc; }
- void setEndLoc(SourceLocation L) { EndLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclStmtClass;
- }
-
- // Iterators over subexpressions.
- child_range children() {
- return child_range(child_iterator(DG.begin(), DG.end()),
- child_iterator(DG.end(), DG.end()));
- }
-
- typedef DeclGroupRef::iterator decl_iterator;
- typedef DeclGroupRef::const_iterator const_decl_iterator;
- typedef llvm::iterator_range<decl_iterator> decl_range;
- typedef llvm::iterator_range<const_decl_iterator> decl_const_range;
-
- 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(); }
- const_decl_iterator decl_end() const { return DG.end(); }
-
- typedef std::reverse_iterator<decl_iterator> reverse_decl_iterator;
- reverse_decl_iterator decl_rbegin() {
- return reverse_decl_iterator(decl_end());
- }
- reverse_decl_iterator decl_rend() {
- return reverse_decl_iterator(decl_begin());
- }
-};
-
-/// NullStmt - This is the null statement ";": C99 6.8.3p3.
-///
-class NullStmt : public Stmt {
- SourceLocation SemiLoc;
-
- /// \brief True if the null statement was preceded by an empty macro, e.g:
- /// @code
- /// #define CALL(x)
- /// CALL(0);
- /// @endcode
- bool HasLeadingEmptyMacro;
-public:
- NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
- : Stmt(NullStmtClass), SemiLoc(L),
- HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
-
- /// \brief Build an empty null statement.
- explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty),
- HasLeadingEmptyMacro(false) { }
-
- SourceLocation getSemiLoc() const { return SemiLoc; }
- void setSemiLoc(SourceLocation L) { SemiLoc = L; }
-
- bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == NullStmtClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// CompoundStmt - This represents a group of statements like { stmt stmt }.
-///
-class CompoundStmt : public Stmt {
- Stmt** Body;
- SourceLocation LBraceLoc, RBraceLoc;
-
- friend class ASTStmtReader;
-
-public:
- CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
- SourceLocation LB, SourceLocation RB);
-
- // \brief Build an empty compound statement with a location.
- explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), Body(nullptr), LBraceLoc(Loc), RBraceLoc(Loc) {
- CompoundStmtBits.NumStmts = 0;
- }
-
- // \brief Build an empty compound statement.
- explicit CompoundStmt(EmptyShell Empty)
- : Stmt(CompoundStmtClass, Empty), Body(nullptr) {
- CompoundStmtBits.NumStmts = 0;
- }
-
- void setStmts(const ASTContext &C, ArrayRef<Stmt *> Stmts);
-
- bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
- unsigned size() const { return CompoundStmtBits.NumStmts; }
-
- typedef Stmt** body_iterator;
- typedef llvm::iterator_range<body_iterator> body_range;
-
- body_range body() { return body_range(body_begin(), body_end()); }
- body_iterator body_begin() { return Body; }
- body_iterator body_end() { return Body + size(); }
- Stmt *body_front() { return !body_empty() ? Body[0] : nullptr; }
- Stmt *body_back() { return !body_empty() ? Body[size()-1] : nullptr; }
-
- void setLastStmt(Stmt *S) {
- assert(!body_empty() && "setLastStmt");
- Body[size()-1] = S;
- }
-
- typedef Stmt* const * const_body_iterator;
- typedef llvm::iterator_range<const_body_iterator> body_const_range;
-
- body_const_range body() const {
- return body_const_range(body_begin(), body_end());
- }
- const_body_iterator body_begin() const { return Body; }
- const_body_iterator body_end() const { return Body + size(); }
- const Stmt *body_front() const {
- return !body_empty() ? Body[0] : nullptr;
- }
- const Stmt *body_back() const {
- return !body_empty() ? Body[size() - 1] : nullptr;
- }
-
- typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
- reverse_body_iterator body_rbegin() {
- return reverse_body_iterator(body_end());
- }
- reverse_body_iterator body_rend() {
- return reverse_body_iterator(body_begin());
- }
-
- typedef std::reverse_iterator<const_body_iterator>
- const_reverse_body_iterator;
-
- const_reverse_body_iterator body_rbegin() const {
- return const_reverse_body_iterator(body_end());
- }
-
- const_reverse_body_iterator body_rend() const {
- return const_reverse_body_iterator(body_begin());
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LBraceLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBraceLoc; }
-
- SourceLocation getLBracLoc() const { return LBraceLoc; }
- SourceLocation getRBracLoc() const { return RBraceLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CompoundStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(Body, Body + CompoundStmtBits.NumStmts);
- }
-
- const_child_range children() const {
- return const_child_range(child_iterator(Body),
- child_iterator(Body + CompoundStmtBits.NumStmts));
- }
-};
-
-// SwitchCase is the base class for CaseStmt and DefaultStmt,
-class SwitchCase : public Stmt {
-protected:
- // A pointer to the following CaseStmt or DefaultStmt class,
- // used by SwitchStmt.
- SwitchCase *NextSwitchCase;
- SourceLocation KeywordLoc;
- SourceLocation ColonLoc;
-
- SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
- : Stmt(SC), NextSwitchCase(nullptr), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {
- }
-
- SwitchCase(StmtClass SC, EmptyShell)
- : Stmt(SC), NextSwitchCase(nullptr) {}
-
-public:
- const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
-
- SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
-
- void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
-
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
- void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
-
- Stmt *getSubStmt();
- const Stmt *getSubStmt() const {
- return const_cast<SwitchCase*>(this)->getSubStmt();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CaseStmtClass ||
- T->getStmtClass() == DefaultStmtClass;
- }
-};
-
-class CaseStmt : public SwitchCase {
- SourceLocation EllipsisLoc;
- enum { LHS, RHS, SUBSTMT, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
- // GNU "case 1 ... 4" extension
-public:
- CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
- SourceLocation ellipsisLoc, SourceLocation colonLoc)
- : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
- SubExprs[SUBSTMT] = nullptr;
- SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
- SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
- EllipsisLoc = ellipsisLoc;
- }
-
- /// \brief Build an empty switch case statement.
- explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { }
-
- SourceLocation getCaseLoc() const { return KeywordLoc; }
- void setCaseLoc(SourceLocation L) { KeywordLoc = L; }
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
-
- Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
- Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
- Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
-
- const Expr *getLHS() const {
- return reinterpret_cast<const Expr*>(SubExprs[LHS]);
- }
- const Expr *getRHS() const {
- return reinterpret_cast<const Expr*>(SubExprs[RHS]);
- }
- const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
-
- void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
- void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
- void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- 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()))
- CS = CS2;
-
- return CS->getSubStmt()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CaseStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
- }
-};
-
-class DefaultStmt : public SwitchCase {
- Stmt* SubStmt;
-public:
- DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
- SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
-
- /// \brief Build an empty default statement.
- explicit DefaultStmt(EmptyShell Empty)
- : SwitchCase(DefaultStmtClass, Empty) { }
-
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
- void setSubStmt(Stmt *S) { SubStmt = S; }
-
- SourceLocation getDefaultLoc() const { return KeywordLoc; }
- void setDefaultLoc(SourceLocation L) { KeywordLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DefaultStmtClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubStmt, &SubStmt+1); }
-};
-
-inline SourceLocation SwitchCase::getLocEnd() const {
- if (const CaseStmt *CS = dyn_cast<CaseStmt>(this))
- return CS->getLocEnd();
- return cast<DefaultStmt>(this)->getLocEnd();
-}
-
-/// LabelStmt - Represents a label, which has a substatement. For example:
-/// foo: return;
-///
-class LabelStmt : public Stmt {
- SourceLocation IdentLoc;
- LabelDecl *TheDecl;
- Stmt *SubStmt;
-
-public:
- LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
- : Stmt(LabelStmtClass), IdentLoc(IL), TheDecl(D), SubStmt(substmt) {
- static_assert(sizeof(LabelStmt) ==
- 2 * sizeof(SourceLocation) + 2 * sizeof(void *),
- "LabelStmt too big");
- }
-
- // \brief Build an empty label statement.
- explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
-
- SourceLocation getIdentLoc() const { return IdentLoc; }
- LabelDecl *getDecl() const { return TheDecl; }
- void setDecl(LabelDecl *D) { TheDecl = D; }
- const char *getName() const;
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
- void setIdentLoc(SourceLocation L) { IdentLoc = L; }
- void setSubStmt(Stmt *SS) { SubStmt = SS; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- child_range children() { return child_range(&SubStmt, &SubStmt+1); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == LabelStmtClass;
- }
-};
-
-
-/// \brief Represents an attribute applied to a statement.
-///
-/// Represents an attribute applied to a statement. For example:
-/// [[omp::for(...)]] for (...) { ... }
-///
-class AttributedStmt : public Stmt {
- Stmt *SubStmt;
- SourceLocation AttrLoc;
- unsigned NumAttrs;
-
- friend class ASTStmtReader;
-
- AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
- : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
- NumAttrs(Attrs.size()) {
- std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
- }
-
- explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
- : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
- std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
- }
-
- const Attr *const *getAttrArrayPtr() const {
- return reinterpret_cast<const Attr *const *>(this + 1);
- }
- const Attr **getAttrArrayPtr() {
- return reinterpret_cast<const Attr **>(this + 1);
- }
-
-public:
- static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
- ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
- // \brief Build an empty attributed statement.
- static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
-
- SourceLocation getAttrLoc() const { return AttrLoc; }
- ArrayRef<const Attr*> getAttrs() const {
- return llvm::makeArrayRef(getAttrArrayPtr(), NumAttrs);
- }
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AttributedStmtClass;
- }
-};
-
-
-/// IfStmt - This represents an if/then/else.
-///
-class IfStmt : public Stmt {
- enum { VAR, COND, THEN, ELSE, END_EXPR };
- Stmt* SubExprs[END_EXPR];
-
- SourceLocation IfLoc;
- SourceLocation ElseLoc;
-
-public:
- IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
- Stmt *then, SourceLocation EL = SourceLocation(),
- Stmt *elsev = nullptr);
-
- /// \brief 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.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// if (int x = foo()) {
- /// printf("x is %d", x);
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
-
- /// If this IfStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
- }
-
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
- const Stmt *getThen() const { return SubExprs[THEN]; }
- void setThen(Stmt *S) { SubExprs[THEN] = S; }
- const Stmt *getElse() const { return SubExprs[ELSE]; }
- void setElse(Stmt *S) { SubExprs[ELSE] = S; }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- Stmt *getThen() { return SubExprs[THEN]; }
- Stmt *getElse() { return SubExprs[ELSE]; }
-
- SourceLocation getIfLoc() const { return IfLoc; }
- void setIfLoc(SourceLocation L) { IfLoc = L; }
- SourceLocation getElseLoc() const { return ElseLoc; }
- void setElseLoc(SourceLocation L) { ElseLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (SubExprs[ELSE])
- return SubExprs[ELSE]->getLocEnd();
- else
- return SubExprs[THEN]->getLocEnd();
- }
-
- // Iterators over subexpressions. The iterators will include iterating
- // over the initialization expression referenced by the condition variable.
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IfStmtClass;
- }
-};
-
-/// SwitchStmt - This represents a 'switch' stmt.
-///
-class SwitchStmt : public Stmt {
- SourceLocation SwitchLoc;
- enum { VAR, COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- // This points to a linked list of case and default statements and, if the
- // SwitchStmt is a switch on an enum value, records whether all the enum
- // values were covered by CaseStmts. The coverage information value is meant
- // to be a hint for possible clients.
- llvm::PointerIntPair<SwitchCase *, 1, bool> FirstCase;
-
-public:
- SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond);
-
- /// \brief Build a empty switch statement.
- explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
-
- /// \brief Retrieve the variable declared in this "switch" statement, if any.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// switch (int x = foo()) {
- /// case 0: break;
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
-
- /// If this SwitchStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
- }
-
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Stmt *getBody() const { return SubExprs[BODY]; }
- const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
- Stmt *getBody() { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
- SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); }
-
- /// \brief Set the case list for this switch statement.
- void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); }
-
- SourceLocation getSwitchLoc() const { return SwitchLoc; }
- void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
-
- void setBody(Stmt *S, SourceLocation SL) {
- SubExprs[BODY] = S;
- SwitchLoc = SL;
- }
- void addSwitchCase(SwitchCase *SC) {
- assert(!SC->getNextSwitchCase()
- && "case/default already added to a switch");
- SC->setNextSwitchCase(FirstCase.getPointer());
- FirstCase.setPointer(SC);
- }
-
- /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
- /// switch over an enum value then all cases have been explicitly covered.
- void setAllEnumCasesCovered() { FirstCase.setInt(true); }
-
- /// Returns true if the SwitchStmt is a switch of an enum value and all cases
- /// have been explicitly covered.
- bool isAllEnumCasesCovered() const { return FirstCase.getInt(); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY] ? SubExprs[BODY]->getLocEnd() : SubExprs[COND]->getLocEnd();
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SwitchStmtClass;
- }
-};
-
-
-/// WhileStmt - This represents a 'while' stmt.
-///
-class WhileStmt : public Stmt {
- SourceLocation WhileLoc;
- enum { VAR, COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
-public:
- WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
- SourceLocation WL);
-
- /// \brief Build an empty while statement.
- explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
-
- /// \brief Retrieve the variable declared in this "while" statement, if any.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// while (int x = random()) {
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
-
- /// If this WhileStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
- }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getBody() const { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getWhileLoc() const { return WhileLoc; }
- void setWhileLoc(SourceLocation L) { WhileLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == WhileStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// DoStmt - This represents a 'do/while' stmt.
-///
-class DoStmt : public Stmt {
- SourceLocation DoLoc;
- enum { BODY, COND, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- SourceLocation WhileLoc;
- SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
-
-public:
- DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
- SourceLocation RP)
- : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = body;
- }
-
- /// \brief Build an empty do-while statement.
- explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getBody() const { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getDoLoc() const { return DoLoc; }
- void setDoLoc(SourceLocation L) { DoLoc = L; }
- SourceLocation getWhileLoc() const { return WhileLoc; }
- void setWhileLoc(SourceLocation L) { WhileLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DoStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-
-/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
-/// the init/cond/inc parts of the ForStmt will be null if they were not
-/// specified in the source.
-///
-class ForStmt : public Stmt {
- SourceLocation ForLoc;
- enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
- SourceLocation LParenLoc, RParenLoc;
-
-public:
- ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
- Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
- SourceLocation RP);
-
- /// \brief 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.
- ///
- /// In the following example, "y" is the condition variable.
- /// \code
- /// for (int x = random(); int y = mangle(x); ++x) {
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
-
- /// If this ForStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
- }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
- Stmt *getBody() { return SubExprs[BODY]; }
-
- const Stmt *getInit() const { return SubExprs[INIT]; }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- void setInit(Stmt *S) { SubExprs[INIT] = S; }
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getForLoc() const { return ForLoc; }
- void setForLoc(SourceLocation L) { ForLoc = L; }
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ForStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// GotoStmt - This represents a direct goto.
-///
-class GotoStmt : public Stmt {
- LabelDecl *Label;
- SourceLocation GotoLoc;
- SourceLocation LabelLoc;
-public:
- GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
- : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
-
- /// \brief Build an empty goto statement.
- explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
-
- LabelDecl *getLabel() const { return Label; }
- void setLabel(LabelDecl *D) { Label = D; }
-
- SourceLocation getGotoLoc() const { return GotoLoc; }
- void setGotoLoc(SourceLocation L) { GotoLoc = L; }
- SourceLocation getLabelLoc() const { return LabelLoc; }
- void setLabelLoc(SourceLocation L) { LabelLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GotoStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// IndirectGotoStmt - This represents an indirect goto.
-///
-class IndirectGotoStmt : public Stmt {
- SourceLocation GotoLoc;
- SourceLocation StarLoc;
- Stmt *Target;
-public:
- IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
- Expr *target)
- : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
- Target((Stmt*)target) {}
-
- /// \brief Build an empty indirect goto statement.
- explicit IndirectGotoStmt(EmptyShell Empty)
- : Stmt(IndirectGotoStmtClass, Empty) { }
-
- void setGotoLoc(SourceLocation L) { GotoLoc = L; }
- SourceLocation getGotoLoc() const { return GotoLoc; }
- void setStarLoc(SourceLocation L) { StarLoc = L; }
- SourceLocation getStarLoc() const { return StarLoc; }
-
- Expr *getTarget() { return reinterpret_cast<Expr*>(Target); }
- const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);}
- void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
-
- /// getConstantTarget - Returns the fixed target of this indirect
- /// goto, if one exists.
- LabelDecl *getConstantTarget();
- const LabelDecl *getConstantTarget() const {
- return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IndirectGotoStmtClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Target, &Target+1); }
-};
-
-
-/// ContinueStmt - This represents a continue.
-///
-class ContinueStmt : public Stmt {
- SourceLocation ContinueLoc;
-public:
- ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
-
- /// \brief Build an empty continue statement.
- explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
-
- SourceLocation getContinueLoc() const { return ContinueLoc; }
- void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ContinueStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// BreakStmt - This represents a break.
-///
-class BreakStmt : public Stmt {
- SourceLocation BreakLoc;
-
-public:
- BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {
- static_assert(sizeof(BreakStmt) == 2 * sizeof(SourceLocation),
- "BreakStmt too large");
- }
-
- /// \brief Build an empty break statement.
- explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
-
- SourceLocation getBreakLoc() const { return BreakLoc; }
- void setBreakLoc(SourceLocation L) { BreakLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BreakStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-
-/// ReturnStmt - This represents a return, optionally of an expression:
-/// return;
-/// return 4;
-///
-/// Note that GCC allows return with no argument in a function declared to
-/// return a value, and it allows returning a value in functions declared to
-/// return void. We explicitly model this in the AST, which means you can't
-/// depend on the return type of the function and the presence of an argument.
-///
-class ReturnStmt : public Stmt {
- SourceLocation RetLoc;
- Stmt *RetExpr;
- const VarDecl *NRVOCandidate;
-
-public:
- explicit ReturnStmt(SourceLocation RL) : ReturnStmt(RL, nullptr, nullptr) {}
-
- ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
- : Stmt(ReturnStmtClass), RetLoc(RL), RetExpr((Stmt *)E),
- NRVOCandidate(NRVOCandidate) {}
-
- /// \brief Build an empty return expression.
- explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
-
- const Expr *getRetValue() const;
- Expr *getRetValue();
- void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
-
- SourceLocation getReturnLoc() const { return RetLoc; }
- void setReturnLoc(SourceLocation L) { RetLoc = L; }
-
- /// \brief Retrieve the variable that might be used for the named return
- /// value optimization.
- ///
- /// The optimization itself can only be performed if the variable is
- /// also marked as an NRVO object.
- const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
- void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return RetExpr ? RetExpr->getLocEnd() : RetLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ReturnStmtClass;
- }
-
- // Iterators
- child_range children() {
- if (RetExpr) return child_range(&RetExpr, &RetExpr+1);
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
-///
-class AsmStmt : public Stmt {
-protected:
- SourceLocation AsmLoc;
- /// \brief 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.
- /// This assembly statement should not be optimized, deleted or moved.
- bool IsVolatile;
-
- unsigned NumOutputs;
- unsigned NumInputs;
- unsigned NumClobbers;
-
- Stmt **Exprs;
-
- AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
- unsigned numoutputs, unsigned numinputs, unsigned numclobbers) :
- Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
- NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { }
-
- friend class ASTStmtReader;
-
-public:
- /// \brief Build an empty inline-assembly statement.
- explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
- Stmt(SC, Empty), Exprs(nullptr) { }
-
- SourceLocation getAsmLoc() const { return AsmLoc; }
- void setAsmLoc(SourceLocation L) { AsmLoc = L; }
-
- bool isSimple() const { return IsSimple; }
- void setSimple(bool V) { IsSimple = V; }
-
- 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(); }
-
- //===--- Asm String Analysis ---===//
-
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
-
- //===--- Output operands ---===//
-
- unsigned getNumOutputs() const { return NumOutputs; }
-
- /// getOutputConstraint - Return the constraint string for the specified
- /// output operand. All output constraints are known to be non-empty (either
- /// '=' or '+').
- StringRef getOutputConstraint(unsigned i) const;
-
- /// isOutputPlusConstraint - Return true if the specified output constraint
- /// is a "+" constraint (which is both an input and an output) or false if it
- /// is an "=" constraint (just an output).
- bool isOutputPlusConstraint(unsigned i) const {
- return getOutputConstraint(i)[0] == '+';
- }
-
- const Expr *getOutputExpr(unsigned i) const;
-
- /// getNumPlusOperands - Return the number of output operands that have a "+"
- /// constraint.
- unsigned getNumPlusOperands() const;
-
- //===--- Input operands ---===//
-
- unsigned getNumInputs() const { return NumInputs; }
-
- /// getInputConstraint - Return the specified input constraint. Unlike output
- /// constraints, these can be empty.
- StringRef getInputConstraint(unsigned i) const;
-
- const Expr *getInputExpr(unsigned i) const;
-
- //===--- Other ---===//
-
- unsigned getNumClobbers() const { return NumClobbers; }
- StringRef getClobber(unsigned i) const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GCCAsmStmtClass ||
- T->getStmtClass() == MSAsmStmtClass;
- }
-
- // Input expr iterators.
-
- typedef ExprIterator inputs_iterator;
- typedef ConstExprIterator const_inputs_iterator;
- typedef llvm::iterator_range<inputs_iterator> inputs_range;
- typedef llvm::iterator_range<const_inputs_iterator> inputs_const_range;
-
- inputs_iterator begin_inputs() {
- return &Exprs[0] + NumOutputs;
- }
-
- inputs_iterator end_inputs() {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
-
- inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }
-
- const_inputs_iterator begin_inputs() const {
- return &Exprs[0] + NumOutputs;
- }
-
- const_inputs_iterator end_inputs() const {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
-
- inputs_const_range inputs() const {
- return inputs_const_range(begin_inputs(), end_inputs());
- }
-
- // Output expr iterators.
-
- typedef ExprIterator outputs_iterator;
- typedef ConstExprIterator const_outputs_iterator;
- typedef llvm::iterator_range<outputs_iterator> outputs_range;
- typedef llvm::iterator_range<const_outputs_iterator> outputs_const_range;
-
- outputs_iterator begin_outputs() {
- return &Exprs[0];
- }
- outputs_iterator end_outputs() {
- return &Exprs[0] + NumOutputs;
- }
- outputs_range outputs() {
- return outputs_range(begin_outputs(), end_outputs());
- }
-
- const_outputs_iterator begin_outputs() const {
- return &Exprs[0];
- }
- const_outputs_iterator end_outputs() const {
- return &Exprs[0] + NumOutputs;
- }
- outputs_const_range outputs() const {
- return outputs_const_range(begin_outputs(), end_outputs());
- }
-
- child_range children() {
- return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
- }
-};
-
-/// This represents a GCC inline-assembly statement extension.
-///
-class GCCAsmStmt : public AsmStmt {
- SourceLocation RParenLoc;
- StringLiteral *AsmStr;
-
- // FIXME: If we wanted to, we could allocate all of these in one big array.
- StringLiteral **Constraints;
- StringLiteral **Clobbers;
- IdentifierInfo **Names;
-
- friend class ASTStmtReader;
-
-public:
- GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
- bool isvolatile, unsigned numoutputs, unsigned numinputs,
- IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
- StringLiteral *asmstr, unsigned numclobbers,
- StringLiteral **clobbers, SourceLocation rparenloc);
-
- /// \brief Build an empty inline-assembly statement.
- explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
- Constraints(nullptr), Clobbers(nullptr), Names(nullptr) { }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- //===--- Asm String Analysis ---===//
-
- const StringLiteral *getAsmString() const { return AsmStr; }
- StringLiteral *getAsmString() { return AsmStr; }
- void setAsmString(StringLiteral *E) { AsmStr = E; }
-
- /// AsmStringPiece - this is part of a decomposed asm string specification
- /// (for use with the AnalyzeAsmString function below). An asm string is
- /// considered to be a concatenation of these parts.
- class AsmStringPiece {
- public:
- enum Kind {
- String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
- Operand // Operand reference, with optional modifier %c4.
- };
- private:
- Kind MyKind;
- std::string Str;
- unsigned OperandNo;
-
- // Source range for operand references.
- CharSourceRange Range;
- public:
- AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
- AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
- SourceLocation End)
- : MyKind(Operand), Str(S), OperandNo(OpNo),
- Range(CharSourceRange::getCharRange(Begin, End)) {
- }
-
- bool isString() const { return MyKind == String; }
- bool isOperand() const { return MyKind == Operand; }
-
- const std::string &getString() const {
- return Str;
- }
-
- unsigned getOperandNo() const {
- assert(isOperand());
- return OperandNo;
- }
-
- CharSourceRange getRange() const {
- assert(isOperand() && "Range is currently used only for Operands.");
- return Range;
- }
-
- /// getModifier - Get the modifier for this operand, if present. This
- /// returns '\0' if there was no modifier.
- char getModifier() const;
- };
-
- /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
- /// it into pieces. If the asm string is erroneous, emit errors and return
- /// true, otherwise return false. This handles canonicalization and
- /// translation of strings from GCC syntax to LLVM IR syntax, and handles
- //// flattening of named references like %[foo] to Operand AsmStringPiece's.
- unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
- const ASTContext &C, unsigned &DiagOffs) const;
-
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
-
- //===--- Output operands ---===//
-
- IdentifierInfo *getOutputIdentifier(unsigned i) const {
- return Names[i];
- }
-
- StringRef getOutputName(unsigned i) const {
- if (IdentifierInfo *II = getOutputIdentifier(i))
- return II->getName();
-
- return StringRef();
- }
-
- StringRef getOutputConstraint(unsigned i) const;
-
- const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
- return Constraints[i];
- }
- StringLiteral *getOutputConstraintLiteral(unsigned i) {
- return Constraints[i];
- }
-
- Expr *getOutputExpr(unsigned i);
-
- const Expr *getOutputExpr(unsigned i) const {
- return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
- }
-
- //===--- Input operands ---===//
-
- IdentifierInfo *getInputIdentifier(unsigned i) const {
- return Names[i + NumOutputs];
- }
-
- StringRef getInputName(unsigned i) const {
- if (IdentifierInfo *II = getInputIdentifier(i))
- return II->getName();
-
- return StringRef();
- }
-
- StringRef getInputConstraint(unsigned i) const;
-
- const StringLiteral *getInputConstraintLiteral(unsigned i) const {
- return Constraints[i + NumOutputs];
- }
- StringLiteral *getInputConstraintLiteral(unsigned i) {
- return Constraints[i + NumOutputs];
- }
-
- Expr *getInputExpr(unsigned i);
- void setInputExpr(unsigned i, Expr *E);
-
- const Expr *getInputExpr(unsigned i) const {
- return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
- }
-
-private:
- void setOutputsAndInputsAndClobbers(const ASTContext &C,
- IdentifierInfo **Names,
- StringLiteral **Constraints,
- Stmt **Exprs,
- unsigned NumOutputs,
- unsigned NumInputs,
- StringLiteral **Clobbers,
- unsigned NumClobbers);
-public:
-
- //===--- Other ---===//
-
- /// getNamedOperand - Given a symbolic operand reference like %[foo],
- /// translate this into a numeric value needed to reference the same operand.
- /// This returns -1 if the operand name is invalid.
- int getNamedOperand(StringRef SymbolicName) const;
-
- StringRef getClobber(unsigned i) const;
- StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
- const StringLiteral *getClobberStringLiteral(unsigned i) const {
- return Clobbers[i];
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GCCAsmStmtClass;
- }
-};
-
-/// This represents a Microsoft inline-assembly statement extension.
-///
-class MSAsmStmt : public AsmStmt {
- SourceLocation LBraceLoc, EndLoc;
- StringRef AsmStr;
-
- unsigned NumAsmToks;
-
- Token *AsmToks;
- StringRef *Constraints;
- StringRef *Clobbers;
-
- friend class ASTStmtReader;
-
-public:
- MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
- SourceLocation lbraceloc, bool issimple, bool isvolatile,
- ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs,
- ArrayRef<StringRef> constraints,
- ArrayRef<Expr*> exprs, StringRef asmstr,
- ArrayRef<StringRef> clobbers, SourceLocation endloc);
-
- /// \brief Build an empty MS-style inline-assembly statement.
- explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
- NumAsmToks(0), AsmToks(nullptr), Constraints(nullptr), Clobbers(nullptr) { }
-
- SourceLocation getLBraceLoc() const { return LBraceLoc; }
- void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
- SourceLocation getEndLoc() const { return EndLoc; }
- void setEndLoc(SourceLocation L) { EndLoc = L; }
-
- bool hasBraces() const { return LBraceLoc.isValid(); }
-
- unsigned getNumAsmToks() { return NumAsmToks; }
- Token *getAsmToks() { return AsmToks; }
-
- //===--- Asm String Analysis ---===//
- StringRef getAsmString() const { return AsmStr; }
-
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
-
- //===--- Output operands ---===//
-
- StringRef getOutputConstraint(unsigned i) const {
- assert(i < NumOutputs);
- return Constraints[i];
- }
-
- Expr *getOutputExpr(unsigned i);
-
- const Expr *getOutputExpr(unsigned i) const {
- return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
- }
-
- //===--- Input operands ---===//
-
- StringRef getInputConstraint(unsigned i) const {
- assert(i < NumInputs);
- return Constraints[i + NumOutputs];
- }
-
- Expr *getInputExpr(unsigned i);
- void setInputExpr(unsigned i, Expr *E);
-
- const Expr *getInputExpr(unsigned i) const {
- return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
- }
-
- //===--- Other ---===//
-
- ArrayRef<StringRef> getAllConstraints() const {
- return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
- }
- ArrayRef<StringRef> getClobbers() const {
- return llvm::makeArrayRef(Clobbers, NumClobbers);
- }
- ArrayRef<Expr*> getAllExprs() const {
- return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
- NumInputs + NumOutputs);
- }
-
- StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
-
-private:
- void initialize(const ASTContext &C, StringRef AsmString,
- ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
- ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
-public:
-
- SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSAsmStmtClass;
- }
-
- child_range children() {
- return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
- }
-};
-
-class SEHExceptStmt : public Stmt {
- SourceLocation Loc;
- Stmt *Children[2];
-
- enum { FILTER_EXPR, BLOCK };
-
- SEHExceptStmt(SourceLocation Loc,
- Expr *FilterExpr,
- Stmt *Block);
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { }
-
-public:
- static SEHExceptStmt* Create(const ASTContext &C,
- SourceLocation ExceptLoc,
- Expr *FilterExpr,
- Stmt *Block);
-
- SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- SourceLocation getExceptLoc() const { return Loc; }
- SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
-
- Expr *getFilterExpr() const {
- return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
- }
-
- CompoundStmt *getBlock() const {
- return cast<CompoundStmt>(Children[BLOCK]);
- }
-
- child_range children() {
- return child_range(Children,Children+2);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHExceptStmtClass;
- }
-
-};
-
-class SEHFinallyStmt : public Stmt {
- SourceLocation Loc;
- Stmt *Block;
-
- SEHFinallyStmt(SourceLocation Loc,
- Stmt *Block);
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { }
-
-public:
- static SEHFinallyStmt* Create(const ASTContext &C,
- SourceLocation FinallyLoc,
- Stmt *Block);
-
- SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- SourceLocation getFinallyLoc() const { return Loc; }
- SourceLocation getEndLoc() const { return Block->getLocEnd(); }
-
- CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
-
- child_range children() {
- return child_range(&Block,&Block+1);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHFinallyStmtClass;
- }
-
-};
-
-class SEHTryStmt : public Stmt {
- bool IsCXXTry;
- SourceLocation TryLoc;
- Stmt *Children[2];
-
- enum { TRY = 0, HANDLER = 1 };
-
- SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
- SourceLocation TryLoc,
- Stmt *TryBlock,
- Stmt *Handler);
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
-
-public:
- static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
- SourceLocation TryLoc, Stmt *TryBlock,
- Stmt *Handler);
-
- SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- SourceLocation getTryLoc() const { return TryLoc; }
- SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
-
- bool getIsCXXTry() const { return IsCXXTry; }
-
- CompoundStmt* getTryBlock() const {
- return cast<CompoundStmt>(Children[TRY]);
- }
-
- Stmt *getHandler() const { return Children[HANDLER]; }
-
- /// Returns 0 if not defined
- SEHExceptStmt *getExceptHandler() const;
- SEHFinallyStmt *getFinallyHandler() const;
-
- child_range children() {
- return child_range(Children,Children+2);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHTryStmtClass;
- }
-};
-
-/// Represents a __leave statement.
-///
-class SEHLeaveStmt : public Stmt {
- SourceLocation LeaveLoc;
-public:
- explicit SEHLeaveStmt(SourceLocation LL)
- : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
-
- /// \brief Build an empty __leave statement.
- explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) { }
-
- SourceLocation getLeaveLoc() const { return LeaveLoc; }
- void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LeaveLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LeaveLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHLeaveStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief 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
-/// #pragma omp parallel
-/// {
-/// compute();
-/// }
-/// @endcode
-class CapturedStmt : public Stmt {
-public:
- /// \brief The different capture forms: by 'this', by reference, capture for
- /// variable-length array type etc.
- enum VariableCaptureKind {
- VCK_This,
- VCK_ByRef,
- VCK_ByCopy,
- VCK_VLAType,
- };
-
- /// \brief Describes the capture of either a variable, or 'this', or
- /// variable-length array type.
- class Capture {
- llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
- SourceLocation Loc;
-
- public:
- /// \brief Create a new capture.
- ///
- /// \param Loc The source location associated with this capture.
- ///
- /// \param Kind The kind of capture (this, ByRef, ...).
- ///
- /// \param Var The variable being captured, or null if capturing this.
- ///
- Capture(SourceLocation Loc, VariableCaptureKind Kind,
- VarDecl *Var = nullptr);
-
- /// \brief Determine the kind of capture.
- VariableCaptureKind getCaptureKind() const;
-
- /// \brief 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.
- bool capturesThis() const { return getCaptureKind() == VCK_This; }
-
- /// \brief 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.
- bool capturesVariableByCopy() const {
- return getCaptureKind() == VCK_ByCopy;
- }
-
- /// \brief 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.
- ///
- /// This operation is only valid if this capture captures a variable.
- VarDecl *getCapturedVar() const;
-
- friend class ASTStmtReader;
- };
-
-private:
- /// \brief The number of variable captured, including 'this'.
- unsigned NumCaptures;
-
- /// \brief 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;
-
- /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
- RecordDecl *TheRecordDecl;
-
- /// \brief 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.
- CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
-
- Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); }
-
- Stmt *const *getStoredStmts() const {
- return reinterpret_cast<Stmt *const *>(this + 1);
- }
-
- Capture *getStoredCaptures() const;
-
- void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
-
-public:
- static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
- CapturedRegionKind Kind,
- ArrayRef<Capture> Captures,
- ArrayRef<Expr *> CaptureInits,
- CapturedDecl *CD, RecordDecl *RD);
-
- static CapturedStmt *CreateDeserialized(const ASTContext &Context,
- unsigned NumCaptures);
-
- /// \brief Retrieve the statement being captured.
- Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
- const Stmt *getCapturedStmt() const { return getStoredStmts()[NumCaptures]; }
-
- /// \brief Retrieve the outlined function declaration.
- CapturedDecl *getCapturedDecl();
- const CapturedDecl *getCapturedDecl() const;
-
- /// \brief Set the outlined function declaration.
- void setCapturedDecl(CapturedDecl *D);
-
- /// \brief Retrieve the captured region kind.
- CapturedRegionKind getCapturedRegionKind() const;
-
- /// \brief Set the captured region kind.
- void setCapturedRegionKind(CapturedRegionKind Kind);
-
- /// \brief Retrieve the record declaration for captured variables.
- const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
-
- /// \brief 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.
- bool capturesVariable(const VarDecl *Var) const;
-
- /// \brief An iterator that walks over the captures.
- typedef Capture *capture_iterator;
- typedef const Capture *const_capture_iterator;
- typedef llvm::iterator_range<capture_iterator> capture_range;
- typedef llvm::iterator_range<const_capture_iterator> capture_const_range;
-
- capture_range captures() {
- return capture_range(capture_begin(), capture_end());
- }
- capture_const_range captures() const {
- return capture_const_range(capture_begin(), capture_end());
- }
-
- /// \brief 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
- /// captures.
- capture_iterator capture_end() const {
- return getStoredCaptures() + NumCaptures;
- }
-
- /// \brief Retrieve the number of captures, including 'this'.
- unsigned capture_size() const { return NumCaptures; }
-
- /// \brief Iterator that walks over the capture initialization arguments.
- typedef Expr **capture_init_iterator;
- typedef llvm::iterator_range<capture_init_iterator> capture_init_range;
-
- /// \brief Const iterator that walks over the capture initialization
- /// arguments.
- typedef Expr *const *const_capture_init_iterator;
- typedef llvm::iterator_range<const_capture_init_iterator>
- const_capture_init_range;
-
- capture_init_range capture_inits() {
- return capture_init_range(capture_init_begin(), capture_init_end());
- }
-
- const_capture_init_range capture_inits() const {
- return const_capture_init_range(capture_init_begin(), capture_init_end());
- }
-
- /// \brief Retrieve the first initialization argument.
- capture_init_iterator capture_init_begin() {
- return reinterpret_cast<Expr **>(getStoredStmts());
- }
-
- const_capture_init_iterator capture_init_begin() const {
- return reinterpret_cast<Expr *const *>(getStoredStmts());
- }
-
- /// \brief Retrieve the iterator pointing one past the last initialization
- /// argument.
- capture_init_iterator capture_init_end() {
- return capture_init_begin() + NumCaptures;
- }
-
- const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCapturedStmt()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCapturedStmt()->getLocEnd();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- return getCapturedStmt()->getSourceRange();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CapturedStmtClass;
- }
-
- child_range children();
-
- friend class ASTStmtReader;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
deleted file mode 100644
index 1ca73e2..0000000
--- a/include/clang/AST/StmtCXX.h
+++ /dev/null
@@ -1,417 +0,0 @@
-//===--- StmtCXX.h - Classes for representing C++ statements ----*- 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 C++ statement AST node classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTCXX_H
-#define LLVM_CLANG_AST_STMTCXX_H
-
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class VarDecl;
-
-/// CXXCatchStmt - This represents a C++ catch block.
-///
-class CXXCatchStmt : public Stmt {
- SourceLocation CatchLoc;
- /// The exception-declaration of the type.
- VarDecl *ExceptionDecl;
- /// The handler block.
- Stmt *HandlerBlock;
-
-public:
- CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
- : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
- HandlerBlock(handlerBlock) {}
-
- CXXCatchStmt(EmptyShell Empty)
- : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
-
- SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return HandlerBlock->getLocEnd();
- }
-
- SourceLocation getCatchLoc() const { return CatchLoc; }
- VarDecl *getExceptionDecl() const { return ExceptionDecl; }
- QualType getCaughtType() const;
- Stmt *getHandlerBlock() const { return HandlerBlock; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXCatchStmtClass;
- }
-
- child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
-
- friend class ASTStmtReader;
-};
-
-/// CXXTryStmt - A C++ try block, including all handlers.
-///
-class CXXTryStmt : public Stmt {
- SourceLocation TryLoc;
- unsigned 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);
- }
-
-public:
- static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
- Stmt *tryBlock, ArrayRef<Stmt*> handlers);
-
- static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
- unsigned numHandlers);
-
- SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- SourceLocation getTryLoc() const { return TryLoc; }
- SourceLocation getEndLoc() const {
- return getStmts()[NumHandlers]->getLocEnd();
- }
-
- CompoundStmt *getTryBlock() {
- return cast<CompoundStmt>(getStmts()[0]);
- }
- const CompoundStmt *getTryBlock() const {
- return cast<CompoundStmt>(getStmts()[0]);
- }
-
- unsigned getNumHandlers() const { return NumHandlers; }
- CXXCatchStmt *getHandler(unsigned i) {
- return cast<CXXCatchStmt>(getStmts()[i + 1]);
- }
- const CXXCatchStmt *getHandler(unsigned i) const {
- return cast<CXXCatchStmt>(getStmts()[i + 1]);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTryStmtClass;
- }
-
- child_range children() {
- return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
- }
-
- friend class ASTStmtReader;
-};
-
-/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
-/// statement, represented as 'for (range-declarator : range-expression)'.
-///
-/// This is stored in a partially-desugared form to allow full semantic
-/// analysis of the constituent components. The original syntactic components
-/// can be extracted using getLoopVariable and getRangeInit.
-class CXXForRangeStmt : public Stmt {
- SourceLocation ForLoc;
- enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
- // SubExprs[RANGE] is an expression or declstmt.
- // SubExprs[COND] and SubExprs[INC] are expressions.
- Stmt *SubExprs[END];
- SourceLocation CoawaitLoc;
- SourceLocation ColonLoc;
- SourceLocation RParenLoc;
-
- friend class ASTStmtReader;
-public:
- CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
- Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
- SourceLocation FL, SourceLocation CAL, SourceLocation CL,
- SourceLocation RPL);
- CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
-
-
- VarDecl *getLoopVariable();
- Expr *getRangeInit();
-
- const VarDecl *getLoopVariable() const;
- const Expr *getRangeInit() const;
-
-
- DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
- DeclStmt *getBeginEndStmt() {
- return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
- }
- Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
- Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
- DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
- Stmt *getBody() { return SubExprs[BODY]; }
-
- const DeclStmt *getRangeStmt() const {
- return cast<DeclStmt>(SubExprs[RANGE]);
- }
- const DeclStmt *getBeginEndStmt() const {
- return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
- }
- const Expr *getCond() const {
- return cast_or_null<Expr>(SubExprs[COND]);
- }
- const Expr *getInc() const {
- return cast_or_null<Expr>(SubExprs[INC]);
- }
- const DeclStmt *getLoopVarStmt() const {
- return cast<DeclStmt>(SubExprs[LOOPVAR]);
- }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
- void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
- void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
- void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getForLoc() const { return ForLoc; }
- SourceLocation getCoawaitLoc() const { return CoawaitLoc; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXForRangeStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[END]);
- }
-};
-
-/// \brief 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
-/// in the program only when a particular dependent name does not exist. For
-/// example:
-///
-/// \code
-/// template<typename T>
-/// void call_foo(T &t) {
-/// __if_exists (T::foo) {
-/// t.foo(); // okay: only called when T::foo exists.
-/// }
-/// }
-/// \endcode
-///
-/// Similarly, the __if_not_exists statement can be used to include the
-/// statements when a particular name does not exist.
-///
-/// Note that this statement only captures __if_exists and __if_not_exists
-/// statements whose name is dependent. All non-dependent cases are handled
-/// directly in the parser, so that they don't introduce a new scope. Clang
-/// introduces scopes in the dependent case to keep names inside the compound
-/// statement from leaking out into the surround statements, which would
-/// compromise the template instantiation model. This behavior differs from
-/// Visual C++ (which never introduces a scope), but is a fairly reasonable
-/// approximation of the VC++ behavior.
-class MSDependentExistsStmt : public Stmt {
- SourceLocation KeywordLoc;
- bool IsIfExists;
- NestedNameSpecifierLoc QualifierLoc;
- DeclarationNameInfo NameInfo;
- Stmt *SubStmt;
-
- friend class ASTReader;
- friend class ASTStmtReader;
-
-public:
- MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists,
- NestedNameSpecifierLoc QualifierLoc,
- DeclarationNameInfo NameInfo,
- CompoundStmt *SubStmt)
- : Stmt(MSDependentExistsStmtClass),
- KeywordLoc(KeywordLoc), IsIfExists(IsIfExists),
- QualifierLoc(QualifierLoc), NameInfo(NameInfo),
- SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
-
- /// \brief 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.
- bool isIfExists() const { return IsIfExists; }
-
- /// \brief Determine whether this is an __if_exists statement.
- bool isIfNotExists() const { return !IsIfExists; }
-
- /// \brief 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
- /// location information
- DeclarationNameInfo getNameInfo() const { return NameInfo; }
-
- /// \brief 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);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- child_range children() {
- return child_range(&SubStmt, &SubStmt+1);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSDependentExistsStmtClass;
- }
-};
-
-/// \brief 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 : public Stmt {
- enum SubStmt {
- Body, ///< The body of the coroutine.
- Promise, ///< The promise statement.
- InitSuspend, ///< The initial suspend statement, run before the body.
- FinalSuspend, ///< The final suspend statement, run after the body.
- OnException, ///< Handler for exceptions thrown in the body.
- OnFallthrough, ///< Handler for control flow falling off the body.
- ReturnValue, ///< Return value for thunk function.
- FirstParamMove ///< First offset for move construction of parameter copies.
- };
- Stmt *SubStmts[SubStmt::FirstParamMove];
-
- friend class ASTStmtReader;
-public:
- CoroutineBodyStmt(Stmt *Body, Stmt *Promise, Stmt *InitSuspend,
- Stmt *FinalSuspend, Stmt *OnException, Stmt *OnFallthrough,
- Expr *ReturnValue, ArrayRef<Expr *> ParamMoves)
- : Stmt(CoroutineBodyStmtClass) {
- SubStmts[CoroutineBodyStmt::Body] = Body;
- SubStmts[CoroutineBodyStmt::Promise] = Promise;
- SubStmts[CoroutineBodyStmt::InitSuspend] = InitSuspend;
- SubStmts[CoroutineBodyStmt::FinalSuspend] = FinalSuspend;
- SubStmts[CoroutineBodyStmt::OnException] = OnException;
- SubStmts[CoroutineBodyStmt::OnFallthrough] = OnFallthrough;
- SubStmts[CoroutineBodyStmt::ReturnValue] = ReturnValue;
- // FIXME: Tail-allocate space for parameter move expressions and store them.
- assert(ParamMoves.empty() && "not implemented yet");
- }
-
- /// \brief Retrieve the body of the coroutine as written. This will be either
- /// a CompoundStmt or a TryStmt.
- Stmt *getBody() const {
- return SubStmts[SubStmt::Body];
- }
-
- Stmt *getPromiseDeclStmt() const { return SubStmts[SubStmt::Promise]; }
- VarDecl *getPromiseDecl() const {
- return cast<VarDecl>(cast<DeclStmt>(getPromiseDeclStmt())->getSingleDecl());
- }
-
- Stmt *getInitSuspendStmt() const { return SubStmts[SubStmt::InitSuspend]; }
- Stmt *getFinalSuspendStmt() const { return SubStmts[SubStmt::FinalSuspend]; }
-
- Stmt *getExceptionHandler() const { return SubStmts[SubStmt::OnException]; }
- Stmt *getFallthroughHandler() const {
- return SubStmts[SubStmt::OnFallthrough];
- }
-
- Expr *getReturnValueInit() const {
- return cast<Expr>(SubStmts[SubStmt::ReturnValue]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBody()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getBody()->getLocEnd();
- }
-
- child_range children() {
- return child_range(SubStmts, SubStmts + SubStmt::FirstParamMove);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoroutineBodyStmtClass;
- }
-};
-
-/// \brief 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
-/// (or braced-init-list), followed by termination of the coroutine.
-///
-/// This initialization is modeled by the evaluation of the operand
-/// followed by a call to one of:
-/// <promise>.return_value(<operand>)
-/// <promise>.return_void()
-/// which we name the "promise call".
-class CoreturnStmt : public Stmt {
- SourceLocation CoreturnLoc;
-
- enum SubStmt { Operand, PromiseCall, Count };
- Stmt *SubStmts[SubStmt::Count];
-
- friend class ASTStmtReader;
-public:
- CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall)
- : Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc) {
- SubStmts[SubStmt::Operand] = Operand;
- SubStmts[SubStmt::PromiseCall] = PromiseCall;
- }
-
- SourceLocation getKeywordLoc() const { return CoreturnLoc; }
-
- /// \brief 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'
- /// statement. Will be nullptr if either the coroutine has not yet been
- /// finalized or the coroutine has no eventual return type.
- Expr *getPromiseCall() const {
- return static_cast<Expr*>(SubStmts[PromiseCall]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getOperand()->getLocEnd();
- }
-
- child_range children() {
- return child_range(SubStmts, SubStmts + SubStmt::Count);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoreturnStmtClass;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
deleted file mode 100644
index ab636a5..0000000
--- a/include/clang/AST/StmtGraphTraits.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===--- StmtGraphTraits.h - Graph Traits for the class Stmt ----*- 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 template specialization of llvm::GraphTraits to
-// treat ASTs (Stmt*) as graphs
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTGRAPHTRAITS_H
-#define LLVM_CLANG_AST_STMTGRAPHTRAITS_H
-
-#include "clang/AST/Stmt.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/ADT/GraphTraits.h"
-
-namespace llvm {
-
-//template <typename T> struct GraphTraits;
-
-
-template <> struct GraphTraits<clang::Stmt*> {
- typedef clang::Stmt NodeType;
- typedef clang::Stmt::child_iterator ChildIteratorType;
- typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
-
- static NodeType* getEntryNode(clang::Stmt* S) { return S; }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- if (N) return N->child_begin();
- else return ChildIteratorType();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- if (N) return N->child_end();
- else return ChildIteratorType();
- }
-
- static nodes_iterator nodes_begin(clang::Stmt* S) {
- return df_begin(S);
- }
-
- static nodes_iterator nodes_end(clang::Stmt* S) {
- return df_end(S);
- }
-};
-
-
-template <> struct GraphTraits<const clang::Stmt*> {
- typedef const clang::Stmt NodeType;
- typedef clang::Stmt::const_child_iterator ChildIteratorType;
- typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
-
- static NodeType* getEntryNode(const clang::Stmt* S) { return S; }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- if (N) return N->child_begin();
- else return ChildIteratorType();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- if (N) return N->child_end();
- else return ChildIteratorType();
- }
-
- static nodes_iterator nodes_begin(const clang::Stmt* S) {
- return df_begin(S);
- }
-
- static nodes_iterator nodes_end(const clang::Stmt* S) {
- return df_end(S);
- }
-};
-
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
deleted file mode 100644
index 81f8ad43..0000000
--- a/include/clang/AST/StmtIterator.h
+++ /dev/null
@@ -1,144 +0,0 @@
-//===--- StmtIterator.h - Iterators for Statements --------------*- 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 StmtIterator and ConstStmtIterator classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTITERATOR_H
-#define LLVM_CLANG_AST_STMTITERATOR_H
-
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-#include <cstddef>
-#include <iterator>
-#include <utility>
-
-namespace clang {
-
-class Stmt;
-class Decl;
-class VariableArrayType;
-
-class StmtIteratorBase {
-protected:
- enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2,
- Flags = 0x3 };
-
- union {
- Stmt **stmt;
- Decl **DGI;
- };
- uintptr_t RawVAPtr;
- Decl **DGE;
-
- bool inDeclGroup() const {
- return (RawVAPtr & Flags) == DeclGroupMode;
- }
-
- bool inSizeOfTypeVA() const {
- return (RawVAPtr & Flags) == SizeOfTypeVAMode;
- }
-
- bool inStmt() const {
- return (RawVAPtr & Flags) == StmtMode;
- }
-
- const VariableArrayType *getVAPtr() const {
- return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
- }
-
- void setVAPtr(const VariableArrayType *P) {
- assert (inDeclGroup() || inSizeOfTypeVA());
- RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
- }
-
- void NextDecl(bool ImmediateAdvance = true);
- bool HandleDecl(Decl* D);
- void NextVA();
-
- Stmt*& GetDeclExpr() const;
-
- StmtIteratorBase(Stmt **s) : stmt(s), RawVAPtr(0) {}
- StmtIteratorBase(const VariableArrayType *t);
- StmtIteratorBase(Decl **dgi, Decl **dge);
- StmtIteratorBase() : stmt(nullptr), RawVAPtr(0) {}
-};
-
-
-template <typename DERIVED, typename REFERENCE>
-class StmtIteratorImpl : public StmtIteratorBase,
- public std::iterator<std::forward_iterator_tag,
- REFERENCE, ptrdiff_t,
- REFERENCE, REFERENCE> {
-protected:
- StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
-public:
- StmtIteratorImpl() {}
- StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
- StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
- StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
-
- DERIVED& operator++() {
- if (inStmt())
- ++stmt;
- else if (getVAPtr())
- NextVA();
- else
- NextDecl();
-
- return static_cast<DERIVED&>(*this);
- }
-
- DERIVED operator++(int) {
- DERIVED tmp = static_cast<DERIVED&>(*this);
- operator++();
- return tmp;
- }
-
- bool operator==(const DERIVED& RHS) const {
- return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr;
- }
-
- bool operator!=(const DERIVED& RHS) const {
- return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr;
- }
-
- REFERENCE operator*() const {
- return inStmt() ? *stmt : GetDeclExpr();
- }
-
- REFERENCE operator->() const { return operator*(); }
-};
-
-struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
- explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
-
- StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
-
- StmtIterator(Decl** dgi, Decl** dge)
- : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
-
- StmtIterator(const VariableArrayType *t)
- : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
-};
-
-struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
- const Stmt*> {
- explicit ConstStmtIterator() :
- StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
-
- ConstStmtIterator(const StmtIterator& RHS) :
- StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
deleted file mode 100644
index 68fe3ef..0000000
--- a/include/clang/AST/StmtObjC.h
+++ /dev/null
@@ -1,375 +0,0 @@
-//===--- StmtObjC.h - Classes for representing ObjC statements --*- 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 Objective-C statement AST node classes.
-
-#ifndef LLVM_CLANG_AST_STMTOBJC_H
-#define LLVM_CLANG_AST_STMTOBJC_H
-
-#include "clang/AST/Stmt.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-/// \brief Represents Objective-C's collection statement.
-///
-/// This is represented as 'for (element 'in' collection-expression)' stmt.
-class ObjCForCollectionStmt : public Stmt {
- enum { ELEM, COLLECTION, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
- SourceLocation ForLoc;
- SourceLocation RParenLoc;
-public:
- ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
- SourceLocation FCL, SourceLocation RPL);
- explicit ObjCForCollectionStmt(EmptyShell Empty) :
- Stmt(ObjCForCollectionStmtClass, Empty) { }
-
- Stmt *getElement() { return SubExprs[ELEM]; }
- Expr *getCollection() {
- return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
- }
- Stmt *getBody() { return SubExprs[BODY]; }
-
- const Stmt *getElement() const { return SubExprs[ELEM]; }
- const Expr *getCollection() const {
- return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
- }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- void setElement(Stmt *S) { SubExprs[ELEM] = S; }
- void setCollection(Expr *E) {
- SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E);
- }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getForLoc() const { return ForLoc; }
- void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCForCollectionStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
- }
-};
-
-/// \brief Represents Objective-C's \@catch statement.
-class ObjCAtCatchStmt : public Stmt {
-private:
- VarDecl *ExceptionDecl;
- Stmt *Body;
- SourceLocation AtCatchLoc, RParenLoc;
-
-public:
- ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
- VarDecl *catchVarDecl,
- Stmt *atCatchStmt)
- : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl),
- Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
-
- explicit ObjCAtCatchStmt(EmptyShell Empty) :
- Stmt(ObjCAtCatchStmtClass, Empty) { }
-
- const Stmt *getCatchBody() const { return Body; }
- Stmt *getCatchBody() { return Body; }
- void setCatchBody(Stmt *S) { Body = S; }
-
- const VarDecl *getCatchParamDecl() const {
- return ExceptionDecl;
- }
- VarDecl *getCatchParamDecl() {
- return ExceptionDecl;
- }
- void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
-
- SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
- void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); }
-
- bool hasEllipsis() const { return getCatchParamDecl() == nullptr; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtCatchStmtClass;
- }
-
- child_range children() { return child_range(&Body, &Body + 1); }
-};
-
-/// \brief Represents Objective-C's \@finally statement
-class ObjCAtFinallyStmt : public Stmt {
- SourceLocation AtFinallyLoc;
- Stmt *AtFinallyStmt;
-
-public:
- ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
- : Stmt(ObjCAtFinallyStmtClass), AtFinallyLoc(atFinallyLoc),
- AtFinallyStmt(atFinallyStmt) {}
-
- explicit ObjCAtFinallyStmt(EmptyShell Empty) :
- Stmt(ObjCAtFinallyStmtClass, Empty) { }
-
- const Stmt *getFinallyBody() const { return AtFinallyStmt; }
- Stmt *getFinallyBody() { return AtFinallyStmt; }
- void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtFinallyLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return AtFinallyStmt->getLocEnd();
- }
-
- SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
- void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtFinallyStmtClass;
- }
-
- child_range children() {
- return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
- }
-};
-
-/// \brief Represents Objective-C's \@try ... \@catch ... \@finally statement.
-class ObjCAtTryStmt : public Stmt {
-private:
- // The location of the @ in the \@try.
- SourceLocation AtTryLoc;
-
- // The number of catch blocks in this statement.
- unsigned NumCatchStmts : 16;
-
- // Whether this statement has a \@finally statement.
- bool HasFinally : 1;
-
- /// \brief 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)
- /// and, finally, the \@finally (if it exists).
- Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
- const Stmt* const *getStmts() const {
- return reinterpret_cast<const Stmt * const*> (this + 1);
- }
-
- ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
- Stmt **CatchStmts, unsigned NumCatchStmts,
- Stmt *atFinallyStmt);
-
- explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
- bool HasFinally)
- : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
- HasFinally(HasFinally) { }
-
-public:
- static ObjCAtTryStmt *Create(const ASTContext &Context,
- SourceLocation atTryLoc, Stmt *atTryStmt,
- Stmt **CatchStmts, unsigned NumCatchStmts,
- Stmt *atFinallyStmt);
- static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context,
- unsigned NumCatchStmts, bool HasFinally);
-
- /// \brief Retrieve the location of the @ in the \@try.
- SourceLocation getAtTryLoc() const { return AtTryLoc; }
- void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
-
- /// \brief 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
- /// block.
- unsigned getNumCatchStmts() const { return NumCatchStmts; }
-
- /// \brief 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.
- 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.
- 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.
- const ObjCAtFinallyStmt *getFinallyStmt() const {
- if (!HasFinally)
- return nullptr;
-
- return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
- }
- ObjCAtFinallyStmt *getFinallyStmt() {
- if (!HasFinally)
- return nullptr;
-
- return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
- }
- void setFinallyStmt(Stmt *S) {
- assert(HasFinally && "@try does not have a @finally slot!");
- getStmts()[1 + NumCatchStmts] = S;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtTryLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtTryStmtClass;
- }
-
- child_range children() {
- return child_range(getStmts(),
- getStmts() + 1 + NumCatchStmts + HasFinally);
- }
-};
-
-/// \brief Represents Objective-C's \@synchronized statement.
-///
-/// Example:
-/// \code
-/// @synchronized (sem) {
-/// do-something;
-/// }
-/// \endcode
-class ObjCAtSynchronizedStmt : public Stmt {
-private:
- SourceLocation AtSynchronizedLoc;
- enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
- Stmt* SubStmts[END_EXPR];
-
-public:
- ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
- Stmt *synchBody)
- : Stmt(ObjCAtSynchronizedStmtClass) {
- SubStmts[SYNC_EXPR] = synchExpr;
- SubStmts[SYNC_BODY] = synchBody;
- AtSynchronizedLoc = atSynchronizedLoc;
- }
- explicit ObjCAtSynchronizedStmt(EmptyShell Empty) :
- Stmt(ObjCAtSynchronizedStmtClass, Empty) { }
-
- SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
- void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; }
-
- const CompoundStmt *getSynchBody() const {
- return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
- }
- CompoundStmt *getSynchBody() {
- return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
- }
- void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; }
-
- const Expr *getSynchExpr() const {
- return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
- }
- Expr *getSynchExpr() {
- return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
- }
- void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtSynchronizedLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSynchBody()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
- }
-
- child_range children() {
- return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
- }
-};
-
-/// \brief Represents Objective-C's \@throw statement.
-class ObjCAtThrowStmt : public Stmt {
- SourceLocation AtThrowLoc;
- Stmt *Throw;
-
-public:
- ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
- : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
- AtThrowLoc = atThrowLoc;
- }
- explicit ObjCAtThrowStmt(EmptyShell Empty) :
- Stmt(ObjCAtThrowStmtClass, Empty) { }
-
- const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
- Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
- void setThrowExpr(Stmt *S) { Throw = S; }
-
- SourceLocation getThrowLoc() { return AtThrowLoc; }
- void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return Throw ? Throw->getLocEnd() : AtThrowLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtThrowStmtClass;
- }
-
- child_range children() { return child_range(&Throw, &Throw+1); }
-};
-
-/// \brief Represents Objective-C's \@autoreleasepool Statement
-class ObjCAutoreleasePoolStmt : public Stmt {
- SourceLocation AtLoc;
- Stmt *SubStmt;
-
-public:
- ObjCAutoreleasePoolStmt(SourceLocation atLoc, Stmt *subStmt)
- : Stmt(ObjCAutoreleasePoolStmtClass), AtLoc(atLoc), SubStmt(subStmt) {}
-
- explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
- Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
-
- const Stmt *getSubStmt() const { return SubStmt; }
- Stmt *getSubStmt() { return SubStmt; }
- void setSubStmt(Stmt *S) { SubStmt = S; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
- }
-
- child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
deleted file mode 100644
index 1ba859c..0000000
--- a/include/clang/AST/StmtOpenMP.h
+++ /dev/null
@@ -1,2422 +0,0 @@
-//===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// \brief This file defines OpenMP AST classes for executable directives and
-/// clauses.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTOPENMP_H
-#define LLVM_CLANG_AST_STMTOPENMP_H
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/OpenMPClause.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-// AST classes for directives.
-//===----------------------------------------------------------------------===//
-
-/// \brief This is a basic class for representing single OpenMP executable
-/// directive.
-///
-class OMPExecutableDirective : public Stmt {
- friend class ASTStmtReader;
- /// \brief Kind of the directive.
- OpenMPDirectiveKind Kind;
- /// \brief Starting location of the directive (directive keyword).
- SourceLocation StartLoc;
- /// \brief Ending location of the directive.
- SourceLocation EndLoc;
- /// \brief Numbers of clauses.
- const unsigned NumClauses;
- /// \brief Number of child expressions/stmts.
- const unsigned NumChildren;
- /// \brief 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.
- MutableArrayRef<OMPClause *> getClauses() {
- OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
- reinterpret_cast<char *>(this) + ClausesOffset);
- return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
- }
-
-protected:
- /// \brief Build instance of directive of class \a K.
- ///
- /// \param SC Statement class.
- /// \param K Kind of OpenMP directive.
- /// \param StartLoc Starting location of the directive (directive keyword).
- /// \param EndLoc Ending location of the directive.
- ///
- template <typename T>
- OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
- SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses, unsigned NumChildren)
- : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
- EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
- NumChildren(NumChildren),
- ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
- llvm::alignOf<OMPClause *>())) {}
-
- /// \brief 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.
- ///
- /// /param S Associated statement.
- ///
- void setAssociatedStmt(Stmt *S) {
- assert(hasAssociatedStmt() && "no associated statement.");
- *child_begin() = S;
- }
-
-public:
- /// \brief Iterates over a filtered subrange of clauses applied to a
- /// directive.
- ///
- /// This iterator visits only clauses of type SpecificClause.
- template <typename SpecificClause>
- class specific_clause_iterator
- : public llvm::iterator_adaptor_base<
- specific_clause_iterator<SpecificClause>,
- ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
- const SpecificClause *, ptrdiff_t, const SpecificClause *,
- const SpecificClause *> {
- ArrayRef<OMPClause *>::const_iterator End;
-
- void SkipToNextClause() {
- while (this->I != End && !isa<SpecificClause>(*this->I))
- ++this->I;
- }
-
- public:
- explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
- : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
- End(Clauses.end()) {
- SkipToNextClause();
- }
-
- const SpecificClause *operator*() const {
- return cast<SpecificClause>(*this->I);
- }
- const SpecificClause *operator->() const { return **this; }
-
- specific_clause_iterator &operator++() {
- ++this->I;
- SkipToNextClause();
- return *this;
- }
- };
-
- template <typename SpecificClause>
- static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
- getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
- return {specific_clause_iterator<SpecificClause>(Clauses),
- specific_clause_iterator<SpecificClause>(
- llvm::makeArrayRef(Clauses.end(), 0))};
- }
-
- template <typename SpecificClause>
- llvm::iterator_range<specific_clause_iterator<SpecificClause>>
- getClausesOfKind() const {
- return getClausesOfKind<SpecificClause>(clauses());
- }
-
- /// Gets a single clause of the specified kind associated with the
- /// current directive iff there is only one clause of this kind (and assertion
- /// is fired if there is more than one clause is associated with the
- /// directive). Returns nullptr if no clause of this kind is associated with
- /// the directive.
- template <typename SpecificClause>
- const SpecificClause *getSingleClause() const {
- auto Clauses = getClausesOfKind<SpecificClause>();
-
- if (Clauses.begin() != Clauses.end()) {
- assert(std::next(Clauses.begin()) == Clauses.end() &&
- "There are at least 2 clauses of the specified kind");
- return *Clauses.begin();
- }
- return nullptr;
- }
-
- /// Returns true if the current directive has one or more clauses of a
- /// specific kind.
- template <typename SpecificClause>
- bool hasClausesOfKind() const {
- auto Clauses = getClausesOfKind<SpecificClause>();
- return Clauses.begin() != Clauses.end();
- }
-
- /// \brief Returns starting location of directive kind.
- SourceLocation getLocStart() const { return StartLoc; }
- /// \brief Returns ending location of directive.
- SourceLocation getLocEnd() const { return EndLoc; }
-
- /// \brief 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.
- ///
- /// \param Loc New ending location of directive.
- ///
- void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
-
- /// \brief Get number of clauses.
- unsigned getNumClauses() const { return NumClauses; }
-
- /// \brief Returns specified clause.
- ///
- /// \param i Number of clause.
- ///
- OMPClause *getClause(unsigned i) const { return clauses()[i]; }
-
- /// \brief Returns true if directive has associated statement.
- bool hasAssociatedStmt() const { return NumChildren > 0; }
-
- /// \brief Returns statement associated with the directive.
- Stmt *getAssociatedStmt() const {
- assert(hasAssociatedStmt() && "no associated statement.");
- return const_cast<Stmt *>(*child_begin());
- }
-
- OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
- S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
- }
-
- child_range children() {
- if (!hasAssociatedStmt())
- return child_range(child_iterator(), child_iterator());
- Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
- return child_range(ChildStorage, ChildStorage + NumChildren);
- }
-
- ArrayRef<OMPClause *> clauses() { return getClauses(); }
-
- ArrayRef<OMPClause *> clauses() const {
- return const_cast<OMPExecutableDirective *>(this)->getClauses();
- }
-};
-
-/// \brief This represents '#pragma omp parallel' directive.
-///
-/// \code
-/// #pragma omp parallel private(a,b) reduction(+: c,d)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clauses 'private'
-/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
-/// variables 'c' and 'd'.
-///
-class OMPParallelDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief true if the construct has inner cancel directive.
- bool HasCancel;
-
- /// \brief 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.
- ///
- OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
- StartLoc, EndLoc, NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPParallelDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement associated with the directive.
- /// \param HasCancel true if this directive has inner cancel directive.
- ///
- static OMPParallelDirective *
- 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.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPParallelDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPParallelDirectiveClass;
- }
-};
-
-/// \brief 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.
- unsigned CollapsedNum;
-
- /// \brief Offsets to the stored exprs.
- /// This enumeration contains offsets to all the pointers to children
- /// expressions stored in OMPLoopDirective.
- /// The first 9 children are nesessary for all the loop directives, and
- /// the next 7 are specific to the worksharing ones.
- /// After the fixed children, three arrays of length CollapsedNum are
- /// allocated: loop counters, their updates and final values.
- ///
- enum {
- AssociatedStmtOffset = 0,
- IterationVariableOffset = 1,
- LastIterationOffset = 2,
- CalcLastIterationOffset = 3,
- PreConditionOffset = 4,
- CondOffset = 5,
- InitOffset = 6,
- IncOffset = 7,
- // The '...End' enumerators do not correspond to child expressions - they
- // specify the offset to the end (and start of the following counters/
- // updates/finals arrays).
- DefaultEnd = 8,
- // The following 7 exprs are used by worksharing loops only.
- IsLastIterVariableOffset = 8,
- LowerBoundVariableOffset = 9,
- UpperBoundVariableOffset = 10,
- StrideVariableOffset = 11,
- EnsureUpperBoundOffset = 12,
- NextLowerBoundOffset = 13,
- NextUpperBoundOffset = 14,
- // Offset to the end (and start of the following counters/updates/finals
- // arrays) for worksharing loop directives.
- WorksharingEnd = 15,
- };
-
- /// \brief 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.
- 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.
- MutableArrayRef<Expr *> getInits() {
- Expr **Storage = reinterpret_cast<Expr **>(
- &*std::next(child_begin(),
- getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
- return MutableArrayRef<Expr *>(Storage, CollapsedNum);
- }
-
- /// \brief Get the updates storage.
- MutableArrayRef<Expr *> getUpdates() {
- Expr **Storage = reinterpret_cast<Expr **>(
- &*std::next(child_begin(),
- getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
- return MutableArrayRef<Expr *>(Storage, CollapsedNum);
- }
-
- /// \brief Get the final counter updates storage.
- MutableArrayRef<Expr *> getFinals() {
- Expr **Storage = reinterpret_cast<Expr **>(
- &*std::next(child_begin(),
- getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
- return MutableArrayRef<Expr *>(Storage, CollapsedNum);
- }
-
-protected:
- /// \brief Build instance of loop directive of class \a Kind.
- ///
- /// \param SC Statement class.
- /// \param Kind Kind of OpenMP directive.
- /// \param StartLoc Starting location of the directive (directive keyword).
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
- /// \param NumClauses Number of clauses.
- /// \param NumSpecialChildren Number of additional directive-specific stmts.
- ///
- template <typename T>
- OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
- SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses,
- unsigned NumSpecialChildren = 0)
- : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
- numLoopChildren(CollapsedNum, Kind) +
- NumSpecialChildren),
- CollapsedNum(CollapsedNum) {}
-
- /// \brief Offset to the start of children expression arrays.
- static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
- return (isOpenMPWorksharingDirective(Kind) ||
- isOpenMPTaskLoopDirective(Kind) ||
- isOpenMPDistributeDirective(Kind))
- ? WorksharingEnd
- : DefaultEnd;
- }
-
- /// \brief Children number.
- static unsigned numLoopChildren(unsigned CollapsedNum,
- OpenMPDirectiveKind Kind) {
- return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
- // PrivateCounters, Inits,
- // Updates and Finals
- }
-
- void setIterationVariable(Expr *IV) {
- *std::next(child_begin(), IterationVariableOffset) = IV;
- }
- void setLastIteration(Expr *LI) {
- *std::next(child_begin(), LastIterationOffset) = LI;
- }
- void setCalcLastIteration(Expr *CLI) {
- *std::next(child_begin(), CalcLastIterationOffset) = CLI;
- }
- void setPreCond(Expr *PC) {
- *std::next(child_begin(), PreConditionOffset) = PC;
- }
- void setCond(Expr *Cond) {
- *std::next(child_begin(), CondOffset) = Cond;
- }
- void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
- void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
- void setIsLastIterVariable(Expr *IL) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), IsLastIterVariableOffset) = IL;
- }
- void setLowerBoundVariable(Expr *LB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), LowerBoundVariableOffset) = LB;
- }
- void setUpperBoundVariable(Expr *UB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), UpperBoundVariableOffset) = UB;
- }
- void setStrideVariable(Expr *ST) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), StrideVariableOffset) = ST;
- }
- void setEnsureUpperBound(Expr *EUB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
- }
- void setNextLowerBound(Expr *NLB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), NextLowerBoundOffset) = NLB;
- }
- void setNextUpperBound(Expr *NUB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), NextUpperBoundOffset) = NUB;
- }
- void setCounters(ArrayRef<Expr *> A);
- void setPrivateCounters(ArrayRef<Expr *> A);
- void setInits(ArrayRef<Expr *> A);
- void setUpdates(ArrayRef<Expr *> A);
- void setFinals(ArrayRef<Expr *> A);
-
-public:
- /// \brief The expressions built for the OpenMP loop CodeGen for the
- /// whole collapsed loop nest.
- struct HelperExprs {
- /// \brief Loop iteration variable.
- Expr *IterationVarRef;
- /// \brief Loop last iteration number.
- Expr *LastIteration;
- /// \brief Loop number of iterations.
- Expr *NumIterations;
- /// \brief Calculation of last iteration.
- Expr *CalcLastIteration;
- /// \brief Loop pre-condition.
- Expr *PreCond;
- /// \brief Loop condition.
- Expr *Cond;
- /// \brief Loop iteration variable init.
- Expr *Init;
- /// \brief Loop increment.
- Expr *Inc;
- /// \brief IsLastIteration - local flag variable passed to runtime.
- Expr *IL;
- /// \brief LowerBound - local variable passed to runtime.
- Expr *LB;
- /// \brief UpperBound - local variable passed to runtime.
- Expr *UB;
- /// \brief Stride - local variable passed to runtime.
- Expr *ST;
- /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
- Expr *EUB;
- /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
- Expr *NLB;
- /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
- Expr *NUB;
- /// \brief Counters Loop counters.
- SmallVector<Expr *, 4> Counters;
- /// \brief PrivateCounters Loop counters.
- SmallVector<Expr *, 4> PrivateCounters;
- /// \brief Expressions for loop counters inits for CodeGen.
- SmallVector<Expr *, 4> Inits;
- /// \brief Expressions for loop counters update for CodeGen.
- SmallVector<Expr *, 4> Updates;
- /// \brief Final loop counter values for GodeGen.
- SmallVector<Expr *, 4> Finals;
-
- /// \brief Check if all the expressions are built (does not check the
- /// worksharing ones).
- bool builtAll() {
- return IterationVarRef != nullptr && LastIteration != nullptr &&
- NumIterations != nullptr && PreCond != nullptr &&
- Cond != nullptr && Init != nullptr && Inc != nullptr;
- }
-
- /// \brief Initialize all the fields to null.
- /// \param Size Number of elements in the counters/finals/updates arrays.
- void clear(unsigned Size) {
- IterationVarRef = nullptr;
- LastIteration = nullptr;
- CalcLastIteration = nullptr;
- PreCond = nullptr;
- Cond = nullptr;
- Init = nullptr;
- Inc = nullptr;
- IL = nullptr;
- LB = nullptr;
- UB = nullptr;
- ST = nullptr;
- EUB = nullptr;
- NLB = nullptr;
- NUB = nullptr;
- Counters.resize(Size);
- PrivateCounters.resize(Size);
- Inits.resize(Size);
- Updates.resize(Size);
- Finals.resize(Size);
- for (unsigned i = 0; i < Size; ++i) {
- Counters[i] = nullptr;
- PrivateCounters[i] = nullptr;
- Inits[i] = nullptr;
- Updates[i] = nullptr;
- Finals[i] = nullptr;
- }
- }
- };
-
- /// \brief Get number of collapsed loops.
- unsigned getCollapsedNumber() const { return CollapsedNum; }
-
- Expr *getIterationVariable() const {
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), IterationVariableOffset)));
- }
- Expr *getLastIteration() const {
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), LastIterationOffset)));
- }
- Expr *getCalcLastIteration() const {
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), CalcLastIterationOffset)));
- }
- Expr *getPreCond() const {
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), PreConditionOffset)));
- }
- Expr *getCond() const {
- return const_cast<Expr *>(
- reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
- }
- Expr *getInit() const {
- return const_cast<Expr *>(
- reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
- }
- Expr *getInc() const {
- return const_cast<Expr *>(
- reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
- }
- Expr *getIsLastIterVariable() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), IsLastIterVariableOffset)));
- }
- Expr *getLowerBoundVariable() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), LowerBoundVariableOffset)));
- }
- Expr *getUpperBoundVariable() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), UpperBoundVariableOffset)));
- }
- Expr *getStrideVariable() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), StrideVariableOffset)));
- }
- Expr *getEnsureUpperBound() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), EnsureUpperBoundOffset)));
- }
- Expr *getNextLowerBound() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), NextLowerBoundOffset)));
- }
- Expr *getNextUpperBound() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), NextUpperBoundOffset)));
- }
- const Stmt *getBody() const {
- // This relies on the loop form is already checked by Sema.
- Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
- Body = cast<ForStmt>(Body)->getBody();
- for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
- Body = Body->IgnoreContainers();
- Body = cast<ForStmt>(Body)->getBody();
- }
- return Body;
- }
-
- ArrayRef<Expr *> counters() { return getCounters(); }
-
- ArrayRef<Expr *> counters() const {
- return const_cast<OMPLoopDirective *>(this)->getCounters();
- }
-
- ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
-
- ArrayRef<Expr *> private_counters() const {
- return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
- }
-
- ArrayRef<Expr *> inits() { return getInits(); }
-
- ArrayRef<Expr *> inits() const {
- return const_cast<OMPLoopDirective *>(this)->getInits();
- }
-
- ArrayRef<Expr *> updates() { return getUpdates(); }
-
- ArrayRef<Expr *> updates() const {
- return const_cast<OMPLoopDirective *>(this)->getUpdates();
- }
-
- ArrayRef<Expr *> finals() { return getFinals(); }
-
- ArrayRef<Expr *> finals() const {
- return const_cast<OMPLoopDirective *>(this)->getFinals();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSimdDirectiveClass ||
- T->getStmtClass() == OMPForDirectiveClass ||
- T->getStmtClass() == OMPForSimdDirectiveClass ||
- T->getStmtClass() == OMPParallelForDirectiveClass ||
- T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
- T->getStmtClass() == OMPTaskLoopDirectiveClass ||
- T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
- T->getStmtClass() == OMPDistributeDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp simd' directive.
-///
-/// \code
-/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clauses 'private'
-/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
-/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
-///
-class OMPSimdDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
- EndLoc, CollapsedNum, NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param CollapsedNum Number of collapsed loops.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param Exprs Helper expressions for CodeGen.
- ///
- static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt,
- const HelperExprs &Exprs);
-
- /// \brief Creates an empty directive with the place
- /// for \a NumClauses clauses.
- ///
- /// \param C AST context.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSimdDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp for' directive.
-///
-/// \code
-/// #pragma omp for private(a,b) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp for' has clauses 'private' with the
-/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
-/// and 'd'.
-///
-class OMPForDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
- CollapsedNum, NumClauses),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param CollapsedNum Number of collapsed loops.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param Exprs Helper expressions for CodeGen.
- /// \param HasCancel true if current directive has inner cancel directive.
- ///
- static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs,
- bool HasCancel);
-
- /// \brief Creates an empty directive with the place
- /// for \a NumClauses clauses.
- ///
- /// \param C AST context.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPForDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp for simd' directive.
-///
-/// \code
-/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp for simd' has clauses 'private'
-/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
-/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
-///
-class OMPForSimdDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
- StartLoc, EndLoc, CollapsedNum, NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param CollapsedNum Number of collapsed loops.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param Exprs Helper expressions for CodeGen.
- ///
- static OMPForSimdDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief Creates an empty directive with the place
- /// for \a NumClauses clauses.
- ///
- /// \param C AST context.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPForSimdDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp sections' directive.
-///
-/// \code
-/// #pragma omp sections private(a,b) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp sections' has clauses 'private' with
-/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
-/// 'c' and 'd'.
-///
-class OMPSectionsDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
- StartLoc, EndLoc, NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPSectionsDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param HasCancel true if current directive has inner directive.
- ///
- static OMPSectionsDirective *
- 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
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSectionsDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp section' directive.
-///
-/// \code
-/// #pragma omp section
-/// \endcode
-///
-class OMPSectionDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
- StartLoc, EndLoc, 0, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPSectionDirective()
- : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
- SourceLocation(), SourceLocation(), 0, 1),
- HasCancel(false) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param HasCancel true if current directive has inner directive.
- ///
- static OMPSectionDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt, bool HasCancel);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSectionDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp single' directive.
-///
-/// \code
-/// #pragma omp single private(a,b) copyprivate(c,d)
-/// \endcode
-/// In this example directive '#pragma omp single' has clauses 'private' with
-/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
-///
-class OMPSingleDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
- StartLoc, EndLoc, NumClauses, 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPSingleDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
- SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPSingleDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPSingleDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSingleDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp master' directive.
-///
-/// \code
-/// #pragma omp master
-/// \endcode
-///
-class OMPMasterDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
- StartLoc, EndLoc, 0, 1) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPMasterDirective()
- : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
- SourceLocation(), SourceLocation(), 0, 1) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPMasterDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPMasterDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp critical' directive.
-///
-/// \code
-/// #pragma omp critical
-/// \endcode
-///
-class OMPCriticalDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Name of the directive.
- DeclarationNameInfo DirName;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param Name Name of the directive.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
- StartLoc, EndLoc, NumClauses, 1),
- DirName(Name) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPCriticalDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- DirName() {}
-
- /// \brief Set name of the directive.
- ///
- /// \param Name Name of the directive.
- ///
- void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param Name Name of the directive.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPCriticalDirective *
- Create(const ASTContext &C, const DeclarationNameInfo &Name,
- SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Return name of the directive.
- ///
- DeclarationNameInfo getDirectiveName() const { return DirName; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPCriticalDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp parallel for' directive.
-///
-/// \code
-/// #pragma omp parallel for private(a,b) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp parallel for' has clauses 'private'
-/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
-/// variables 'c' and 'd'.
-///
-class OMPParallelForDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current region has inner cancel directive.
- bool HasCancel;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
- StartLoc, EndLoc, CollapsedNum, NumClauses),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param CollapsedNum Number of collapsed loops.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param Exprs Helper expressions for CodeGen.
- /// \param HasCancel true if current directive has inner cancel directive.
- ///
- static OMPParallelForDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
-
- /// \brief Creates an empty directive with the place
- /// for \a NumClauses clauses.
- ///
- /// \param C AST context.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPParallelForDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp parallel for simd' directive.
-///
-/// \code
-/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp parallel for simd' has clauses
-/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
-/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
-/// 'd'.
-///
-class OMPParallelForSimdDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
- OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
- NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
- unsigned NumClauses)
- : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
- OMPD_parallel_for_simd, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param CollapsedNum Number of collapsed loops.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param Exprs Helper expressions for CodeGen.
- ///
- static OMPParallelForSimdDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief Creates an empty directive with the place
- /// for \a NumClauses clauses.
- ///
- /// \param C AST context.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp parallel sections' directive.
-///
-/// \code
-/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp parallel sections' has clauses
-/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
-/// and variables 'c' and 'd'.
-///
-class OMPParallelSectionsDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
- OMPD_parallel_sections, StartLoc, EndLoc,
- NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPParallelSectionsDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
- OMPD_parallel_sections, SourceLocation(),
- SourceLocation(), NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param HasCancel true if current directive has inner cancel directive.
- ///
- static OMPParallelSectionsDirective *
- 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
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPParallelSectionsDirective *
- CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp task' directive.
-///
-/// \code
-/// #pragma omp task private(a,b) final(d)
-/// \endcode
-/// In this example directive '#pragma omp task' has clauses 'private' with the
-/// variables 'a' and 'b' and 'final' with condition 'd'.
-///
-class OMPTaskDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief true if this directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
- EndLoc, NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTaskDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param HasCancel true, if current directive has inner cancel directive.
- ///
- static OMPTaskDirective *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
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
- EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskyield' directive.
-///
-/// \code
-/// #pragma omp taskyield
-/// \endcode
-///
-class OMPTaskyieldDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
- StartLoc, EndLoc, 0, 0) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPTaskyieldDirective()
- : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
- SourceLocation(), SourceLocation(), 0, 0) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- ///
- static OMPTaskyieldDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskyieldDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp barrier' directive.
-///
-/// \code
-/// #pragma omp barrier
-/// \endcode
-///
-class OMPBarrierDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
- StartLoc, EndLoc, 0, 0) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPBarrierDirective()
- : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
- SourceLocation(), SourceLocation(), 0, 0) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- ///
- static OMPBarrierDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPBarrierDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskwait' directive.
-///
-/// \code
-/// #pragma omp taskwait
-/// \endcode
-///
-class OMPTaskwaitDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
- StartLoc, EndLoc, 0, 0) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPTaskwaitDirective()
- : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
- SourceLocation(), SourceLocation(), 0, 0) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- ///
- static OMPTaskwaitDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskwaitDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskgroup' directive.
-///
-/// \code
-/// #pragma omp taskgroup
-/// \endcode
-///
-class OMPTaskgroupDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
- StartLoc, EndLoc, 0, 1) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPTaskgroupDirective()
- : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
- SourceLocation(), SourceLocation(), 0, 1) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPTaskgroupDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskgroupDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp flush' directive.
-///
-/// \code
-/// #pragma omp flush(a,b)
-/// \endcode
-/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
-/// and 'b'.
-/// 'omp flush' directive does not have clauses but have an optional list of
-/// variables to flush. This list of variables is stored within some fake clause
-/// FlushClause.
-class OMPFlushDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
- StartLoc, EndLoc, NumClauses, 0) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPFlushDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
- SourceLocation(), SourceLocation(), NumClauses,
- 0) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses (only single OMPFlushClause clause is
- /// allowed).
- ///
- static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPFlushDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPFlushDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp ordered' directive.
-///
-/// \code
-/// #pragma omp ordered
-/// \endcode
-///
-class OMPOrderedDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
- StartLoc, EndLoc, NumClauses, 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPOrderedDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
- SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPOrderedDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPOrderedDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp atomic' directive.
-///
-/// \code
-/// #pragma omp atomic capture
-/// \endcode
-/// In this example directive '#pragma omp atomic' has clause 'capture'.
-///
-class OMPAtomicDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
- /// have atomic expressions of forms
- /// \code
- /// x = x binop expr;
- /// x = expr binop x;
- /// \endcode
- /// This field is true for the first form of the expression and false for the
- /// second. Required for correct codegen of non-associative operations (like
- /// << or >>).
- bool IsXLHSInRHSPart;
- /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
- /// have atomic expressions of forms
- /// \code
- /// v = x; <update x>;
- /// <update x>; v = x;
- /// \endcode
- /// This field is true for the first(postfix) form of the expression and false
- /// otherwise.
- bool IsPostfixUpdate;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
- StartLoc, EndLoc, NumClauses, 5),
- IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPAtomicDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
- SourceLocation(), SourceLocation(), NumClauses,
- 5),
- IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
-
- /// \brief Set 'x' part of the associated expression/statement.
- void setX(Expr *X) { *std::next(child_begin()) = X; }
- /// \brief 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.
- void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
- /// \brief 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'
- /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
- /// detailed description of 'x', 'v' and 'expr').
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param X 'x' part of the associated expression/statement.
- /// \param V 'v' part of the associated expression/statement.
- /// \param E 'expr' part of the associated expression/statement.
- /// \param UE Helper expression of the form
- /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
- /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
- /// second.
- /// \param IsPostfixUpdate true if original value of 'x' must be stored in
- /// 'v', not an updated one.
- static OMPAtomicDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- 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
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief 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
- /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
- /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- Expr *getUpdateExpr() {
- return cast_or_null<Expr>(*std::next(child_begin(), 2));
- }
- const Expr *getUpdateExpr() const {
- return cast_or_null<Expr>(*std::next(child_begin(), 2));
- }
- /// \brief 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
- /// '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.
- 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.
- 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));
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPAtomicDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp target' directive.
-///
-/// \code
-/// #pragma omp target if(a)
-/// \endcode
-/// In this example directive '#pragma omp target' has clause 'if' with
-/// condition 'a'.
-///
-class OMPTargetDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
- StartLoc, EndLoc, NumClauses, 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTargetDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
- SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPTargetDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPTargetDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTargetDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp target data' directive.
-///
-/// \code
-/// #pragma omp target data device(0) if(a) map(b[:])
-/// \endcode
-/// In this example directive '#pragma omp target data' has clauses 'device'
-/// with the value '0', 'if' with condition 'a' and 'map' with array
-/// section 'b[:]'.
-///
-class OMPTargetDataDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param NumClauses The number of clauses.
- ///
- OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
- OMPD_target_data, StartLoc, EndLoc, NumClauses,
- 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTargetDataDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
- OMPD_target_data, SourceLocation(),
- SourceLocation(), NumClauses, 1) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPTargetDataDirective *
- 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.
- ///
- /// \param C AST context.
- /// \param N The number of clauses.
- ///
- static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
- EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTargetDataDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp teams' directive.
-///
-/// \code
-/// #pragma omp teams if(a)
-/// \endcode
-/// In this example directive '#pragma omp teams' has clause 'if' with
-/// condition 'a'.
-///
-class OMPTeamsDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
- StartLoc, EndLoc, NumClauses, 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTeamsDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
- SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTeamsDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp cancellation point' directive.
-///
-/// \code
-/// #pragma omp cancellation point for
-/// \endcode
-///
-/// In this example a cancellation point is created for innermost 'for' region.
-class OMPCancellationPointDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- OpenMPDirectiveKind CancelRegion;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
- OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
- CancelRegion(OMPD_unknown) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPCancellationPointDirective()
- : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
- OMPD_cancellation_point, SourceLocation(),
- SourceLocation(), 0, 0),
- CancelRegion(OMPD_unknown) {}
-
- /// \brief Set cancel region for current cancellation point.
- /// \param CR Cancellation region.
- void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- ///
- static OMPCancellationPointDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- OpenMPDirectiveKind CancelRegion);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
- EmptyShell);
-
- /// \brief Get cancellation region for the current cancellation point.
- OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPCancellationPointDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp cancel' directive.
-///
-/// \code
-/// #pragma omp cancel for
-/// \endcode
-///
-/// In this example a cancel is created for innermost 'for' region.
-class OMPCancelDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- OpenMPDirectiveKind CancelRegion;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
- StartLoc, EndLoc, NumClauses, 0),
- CancelRegion(OMPD_unknown) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- explicit OMPCancelDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
- SourceLocation(), SourceLocation(), NumClauses,
- 0),
- CancelRegion(OMPD_unknown) {}
-
- /// \brief Set cancel region for current cancellation point.
- /// \param CR Cancellation region.
- void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- ///
- static OMPCancelDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPCancelDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Get cancellation region for the current cancellation point.
- OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPCancelDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskloop' directive.
-///
-/// \code
-/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
-/// \endcode
-/// In this example directive '#pragma omp taskloop' has clauses 'private'
-/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
-/// 'num_tasks' with expression 'num'.
-///
-class OMPTaskLoopDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
- StartLoc, EndLoc, CollapsedNum, NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param CollapsedNum Number of collapsed loops.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param Exprs Helper expressions for CodeGen.
- ///
- static OMPTaskLoopDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief Creates an empty directive with the place
- /// for \a NumClauses clauses.
- ///
- /// \param C AST context.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskLoopDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskloop simd' directive.
-///
-/// \code
-/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
-/// \endcode
-/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
-/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
-/// 'num_tasks' with expression 'num'.
-///
-class OMPTaskLoopSimdDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
- OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
- NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
- OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
- CollapsedNum, NumClauses) {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param CollapsedNum Number of collapsed loops.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param Exprs Helper expressions for CodeGen.
- ///
- static OMPTaskLoopSimdDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief Creates an empty directive with the place
- /// for \a NumClauses clauses.
- ///
- /// \param C AST context.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp distribute' directive.
-///
-/// \code
-/// #pragma omp distribute private(a,b)
-/// \endcode
-/// In this example directive '#pragma omp distribute' has clauses 'private'
-/// with the variables 'a' and 'b'
-///
-class OMPDistributeDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
- StartLoc, EndLoc, CollapsedNum, NumClauses)
- {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses)
- {}
-
-public:
- /// \brief Creates directive with a list of \a Clauses.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param CollapsedNum Number of collapsed loops.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param Exprs Helper expressions for CodeGen.
- ///
- static OMPDistributeDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief Creates an empty directive with the place
- /// for \a NumClauses clauses.
- ///
- /// \param C AST context.
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPDistributeDirectiveClass;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
deleted file mode 100644
index df4a2d8..0000000
--- a/include/clang/AST/StmtVisitor.h
+++ /dev/null
@@ -1,227 +0,0 @@
-//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- 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 StmtVisitor and ConstStmtVisitor interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTVISITOR_H
-#define LLVM_CLANG_AST_STMTVISITOR_H
-
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprOpenMP.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-#include "clang/AST/StmtOpenMP.h"
-
-namespace clang {
-
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
-
-/// StmtVisitorBase - This class implements a simple visitor for Stmt
-/// subclasses. Since Expr derives from Stmt, this also includes support for
-/// visiting Exprs.
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
-class StmtVisitorBase {
-public:
-
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
-
- RetTy Visit(PTR(Stmt) S) {
-
- // If we have a binary expr, dispatch to the subcode of the binop. A smart
- // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
- // below.
- if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) {
- switch (BinOp->getOpcode()) {
- case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator);
- case BO_PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator);
- case BO_Mul: DISPATCH(BinMul, BinaryOperator);
- case BO_Div: DISPATCH(BinDiv, BinaryOperator);
- case BO_Rem: DISPATCH(BinRem, BinaryOperator);
- case BO_Add: DISPATCH(BinAdd, BinaryOperator);
- case BO_Sub: DISPATCH(BinSub, BinaryOperator);
- case BO_Shl: DISPATCH(BinShl, BinaryOperator);
- case BO_Shr: DISPATCH(BinShr, BinaryOperator);
-
- case BO_LT: DISPATCH(BinLT, BinaryOperator);
- case BO_GT: DISPATCH(BinGT, BinaryOperator);
- case BO_LE: DISPATCH(BinLE, BinaryOperator);
- case BO_GE: DISPATCH(BinGE, BinaryOperator);
- case BO_EQ: DISPATCH(BinEQ, BinaryOperator);
- case BO_NE: DISPATCH(BinNE, BinaryOperator);
-
- case BO_And: DISPATCH(BinAnd, BinaryOperator);
- case BO_Xor: DISPATCH(BinXor, BinaryOperator);
- case BO_Or : DISPATCH(BinOr, BinaryOperator);
- case BO_LAnd: DISPATCH(BinLAnd, BinaryOperator);
- case BO_LOr : DISPATCH(BinLOr, BinaryOperator);
- case BO_Assign: DISPATCH(BinAssign, BinaryOperator);
- case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator);
- case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator);
- case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator);
- case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator);
- case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator);
- case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator);
- case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator);
- case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator);
- case BO_OrAssign: DISPATCH(BinOrAssign, CompoundAssignOperator);
- case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
- case BO_Comma: DISPATCH(BinComma, BinaryOperator);
- }
- } else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) {
- switch (UnOp->getOpcode()) {
- case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator);
- case UO_PostDec: DISPATCH(UnaryPostDec, UnaryOperator);
- case UO_PreInc: DISPATCH(UnaryPreInc, UnaryOperator);
- case UO_PreDec: DISPATCH(UnaryPreDec, UnaryOperator);
- case UO_AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator);
- case UO_Deref: DISPATCH(UnaryDeref, UnaryOperator);
- case UO_Plus: DISPATCH(UnaryPlus, UnaryOperator);
- case UO_Minus: DISPATCH(UnaryMinus, UnaryOperator);
- case UO_Not: DISPATCH(UnaryNot, UnaryOperator);
- case UO_LNot: DISPATCH(UnaryLNot, UnaryOperator);
- case UO_Real: DISPATCH(UnaryReal, UnaryOperator);
- case UO_Imag: DISPATCH(UnaryImag, UnaryOperator);
- case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator);
- case UO_Coawait: DISPATCH(UnaryCoawait, UnaryOperator);
- }
- }
-
- // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
- switch (S->getStmtClass()) {
- default: llvm_unreachable("Unknown stmt kind!");
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
-#include "clang/AST/StmtNodes.inc"
- }
- }
-
- // If the implementation chooses not to implement a certain visit method, fall
- // back on VisitExpr or whatever else is the superclass.
-#define STMT(CLASS, PARENT) \
- RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
-#include "clang/AST/StmtNodes.inc"
-
- // If the implementation doesn't implement binary operator methods, fall back
- // on VisitBinaryOperator.
-#define BINOP_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
- DISPATCH(BinaryOperator, BinaryOperator); \
- }
- BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
- BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem)
- BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl)
- BINOP_FALLBACK(Shr)
-
- BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
- BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
- BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
- BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
-
- BINOP_FALLBACK(Assign)
- BINOP_FALLBACK(Comma)
-#undef BINOP_FALLBACK
-
- // If the implementation doesn't implement compound assignment operator
- // methods, fall back on VisitCompoundAssignOperator.
-#define CAO_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
- DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
- }
- CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
- CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
- CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
- CAO_FALLBACK(XorAssign)
-#undef CAO_FALLBACK
-
- // If the implementation doesn't implement unary operator methods, fall back
- // on VisitUnaryOperator.
-#define UNARYOP_FALLBACK(NAME) \
- RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
- DISPATCH(UnaryOperator, UnaryOperator); \
- }
- UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
- UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec)
- UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref)
-
- UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus)
- UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot)
- UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag)
- UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(Coawait)
-#undef UNARYOP_FALLBACK
-
- // Base case, ignore it. :)
- RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
-
-#undef PTR
-#undef DISPATCH
-};
-
-/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
-/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
-///
-/// This class does not preserve constness of Stmt pointers (see also
-/// ConstStmtVisitor).
-template<typename ImplClass, typename RetTy=void>
-class StmtVisitor
- : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
-
-/// ConstStmtVisitor - This class implements a simple visitor for Stmt
-/// subclasses. Since Expr derives from Stmt, this also includes support for
-/// visiting Exprs.
-///
-/// This class preserves constness of Stmt pointers (see also StmtVisitor).
-template<typename ImplClass, typename RetTy=void>
-class ConstStmtVisitor
- : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
-
-/// \brief This class implements a simple visitor for OMPClause
-/// subclasses.
-template<class ImplClass, template <typename> class Ptr, typename RetTy>
-class OMPClauseVisitorBase {
-public:
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
-
-#define OPENMP_CLAUSE(Name, Class) \
- RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
-#include "clang/Basic/OpenMPKinds.def"
-
- RetTy Visit(PTR(OMPClause) S) {
- // Top switch clause: visit each OMPClause.
- switch (S->getClauseKind()) {
- default: llvm_unreachable("Unknown clause kind!");
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
-#include "clang/Basic/OpenMPKinds.def"
- }
- }
- // Base case, ignore it. :)
- RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
-#undef PTR
-#undef DISPATCH
-};
-
-template<class ImplClass, typename RetTy = void>
-class OMPClauseVisitor :
- public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {};
-template<class ImplClass, typename RetTy = void>
-class ConstOMPClauseVisitor :
- public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
deleted file mode 100644
index f87171a..0000000
--- a/include/clang/AST/TemplateBase.h
+++ /dev/null
@@ -1,661 +0,0 @@
-//===-- TemplateBase.h - Core classes for 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 definitions which are common for all kinds of
-// template representation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
-#define LLVM_CLANG_AST_TEMPLATEBASE_H
-
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/TrailingObjects.h"
-
-namespace llvm {
- class FoldingSetNodeID;
-}
-
-namespace clang {
-
-class DiagnosticBuilder;
-class Expr;
-struct PrintingPolicy;
-class TypeSourceInfo;
-class ValueDecl;
-
-/// \brief Represents a template argument.
-class TemplateArgument {
-public:
- /// \brief The kind of template argument we're storing.
- enum ArgKind {
- /// \brief Represents an empty template argument, e.g., one that has not
- /// been deduced.
- Null = 0,
- /// The template argument is a type.
- Type,
- /// The template argument is a declaration that was provided for a pointer,
- /// reference, or pointer to member non-type template parameter.
- Declaration,
- /// The template argument is a null pointer or null pointer to member that
- /// was provided for a non-type template parameter.
- NullPtr,
- /// The template argument is an integral value stored in an llvm::APSInt
- /// that was provided for an integral non-type template parameter.
- Integral,
- /// The template argument is a template name that was provided for a
- /// template template parameter.
- Template,
- /// The template argument is a pack expansion of a template name that was
- /// provided for a template template parameter.
- TemplateExpansion,
- /// The template argument is an expression, and we've not resolved it to one
- /// of the other forms yet, either because it's dependent or because we're
- /// representing a non-canonical template argument (for instance, in a
- /// TemplateSpecializationType). Also used to represent a non-dependent
- /// __uuidof expression (a Microsoft extension).
- Expression,
- /// The template argument is actually a parameter pack. Arguments are stored
- /// in the Args struct.
- Pack
- };
-
-private:
- /// \brief The kind of template argument we're storing.
-
- struct DA {
- unsigned Kind;
- void *QT;
- ValueDecl *D;
- };
- struct I {
- unsigned Kind;
- // We store a decomposed APSInt with the data allocated by ASTContext if
- // BitWidth > 64. The memory may be shared between multiple
- // TemplateArgument instances.
- unsigned BitWidth : 31;
- unsigned IsUnsigned : 1;
- union {
- uint64_t VAL; ///< Used to store the <= 64 bits integer value.
- const uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
- void *Type;
- };
- struct A {
- unsigned Kind;
- unsigned NumArgs;
- const TemplateArgument *Args;
- };
- struct TA {
- unsigned Kind;
- unsigned NumExpansions;
- void *Name;
- };
- struct TV {
- unsigned Kind;
- uintptr_t V;
- };
- union {
- struct DA DeclArg;
- struct I Integer;
- struct A Args;
- struct TA TemplateArg;
- struct TV TypeOrValue;
- };
-
- TemplateArgument(TemplateName, bool) = delete;
-
-public:
- /// \brief Construct an empty, invalid template argument.
- TemplateArgument() {
- TypeOrValue.Kind = Null;
- TypeOrValue.V = 0;
- }
-
- /// \brief 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
- /// declaration, which is either an external declaration or a
- /// template declaration.
- TemplateArgument(ValueDecl *D, QualType QT) {
- assert(D && "Expected decl");
- DeclArg.Kind = Declaration;
- DeclArg.QT = QT.getAsOpaquePtr();
- DeclArg.D = D;
- }
-
- /// \brief 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
- /// 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.
- ///
- /// This form of template argument is generally used for template template
- /// parameters. However, the template name could be a dependent template
- /// name that ends up being instantiated to a function template whose address
- /// is taken.
- ///
- /// \param Name The template name.
- TemplateArgument(TemplateName Name) {
- TemplateArg.Kind = Template;
- TemplateArg.Name = Name.getAsVoidPointer();
- TemplateArg.NumExpansions = 0;
- }
-
- /// \brief 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
- /// name that ends up being instantiated to a function template whose address
- /// is taken.
- ///
- /// \param Name The template name.
- ///
- /// \param NumExpansions The number of expansions that will be generated by
- /// instantiating
- TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
- TemplateArg.Kind = TemplateExpansion;
- TemplateArg.Name = Name.getAsVoidPointer();
- if (NumExpansions)
- TemplateArg.NumExpansions = *NumExpansions + 1;
- else
- TemplateArg.NumExpansions = 0;
- }
-
- /// \brief 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
- /// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E) {
- TypeOrValue.Kind = Expression;
- TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
- }
-
- /// \brief Construct a template argument that is a template argument pack.
- ///
- /// We assume that storage for the template arguments provided
- /// outlives the TemplateArgument itself.
- explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
- this->Args.Kind = Pack;
- this->Args.Args = Args.data();
- this->Args.NumArgs = Args.size();
- }
-
- static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
-
- /// \brief 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.
- ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
-
- /// \brief Determine whether this template argument has no value.
- bool isNull() const { return getKind() == Null; }
-
- /// \brief 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
- /// parameter.
- bool isInstantiationDependent() const;
-
- /// \brief Whether this template argument contains an unexpanded
- /// parameter pack.
- bool containsUnexpandedParameterPack() const;
-
- /// \brief Determine whether this template argument is a pack expansion.
- bool isPackExpansion() const;
-
- /// \brief 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
- /// template argument.
- ValueDecl *getAsDecl() const {
- assert(getKind() == Declaration && "Unexpected kind");
- return DeclArg.D;
- }
-
- QualType getParamTypeForDecl() const {
- assert(getKind() == Declaration && "Unexpected kind");
- return QualType::getFromOpaquePtr(DeclArg.QT);
- }
-
- /// \brief 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.
- 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
- /// is a pack expansion, return the pattern as a template name.
- TemplateName getAsTemplateOrTemplatePattern() const {
- assert((getKind() == Template || getKind() == TemplateExpansion) &&
- "Unexpected kind");
-
- return TemplateName::getFromVoidPointer(TemplateArg.Name);
- }
-
- /// \brief 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.
- // FIXME: Provide a way to read the integral data without copying the value.
- llvm::APSInt getAsIntegral() const {
- assert(getKind() == Integral && "Unexpected kind");
- using namespace llvm;
- if (Integer.BitWidth <= 64)
- return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
-
- unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
- return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
- Integer.IsUnsigned);
- }
-
- /// \brief Retrieve the type of the integral value.
- QualType getIntegralType() const {
- assert(getKind() == Integral && "Unexpected kind");
- return QualType::getFromOpaquePtr(Integer.Type);
- }
-
- void setIntegralType(QualType T) {
- assert(getKind() == Integral && "Unexpected kind");
- Integer.Type = T.getAsOpaquePtr();
- }
-
- /// \brief 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.
- typedef const TemplateArgument * pack_iterator;
-
- /// \brief 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
- /// 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
- /// argument pack.
- llvm::iterator_range<pack_iterator> pack_elements() const {
- return llvm::make_range(pack_begin(), pack_end());
- }
-
- /// \brief 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.
- ArrayRef<TemplateArgument> getPackAsArray() const {
- assert(getKind() == Pack);
- return llvm::makeArrayRef(Args.Args, Args.NumArgs);
- }
-
- /// \brief 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
- /// the pattern of the pack expansion.
- TemplateArgument getPackExpansionPattern() const;
-
- /// \brief Print this template argument to the given output stream.
- void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
-
- /// \brief Used to insert TemplateArguments into FoldingSets.
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
-};
-
-/// Location information for a TemplateArgument.
-struct TemplateArgumentLocInfo {
-private:
-
- struct T {
- // FIXME: We'd like to just use the qualifier in the TemplateName,
- // but template arguments get canonicalized too quickly.
- NestedNameSpecifier *Qualifier;
- void *QualifierLocData;
- unsigned TemplateNameLoc;
- unsigned EllipsisLoc;
- };
-
- union {
- struct T Template;
- Expr *Expression;
- TypeSourceInfo *Declarator;
- };
-
-public:
- TemplateArgumentLocInfo();
-
- TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
-
- TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
-
- TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateNameLoc,
- SourceLocation EllipsisLoc)
- {
- Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
- Template.QualifierLocData = QualifierLoc.getOpaqueData();
- Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
- Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
- }
-
- TypeSourceInfo *getAsTypeSourceInfo() const {
- return Declarator;
- }
-
- Expr *getAsExpr() const {
- return Expression;
- }
-
- NestedNameSpecifierLoc getTemplateQualifierLoc() const {
- return NestedNameSpecifierLoc(Template.Qualifier,
- Template.QualifierLocData);
- }
-
- SourceLocation getTemplateNameLoc() const {
- return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
- }
-
- SourceLocation getTemplateEllipsisLoc() const {
- return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
- }
-};
-
-/// Location wrapper for a TemplateArgument. TemplateArgument is to
-/// TemplateArgumentLoc as Type is to TypeLoc.
-class TemplateArgumentLoc {
- TemplateArgument Argument;
- TemplateArgumentLocInfo LocInfo;
-
-public:
- TemplateArgumentLoc() {}
-
- TemplateArgumentLoc(const TemplateArgument &Argument,
- TemplateArgumentLocInfo Opaque)
- : Argument(Argument), LocInfo(Opaque) {
- }
-
- TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
- : Argument(Argument), LocInfo(TInfo) {
- assert(Argument.getKind() == TemplateArgument::Type);
- }
-
- TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
- : Argument(Argument), LocInfo(E) {
- assert(Argument.getKind() == TemplateArgument::Expression);
- }
-
- TemplateArgumentLoc(const TemplateArgument &Argument,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateNameLoc,
- SourceLocation EllipsisLoc = SourceLocation())
- : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
- }
-
- /// \brief - Fetches the primary location of the argument.
- SourceLocation getLocation() const {
- if (Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion)
- return getTemplateNameLoc();
-
- return getSourceRange().getBegin();
- }
-
- /// \brief - Fetches the full source range of the argument.
- SourceRange getSourceRange() const LLVM_READONLY;
-
- const TemplateArgument &getArgument() const {
- return Argument;
- }
-
- TemplateArgumentLocInfo getLocInfo() const {
- return LocInfo;
- }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- assert(Argument.getKind() == TemplateArgument::Type);
- return LocInfo.getAsTypeSourceInfo();
- }
-
- Expr *getSourceExpression() const {
- assert(Argument.getKind() == TemplateArgument::Expression);
- return LocInfo.getAsExpr();
- }
-
- Expr *getSourceDeclExpression() const {
- assert(Argument.getKind() == TemplateArgument::Declaration);
- return LocInfo.getAsExpr();
- }
-
- Expr *getSourceNullPtrExpression() const {
- assert(Argument.getKind() == TemplateArgument::NullPtr);
- return LocInfo.getAsExpr();
- }
-
- Expr *getSourceIntegralExpression() const {
- assert(Argument.getKind() == TemplateArgument::Integral);
- return LocInfo.getAsExpr();
- }
-
- NestedNameSpecifierLoc getTemplateQualifierLoc() const {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
- return LocInfo.getTemplateQualifierLoc();
- }
-
- SourceLocation getTemplateNameLoc() const {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
- return LocInfo.getTemplateNameLoc();
- }
-
- SourceLocation getTemplateEllipsisLoc() const {
- assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
- return LocInfo.getTemplateEllipsisLoc();
- }
-};
-
-/// A convenient class for passing around template argument
-/// information. Designed to be passed by reference.
-class TemplateArgumentListInfo {
- SmallVector<TemplateArgumentLoc, 8> Arguments;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
-
- // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
- // instead.
- void *operator new(size_t bytes, ASTContext &C) = delete;
-
-public:
- TemplateArgumentListInfo() {}
-
- TemplateArgumentListInfo(SourceLocation LAngleLoc,
- SourceLocation RAngleLoc)
- : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
-
- SourceLocation getLAngleLoc() const { return LAngleLoc; }
- SourceLocation getRAngleLoc() const { return RAngleLoc; }
-
- void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
- void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
-
- unsigned size() const { return Arguments.size(); }
-
- const TemplateArgumentLoc *getArgumentArray() const {
- return Arguments.data();
- }
-
- llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
- return Arguments;
- }
-
- const TemplateArgumentLoc &operator[](unsigned I) const {
- return Arguments[I];
- }
-
- TemplateArgumentLoc &operator[](unsigned I) {
- return Arguments[I];
- }
-
- void addArgument(const TemplateArgumentLoc &Loc) {
- Arguments.push_back(Loc);
- }
-};
-
-/// \brief 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.
-struct ASTTemplateArgumentListInfo final
- : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
- TemplateArgumentLoc> {
-private:
- friend TrailingObjects;
-
- ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
-
-public:
- /// \brief The source location of the left angle bracket ('<').
- SourceLocation LAngleLoc;
-
- /// \brief The source location of the right angle bracket ('>').
- SourceLocation RAngleLoc;
-
- /// \brief The number of template arguments in TemplateArgs.
- unsigned NumTemplateArgs;
-
- /// \brief Retrieve the template arguments
- const TemplateArgumentLoc *getTemplateArgs() const {
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- const TemplateArgumentLoc &operator[](unsigned I) const {
- return getTemplateArgs()[I];
- }
-
- static const ASTTemplateArgumentListInfo *
- Create(ASTContext &C, const TemplateArgumentListInfo &List);
-};
-
-/// \brief 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
-/// as such, doesn't contain the array of TemplateArgumentLoc itself,
-/// but expects the containing object to also provide storage for
-/// that.
-struct LLVM_ALIGNAS(LLVM_PTR_SIZE) ASTTemplateKWAndArgsInfo {
- /// \brief The source location of the left angle bracket ('<').
- SourceLocation LAngleLoc;
-
- /// \brief The source location of the right angle bracket ('>').
- SourceLocation RAngleLoc;
-
- /// \brief 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.
- unsigned NumTemplateArgs;
-
- void initializeFrom(SourceLocation TemplateKWLoc,
- const TemplateArgumentListInfo &List,
- TemplateArgumentLoc *OutArgArray);
- void initializeFrom(SourceLocation TemplateKWLoc,
- const TemplateArgumentListInfo &List,
- TemplateArgumentLoc *OutArgArray, bool &Dependent,
- bool &InstantiationDependent,
- bool &ContainsUnexpandedParameterPack);
- void initializeFrom(SourceLocation TemplateKWLoc);
-
- void copyInto(const TemplateArgumentLoc *ArgArray,
- TemplateArgumentListInfo &List) const;
-};
-
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const TemplateArgument &Arg);
-
-inline TemplateSpecializationType::iterator
- TemplateSpecializationType::end() const {
- return getArgs() + getNumArgs();
-}
-
-inline DependentTemplateSpecializationType::iterator
- DependentTemplateSpecializationType::end() const {
- return getArgs() + getNumArgs();
-}
-
-inline const TemplateArgument &
- TemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
-inline const TemplateArgument &
- DependentTemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
deleted file mode 100644
index 3e10d2f..0000000
--- a/include/clang/AST/TemplateName.h
+++ /dev/null
@@ -1,533 +0,0 @@
-//===--- TemplateName.h - C++ Template Name Representation-------*- 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 TemplateName interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
-#define LLVM_CLANG_AST_TEMPLATENAME_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/PointerUnion.h"
-
-namespace clang {
-
-class ASTContext;
-class DependentTemplateName;
-class DiagnosticBuilder;
-class IdentifierInfo;
-class NamedDecl;
-class NestedNameSpecifier;
-enum OverloadedOperatorKind : int;
-class OverloadedTemplateStorage;
-struct PrintingPolicy;
-class QualifiedTemplateName;
-class SubstTemplateTemplateParmPackStorage;
-class SubstTemplateTemplateParmStorage;
-class TemplateArgument;
-class TemplateDecl;
-class TemplateTemplateParmDecl;
-
-/// \brief Implementation class used to describe either a set of overloaded
-/// template names or an already-substituted template template parameter pack.
-class UncommonTemplateNameStorage {
-protected:
- enum Kind {
- Overloaded,
- SubstTemplateTemplateParm,
- SubstTemplateTemplateParmPack
- };
-
- struct BitsTag {
- /// \brief A Kind.
- unsigned Kind : 2;
-
- /// \brief The number of stored templates or template arguments,
- /// depending on which subclass we have.
- unsigned Size : 30;
- };
-
- union {
- struct BitsTag Bits;
- void *PointerAlignment;
- };
-
- UncommonTemplateNameStorage(Kind kind, unsigned size) {
- Bits.Kind = kind;
- Bits.Size = size;
- }
-
-public:
- unsigned size() const { return Bits.Size; }
-
- OverloadedTemplateStorage *getAsOverloadedStorage() {
- return Bits.Kind == Overloaded
- ? reinterpret_cast<OverloadedTemplateStorage *>(this)
- : nullptr;
- }
-
- SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
- return Bits.Kind == SubstTemplateTemplateParm
- ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
- : nullptr;
- }
-
- SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
- return Bits.Kind == SubstTemplateTemplateParmPack
- ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
- : nullptr;
- }
-};
-
-/// \brief A structure for storing the information associated with an
-/// overloaded template name.
-class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
- friend class ASTContext;
-
- OverloadedTemplateStorage(unsigned size)
- : UncommonTemplateNameStorage(Overloaded, size) { }
-
- NamedDecl **getStorage() {
- return reinterpret_cast<NamedDecl **>(this + 1);
- }
- NamedDecl * const *getStorage() const {
- return reinterpret_cast<NamedDecl *const *>(this + 1);
- }
-
-public:
- typedef NamedDecl *const *iterator;
-
- iterator begin() const { return getStorage(); }
- iterator end() const { return getStorage() + size(); }
-};
-
-/// \brief A structure for storing an already-substituted template template
-/// parameter pack.
-///
-/// This kind of template names occurs when the parameter pack has been
-/// provided with a template template argument pack in a context where its
-/// enclosing pack expansion could not be fully expanded.
-class SubstTemplateTemplateParmPackStorage
- : public UncommonTemplateNameStorage, public llvm::FoldingSetNode
-{
- TemplateTemplateParmDecl *Parameter;
- const TemplateArgument *Arguments;
-
-public:
- SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
- unsigned Size,
- const TemplateArgument *Arguments)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
- Parameter(Parameter), Arguments(Arguments) { }
-
- /// \brief Retrieve the template template parameter pack being substituted.
- TemplateTemplateParmDecl *getParameterPack() const {
- return Parameter;
- }
-
- /// \brief Retrieve the template template argument pack with which this
- /// parameter was substituted.
- TemplateArgument getArgumentPack() const;
-
- void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- ASTContext &Context,
- TemplateTemplateParmDecl *Parameter,
- const TemplateArgument &ArgPack);
-};
-
-/// \brief 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
-/// class template, e.g.
-///
-/// \code
-/// template<typename T> class X { };
-///
-/// X<int> xi;
-/// \endcode
-///
-/// Here, the 'X' in \c X<int> is a template name that refers to the
-/// declaration of the class template X, above. Template names can
-/// also refer to function templates, C++0x template aliases, etc.
-///
-/// Some template names are dependent. For example, consider:
-///
-/// \code
-/// template<typename MetaFun, typename T1, typename T2> struct apply2 {
-/// typedef typename MetaFun::template apply<T1, T2>::type type;
-/// };
-/// \endcode
-///
-/// Here, "apply" is treated as a template name within the typename
-/// specifier in the typedef. "apply" is a nested template, and can
-/// only be understood in the context of
-class TemplateName {
- typedef llvm::PointerUnion4<TemplateDecl *,
- UncommonTemplateNameStorage *,
- QualifiedTemplateName *,
- DependentTemplateName *> StorageType;
-
- StorageType Storage;
-
- explicit TemplateName(void *Ptr);
-
-public:
- // \brief Kind of name that is actually stored.
- enum NameKind {
- /// \brief A single template declaration.
- Template,
- /// \brief A set of overloaded template declarations.
- OverloadedTemplate,
- /// \brief 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
- /// template (or set of templates).
- DependentTemplate,
- /// \brief 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 argument pack, but has not yet been expanded into
- /// individual arguments.
- SubstTemplateTemplateParmPack
- };
-
- TemplateName() : Storage() { }
- explicit TemplateName(TemplateDecl *Template);
- explicit TemplateName(OverloadedTemplateStorage *Storage);
- explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
- explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage);
- explicit TemplateName(QualifiedTemplateName *Qual);
- explicit TemplateName(DependentTemplateName *Dep);
-
- /// \brief Determine whether this template name is NULL.
- bool isNull() const;
-
- // \brief Get the kind of name that is actually stored.
- NameKind getKind() const;
-
- /// \brief Retrieve the underlying template declaration that
- /// this template name refers to, if known.
- ///
- /// \returns The template declaration that this template name refers
- /// to, if any. If the template name does not refer to a specific
- /// declaration because it is a dependent name, or if it refers to a
- /// set of function templates, returns NULL.
- TemplateDecl *getAsTemplateDecl() const;
-
- /// \brief 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
- /// name refers to, if known. If the template name does not refer to a
- /// specific set of function templates because it is a dependent name or
- /// refers to a single template, returns NULL.
- OverloadedTemplateStorage *getAsOverloadedTemplate() const;
-
- /// \brief 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
- /// known.
- ///
- /// \returns The storage for the substituted template template parameter pack,
- /// if known. Otherwise, returns NULL.
- SubstTemplateTemplateParmPackStorage *
- getAsSubstTemplateTemplateParmPack() const;
-
- /// \brief Retrieve the underlying qualified template name
- /// structure, if any.
- QualifiedTemplateName *getAsQualifiedTemplateName() const;
-
- /// \brief Retrieve the underlying dependent template name
- /// structure, if any.
- DependentTemplateName *getAsDependentTemplateName() const;
-
- TemplateName getUnderlying() const;
-
- /// \brief Determines whether this is a dependent template name.
- bool isDependent() const;
-
- /// \brief 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
- /// unexpanded parameter pack (for C++0x variadic templates).
- bool containsUnexpandedParameterPack() const;
-
- /// \brief Print the template name.
- ///
- /// \param OS the output stream to which the template name will be
- /// printed.
- ///
- /// \param SuppressNNS if true, don't print the
- /// nested-name-specifier that precedes the template name (if it has
- /// one).
- void print(raw_ostream &OS, const PrintingPolicy &Policy,
- bool SuppressNNS = false) const;
-
- /// \brief Debugging aid that dumps the template name.
- void dump(raw_ostream &OS) const;
-
- /// \brief Debugging aid that dumps the template name to standard
- /// error.
- void dump() const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- ID.AddPointer(Storage.getOpaqueValue());
- }
-
- /// \brief Retrieve the template name as a void pointer.
- void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
-
- /// \brief Build a template name from a void pointer.
- static TemplateName getFromVoidPointer(void *Ptr) {
- return TemplateName(Ptr);
- }
-};
-
-/// Insertion operator for diagnostics. This allows sending TemplateName's
-/// into a diagnostic with <<.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- TemplateName N);
-
-/// \brief A structure for storing the information associated with a
-/// substituted template template parameter.
-class SubstTemplateTemplateParmStorage
- : public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
- friend class ASTContext;
-
- TemplateTemplateParmDecl *Parameter;
- TemplateName Replacement;
-
- SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
- TemplateName replacement)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
- Parameter(parameter), Replacement(replacement) {}
-
-public:
- TemplateTemplateParmDecl *getParameter() const { return Parameter; }
- TemplateName getReplacement() const { return Replacement; }
-
- void Profile(llvm::FoldingSetNodeID &ID);
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- TemplateTemplateParmDecl *parameter,
- TemplateName replacement);
-};
-
-inline TemplateName TemplateName::getUnderlying() const {
- if (SubstTemplateTemplateParmStorage *subst
- = getAsSubstTemplateTemplateParm())
- return subst->getReplacement().getUnderlying();
- return *this;
-}
-
-/// \brief Represents a template name that was expressed as a
-/// qualified name.
-///
-/// This kind of template name refers to a template name that was
-/// preceded by a nested name specifier, e.g., \c std::vector. Here,
-/// the nested name specifier is "std::" and the template name is the
-/// declaration for "vector". The QualifiedTemplateName class is only
-/// used to provide "sugar" for template names that were expressed
-/// with a qualified name, and has no semantic meaning. In this
-/// manner, it is to TemplateName what ElaboratedType is to Type,
-/// providing extra syntactic sugar for downstream clients.
-class QualifiedTemplateName : public llvm::FoldingSetNode {
- /// \brief 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
- /// "template" keyword is always redundant in this case (otherwise,
- /// the template name would be a dependent name and we would express
- /// this name with DependentTemplateName).
- llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
-
- /// \brief The template declaration or set of overloaded function templates
- /// that this qualified name refers to.
- TemplateDecl *Template;
-
- friend class ASTContext;
-
- QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
- TemplateDecl *Template)
- : Qualifier(NNS, TemplateKeyword? 1 : 0),
- Template(Template) { }
-
-public:
- /// \brief 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"
- /// keyword.
- bool hasTemplateKeyword() const { return Qualifier.getInt(); }
-
- /// \brief The template declaration that this qualified name refers
- /// to.
- TemplateDecl *getDecl() const { return Template; }
-
- /// \brief The template declaration to which this qualified name
- /// refers.
- TemplateDecl *getTemplateDecl() const { return Template; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- bool TemplateKeyword, TemplateDecl *Template) {
- ID.AddPointer(NNS);
- ID.AddBoolean(TemplateKeyword);
- ID.AddPointer(Template);
- }
-};
-
-/// \brief Represents a dependent template name that cannot be
-/// resolved prior to template instantiation.
-///
-/// This kind of template name refers to a dependent template name,
-/// including its nested name specifier (if any). For example,
-/// DependentTemplateName can refer to "MetaFun::template apply",
-/// where "MetaFun::" is the nested name specifier and "apply" is the
-/// template name referenced. The "template" keyword is implied.
-class DependentTemplateName : public llvm::FoldingSetNode {
- /// \brief The nested name specifier that qualifies the template
- /// name.
- ///
- /// The bit stored in this qualifier describes whether the \c Name field
- /// is interpreted as an IdentifierInfo pointer (when clear) or as an
- /// overloaded operator kind (when set).
- llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
-
- /// \brief The dependent template name.
- union {
- /// \brief The identifier template name.
- ///
- /// Only valid when the bit on \c Qualifier is clear.
- const IdentifierInfo *Identifier;
-
- /// \brief 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
- /// template name refers.
- ///
- /// The canonical template name for a dependent template name is
- /// another dependent template name whose nested name specifier is
- /// canonical.
- TemplateName CanonicalTemplateName;
-
- friend class ASTContext;
-
- DependentTemplateName(NestedNameSpecifier *Qualifier,
- const IdentifierInfo *Identifier)
- : Qualifier(Qualifier, false), Identifier(Identifier),
- CanonicalTemplateName(this) { }
-
- DependentTemplateName(NestedNameSpecifier *Qualifier,
- const IdentifierInfo *Identifier,
- TemplateName Canon)
- : Qualifier(Qualifier, false), Identifier(Identifier),
- CanonicalTemplateName(Canon) { }
-
- DependentTemplateName(NestedNameSpecifier *Qualifier,
- OverloadedOperatorKind Operator)
- : Qualifier(Qualifier, true), Operator(Operator),
- CanonicalTemplateName(this) { }
-
- DependentTemplateName(NestedNameSpecifier *Qualifier,
- OverloadedOperatorKind Operator,
- TemplateName Canon)
- : Qualifier(Qualifier, true), Operator(Operator),
- CanonicalTemplateName(Canon) { }
-
-public:
- /// \brief 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.
- bool isIdentifier() const { return !Qualifier.getInt(); }
-
- /// \brief 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
- /// operator.
- bool isOverloadedOperator() const { return Qualifier.getInt(); }
-
- /// \brief Return the overloaded operator to which this template name refers.
- OverloadedOperatorKind getOperator() const {
- assert(isOverloadedOperator() &&
- "Template name isn't an overloaded operator?");
- return Operator;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- if (isIdentifier())
- Profile(ID, getQualifier(), getIdentifier());
- else
- Profile(ID, getQualifier(), getOperator());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- const IdentifierInfo *Identifier) {
- ID.AddPointer(NNS);
- ID.AddBoolean(false);
- ID.AddPointer(Identifier);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- OverloadedOperatorKind Operator) {
- ID.AddPointer(NNS);
- ID.AddBoolean(true);
- ID.AddInteger(Operator);
- }
-};
-
-} // end namespace clang.
-
-namespace llvm {
-
-/// \brief The clang::TemplateName class is effectively a pointer.
-template<>
-class PointerLikeTypeTraits<clang::TemplateName> {
-public:
- static inline void *getAsVoidPointer(clang::TemplateName TN) {
- return TN.getAsVoidPointer();
- }
-
- static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
- return clang::TemplateName::getFromVoidPointer(Ptr);
- }
-
- // No bits are available!
- enum { NumLowBitsAvailable = 0 };
-};
-
-} // end namespace llvm.
-
-#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
deleted file mode 100644
index 0c08130..0000000
--- a/include/clang/AST/Type.h
+++ /dev/null
@@ -1,5683 +0,0 @@
-//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// \brief C Language Family Type Representation
-///
-/// This file defines the clang::Type interface and subclasses, used to
-/// represent types for languages in the C family.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPE_H
-#define LLVM_CLANG_AST_TYPE_H
-
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/ExceptionSpecificationType.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Linkage.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/Visibility.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
- enum {
- TypeAlignmentInBits = 4,
- TypeAlignment = 1 << TypeAlignmentInBits
- };
- class Type;
- class ExtQuals;
- class QualType;
-}
-
-namespace llvm {
- template <typename T>
- class PointerLikeTypeTraits;
- template<>
- class PointerLikeTypeTraits< ::clang::Type*> {
- public:
- static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
- static inline ::clang::Type *getFromVoidPointer(void *P) {
- return static_cast< ::clang::Type*>(P);
- }
- enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
- };
- template<>
- class PointerLikeTypeTraits< ::clang::ExtQuals*> {
- public:
- static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
- static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
- return static_cast< ::clang::ExtQuals*>(P);
- }
- enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
- };
-
- template <>
- struct isPodLike<clang::QualType> { static const bool value = true; };
-}
-
-namespace clang {
- class ASTContext;
- class TypedefNameDecl;
- class TemplateDecl;
- class TemplateTypeParmDecl;
- class NonTypeTemplateParmDecl;
- class TemplateTemplateParmDecl;
- class TagDecl;
- class RecordDecl;
- class CXXRecordDecl;
- class EnumDecl;
- class FieldDecl;
- class FunctionDecl;
- class ObjCInterfaceDecl;
- class ObjCProtocolDecl;
- class ObjCMethodDecl;
- class UnresolvedUsingTypenameDecl;
- class Expr;
- class Stmt;
- class SourceLocation;
- class StmtIteratorBase;
- class TemplateArgument;
- class TemplateArgumentLoc;
- class TemplateArgumentListInfo;
- class ElaboratedType;
- class ExtQuals;
- class ExtQualsTypeCommonBase;
- struct PrintingPolicy;
-
- template <typename> class CanQual;
- typedef CanQual<Type> CanQualType;
-
- // Provide forward declarations for all of the *Type classes
-#define TYPE(Class, Base) class Class##Type;
-#include "clang/AST/TypeNodes.def"
-
-/// The collection of all-type qualifiers we support.
-/// Clang supports five independent qualifiers:
-/// * C99: const, volatile, and restrict
-/// * Embedded C (TR18037): address spaces
-/// * Objective C: the GC attributes (none, weak, or strong)
-class Qualifiers {
-public:
- enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
- Const = 0x1,
- Restrict = 0x2,
- Volatile = 0x4,
- CVRMask = Const | Volatile | Restrict
- };
-
- enum GC {
- GCNone = 0,
- Weak,
- Strong
- };
-
- enum ObjCLifetime {
- /// There is no lifetime qualification on this type.
- OCL_None,
-
- /// This object can be modified without requiring retains or
- /// releases.
- OCL_ExplicitNone,
-
- /// Assigning into this object requires the old value to be
- /// released and the new value to be retained. The timing of the
- /// release of the old value is inexact: it may be moved to
- /// immediately after the last known point where the value is
- /// live.
- OCL_Strong,
-
- /// Reading or writing from this object requires a barrier call.
- OCL_Weak,
-
- /// Assigning into this object requires a lifetime extension.
- OCL_Autoreleasing
- };
-
- enum {
- /// The maximum supported address space number.
- /// 24 bits should be enough for anyone.
- MaxAddressSpace = 0xffffffu,
-
- /// The width of the "fast" qualifier mask.
- FastWidth = 3,
-
- /// The fast qualifier mask.
- FastMask = (1 << FastWidth) - 1
- };
-
- Qualifiers() : Mask(0) {}
-
- /// Returns the common set of qualifiers while removing them from
- /// the given sets.
- static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
- // If both are only CVR-qualified, bit operations are sufficient.
- if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
- Qualifiers Q;
- Q.Mask = L.Mask & R.Mask;
- L.Mask &= ~Q.Mask;
- R.Mask &= ~Q.Mask;
- return Q;
- }
-
- Qualifiers Q;
- unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers();
- Q.addCVRQualifiers(CommonCRV);
- L.removeCVRQualifiers(CommonCRV);
- R.removeCVRQualifiers(CommonCRV);
-
- if (L.getObjCGCAttr() == R.getObjCGCAttr()) {
- Q.setObjCGCAttr(L.getObjCGCAttr());
- L.removeObjCGCAttr();
- R.removeObjCGCAttr();
- }
-
- if (L.getObjCLifetime() == R.getObjCLifetime()) {
- Q.setObjCLifetime(L.getObjCLifetime());
- L.removeObjCLifetime();
- R.removeObjCLifetime();
- }
-
- if (L.getAddressSpace() == R.getAddressSpace()) {
- Q.setAddressSpace(L.getAddressSpace());
- L.removeAddressSpace();
- R.removeAddressSpace();
- }
- return Q;
- }
-
- static Qualifiers fromFastMask(unsigned Mask) {
- Qualifiers Qs;
- Qs.addFastQualifiers(Mask);
- return Qs;
- }
-
- static Qualifiers fromCVRMask(unsigned CVR) {
- Qualifiers Qs;
- Qs.addCVRQualifiers(CVR);
- return Qs;
- }
-
- // Deserialize qualifiers from an opaque representation.
- static Qualifiers fromOpaqueValue(unsigned opaque) {
- Qualifiers Qs;
- Qs.Mask = opaque;
- return Qs;
- }
-
- // Serialize these qualifiers into an opaque representation.
- unsigned getAsOpaqueValue() const {
- return Mask;
- }
-
- bool hasConst() const { return Mask & Const; }
- void setConst(bool flag) {
- Mask = (Mask & ~Const) | (flag ? Const : 0);
- }
- void removeConst() { Mask &= ~Const; }
- void addConst() { Mask |= Const; }
-
- bool hasVolatile() const { return Mask & Volatile; }
- void setVolatile(bool flag) {
- Mask = (Mask & ~Volatile) | (flag ? Volatile : 0);
- }
- void removeVolatile() { Mask &= ~Volatile; }
- void addVolatile() { Mask |= Volatile; }
-
- bool hasRestrict() const { return Mask & Restrict; }
- void setRestrict(bool flag) {
- Mask = (Mask & ~Restrict) | (flag ? Restrict : 0);
- }
- void removeRestrict() { Mask &= ~Restrict; }
- void addRestrict() { Mask |= Restrict; }
-
- bool hasCVRQualifiers() const { return getCVRQualifiers(); }
- unsigned getCVRQualifiers() const { return Mask & CVRMask; }
- void setCVRQualifiers(unsigned mask) {
- assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
- Mask = (Mask & ~CVRMask) | mask;
- }
- void removeCVRQualifiers(unsigned mask) {
- assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
- Mask &= ~mask;
- }
- void removeCVRQualifiers() {
- removeCVRQualifiers(CVRMask);
- }
- void addCVRQualifiers(unsigned mask) {
- assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
- Mask |= mask;
- }
-
- bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
- GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
- void setObjCGCAttr(GC type) {
- Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift);
- }
- void removeObjCGCAttr() { setObjCGCAttr(GCNone); }
- void addObjCGCAttr(GC type) {
- assert(type);
- setObjCGCAttr(type);
- }
- Qualifiers withoutObjCGCAttr() const {
- Qualifiers qs = *this;
- qs.removeObjCGCAttr();
- return qs;
- }
- Qualifiers withoutObjCLifetime() const {
- Qualifiers qs = *this;
- qs.removeObjCLifetime();
- return qs;
- }
-
- bool hasObjCLifetime() const { return Mask & LifetimeMask; }
- ObjCLifetime getObjCLifetime() const {
- return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
- }
- void setObjCLifetime(ObjCLifetime type) {
- Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift);
- }
- void removeObjCLifetime() { setObjCLifetime(OCL_None); }
- void addObjCLifetime(ObjCLifetime type) {
- assert(type);
- assert(!hasObjCLifetime());
- Mask |= (type << LifetimeShift);
- }
-
- /// True if the lifetime is neither None or ExplicitNone.
- bool hasNonTrivialObjCLifetime() const {
- ObjCLifetime lifetime = getObjCLifetime();
- return (lifetime > OCL_ExplicitNone);
- }
-
- /// True if the lifetime is either strong or weak.
- bool hasStrongOrWeakObjCLifetime() const {
- ObjCLifetime lifetime = getObjCLifetime();
- return (lifetime == OCL_Strong || lifetime == OCL_Weak);
- }
-
- bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
- unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
- void setAddressSpace(unsigned space) {
- assert(space <= MaxAddressSpace);
- Mask = (Mask & ~AddressSpaceMask)
- | (((uint32_t) space) << AddressSpaceShift);
- }
- void removeAddressSpace() { setAddressSpace(0); }
- void addAddressSpace(unsigned space) {
- assert(space);
- setAddressSpace(space);
- }
-
- // Fast qualifiers are those that can be allocated directly
- // on a QualType object.
- bool hasFastQualifiers() const { return getFastQualifiers(); }
- unsigned getFastQualifiers() const { return Mask & FastMask; }
- void setFastQualifiers(unsigned mask) {
- assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
- Mask = (Mask & ~FastMask) | mask;
- }
- void removeFastQualifiers(unsigned mask) {
- assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
- Mask &= ~mask;
- }
- void removeFastQualifiers() {
- removeFastQualifiers(FastMask);
- }
- void addFastQualifiers(unsigned mask) {
- assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
- Mask |= mask;
- }
-
- /// Return true if the set contains any qualifiers which require an ExtQuals
- /// node to be allocated.
- bool hasNonFastQualifiers() const { return Mask & ~FastMask; }
- Qualifiers getNonFastQualifiers() const {
- Qualifiers Quals = *this;
- Quals.setFastQualifiers(0);
- return Quals;
- }
-
- /// Return true if the set contains any qualifiers.
- bool hasQualifiers() const { return Mask; }
- bool empty() const { return !Mask; }
-
- /// Add the qualifiers from the given set to this set.
- void addQualifiers(Qualifiers Q) {
- // If the other set doesn't have any non-boolean qualifiers, just
- // bit-or it in.
- if (!(Q.Mask & ~CVRMask))
- Mask |= Q.Mask;
- else {
- Mask |= (Q.Mask & CVRMask);
- if (Q.hasAddressSpace())
- addAddressSpace(Q.getAddressSpace());
- if (Q.hasObjCGCAttr())
- addObjCGCAttr(Q.getObjCGCAttr());
- if (Q.hasObjCLifetime())
- addObjCLifetime(Q.getObjCLifetime());
- }
- }
-
- /// \brief 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.
- if (!(Q.Mask & ~CVRMask))
- Mask &= ~Q.Mask;
- else {
- Mask &= ~(Q.Mask & CVRMask);
- if (getObjCGCAttr() == Q.getObjCGCAttr())
- removeObjCGCAttr();
- if (getObjCLifetime() == Q.getObjCLifetime())
- removeObjCLifetime();
- if (getAddressSpace() == Q.getAddressSpace())
- removeAddressSpace();
- }
- }
-
- /// Add the qualifiers from the given set to this set, given that
- /// they don't conflict.
- void addConsistentQualifiers(Qualifiers qs) {
- assert(getAddressSpace() == qs.getAddressSpace() ||
- !hasAddressSpace() || !qs.hasAddressSpace());
- assert(getObjCGCAttr() == qs.getObjCGCAttr() ||
- !hasObjCGCAttr() || !qs.hasObjCGCAttr());
- assert(getObjCLifetime() == qs.getObjCLifetime() ||
- !hasObjCLifetime() || !qs.hasObjCLifetime());
- Mask |= qs.Mask;
- }
-
- /// Returns true if this address space is a superset of the other one.
- /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of
- /// overlapping address spaces.
- /// CL1.1 or CL1.2:
- /// every address space is a superset of itself.
- /// CL2.0 adds:
- /// __generic is a superset of any address space except for __constant.
- bool isAddressSpaceSupersetOf(Qualifiers other) const {
- return
- // Address spaces must match exactly.
- getAddressSpace() == other.getAddressSpace() ||
- // Otherwise in OpenCLC v2.0 s6.5.5: every address space except
- // for __constant can be used as __generic.
- (getAddressSpace() == LangAS::opencl_generic &&
- other.getAddressSpace() != LangAS::opencl_constant);
- }
-
- /// Determines if these qualifiers compatibly include another set.
- /// Generally this answers the question of whether an object with the other
- /// qualifiers can be safely used as an object with these qualifiers.
- bool compatiblyIncludes(Qualifiers other) const {
- return isAddressSpaceSupersetOf(other) &&
- // ObjC GC qualifiers can match, be added, or be removed, but can't
- // be changed.
- (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() ||
- !other.hasObjCGCAttr()) &&
- // ObjC lifetime qualifiers must match exactly.
- getObjCLifetime() == other.getObjCLifetime() &&
- // CVR qualifiers may subset.
- (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
- }
-
- /// \brief 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
- /// if the lifetime qualifiers match, or if both are non-__weak and the
- /// including set also contains the 'const' qualifier, or both are non-__weak
- /// and one is None (which can only happen in non-ARC modes).
- bool compatiblyIncludesObjCLifetime(Qualifiers other) const {
- if (getObjCLifetime() == other.getObjCLifetime())
- return true;
-
- if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak)
- return false;
-
- if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None)
- return true;
-
- return hasConst();
- }
-
- /// \brief Determine whether this set of qualifiers is a strict superset of
- /// another set of qualifiers, not considering qualifier compatibility.
- bool isStrictSupersetOf(Qualifiers Other) const;
-
- bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
- bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
-
- explicit operator bool() const { return hasQualifiers(); }
-
- Qualifiers &operator+=(Qualifiers R) {
- addQualifiers(R);
- return *this;
- }
-
- // Union two qualifier sets. If an enumerated qualifier appears
- // in both sets, use the one from the right.
- friend Qualifiers operator+(Qualifiers L, Qualifiers R) {
- L += R;
- return L;
- }
-
- Qualifiers &operator-=(Qualifiers R) {
- removeQualifiers(R);
- return *this;
- }
-
- /// \brief Compute the difference between two qualifier sets.
- friend Qualifiers operator-(Qualifiers L, Qualifiers R) {
- L -= R;
- return L;
- }
-
- std::string getAsString() const;
- std::string getAsString(const PrintingPolicy &Policy) const;
-
- bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const;
- void print(raw_ostream &OS, const PrintingPolicy &Policy,
- bool appendSpaceIfNonEmpty = false) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger(Mask);
- }
-
-private:
-
- // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31|
- // |C R V|GCAttr|Lifetime|AddressSpace|
- uint32_t Mask;
-
- static const uint32_t GCAttrMask = 0x18;
- static const uint32_t GCAttrShift = 3;
- static const uint32_t LifetimeMask = 0xE0;
- static const uint32_t LifetimeShift = 5;
- static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask);
- static const uint32_t AddressSpaceShift = 8;
-};
-
-/// A std::pair-like structure for storing a qualified type split
-/// into its local qualifiers and its locally-unqualified type.
-struct SplitQualType {
- /// The locally-unqualified type.
- const Type *Ty;
-
- /// The local qualifiers.
- Qualifiers Quals;
-
- SplitQualType() : Ty(nullptr), Quals() {}
- SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
-
- SplitQualType getSingleStepDesugaredType() const; // end of this file
-
- // Make std::tie work.
- std::pair<const Type *,Qualifiers> asPair() const {
- return std::pair<const Type *, Qualifiers>(Ty, Quals);
- }
-
- friend bool operator==(SplitQualType a, SplitQualType b) {
- return a.Ty == b.Ty && a.Quals == b.Quals;
- }
- friend bool operator!=(SplitQualType a, SplitQualType b) {
- return a.Ty != b.Ty || a.Quals != b.Quals;
- }
-};
-
-/// The kind of type we are substituting Objective-C type arguments into.
-///
-/// The kind of substitution affects the replacement of type parameters when
-/// no concrete type information is provided, e.g., when dealing with an
-/// unspecialized type.
-enum class ObjCSubstitutionContext {
- /// An ordinary type.
- Ordinary,
- /// The result type of a method or function.
- Result,
- /// The parameter type of a method or function.
- Parameter,
- /// The type of a property.
- Property,
- /// The superclass of a type.
- Superclass,
-};
-
-/// A (possibly-)qualified type.
-///
-/// For efficiency, we don't store CV-qualified types as nodes on their
-/// own: instead each reference to a type stores the qualifiers. This
-/// greatly reduces the number of nodes we need to allocate for types (for
-/// example we only need one for 'int', 'const int', 'volatile int',
-/// 'const volatile int', etc).
-///
-/// As an added efficiency bonus, instead of making this a pair, we
-/// just store the two bits we care about in the low bits of the
-/// pointer. To handle the packing/unpacking, we make QualType be a
-/// simple wrapper class that acts like a smart pointer. A third bit
-/// indicates whether there are extended qualifiers present, in which
-/// case the pointer points to a special structure.
-class QualType {
- // Thankfully, these are efficiently composable.
- llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
- Qualifiers::FastWidth> Value;
-
- const ExtQuals *getExtQualsUnsafe() const {
- return Value.getPointer().get<const ExtQuals*>();
- }
-
- const Type *getTypePtrUnsafe() const {
- return Value.getPointer().get<const Type*>();
- }
-
- const ExtQualsTypeCommonBase *getCommonPtr() const {
- assert(!isNull() && "Cannot retrieve a NULL type pointer");
- uintptr_t CommonPtrVal
- = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
- CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
- return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
- }
-
- friend class QualifierCollector;
-public:
- QualType() {}
-
- QualType(const Type *Ptr, unsigned Quals)
- : Value(Ptr, Quals) {}
- QualType(const ExtQuals *Ptr, unsigned Quals)
- : Value(Ptr, Quals) {}
-
- unsigned getLocalFastQualifiers() const { return Value.getInt(); }
- void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
-
- /// Retrieves a pointer to the underlying (unqualified) type.
- ///
- /// This function requires that the type not be NULL. If the type might be
- /// NULL, use the (slightly less efficient) \c getTypePtrOrNull().
- const Type *getTypePtr() const;
-
- const Type *getTypePtrOrNull() const;
-
- /// Retrieves a pointer to the name of the base type.
- const IdentifierInfo *getBaseTypeIdentifier() const;
-
- /// Divides a QualType into its unqualified type and a set of local
- /// qualifiers.
- SplitQualType split() const;
-
- void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
- static QualType getFromOpaquePtr(const void *Ptr) {
- QualType T;
- T.Value.setFromOpaqueValue(const_cast<void*>(Ptr));
- return T;
- }
-
- const Type &operator*() const {
- return *getTypePtr();
- }
-
- const Type *operator->() const {
- return getTypePtr();
- }
-
- bool isCanonical() const;
- bool isCanonicalAsParam() const;
-
- /// Return true if this QualType doesn't point to a type yet.
- bool isNull() const {
- return Value.getPointer().isNull();
- }
-
- /// \brief 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.
- bool isConstQualified() const;
-
- /// \brief 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.
- bool isRestrictQualified() const;
-
- /// \brief 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.
- bool isVolatileQualified() const;
-
- /// \brief 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.
- bool hasQualifiers() const;
-
- /// \brief 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
- /// instance, not including any qualifiers acquired through typedefs or
- /// other sugar.
- Qualifiers getLocalQualifiers() const;
-
- /// \brief Retrieve the set of qualifiers applied to this type.
- Qualifiers getQualifiers() const;
-
- /// \brief 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
- /// applied to this type.
- unsigned getCVRQualifiers() const;
-
- bool isConstant(ASTContext& Ctx) const {
- return QualType::isConstant(*this, Ctx);
- }
-
- /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
- bool isPODType(ASTContext &Context) const;
-
- /// Return true if this is a POD type according to the rules of the C++98
- /// standard, regardless of the current compilation's language.
- bool isCXX98PODType(ASTContext &Context) const;
-
- /// 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)
- bool isCXX11PODType(ASTContext &Context) const;
-
- /// Return true if this is a trivial type per (C++0x [basic.types]p9)
- bool isTrivialType(ASTContext &Context) const;
-
- /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
- bool isTriviallyCopyableType(ASTContext &Context) const;
-
- // Don't promise in the API that anything besides 'const' can be
- // easily added.
-
- /// Add the `const` type qualifier to this QualType.
- void addConst() {
- addFastQualifiers(Qualifiers::Const);
- }
- QualType withConst() const {
- return withFastQualifiers(Qualifiers::Const);
- }
-
- /// Add the `volatile` type qualifier to this QualType.
- void addVolatile() {
- addFastQualifiers(Qualifiers::Volatile);
- }
- QualType withVolatile() const {
- return withFastQualifiers(Qualifiers::Volatile);
- }
-
- /// Add the `restrict` qualifier to this QualType.
- void addRestrict() {
- addFastQualifiers(Qualifiers::Restrict);
- }
- QualType withRestrict() const {
- return withFastQualifiers(Qualifiers::Restrict);
- }
-
- QualType withCVRQualifiers(unsigned CVR) const {
- return withFastQualifiers(CVR);
- }
-
- void addFastQualifiers(unsigned TQs) {
- assert(!(TQs & ~Qualifiers::FastMask)
- && "non-fast qualifier bits set in mask!");
- Value.setInt(Value.getInt() | TQs);
- }
-
- void removeLocalConst();
- void removeLocalVolatile();
- void removeLocalRestrict();
- void removeLocalCVRQualifiers(unsigned Mask);
-
- void removeLocalFastQualifiers() { Value.setInt(0); }
- void removeLocalFastQualifiers(unsigned Mask) {
- assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers");
- Value.setInt(Value.getInt() & ~Mask);
- }
-
- // Creates a type with the given qualifiers in addition to any
- // qualifiers already on this type.
- QualType withFastQualifiers(unsigned TQs) const {
- QualType T = *this;
- T.addFastQualifiers(TQs);
- return T;
- }
-
- // Creates a type with exactly the given fast qualifiers, removing
- // any existing fast qualifiers.
- QualType withExactLocalFastQualifiers(unsigned TQs) const {
- return withoutLocalFastQualifiers().withFastQualifiers(TQs);
- }
-
- // Removes fast qualifiers, but leaves any extended qualifiers in place.
- QualType withoutLocalFastQualifiers() const {
- QualType T = *this;
- T.removeLocalFastQualifiers();
- return T;
- }
-
- QualType getCanonicalType() const;
-
- /// \brief 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,
- /// removing as little sugar as possible.
- ///
- /// This routine looks through various kinds of sugar to find the
- /// least-desugared type that is unqualified. For example, given:
- ///
- /// \code
- /// typedef int Integer;
- /// typedef const Integer CInteger;
- /// typedef CInteger DifferenceType;
- /// \endcode
- ///
- /// Executing \c getUnqualifiedType() on the type \c DifferenceType will
- /// desugar until we hit the type \c Integer, which has no qualifiers on it.
- ///
- /// The resulting type might still be qualified if it's sugar for an array
- /// type. To strip qualifiers even from within a sugared array type, use
- /// ASTContext::getUnqualifiedArrayType.
- inline QualType getUnqualifiedType() const;
-
- /// Retrieve the unqualified variant of the given type, removing as little
- /// sugar as possible.
- ///
- /// Like getUnqualifiedType(), but also returns the set of
- /// qualifiers that were built up.
- ///
- /// The resulting type might still be qualified if it's sugar for an array
- /// type. To strip qualifiers even from within a sugared array type, use
- /// ASTContext::getUnqualifiedArrayType.
- inline SplitQualType getSplitUnqualifiedType() const;
-
- /// \brief 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
- /// 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
- /// specified result type.
- ///
- /// This routine should be used for expressions for which the return type is
- /// explicitly specified (e.g., in a cast or call) and isn't necessarily
- /// an lvalue. It removes a top-level reference (since there are no
- /// expressions of reference type) and deletes top-level cvr-qualifiers
- /// from non-class types (in C++) or all types (in C).
- QualType getNonLValueExprType(const ASTContext &Context) const;
-
- /// Return the specified type with any "sugar" removed from
- /// the type. This takes off typedefs, typeof's etc. If the outer level of
- /// the type is already concrete, it returns it unmodified. This is similar
- /// to getting the canonical type, but it doesn't remove *all* typedefs. For
- /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
- /// concrete.
- ///
- /// Qualifiers are left in place.
- QualType getDesugaredType(const ASTContext &Context) const {
- return getDesugaredType(*this, Context);
- }
-
- SplitQualType getSplitDesugaredType() const {
- return getSplitDesugaredType(*this);
- }
-
- /// \brief 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
- /// of the type is already concrete, it returns it unmodified.
- QualType getSingleStepDesugaredType(const ASTContext &Context) const {
- return getSingleStepDesugaredTypeImpl(*this, Context);
- }
-
- /// Returns the specified type after dropping any
- /// outer-level parentheses.
- QualType IgnoreParens() const {
- if (isa<ParenType>(*this))
- return QualType::IgnoreParens(*this);
- return *this;
- }
-
- /// Indicate whether the specified types and qualifiers are identical.
- friend bool operator==(const QualType &LHS, const QualType &RHS) {
- return LHS.Value == RHS.Value;
- }
- friend bool operator!=(const QualType &LHS, const QualType &RHS) {
- return LHS.Value != RHS.Value;
- }
- std::string getAsString() const {
- return getAsString(split());
- }
- static std::string getAsString(SplitQualType split) {
- return getAsString(split.Ty, split.Quals);
- }
- static std::string getAsString(const Type *ty, Qualifiers qs);
-
- std::string getAsString(const PrintingPolicy &Policy) const;
-
- void print(raw_ostream &OS, const PrintingPolicy &Policy,
- const Twine &PlaceHolder = Twine()) const {
- print(split(), OS, Policy, PlaceHolder);
- }
- static void print(SplitQualType split, raw_ostream &OS,
- const PrintingPolicy &policy, const Twine &PlaceHolder) {
- return print(split.Ty, split.Quals, OS, policy, PlaceHolder);
- }
- static void print(const Type *ty, Qualifiers qs,
- raw_ostream &OS, const PrintingPolicy &policy,
- const Twine &PlaceHolder);
-
- void getAsStringInternal(std::string &Str,
- const PrintingPolicy &Policy) const {
- return getAsStringInternal(split(), Str, Policy);
- }
- static void getAsStringInternal(SplitQualType split, std::string &out,
- const PrintingPolicy &policy) {
- return getAsStringInternal(split.Ty, split.Quals, out, policy);
- }
- static void getAsStringInternal(const Type *ty, Qualifiers qs,
- std::string &out,
- const PrintingPolicy &policy);
-
- class StreamedQualTypeHelper {
- const QualType &T;
- const PrintingPolicy &Policy;
- const Twine &PlaceHolder;
- public:
- StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy,
- const Twine &PlaceHolder)
- : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { }
-
- friend raw_ostream &operator<<(raw_ostream &OS,
- const StreamedQualTypeHelper &SQT) {
- SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder);
- return OS;
- }
- };
-
- StreamedQualTypeHelper stream(const PrintingPolicy &Policy,
- const Twine &PlaceHolder = Twine()) const {
- return StreamedQualTypeHelper(*this, Policy, PlaceHolder);
- }
-
- void dump(const char *s) const;
- void dump() const;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddPointer(getAsOpaquePtr());
- }
-
- /// Return the address space of this type.
- inline unsigned getAddressSpace() const;
-
- /// Returns gc attribute of this type.
- inline Qualifiers::GC getObjCGCAttr() const;
-
- /// true when Type is objc's weak.
- bool isObjCGCWeak() const {
- return getObjCGCAttr() == Qualifiers::Weak;
- }
-
- /// true when Type is objc's strong.
- bool isObjCGCStrong() const {
- return getObjCGCAttr() == Qualifiers::Strong;
- }
-
- /// Returns lifetime attribute of this type.
- Qualifiers::ObjCLifetime getObjCLifetime() const {
- return getQualifiers().getObjCLifetime();
- }
-
- bool hasNonTrivialObjCLifetime() const {
- return getQualifiers().hasNonTrivialObjCLifetime();
- }
-
- bool hasStrongOrWeakObjCLifetime() const {
- return getQualifiers().hasStrongOrWeakObjCLifetime();
- }
-
- enum DestructionKind {
- DK_none,
- DK_cxx_destructor,
- DK_objc_strong_lifetime,
- DK_objc_weak_lifetime
- };
-
- /// Returns a nonzero value if objects of this type require
- /// non-trivial work to clean up after. Non-zero because it's
- /// conceivable that qualifiers (objc_gc(weak)?) could make
- /// something require destruction.
- DestructionKind isDestructedType() const {
- return isDestructedTypeImpl(*this);
- }
-
- /// Determine whether expressions of the given type are forbidden
- /// from being lvalues in C.
- ///
- /// The expression types that are forbidden to be lvalues are:
- /// - 'void', but not qualified void
- /// - function types
- ///
- /// The exact rule here is C99 6.3.2.1:
- /// An lvalue is an expression with an object type or an incomplete
- /// type other than void.
- bool isCForbiddenLValueType() const;
-
- /// Substitute type arguments for the Objective-C type parameters used in the
- /// subject type.
- ///
- /// \param ctx ASTContext in which the type exists.
- ///
- /// \param typeArgs The type arguments that will be substituted for the
- /// Objective-C type parameters in the subject type, which are generally
- /// computed via \c Type::getObjCSubstitutions. If empty, the type
- /// parameters will be replaced with their bounds or id/Class, as appropriate
- /// for the context.
- ///
- /// \param context The context in which the subject type was written.
- ///
- /// \returns the resulting type.
- QualType substObjCTypeArgs(ASTContext &ctx,
- ArrayRef<QualType> typeArgs,
- ObjCSubstitutionContext context) const;
-
- /// Substitute type arguments from an object type for the Objective-C type
- /// parameters used in the subject type.
- ///
- /// This operation combines the computation of type arguments for
- /// substitution (\c Type::getObjCSubstitutions) with the actual process of
- /// substitution (\c QualType::substObjCTypeArgs) for the convenience of
- /// callers that need to perform a single substitution in isolation.
- ///
- /// \param objectType The type of the object whose member type we're
- /// substituting into. For example, this might be the receiver of a message
- /// or the base of a property access.
- ///
- /// \param dc The declaration context from which the subject type was
- /// retrieved, which indicates (for example) which type parameters should
- /// be substituted.
- ///
- /// \param context The context in which the subject type was written.
- ///
- /// \returns the subject type after replacing all of the Objective-C type
- /// parameters with their corresponding arguments.
- QualType substObjCMemberType(QualType objectType,
- const DeclContext *dc,
- ObjCSubstitutionContext context) const;
-
- /// Strip Objective-C "__kindof" types from the given type.
- QualType stripObjCKindOfType(const ASTContext &ctx) const;
-
-private:
- // These methods are implemented in a separate translation unit;
- // "static"-ize them to avoid creating temporary QualTypes in the
- // caller.
- static bool isConstant(QualType T, ASTContext& Ctx);
- static QualType getDesugaredType(QualType T, const ASTContext &Context);
- static SplitQualType getSplitDesugaredType(QualType T);
- static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
- static QualType getSingleStepDesugaredTypeImpl(QualType type,
- const ASTContext &C);
- static QualType IgnoreParens(QualType T);
- static DestructionKind isDestructedTypeImpl(QualType type);
-};
-
-} // end clang.
-
-namespace llvm {
-/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
-/// to a specific Type class.
-template<> struct simplify_type< ::clang::QualType> {
- typedef const ::clang::Type *SimpleType;
- static SimpleType getSimplifiedValue(::clang::QualType Val) {
- return Val.getTypePtr();
- }
-};
-
-// Teach SmallPtrSet that QualType is "basically a pointer".
-template<>
-class PointerLikeTypeTraits<clang::QualType> {
-public:
- static inline void *getAsVoidPointer(clang::QualType P) {
- return P.getAsOpaquePtr();
- }
- static inline clang::QualType getFromVoidPointer(void *P) {
- return clang::QualType::getFromOpaquePtr(P);
- }
- // Various qualifiers go in low bits.
- enum { NumLowBitsAvailable = 0 };
-};
-
-} // end namespace llvm
-
-namespace clang {
-
-/// \brief 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 {
- ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
- : BaseType(baseType), CanonicalType(canon) {}
-
- /// \brief 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.
- QualType CanonicalType;
-
- friend class QualType;
- friend class Type;
- friend class ExtQuals;
-};
-
-/// We can encode up to four bits in the low bits of a
-/// type pointer, but there are many more type qualifiers that we want
-/// to be able to apply to an arbitrary type. Therefore we have this
-/// struct, intended to be heap-allocated and used by QualType to
-/// store qualifiers.
-///
-/// The current design tags the 'const', 'restrict', and 'volatile' qualifiers
-/// in three low bits on the QualType pointer; a fourth bit records whether
-/// the pointer is an ExtQuals node. The extended qualifiers (address spaces,
-/// Objective-C GC attributes) are much more rare.
-class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
- // NOTE: changing the fast qualifiers should be straightforward as
- // long as you don't make 'const' non-fast.
- // 1. Qualifiers:
- // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ).
- // Fast qualifiers must occupy the low-order bits.
- // b) Update Qualifiers::FastWidth and FastMask.
- // 2. QualType:
- // a) Update is{Volatile,Restrict}Qualified(), defined inline.
- // b) Update remove{Volatile,Restrict}, defined near the end of
- // this header.
- // 3. ASTContext:
- // a) Update get{Volatile,Restrict}Type.
-
- /// The immutable set of qualifiers applied by this node. Always contains
- /// extended qualifiers.
- Qualifiers Quals;
-
- ExtQuals *this_() { return this; }
-
-public:
- ExtQuals(const Type *baseType, QualType canon, Qualifiers quals)
- : ExtQualsTypeCommonBase(baseType,
- canon.isNull() ? QualType(this_(), 0) : canon),
- Quals(quals)
- {
- assert(Quals.hasNonFastQualifiers()
- && "ExtQuals created with no fast qualifiers");
- assert(!Quals.hasFastQualifiers()
- && "ExtQuals created with fast qualifiers");
- }
-
- Qualifiers getQualifiers() const { return Quals; }
-
- bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
- Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
-
- bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); }
- Qualifiers::ObjCLifetime getObjCLifetime() const {
- return Quals.getObjCLifetime();
- }
-
- bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
- unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
-
- const Type *getBaseType() const { return BaseType; }
-
-public:
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, getBaseType(), Quals);
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- const Type *BaseType,
- Qualifiers Quals) {
- assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!");
- ID.AddPointer(BaseType);
- Quals.Profile(ID);
- }
-};
-
-/// The kind of C++11 ref-qualifier associated with a function type.
-/// This determines whether a member function's "this" object can be an
-/// lvalue, rvalue, or neither.
-enum RefQualifierKind {
- /// \brief No ref-qualifier was provided.
- RQ_None = 0,
- /// \brief An lvalue ref-qualifier was provided (\c &).
- RQ_LValue,
- /// \brief An rvalue ref-qualifier was provided (\c &&).
- RQ_RValue
-};
-
-/// Which keyword(s) were used to create an AutoType.
-enum class AutoTypeKeyword {
- /// \brief auto
- Auto,
- /// \brief decltype(auto)
- DecltypeAuto,
- /// \brief __auto_type (GNU extension)
- GNUAutoType
-};
-
-/// The base class of the type hierarchy.
-///
-/// A central concept with types is that each type always has a canonical
-/// type. A canonical type is the type with any typedef names stripped out
-/// of it or the types it references. For example, consider:
-///
-/// typedef int foo;
-/// typedef foo* bar;
-/// 'int *' 'foo *' 'bar'
-///
-/// There will be a Type object created for 'int'. Since int is canonical, its
-/// CanonicalType pointer points to itself. There is also a Type for 'foo' (a
-/// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next
-/// there is a PointerType that represents 'int*', which, like 'int', is
-/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical
-/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
-/// is also 'int*'.
-///
-/// Non-canonical types are useful for emitting diagnostics, without losing
-/// information about typedefs being used. Canonical types are useful for type
-/// comparisons (they allow by-pointer equality tests) and useful for reasoning
-/// about whether something has a particular form (e.g. is a function type),
-/// because they implicitly, recursively, strip all typedefs out of a type.
-///
-/// Types, once created, are immutable.
-///
-class Type : public ExtQualsTypeCommonBase {
-public:
- enum TypeClass {
-#define TYPE(Class, Base) Class,
-#define LAST_TYPE(Class) TypeLast = Class,
-#define ABSTRACT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
- TagFirst = Record, TagLast = Enum
- };
-
-private:
- Type(const Type &) = delete;
- void operator=(const Type &) = delete;
-
- /// Bitfields required by the Type class.
- class TypeBitfields {
- friend class Type;
- template <class T> friend class TypePropertyCache;
-
- /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
- unsigned TC : 8;
-
- /// Whether this type is a dependent type (C++ [temp.dep.type]).
- unsigned Dependent : 1;
-
- /// Whether this type somehow involves a template parameter, even
- /// if the resolution of the type does not depend on a template parameter.
- unsigned InstantiationDependent : 1;
-
- /// Whether this type is a variably-modified type (C99 6.7.5).
- unsigned VariablyModified : 1;
-
- /// \brief 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
- /// 'Cache') is valid.
- mutable unsigned CacheValid : 1;
-
- /// \brief Linkage of this type.
- mutable unsigned CachedLinkage : 3;
-
- /// \brief Whether this type involves and local or unnamed types.
- mutable unsigned CachedLocalOrUnnamed : 1;
-
- /// \brief Whether this type comes from an AST file.
- mutable unsigned FromAST : 1;
-
- bool isCacheValid() const {
- return CacheValid;
- }
- Linkage getLinkage() const {
- assert(isCacheValid() && "getting linkage from invalid cache");
- return static_cast<Linkage>(CachedLinkage);
- }
- bool hasLocalOrUnnamedType() const {
- assert(isCacheValid() && "getting linkage from invalid cache");
- return CachedLocalOrUnnamed;
- }
- };
- enum { NumTypeBits = 18 };
-
-protected:
- // These classes allow subclasses to somewhat cleanly pack bitfields
- // into Type.
-
- class ArrayTypeBitfields {
- friend class ArrayType;
-
- unsigned : NumTypeBits;
-
- /// CVR qualifiers from declarations like
- /// 'int X[static restrict 4]'. For function parameters only.
- unsigned IndexTypeQuals : 3;
-
- /// Storage class qualifiers from declarations like
- /// 'int X[static restrict 4]'. For function parameters only.
- /// Actually an ArrayType::ArraySizeModifier.
- unsigned SizeModifier : 3;
- };
-
- class BuiltinTypeBitfields {
- friend class BuiltinType;
-
- unsigned : NumTypeBits;
-
- /// The kind (BuiltinType::Kind) of builtin type this is.
- unsigned Kind : 8;
- };
-
- class FunctionTypeBitfields {
- friend class FunctionType;
- friend class FunctionProtoType;
-
- unsigned : NumTypeBits;
-
- /// Extra information which affects how the function is called, like
- /// regparm and the calling convention.
- unsigned ExtInfo : 9;
-
- /// Used only by FunctionProtoType, put here to pack with the
- /// other bitfields.
- /// The qualifiers are part of FunctionProtoType because...
- ///
- /// C++ 8.3.5p4: The return type, the parameter type list and the
- /// cv-qualifier-seq, [...], are part of the function type.
- unsigned TypeQuals : 3;
-
- /// \brief The ref-qualifier associated with a \c FunctionProtoType.
- ///
- /// This is a value of type \c RefQualifierKind.
- unsigned RefQualifier : 2;
- };
-
- class ObjCObjectTypeBitfields {
- friend class ObjCObjectType;
-
- unsigned : NumTypeBits;
-
- /// The number of type arguments stored directly on this object type.
- unsigned NumTypeArgs : 7;
-
- /// The number of protocols stored directly on this object type.
- unsigned NumProtocols : 6;
-
- /// Whether this is a "kindof" type.
- unsigned IsKindOf : 1;
- };
- static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned");
-
- class ReferenceTypeBitfields {
- friend class ReferenceType;
-
- unsigned : NumTypeBits;
-
- /// True if the type was originally spelled with an lvalue sigil.
- /// This is never true of rvalue references but can also be false
- /// on lvalue references because of C++0x [dcl.typedef]p9,
- /// as follows:
- ///
- /// typedef int &ref; // lvalue, spelled lvalue
- /// typedef int &&rvref; // rvalue
- /// ref &a; // lvalue, inner ref, spelled lvalue
- /// ref &&a; // lvalue, inner ref
- /// rvref &a; // lvalue, inner ref, spelled lvalue
- /// rvref &&a; // rvalue, inner ref
- unsigned SpelledAsLValue : 1;
-
- /// True if the inner type is a reference type. This only happens
- /// in non-canonical forms.
- unsigned InnerRef : 1;
- };
-
- class TypeWithKeywordBitfields {
- friend class TypeWithKeyword;
-
- unsigned : NumTypeBits;
-
- /// An ElaboratedTypeKeyword. 8 bits for efficient access.
- unsigned Keyword : 8;
- };
-
- class VectorTypeBitfields {
- friend class VectorType;
-
- unsigned : NumTypeBits;
-
- /// The kind of vector, either a generic vector type or some
- /// target-specific vector type such as for AltiVec or Neon.
- unsigned VecKind : 3;
-
- /// The number of elements in the vector.
- unsigned NumElements : 29 - NumTypeBits;
-
- enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
- };
-
- class AttributedTypeBitfields {
- friend class AttributedType;
-
- unsigned : NumTypeBits;
-
- /// An AttributedType::Kind
- unsigned AttrKind : 32 - NumTypeBits;
- };
-
- class AutoTypeBitfields {
- friend class AutoType;
-
- unsigned : NumTypeBits;
-
- /// Was this placeholder type spelled as 'auto', 'decltype(auto)',
- /// or '__auto_type'? AutoTypeKeyword value.
- unsigned Keyword : 2;
- };
-
- union {
- TypeBitfields TypeBits;
- ArrayTypeBitfields ArrayTypeBits;
- AttributedTypeBitfields AttributedTypeBits;
- AutoTypeBitfields AutoTypeBits;
- BuiltinTypeBitfields BuiltinTypeBits;
- FunctionTypeBitfields FunctionTypeBits;
- ObjCObjectTypeBitfields ObjCObjectTypeBits;
- ReferenceTypeBitfields ReferenceTypeBits;
- TypeWithKeywordBitfields TypeWithKeywordBits;
- VectorTypeBitfields VectorTypeBits;
- };
-
-private:
- /// \brief Set whether this type comes from an AST file.
- void setFromAST(bool V = true) const {
- TypeBits.FromAST = V;
- }
-
- template <class T> friend class TypePropertyCache;
-
-protected:
- // silence VC++ warning C4355: 'this' : used in base member initializer list
- Type *this_() { return this; }
- Type(TypeClass tc, QualType canon, bool Dependent,
- bool InstantiationDependent, bool VariablyModified,
- bool ContainsUnexpandedParameterPack)
- : ExtQualsTypeCommonBase(this,
- canon.isNull() ? QualType(this_(), 0) : canon) {
- TypeBits.TC = tc;
- TypeBits.Dependent = Dependent;
- TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
- TypeBits.VariablyModified = VariablyModified;
- TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
- TypeBits.CacheValid = false;
- TypeBits.CachedLocalOrUnnamed = false;
- TypeBits.CachedLinkage = NoLinkage;
- TypeBits.FromAST = false;
- }
- friend class ASTContext;
-
- void setDependent(bool D = true) {
- TypeBits.Dependent = D;
- if (D)
- TypeBits.InstantiationDependent = true;
- }
- void setInstantiationDependent(bool D = true) {
- TypeBits.InstantiationDependent = D; }
- void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM;
- }
- void setContainsUnexpandedParameterPack(bool PP = true) {
- TypeBits.ContainsUnexpandedParameterPack = PP;
- }
-
-public:
- TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
-
- /// \brief Whether this type comes from an AST file.
- bool isFromAST() const { return TypeBits.FromAST; }
-
- /// \brief 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
- /// ellipsis operator at some point. For example, the typedef in the
- /// following example contains an unexpanded parameter pack 'T':
- ///
- /// \code
- /// template<typename ...T>
- /// struct X {
- /// typedef T* pointer_types; // ill-formed; T is a parameter pack.
- /// };
- /// \endcode
- ///
- /// Note that this routine does not specify which
- bool containsUnexpandedParameterPack() const {
- return TypeBits.ContainsUnexpandedParameterPack;
- }
-
- /// Determines if this type would be canonical if it had no further
- /// qualification.
- bool isCanonicalUnqualified() const {
- return CanonicalType == QualType(this, 0);
- }
-
- /// Pull a single level of sugar off of this locally-unqualified type.
- /// Users should generally prefer SplitQualType::getSingleStepDesugaredType()
- /// or QualType::getSingleStepDesugaredType(const ASTContext&).
- QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
-
- /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
- /// object types, function types, and incomplete types.
-
- /// Return true if this is an incomplete type.
- /// A type that can describe objects, but which lacks information needed to
- /// 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
- /// 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;
-
- /// Return true if this is an incomplete or object
- /// type, in other words, not a function type.
- bool isIncompleteOrObjectType() const {
- return !isFunctionType();
- }
-
- /// \brief 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
- // function type, not a reference type, and not a void type.
- return !isReferenceType() && !isFunctionType() && !isVoidType();
- }
-
- /// Return true if this is a literal type
- /// (C++11 [basic.types]p10)
- bool isLiteralType(const ASTContext &Ctx) const;
-
- /// Test if this type is a standard-layout type.
- /// (C++0x [basic.type]p9)
- bool isStandardLayoutType() const;
-
- /// Helper methods to distinguish type categories. All type predicates
- /// operate on the canonical type, ignoring typedefs and qualifiers.
-
- /// Returns true if the type is a builtin type.
- bool isBuiltinType() const;
-
- /// Test for a particular builtin type.
- bool isSpecificBuiltinType(unsigned K) const;
-
- /// Test for a type which does not represent an actual type-system type but
- /// is instead used as a placeholder for various convenient purposes within
- /// Clang. All such types are BuiltinTypes.
- bool isPlaceholderType() const;
- const BuiltinType *getAsPlaceholderType() const;
-
- /// Test for a specific placeholder type.
- bool isSpecificPlaceholderType(unsigned K) const;
-
- /// Test for a placeholder type other than Overload; see
- /// BuiltinType::isNonOverloadPlaceholderType.
- bool isNonOverloadPlaceholderType() const;
-
- /// isIntegerType() does *not* include complex integers (a GCC extension).
- /// isComplexIntegerType() can be used to test for complex integers.
- bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
- bool isEnumeralType() const;
- bool isBooleanType() const;
- bool isCharType() const;
- bool isWideCharType() const;
- bool isChar16Type() const;
- bool isChar32Type() const;
- bool isAnyCharacterType() const;
- bool isIntegralType(ASTContext &Ctx) const;
-
- /// Determine whether this type is an integral or enumeration type.
- bool isIntegralOrEnumerationType() const;
- /// Determine whether this type is an integral or unscoped enumeration type.
- bool isIntegralOrUnscopedEnumerationType() const;
-
- /// Floating point categories.
- bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
- /// isComplexType() does *not* include complex integers (a GCC extension).
- /// isComplexIntegerType() can be used to test for complex integers.
- bool isComplexType() const; // C99 6.2.5p11 (complex)
- 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 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
- bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
- bool isAggregateType() const;
- bool isFundamentalType() const;
- bool isCompoundType() const;
-
- // Type Predicates: Check to see if this type is structurally the specified
- // type, ignoring typedefs and qualifiers.
- bool isFunctionType() const;
- bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
- bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
- bool isPointerType() const;
- bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
- bool isBlockPointerType() const;
- bool isVoidPointerType() const;
- bool isReferenceType() const;
- bool isLValueReferenceType() const;
- bool isRValueReferenceType() const;
- bool isFunctionPointerType() const;
- bool isMemberPointerType() const;
- bool isMemberFunctionPointerType() const;
- bool isMemberDataPointerType() const;
- bool isArrayType() const;
- bool isConstantArrayType() const;
- bool isIncompleteArrayType() const;
- bool isVariableArrayType() const;
- bool isDependentSizedArrayType() const;
- bool isRecordType() const;
- bool isClassType() const;
- bool isStructureType() const;
- bool isObjCBoxableRecordType() const;
- bool isInterfaceType() const;
- bool isStructureOrClassType() const;
- bool isUnionType() const;
- bool isComplexIntegerType() const; // GCC _Complex integer type.
- bool isVectorType() const; // GCC vector type.
- bool isExtVectorType() const; // Extended vector type.
- bool isObjCObjectPointerType() const; // pointer to ObjC object
- bool isObjCRetainableType() const; // ObjC object or block pointer
- bool isObjCLifetimeType() const; // (array of)* retainable type
- bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type
- bool isObjCNSObjectType() const; // __attribute__((NSObject))
- bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class))
- // FIXME: change this to 'raw' interface type, so we can used 'interface' type
- // for the common case.
- bool isObjCObjectType() const; // NSString or typeof(*(id)0)
- bool isObjCQualifiedInterfaceType() const; // NSString<foo>
- bool isObjCQualifiedIdType() const; // id<foo>
- bool isObjCQualifiedClassType() const; // Class<foo>
- bool isObjCObjectOrInterfaceType() const;
- bool isObjCIdType() const; // id
- bool isObjCInertUnsafeUnretainedType() const;
-
- /// Whether the type is Objective-C 'id' or a __kindof type of an
- /// object type, e.g., __kindof NSView * or __kindof id
- /// <NSCopying>.
- ///
- /// \param bound Will be set to the bound on non-id subtype types,
- /// which will be (possibly specialized) Objective-C class type, or
- /// null for 'id.
- bool isObjCIdOrObjectKindOfType(const ASTContext &ctx,
- const ObjCObjectType *&bound) const;
-
- bool isObjCClassType() const; // Class
-
- /// Whether the type is Objective-C 'Class' or a __kindof type of an
- /// Class type, e.g., __kindof Class <NSCopying>.
- ///
- /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound
- /// here because Objective-C's type system cannot express "a class
- /// object for a subclass of NSFoo".
- bool isObjCClassOrClassKindOfType() const;
-
- bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const;
- bool isObjCSelType() const; // Class
- bool isObjCBuiltinType() const; // 'id' or 'Class'
- bool isObjCARCBridgableType() const;
- bool isCARCBridgableType() const;
- bool isTemplateTypeParmType() const; // C++ template type parameter
- bool isNullPtrType() const; // C++0x nullptr_t
- bool isAtomicType() const; // C11 _Atomic()
-
- bool isImage1dT() const; // OpenCL image1d_t
- bool isImage1dArrayT() const; // OpenCL image1d_array_t
- bool isImage1dBufferT() const; // OpenCL image1d_buffer_t
- bool isImage2dT() const; // OpenCL image2d_t
- bool isImage2dArrayT() const; // OpenCL image2d_array_t
- bool isImage2dDepthT() const; // OpenCL image_2d_depth_t
- bool isImage2dArrayDepthT() const; // OpenCL image_2d_array_depth_t
- bool isImage2dMSAAT() const; // OpenCL image_2d_msaa_t
- bool isImage2dArrayMSAAT() const; // OpenCL image_2d_array_msaa_t
- bool isImage2dMSAATDepth() const; // OpenCL image_2d_msaa_depth_t
- bool isImage2dArrayMSAATDepth() const; // OpenCL image_2d_array_msaa_depth_t
- bool isImage3dT() const; // OpenCL image3d_t
-
- bool isImageType() const; // Any OpenCL image type
-
- bool isSamplerT() const; // OpenCL sampler_t
- bool isEventT() const; // OpenCL event_t
- bool isClkEventT() const; // OpenCL clk_event_t
- bool isQueueT() const; // OpenCL queue_t
- bool isNDRangeT() const; // OpenCL ndrange_t
- bool isReserveIDT() const; // OpenCL reserve_id_t
-
- bool isOpenCLSpecificType() const; // Any OpenCL specific type
-
- /// Determines if this type, which must satisfy
- /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
- /// than implicitly __strong.
- bool isObjCARCImplicitlyUnretainedType() const;
-
- /// Return the implicit lifetime for this type, which must not be dependent.
- Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
-
- enum ScalarTypeKind {
- STK_CPointer,
- STK_BlockPointer,
- STK_ObjCObjectPointer,
- STK_MemberPointer,
- STK_Bool,
- STK_Integral,
- STK_Floating,
- STK_IntegralComplex,
- STK_FloatingComplex
- };
- /// Given that this is a scalar type, classify it.
- ScalarTypeKind getScalarTypeKind() const;
-
- /// Whether this type is a dependent type, meaning that its definition
- /// 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,
- /// meaning that the type involves a template parameter (even if the
- /// definition does not actually depend on the type substituted for that
- /// template parameter).
- bool isInstantiationDependentType() const {
- return TypeBits.InstantiationDependent;
- }
-
- /// \brief Determine whether this type is an undeduced type, meaning that
- /// it somehow involves a C++11 'auto' type which has not yet been deduced.
- bool isUndeducedType() const;
-
- /// \brief 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
- /// with a definite size.
- bool hasSizedVLAType() const;
-
- /// \brief 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.
- bool isElaboratedTypeSpecifier() const;
-
- bool canDecayToPointerType() const;
-
- /// Whether this type is represented natively as a pointer. This includes
- /// pointers, references, block pointers, and Objective-C interface,
- /// qualified id, and qualified interface types, as well as nullptr_t.
- bool hasPointerRepresentation() const;
-
- /// Whether this type can represent an objective pointer type for the
- /// purpose of GC'ability
- bool hasObjCPointerRepresentation() const;
-
- /// \brief 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
- /// 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
- /// 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
- /// of some sort, e.g., it is a floating-point type or a vector thereof.
- bool hasFloatingRepresentation() const;
-
- // Type Checking Functions: Check to see if this type is structurally the
- // specified type, ignoring typedefs and qualifiers, and return a pointer to
- // the best type we can.
- const RecordType *getAsStructureType() const;
- /// NOTE: getAs*ArrayType are methods on ASTContext.
- const RecordType *getAsUnionType() const;
- const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
- const ObjCObjectType *getAsObjCInterfaceType() const;
- // The following is a convenience method that returns an ObjCObjectPointerType
- // for object declared using an interface.
- const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
- const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
- const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
- const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
-
- /// \brief 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
- /// 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.
- ///
- /// If this is not a pointer or reference, or the type being pointed to does
- /// not refer to a CXXRecordDecl, returns NULL.
- const CXXRecordDecl *getPointeeCXXRecordDecl() const;
-
- /// Get the AutoType whose type will be deduced for a variable with
- /// an initializer of this type. This looks through declarators like pointer
- /// types, but not through decltype or typedefs.
- AutoType *getContainedAutoType() const;
-
- /// Member-template getAs<specific type>'. Look through sugar for
- /// an instance of \<specific type>. This scheme will eventually
- /// replace the specific getAsXXXX methods above.
- ///
- /// There are some specializations of this member template listed
- /// immediately following this class.
- template <typename T> const T *getAs() const;
-
- /// A variant of getAs<> for array types which silently discards
- /// qualifiers from the outermost type.
- const ArrayType *getAsArrayTypeUnsafe() const;
-
- /// Member-template castAs<specific type>. Look through sugar for
- /// the underlying instance of \<specific type>.
- ///
- /// This method has the same relationship to getAs<T> as cast<T> has
- /// to dyn_cast<T>; which is to say, the underlying type *must*
- /// have the intended type, and this method will never return null.
- template <typename T> const T *castAs() const;
-
- /// A variant of castAs<> for array type which silently discards
- /// qualifiers from the outermost type.
- const ArrayType *castAsArrayTypeUnsafe() const;
-
- /// Get the base element type of this type, potentially discarding type
- /// qualifiers. This should never be used when type qualifiers
- /// are meaningful.
- const Type *getBaseElementTypeUnsafe() const;
-
- /// If this is an array type, return the element type of the array,
- /// potentially with type qualifiers missing.
- /// This should never be used when type qualifiers are meaningful.
- const Type *getArrayElementTypeNoTypeQual() const;
-
- /// If this is a pointer, ObjC object pointer, or block
- /// pointer, this returns the respective pointee.
- QualType getPointeeType() const;
-
- /// Return the specified type with any "sugar" removed from the type,
- /// removing any typedefs, typeofs, etc., as well as any qualifiers.
- const Type *getUnqualifiedDesugaredType() const;
-
- /// More type predicates useful for type checking/promotion
- bool isPromotableIntegerType() const; // C99 6.3.1.1p2
-
- /// Return true if this is an integer type that is
- /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
- /// or an enum decl which has a signed representation.
- bool isSignedIntegerType() const;
-
- /// Return true if this is an integer type that is
- /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool],
- /// or an enum decl which has an unsigned representation.
- bool isUnsignedIntegerType() const;
-
- /// Determines whether this is an integer type that is signed or an
- /// enumeration types whose underlying type is a signed integer type.
- bool isSignedIntegerOrEnumerationType() const;
-
- /// Determines whether this is an integer type that is unsigned or an
- /// enumeration types whose underlying type is a unsigned integer type.
- bool isUnsignedIntegerOrEnumerationType() 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.
- bool isConstantSizeType() const;
-
- /// Returns true if this type can be represented by some
- /// set of type specifiers.
- bool isSpecifierType() const;
-
- /// Determine the linkage of this type.
- Linkage getLinkage() const;
-
- /// Determine the visibility of this type.
- Visibility getVisibility() const {
- return getLinkageAndVisibility().getVisibility();
- }
-
- /// Return true if the visibility was explicitly set is the code.
- bool isVisibilityExplicit() const {
- return getLinkageAndVisibility().isVisibilityExplicit();
- }
-
- /// Determine the linkage and visibility of this type.
- LinkageInfo getLinkageAndVisibility() const;
-
- /// True if the computed linkage is valid. Used for consistency
- /// checking. Should always return true.
- bool isLinkageValid() const;
-
- /// Determine the nullability of the given type.
- ///
- /// Note that nullability is only captured as sugar within the type
- /// system, not as part of the canonical type, so nullability will
- /// be lost by canonicalization and desugaring.
- Optional<NullabilityKind> getNullability(const ASTContext &context) const;
-
- /// Determine whether the given type can have a nullability
- /// specifier applied to it, i.e., if it is any kind of pointer type
- /// or a dependent type that could instantiate to any kind of
- /// pointer type.
- bool canHaveNullability() const;
-
- /// Retrieve the set of substitutions required when accessing a member
- /// of the Objective-C receiver type that is declared in the given context.
- ///
- /// \c *this is the type of the object we're operating on, e.g., the
- /// receiver for a message send or the base of a property access, and is
- /// expected to be of some object or object pointer type.
- ///
- /// \param dc The declaration context for which we are building up a
- /// substitution mapping, which should be an Objective-C class, extension,
- /// category, or method within.
- ///
- /// \returns an array of type arguments that can be substituted for
- /// the type parameters of the given declaration context in any type described
- /// within that context, or an empty optional to indicate that no
- /// substitution is required.
- Optional<ArrayRef<QualType>>
- getObjCSubstitutions(const DeclContext *dc) const;
-
- /// Determines if this is an ObjC interface type that may accept type
- /// parameters.
- bool acceptsObjCTypeParams() const;
-
- const char *getTypeClassName() const;
-
- QualType getCanonicalTypeInternal() const {
- return CanonicalType;
- }
- CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
- void dump() const;
-
- friend class ASTReader;
- friend class ASTWriter;
-};
-
-/// \brief 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
-/// 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
-/// until it reaches an AttributedType or a non-sugared type.
-template <> const AttributedType *Type::getAs() const;
-
-// We can do canonical leaf types faster, because we don't have to
-// worry about preserving child type decoration.
-#define TYPE(Class, Base)
-#define LEAF_TYPE(Class) \
-template <> inline const Class##Type *Type::getAs() const { \
- return dyn_cast<Class##Type>(CanonicalType); \
-} \
-template <> inline const Class##Type *Type::castAs() const { \
- return cast<Class##Type>(CanonicalType); \
-}
-#include "clang/AST/TypeNodes.def"
-
-
-/// This class is used for builtin types like 'int'. Builtin
-/// types are always canonical and have a literal name field.
-class BuiltinType : public Type {
-public:
- enum Kind {
-#define BUILTIN_TYPE(Id, SingletonId) Id,
-#define LAST_BUILTIN_TYPE(Id) LastKind = Id
-#include "clang/AST/BuiltinTypes.def"
- };
-
-public:
- BuiltinType(Kind K)
- : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
- /*InstantiationDependent=*/(K == Dependent),
- /*VariablyModified=*/false,
- /*Unexpanded paramter pack=*/false) {
- BuiltinTypeBits.Kind = K;
- }
-
- Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); }
- StringRef getName(const PrintingPolicy &Policy) const;
- const char *getNameAsCString(const PrintingPolicy &Policy) const {
- // The StringRef is null-terminated.
- StringRef str = getName(Policy);
- assert(!str.empty() && str.data()[str.size()] == '\0');
- return str.data();
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- bool isInteger() const {
- return getKind() >= Bool && getKind() <= Int128;
- }
-
- bool isSignedInteger() const {
- return getKind() >= Char_S && getKind() <= Int128;
- }
-
- bool isUnsignedInteger() const {
- return getKind() >= Bool && getKind() <= UInt128;
- }
-
- bool isFloatingPoint() const {
- return getKind() >= Half && getKind() <= LongDouble;
- }
-
- /// Determines whether the given kind corresponds to a placeholder type.
- static bool isPlaceholderTypeKind(Kind K) {
- return K >= Overload;
- }
-
- /// Determines whether this type is a placeholder type, i.e. a type
- /// which cannot appear in arbitrary positions in a fully-formed
- /// expression.
- bool isPlaceholderType() const {
- return isPlaceholderTypeKind(getKind());
- }
-
- /// Determines whether this type is a placeholder type other than
- /// Overload. Most placeholder types require only syntactic
- /// information about their context in order to be resolved (e.g.
- /// whether it is a call expression), which means they can (and
- /// should) be resolved in an earlier "phase" of analysis.
- /// Overload expressions sometimes pick up further information
- /// from their context, like whether the context expects a
- /// specific function-pointer type, and so frequently need
- /// special treatment.
- bool isNonOverloadPlaceholderType() const {
- return getKind() > Overload;
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
-};
-
-/// Complex values, per C99 6.2.5p11. This supports the C99 complex
-/// types (_Complex float etc) as well as the GCC integer complex extensions.
-///
-class ComplexType : public Type, public llvm::FoldingSetNode {
- QualType ElementType;
- ComplexType(QualType Element, QualType CanonicalPtr) :
- Type(Complex, CanonicalPtr, Element->isDependentType(),
- Element->isInstantiationDependentType(),
- Element->isVariablyModifiedType(),
- Element->containsUnexpandedParameterPack()),
- ElementType(Element) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getElementType() const { return ElementType; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
- ID.AddPointer(Element.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
-};
-
-/// Sugar for parentheses used when specifying types.
-///
-class ParenType : public Type, public llvm::FoldingSetNode {
- QualType Inner;
-
- ParenType(QualType InnerType, QualType CanonType) :
- Type(Paren, CanonType, InnerType->isDependentType(),
- InnerType->isInstantiationDependentType(),
- InnerType->isVariablyModifiedType(),
- InnerType->containsUnexpandedParameterPack()),
- Inner(InnerType) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
-
- QualType getInnerType() const { return Inner; }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return getInnerType(); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getInnerType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) {
- Inner.Profile(ID);
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Paren; }
-};
-
-/// PointerType - C99 6.7.5.1 - Pointer Declarators.
-///
-class PointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
-
- PointerType(QualType Pointee, QualType CanonicalPtr) :
- Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
-
- QualType getPointeeType() const { return PointeeType; }
-
- /// Returns true if address spaces of pointers overlap.
- /// OpenCL v2.0 defines conversion rules for pointers to different
- /// address spaces (OpenCLC v2.0 s6.5.5) and notion of overlapping
- /// address spaces.
- /// CL1.1 or CL1.2:
- /// address spaces overlap iff they are they same.
- /// CL2.0 adds:
- /// __generic overlaps with any address space except for __constant.
- bool isAddressSpaceOverlapping(const PointerType &other) const {
- Qualifiers thisQuals = PointeeType.getQualifiers();
- Qualifiers otherQuals = other.getPointeeType().getQualifiers();
- // Address spaces overlap if at least one of them is a superset of another
- return thisQuals.isAddressSpaceSupersetOf(otherQuals) ||
- otherQuals.isAddressSpaceSupersetOf(thisQuals);
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
-};
-
-/// Represents a type which was implicitly adjusted by the semantic
-/// engine for arbitrary reasons. For example, array and function types can
-/// decay, and function types can have their calling conventions adjusted.
-class AdjustedType : public Type, public llvm::FoldingSetNode {
- QualType OriginalTy;
- QualType AdjustedTy;
-
-protected:
- AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
- QualType CanonicalPtr)
- : Type(TC, CanonicalPtr, OriginalTy->isDependentType(),
- OriginalTy->isInstantiationDependentType(),
- OriginalTy->isVariablyModifiedType(),
- OriginalTy->containsUnexpandedParameterPack()),
- OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getOriginalType() const { return OriginalTy; }
- QualType getAdjustedType() const { return AdjustedTy; }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return AdjustedTy; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, OriginalTy, AdjustedTy);
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
- ID.AddPointer(Orig.getAsOpaquePtr());
- ID.AddPointer(New.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed;
- }
-};
-
-/// Represents a pointer type decayed from an array or function type.
-class DecayedType : public AdjustedType {
-
- DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr)
- : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
- assert(isa<PointerType>(getAdjustedType()));
- }
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getDecayedType() const { return getAdjustedType(); }
-
- QualType getPointeeType() const {
- return cast<PointerType>(getDecayedType())->getPointeeType();
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
-};
-
-/// Pointer to a block type.
-/// This type is to represent types syntactically represented as
-/// "void (^)(int)", etc. Pointee is required to always be a function type.
-///
-class BlockPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType; // Block is some kind of pointer type
- BlockPointerType(QualType Pointee, QualType CanonicalCls) :
- Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
-
- // Get the pointee type. Pointee is required to always be a function type.
- QualType getPointeeType() const { return PointeeType; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == BlockPointer;
- }
-};
-
-/// Base for LValueReferenceType and RValueReferenceType
-///
-class ReferenceType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
-
-protected:
- ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
- bool SpelledAsLValue) :
- Type(tc, CanonicalRef, Referencee->isDependentType(),
- Referencee->isInstantiationDependentType(),
- Referencee->isVariablyModifiedType(),
- Referencee->containsUnexpandedParameterPack()),
- PointeeType(Referencee)
- {
- ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue;
- ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
- }
-
-public:
- bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; }
- bool isInnerRef() const { return ReferenceTypeBits.InnerRef; }
-
- QualType getPointeeTypeAsWritten() const { return PointeeType; }
- QualType getPointeeType() const {
- // FIXME: this might strip inner qualifiers; okay?
- const ReferenceType *T = this;
- while (T->isInnerRef())
- T = T->PointeeType->castAs<ReferenceType>();
- return T->PointeeType;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, PointeeType, isSpelledAsLValue());
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- QualType Referencee,
- bool SpelledAsLValue) {
- ID.AddPointer(Referencee.getAsOpaquePtr());
- ID.AddBoolean(SpelledAsLValue);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == LValueReference ||
- T->getTypeClass() == RValueReference;
- }
-};
-
-/// An lvalue reference type, per C++11 [dcl.ref].
-///
-class LValueReferenceType : public ReferenceType {
- LValueReferenceType(QualType Referencee, QualType CanonicalRef,
- bool SpelledAsLValue) :
- ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
- {}
- friend class ASTContext; // ASTContext creates these
-public:
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == LValueReference;
- }
-};
-
-/// An rvalue reference type, per C++11 [dcl.ref].
-///
-class RValueReferenceType : public ReferenceType {
- RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
- ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
- }
- friend class ASTContext; // ASTContext creates these
-public:
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == RValueReference;
- }
-};
-
-/// A pointer to member type per C++ 8.3.3 - Pointers to members.
-///
-/// This includes both pointers to data members and pointer to member functions.
-///
-class MemberPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
- /// The class of which the pointee is a member. Must ultimately be a
- /// RecordType, but could be a typedef or a template parameter too.
- const Type *Class;
-
- MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
- Type(MemberPointer, CanonicalPtr,
- Cls->isDependentType() || Pointee->isDependentType(),
- (Cls->isInstantiationDependentType() ||
- Pointee->isInstantiationDependentType()),
- Pointee->isVariablyModifiedType(),
- (Cls->containsUnexpandedParameterPack() ||
- Pointee->containsUnexpandedParameterPack())),
- PointeeType(Pointee), Class(Cls) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getPointeeType() const { return PointeeType; }
-
- /// Returns true if the member type (i.e. the pointee type) is a
- /// function type rather than a data-member type.
- bool isMemberFunctionPointer() const {
- return PointeeType->isFunctionProtoType();
- }
-
- /// Returns true if the member type (i.e. the pointee type) is a
- /// data type rather than a function type.
- bool isMemberDataPointer() const {
- return !PointeeType->isFunctionProtoType();
- }
-
- const Type *getClass() const { return Class; }
- CXXRecordDecl *getMostRecentCXXRecordDecl() const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType(), getClass());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
- const Type *Class) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- ID.AddPointer(Class);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == MemberPointer;
- }
-};
-
-/// Represents an array type, per C99 6.7.5.2 - Array Declarators.
-///
-class ArrayType : public Type, public llvm::FoldingSetNode {
-public:
- /// Capture whether this is a normal array (e.g. int X[4])
- /// an array with a static size (e.g. int X[static 4]), or an array
- /// with a star size (e.g. int X[*]).
- /// 'static' is only allowed on function parameters.
- enum ArraySizeModifier {
- Normal, Static, Star
- };
-private:
- /// The element type of the array.
- QualType ElementType;
-
-protected:
- // C++ [temp.dep.type]p1:
- // A type is dependent if it is...
- // - an array type constructed from any dependent type or whose
- // size is specified by a constant expression that is
- // value-dependent,
- ArrayType(TypeClass tc, QualType et, QualType can,
- ArraySizeModifier sm, unsigned tq,
- bool ContainsUnexpandedParameterPack)
- : Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
- et->isInstantiationDependentType() || tc == DependentSizedArray,
- (tc == VariableArray || et->isVariablyModifiedType()),
- ContainsUnexpandedParameterPack),
- ElementType(et) {
- ArrayTypeBits.IndexTypeQuals = tq;
- ArrayTypeBits.SizeModifier = sm;
- }
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getElementType() const { return ElementType; }
- ArraySizeModifier getSizeModifier() const {
- return ArraySizeModifier(ArrayTypeBits.SizeModifier);
- }
- Qualifiers getIndexTypeQualifiers() const {
- return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers());
- }
- unsigned getIndexTypeCVRQualifiers() const {
- return ArrayTypeBits.IndexTypeQuals;
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == VariableArray ||
- T->getTypeClass() == IncompleteArray ||
- T->getTypeClass() == DependentSizedArray;
- }
-};
-
-/// Represents the canonical version of C arrays with a specified constant size.
-/// For example, the canonical type for 'int A[4 + 4*100]' is a
-/// ConstantArrayType where the element type is 'int' and the size is 404.
-class ConstantArrayType : public ArrayType {
- llvm::APInt Size; // Allows us to unique the type.
-
- ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
- ArraySizeModifier sm, unsigned tq)
- : ArrayType(ConstantArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()),
- Size(size) {}
-protected:
- ConstantArrayType(TypeClass tc, QualType et, QualType can,
- const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
- : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()),
- Size(size) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- const llvm::APInt &getSize() const { return Size; }
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
-
- /// \brief 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(ASTContext &Context,
- QualType ElementType,
- const llvm::APInt &NumElements);
-
- /// \brief 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(ASTContext &Context);
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getSize(),
- getSizeModifier(), getIndexTypeCVRQualifiers());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
- const llvm::APInt &ArraySize, ArraySizeModifier SizeMod,
- unsigned TypeQuals) {
- ID.AddPointer(ET.getAsOpaquePtr());
- ID.AddInteger(ArraySize.getZExtValue());
- ID.AddInteger(SizeMod);
- ID.AddInteger(TypeQuals);
- }
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray;
- }
-};
-
-/// Represents a C array with an unspecified size. For example 'int A[]' has
-/// an IncompleteArrayType where the element type is 'int' and the size is
-/// unspecified.
-class IncompleteArrayType : public ArrayType {
-
- IncompleteArrayType(QualType et, QualType can,
- ArraySizeModifier sm, unsigned tq)
- : ArrayType(IncompleteArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == IncompleteArray;
- }
-
- friend class StmtIteratorBase;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getSizeModifier(),
- getIndexTypeCVRQualifiers());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
- ArraySizeModifier SizeMod, unsigned TypeQuals) {
- ID.AddPointer(ET.getAsOpaquePtr());
- ID.AddInteger(SizeMod);
- ID.AddInteger(TypeQuals);
- }
-};
-
-/// Represents a C array with a specified size that is not an
-/// integer-constant-expression. For example, 'int s[x+foo()]'.
-/// Since the size expression is an arbitrary expression, we store it as such.
-///
-/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
-/// should not be: two lexically equivalent variable array types could mean
-/// different things, for example, these variables do not have the same type
-/// dynamically:
-///
-/// void foo(int x) {
-/// int Y[x];
-/// ++x;
-/// int Z[x];
-/// }
-///
-class VariableArrayType : public ArrayType {
- /// An assignment-expression. VLA's are only permitted within
- /// a function block.
- Stmt *SizeExpr;
- /// The range spanned by the left and right array brackets.
- SourceRange Brackets;
-
- VariableArrayType(QualType et, QualType can, Expr *e,
- ArraySizeModifier sm, unsigned tq,
- SourceRange brackets)
- : ArrayType(VariableArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()),
- SizeExpr((Stmt*) e), Brackets(brackets) {}
- friend class ASTContext; // ASTContext creates these.
-
-public:
- Expr *getSizeExpr() const {
- // We use C-style casts instead of cast<> here because we do not wish
- // to have a dependency of Type.h on Stmt.h/Expr.h.
- return (Expr*) SizeExpr;
- }
- SourceRange getBracketsRange() const { return Brackets; }
- SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
- SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == VariableArray;
- }
-
- friend class StmtIteratorBase;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- llvm_unreachable("Cannot unique VariableArrayTypes.");
- }
-};
-
-/// Represents an array type in C++ whose size is a value-dependent expression.
-///
-/// For example:
-/// \code
-/// template<typename T, int Size>
-/// class array {
-/// T data[Size];
-/// };
-/// \endcode
-///
-/// For these types, we won't actually know what the array bound is
-/// until template instantiation occurs, at which point this will
-/// become either a ConstantArrayType or a VariableArrayType.
-class DependentSizedArrayType : public ArrayType {
- const ASTContext &Context;
-
- /// \brief An assignment expression that will instantiate to the
- /// size of the array.
- ///
- /// The expression itself might be null, in which case the array
- /// type will have its size deduced from an initializer.
- Stmt *SizeExpr;
-
- /// The range spanned by the left and right array brackets.
- SourceRange Brackets;
-
- DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can,
- Expr *e, ArraySizeModifier sm, unsigned tq,
- SourceRange brackets);
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- Expr *getSizeExpr() const {
- // We use C-style casts instead of cast<> here because we do not wish
- // to have a dependency of Type.h on Stmt.h/Expr.h.
- return (Expr*) SizeExpr;
- }
- SourceRange getBracketsRange() const { return Brackets; }
- SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
- SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentSizedArray;
- }
-
- friend class StmtIteratorBase;
-
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getElementType(),
- getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- QualType ET, ArraySizeModifier SizeMod,
- unsigned TypeQuals, Expr *E);
-};
-
-/// Represents an extended vector type where either the type or size is
-/// dependent.
-///
-/// For example:
-/// \code
-/// template<typename T, int Size>
-/// class vector {
-/// typedef T __attribute__((ext_vector_type(Size))) type;
-/// }
-/// \endcode
-class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
- const ASTContext &Context;
- Expr *SizeExpr;
- /// The element type of the array.
- QualType ElementType;
- SourceLocation loc;
-
- DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType,
- QualType can, Expr *SizeExpr, SourceLocation loc);
-
- friend class ASTContext;
-
-public:
- Expr *getSizeExpr() const { return SizeExpr; }
- QualType getElementType() const { return ElementType; }
- SourceLocation getAttributeLoc() const { return loc; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentSizedExtVector;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getElementType(), getSizeExpr());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- QualType ElementType, Expr *SizeExpr);
-};
-
-
-/// Represents a GCC generic vector type. This type is created using
-/// __attribute__((vector_size(n)), where "n" specifies the vector size in
-/// bytes; or from an Altivec __vector or vector declaration.
-/// Since the constructor takes the number of vector elements, the
-/// client is responsible for converting the size into the number of elements.
-class VectorType : public Type, public llvm::FoldingSetNode {
-public:
- enum VectorKind {
- GenericVector, ///< not a target-specific vector type
- AltiVecVector, ///< is AltiVec vector
- AltiVecPixel, ///< is AltiVec 'vector Pixel'
- AltiVecBool, ///< is AltiVec 'vector bool ...'
- NeonVector, ///< is ARM Neon vector
- NeonPolyVector ///< is ARM Neon polynomial vector
- };
-protected:
- /// The element type of the vector.
- QualType ElementType;
-
- VectorType(QualType vecType, unsigned nElements, QualType canonType,
- VectorKind vecKind);
-
- VectorType(TypeClass tc, QualType vecType, unsigned nElements,
- QualType canonType, VectorKind vecKind);
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
-
- QualType getElementType() const { return ElementType; }
- unsigned getNumElements() const { return VectorTypeBits.NumElements; }
- static bool isVectorSizeTooLarge(unsigned NumElements) {
- return NumElements > VectorTypeBitfields::MaxNumElements;
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- VectorKind getVectorKind() const {
- return VectorKind(VectorTypeBits.VecKind);
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getNumElements(),
- getTypeClass(), getVectorKind());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
- unsigned NumElements, TypeClass TypeClass,
- VectorKind VecKind) {
- ID.AddPointer(ElementType.getAsOpaquePtr());
- ID.AddInteger(NumElements);
- ID.AddInteger(TypeClass);
- ID.AddInteger(VecKind);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
- }
-};
-
-/// 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
-/// class enables syntactic extensions, like Vector Components for accessing
-/// points, colors, and textures (modeled after OpenGL Shading Language).
-class ExtVectorType : public VectorType {
- ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
- VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- static int getPointAccessorIdx(char c) {
- switch (c) {
- default: return -1;
- case 'x': return 0;
- case 'y': return 1;
- case 'z': return 2;
- case 'w': return 3;
- }
- }
- static int getNumericAccessorIdx(char c) {
- switch (c) {
- default: return -1;
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- case 'A':
- case 'a': return 10;
- case 'B':
- case 'b': return 11;
- case 'C':
- case 'c': return 12;
- case 'D':
- case 'd': return 13;
- case 'E':
- case 'e': return 14;
- case 'F':
- case 'f': return 15;
- }
- }
-
- static int getAccessorIdx(char c) {
- if (int idx = getPointAccessorIdx(c)+1) return idx-1;
- return getNumericAccessorIdx(c);
- }
-
- bool isAccessorWithinNumElements(char c) const {
- if (int idx = getAccessorIdx(c)+1)
- return unsigned(idx-1) < getNumElements();
- return false;
- }
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ExtVector;
- }
-};
-
-/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
-/// class of FunctionNoProtoType and FunctionProtoType.
-///
-class FunctionType : public Type {
- // The type returned by the function.
- QualType ResultType;
-
- public:
- /// A class which abstracts out some details necessary for
- /// making a call.
- ///
- /// It is not actually used directly for storing this information in
- /// a FunctionType, although FunctionType does currently use the
- /// same bit-pattern.
- ///
- // If you add a field (say Foo), other than the obvious places (both,
- // constructors, compile failures), what you need to update is
- // * Operator==
- // * getFoo
- // * withFoo
- // * functionType. Add Foo, getFoo.
- // * ASTContext::getFooType
- // * ASTContext::mergeFunctionTypes
- // * FunctionNoProtoType::Profile
- // * FunctionProtoType::Profile
- // * TypePrinter::PrintFunctionProto
- // * AST read and write
- // * Codegen
- class ExtInfo {
- // Feel free to rearrange or add bits, but if you go over 9,
- // you'll need to adjust both the Bits field below and
- // Type::FunctionTypeBitfields.
-
- // | CC |noreturn|produces|regparm|
- // |0 .. 3| 4 | 5 | 6 .. 8|
- //
- // regparm is either 0 (no regparm attribute) or the regparm value+1.
- enum { CallConvMask = 0xF };
- enum { NoReturnMask = 0x10 };
- enum { ProducesResultMask = 0x20 };
- enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
- RegParmOffset = 6 }; // Assumed to be the last field
-
- uint16_t Bits;
-
- ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
-
- friend class FunctionType;
-
- 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) {
- assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
- Bits = ((unsigned) cc) |
- (noReturn ? NoReturnMask : 0) |
- (producesResult ? ProducesResultMask : 0) |
- (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0);
- }
-
- // Constructor with all defaults. Use when for example creating a
- // function known to use defaults.
- ExtInfo() : Bits(CC_C) { }
-
- // Constructor with just the calling convention, which is an important part
- // of the canonical type.
- ExtInfo(CallingConv CC) : Bits(CC) { }
-
- bool getNoReturn() const { return Bits & NoReturnMask; }
- bool getProducesResult() const { return Bits & ProducesResultMask; }
- bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
- unsigned getRegParm() const {
- unsigned RegParm = Bits >> RegParmOffset;
- if (RegParm > 0)
- --RegParm;
- return RegParm;
- }
- CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
-
- bool operator==(ExtInfo Other) const {
- return Bits == Other.Bits;
- }
- bool operator!=(ExtInfo Other) const {
- return Bits != Other.Bits;
- }
-
- // Note that we don't have setters. That is by design, use
- // the following with methods instead of mutating these objects.
-
- ExtInfo withNoReturn(bool noReturn) const {
- if (noReturn)
- return ExtInfo(Bits | NoReturnMask);
- else
- return ExtInfo(Bits & ~NoReturnMask);
- }
-
- ExtInfo withProducesResult(bool producesResult) const {
- if (producesResult)
- return ExtInfo(Bits | ProducesResultMask);
- else
- return ExtInfo(Bits & ~ProducesResultMask);
- }
-
- ExtInfo withRegParm(unsigned RegParm) const {
- assert(RegParm < 7 && "Invalid regparm value");
- return ExtInfo((Bits & ~RegParmMask) |
- ((RegParm + 1) << RegParmOffset));
- }
-
- ExtInfo withCallingConv(CallingConv cc) const {
- return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc);
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger(Bits);
- }
- };
-
-protected:
- FunctionType(TypeClass tc, QualType res,
- QualType Canonical, bool Dependent,
- bool InstantiationDependent,
- bool VariablyModified, bool ContainsUnexpandedParameterPack,
- ExtInfo Info)
- : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
- ContainsUnexpandedParameterPack),
- ResultType(res) {
- FunctionTypeBits.ExtInfo = Info.Bits;
- }
- unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
-
-public:
- QualType getReturnType() const { return ResultType; }
-
- bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
- unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
- /// Determine whether this function type includes the GNU noreturn
- /// attribute. The C++11 [[noreturn]] attribute does not affect the function
- /// type.
- bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
- CallingConv getCallConv() const { return getExtInfo().getCC(); }
- ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
- bool isConst() const { return getTypeQuals() & Qualifiers::Const; }
- 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
- /// this type.
- QualType getCallResultType(ASTContext &Context) const {
- return getReturnType().getNonLValueExprType(Context);
- }
-
- static StringRef getNameForCallConv(CallingConv CC);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionNoProto ||
- T->getTypeClass() == FunctionProto;
- }
-};
-
-/// Represents a K&R-style 'int foo()' function, which has
-/// no information available about its arguments.
-class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
- FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
- : FunctionType(FunctionNoProto, Result, Canonical,
- /*Dependent=*/false, /*InstantiationDependent=*/false,
- Result->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false, Info) {}
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- // No additional state past what FunctionType provides.
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReturnType(), getExtInfo());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
- ExtInfo Info) {
- Info.Profile(ID);
- ID.AddPointer(ResultType.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionNoProto;
- }
-};
-
-/// Represents a prototype with parameter type info, e.g.
-/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
-/// parameters, not as having a single void parameter. Such a type can have an
-/// exception specification, but this specification is not part of the canonical
-/// type.
-class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
-public:
- struct ExceptionSpecInfo {
- ExceptionSpecInfo()
- : Type(EST_None), NoexceptExpr(nullptr),
- SourceDecl(nullptr), SourceTemplate(nullptr) {}
-
- ExceptionSpecInfo(ExceptionSpecificationType EST)
- : Type(EST), NoexceptExpr(nullptr), SourceDecl(nullptr),
- SourceTemplate(nullptr) {}
-
- /// The kind of exception specification this is.
- ExceptionSpecificationType Type;
- /// Explicitly-specified list of exception types.
- ArrayRef<QualType> Exceptions;
- /// Noexcept expression, if this is EST_ComputedNoexcept.
- Expr *NoexceptExpr;
- /// The function whose exception specification this is, for
- /// EST_Unevaluated and EST_Uninstantiated.
- FunctionDecl *SourceDecl;
- /// The function template whose exception specification this is instantiated
- /// from, for EST_Uninstantiated.
- FunctionDecl *SourceTemplate;
- };
-
- /// Extra information about a function prototype.
- struct ExtProtoInfo {
- ExtProtoInfo()
- : Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- RefQualifier(RQ_None), ConsumedParameters(nullptr) {}
-
- ExtProtoInfo(CallingConv CC)
- : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- RefQualifier(RQ_None), ConsumedParameters(nullptr) {}
-
- ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) {
- ExtProtoInfo Result(*this);
- Result.ExceptionSpec = O;
- return Result;
- }
-
- FunctionType::ExtInfo ExtInfo;
- bool Variadic : 1;
- bool HasTrailingReturn : 1;
- unsigned char TypeQuals;
- RefQualifierKind RefQualifier;
- ExceptionSpecInfo ExceptionSpec;
- const bool *ConsumedParameters;
- };
-
-private:
- /// \brief Determine whether there are any argument types that
- /// contain an unexpanded parameter pack.
- static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray,
- unsigned numArgs) {
- for (unsigned Idx = 0; Idx < numArgs; ++Idx)
- if (ArgArray[Idx]->containsUnexpandedParameterPack())
- return true;
-
- return false;
- }
-
- FunctionProtoType(QualType result, ArrayRef<QualType> params,
- QualType canonical, const ExtProtoInfo &epi);
-
- /// The number of parameters this function has, not counting '...'.
- unsigned NumParams : 15;
-
- /// The number of types in the exception spec, if any.
- unsigned NumExceptions : 9;
-
- /// The type of exception specification this function has.
- unsigned ExceptionSpecType : 4;
-
- /// Whether this function has any consumed parameters.
- unsigned HasAnyConsumedParams : 1;
-
- /// Whether the function is variadic.
- unsigned Variadic : 1;
-
- /// Whether this function has a trailing return type.
- unsigned HasTrailingReturn : 1;
-
- // ParamInfo - There is an variable size array after the class in memory that
- // holds the parameter types.
-
- // Exceptions - There is another variable size array after ArgInfo that
- // holds the exception types.
-
- // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
- // to the expression in the noexcept() specifier.
-
- // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may
- // be a pair of FunctionDecl* pointing to the function which should be used to
- // instantiate this function type's exception specification, and the function
- // from which it should be instantiated.
-
- // ConsumedParameters - A variable size array, following Exceptions
- // and of length NumParams, holding flags indicating which parameters
- // are consumed. This only appears if HasAnyConsumedParams is true.
-
- friend class ASTContext; // ASTContext creates these.
-
- const bool *getConsumedParamsBuffer() const {
- assert(hasAnyConsumedParams());
-
- // Find the end of the exceptions.
- Expr *const *eh_end = reinterpret_cast<Expr *const *>(exception_end());
- if (getExceptionSpecType() == EST_ComputedNoexcept)
- eh_end += 1; // NoexceptExpr
- // The memory layout of these types isn't handled here, so
- // hopefully this is never called for them?
- assert(getExceptionSpecType() != EST_Uninstantiated &&
- getExceptionSpecType() != EST_Unevaluated);
-
- return reinterpret_cast<const bool*>(eh_end);
- }
-
-public:
- unsigned getNumParams() const { return NumParams; }
- QualType getParamType(unsigned i) const {
- assert(i < NumParams && "invalid parameter index");
- return param_type_begin()[i];
- }
- ArrayRef<QualType> getParamTypes() const {
- return llvm::makeArrayRef(param_type_begin(), param_type_end());
- }
-
- ExtProtoInfo getExtProtoInfo() const {
- ExtProtoInfo EPI;
- EPI.ExtInfo = getExtInfo();
- EPI.Variadic = isVariadic();
- EPI.HasTrailingReturn = hasTrailingReturn();
- EPI.ExceptionSpec.Type = getExceptionSpecType();
- EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
- EPI.RefQualifier = getRefQualifier();
- if (EPI.ExceptionSpec.Type == EST_Dynamic) {
- EPI.ExceptionSpec.Exceptions = exceptions();
- } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) {
- EPI.ExceptionSpec.NoexceptExpr = getNoexceptExpr();
- } else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
- EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
- EPI.ExceptionSpec.SourceTemplate = getExceptionSpecTemplate();
- } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) {
- EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
- }
- if (hasAnyConsumedParams())
- EPI.ConsumedParameters = getConsumedParamsBuffer();
- return EPI;
- }
-
- /// Get the kind of exception specification on this function.
- ExceptionSpecificationType getExceptionSpecType() const {
- return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
- }
- /// Return whether this function has any kind of exception spec.
- bool hasExceptionSpec() const {
- return getExceptionSpecType() != EST_None;
- }
- /// Return whether this function has a dynamic (throw) exception spec.
- bool hasDynamicExceptionSpec() const {
- return isDynamicExceptionSpec(getExceptionSpecType());
- }
- /// Return whether this function has a noexcept exception spec.
- bool hasNoexceptExceptionSpec() const {
- return isNoexceptExceptionSpec(getExceptionSpecType());
- }
- /// Return whether this function has a dependent exception spec.
- bool hasDependentExceptionSpec() const;
- /// Result type of getNoexceptSpec().
- enum NoexceptResult {
- NR_NoNoexcept, ///< There is no noexcept specifier.
- NR_BadNoexcept, ///< The noexcept specifier has a bad expression.
- NR_Dependent, ///< The noexcept specifier is dependent.
- NR_Throw, ///< The noexcept specifier evaluates to false.
- NR_Nothrow ///< The noexcept specifier evaluates to true.
- };
- /// 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)
- 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
- /// 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.
- FunctionDecl *getExceptionSpecDecl() const {
- if (getExceptionSpecType() != EST_Uninstantiated &&
- getExceptionSpecType() != EST_Unevaluated)
- return nullptr;
- return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
- }
- /// \brief 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.
- FunctionDecl *getExceptionSpecTemplate() const {
- if (getExceptionSpecType() != EST_Uninstantiated)
- return nullptr;
- return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
- }
- /// 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;
-
- bool isVariadic() const { return Variadic; }
-
- /// Determines whether this function prototype contains a
- /// parameter pack at the end.
- ///
- /// A function template whose last parameter is a parameter pack can be
- /// called with an arbitrary number of arguments, much like a variadic
- /// function.
- bool isTemplateVariadic() const;
-
- bool hasTrailingReturn() const { return HasTrailingReturn; }
-
- unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
-
-
- /// Retrieve the ref-qualifier associated with this function type.
- RefQualifierKind getRefQualifier() const {
- return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier);
- }
-
- typedef const QualType *param_type_iterator;
- typedef llvm::iterator_range<param_type_iterator> param_type_range;
-
- param_type_range param_types() const {
- return param_type_range(param_type_begin(), param_type_end());
- }
- param_type_iterator param_type_begin() const {
- return reinterpret_cast<const QualType *>(this+1);
- }
- param_type_iterator param_type_end() const {
- return param_type_begin() + NumParams;
- }
-
- typedef const QualType *exception_iterator;
-
- ArrayRef<QualType> exceptions() const {
- return llvm::makeArrayRef(exception_begin(), exception_end());
- }
- exception_iterator exception_begin() const {
- // exceptions begin where arguments end
- return param_type_end();
- }
- exception_iterator exception_end() const {
- if (getExceptionSpecType() != EST_Dynamic)
- return exception_begin();
- return exception_begin() + NumExceptions;
- }
-
- bool hasAnyConsumedParams() const { return HasAnyConsumedParams; }
- bool isParamConsumed(unsigned I) const {
- assert(I < getNumParams() && "parameter index out of range");
- if (hasAnyConsumedParams())
- return getConsumedParamsBuffer()[I];
- return false;
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void printExceptionSpecification(raw_ostream &OS,
- const PrintingPolicy &Policy) const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionProto;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
- param_type_iterator ArgTys, unsigned NumArgs,
- const ExtProtoInfo &EPI, const ASTContext &Context);
-};
-
-/// \brief Represents the dependent type named by a dependently-scoped
-/// typename using declaration, e.g.
-/// using typename Base<T>::foo;
-///
-/// Template instantiation turns these into the underlying type.
-class UnresolvedUsingType : public Type {
- UnresolvedUsingTypenameDecl *Decl;
-
- UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
- : Type(UnresolvedUsing, QualType(), true, true, false,
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
- friend class ASTContext; // ASTContext creates these.
-public:
-
- UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == UnresolvedUsing;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- return Profile(ID, Decl);
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- UnresolvedUsingTypenameDecl *D) {
- ID.AddPointer(D);
- }
-};
-
-
-class TypedefType : public Type {
- TypedefNameDecl *Decl;
-protected:
- TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
- : Type(tc, can, can->isDependentType(),
- can->isInstantiationDependentType(),
- can->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<TypedefNameDecl*>(D)) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
- }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- TypedefNameDecl *getDecl() const { return Decl; }
-
- bool isSugared() const { return true; }
- QualType desugar() const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
-};
-
-/// Represents a `typeof` (or __typeof__) expression (a GCC extension).
-class TypeOfExprType : public Type {
- Expr *TOExpr;
-
-protected:
- TypeOfExprType(Expr *E, QualType can = QualType());
- friend class ASTContext; // ASTContext creates these.
-public:
- Expr *getUnderlyingExpr() const { return TOExpr; }
-
- /// \brief Remove a single level of sugar.
- QualType desugar() const;
-
- /// \brief 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
-/// `typeof(expr)` types.
-///
-/// This class is used internally by the ASTContext to manage
-/// canonical, dependent types, only. Clients will only see instances
-/// of this class via TypeOfExprType nodes.
-class DependentTypeOfExprType
- : public TypeOfExprType, public llvm::FoldingSetNode {
- const ASTContext &Context;
-
-public:
- DependentTypeOfExprType(const ASTContext &Context, Expr *E)
- : TypeOfExprType(E), Context(Context) { }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getUnderlyingExpr());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- Expr *E);
-};
-
-/// Represents `typeof(type)`, a GCC extension.
-class TypeOfType : public Type {
- QualType TOType;
- TypeOfType(QualType T, QualType can)
- : Type(TypeOf, can, T->isDependentType(),
- T->isInstantiationDependentType(),
- T->isVariablyModifiedType(),
- T->containsUnexpandedParameterPack()),
- TOType(T) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
- }
- friend class ASTContext; // ASTContext creates these.
-public:
- QualType getUnderlyingType() const { return TOType; }
-
- /// \brief Remove a single level of sugar.
- QualType desugar() const { return getUnderlyingType(); }
-
- /// \brief Returns whether this type directly provides sugar.
- bool isSugared() const { return true; }
-
- static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
-};
-
-/// Represents the type `decltype(expr)` (C++11).
-class DecltypeType : public Type {
- Expr *E;
- QualType UnderlyingType;
-
-protected:
- DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
- friend class ASTContext; // ASTContext creates these.
-public:
- Expr *getUnderlyingExpr() const { return E; }
- QualType getUnderlyingType() const { return UnderlyingType; }
-
- /// \brief Remove a single level of sugar.
- QualType desugar() const;
-
- /// \brief 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
-/// decltype(expr) types.
-///
-/// This class is used internally by the ASTContext to manage
-/// canonical, dependent types, only. Clients will only see instances
-/// of this class via DecltypeType nodes.
-class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
- const ASTContext &Context;
-
-public:
- DependentDecltypeType(const ASTContext &Context, Expr *E);
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getUnderlyingExpr());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- Expr *E);
-};
-
-/// A unary type transform, which is a type constructed from another.
-class UnaryTransformType : public Type {
-public:
- enum UTTKind {
- EnumUnderlyingType
- };
-
-private:
- /// The untransformed type.
- QualType BaseType;
- /// The transformed type if not dependent, otherwise the same as BaseType.
- QualType UnderlyingType;
-
- UTTKind UKind;
-protected:
- UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind,
- QualType CanonicalTy);
- friend class ASTContext;
-public:
- bool isSugared() const { return !isDependentType(); }
- QualType desugar() const { return UnderlyingType; }
-
- QualType getUnderlyingType() const { return UnderlyingType; }
- QualType getBaseType() const { return BaseType; }
-
- UTTKind getUTTKind() const { return UKind; }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == UnaryTransform;
- }
-};
-
-class TagType : public Type {
- /// Stores the TagDecl associated with this type. The decl may point to any
- /// TagDecl that declares the entity.
- TagDecl * decl;
-
- friend class ASTReader;
-
-protected:
- TagType(TypeClass TC, const TagDecl *D, QualType can);
-
-public:
- TagDecl *getDecl() const;
-
- /// Determines whether this type is in the process of being defined.
- bool isBeingDefined() const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
- }
-};
-
-/// A helper class that allows the use of isa/cast/dyncast
-/// to detect TagType objects of structs/unions/classes.
-class RecordType : public TagType {
-protected:
- explicit RecordType(const RecordDecl *D)
- : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
- explicit RecordType(TypeClass TC, RecordDecl *D)
- : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- RecordDecl *getDecl() const {
- return reinterpret_cast<RecordDecl*>(TagType::getDecl());
- }
-
- // FIXME: This predicate is a helper to QualType/Type. It needs to
- // recursively check all fields for const-ness. If any field is declared
- // const, it needs to return false.
- bool hasConstFields() const { return false; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Record; }
-};
-
-/// A helper class that allows the use of isa/cast/dyncast
-/// to detect TagType objects of enums.
-class EnumType : public TagType {
- explicit EnumType(const EnumDecl *D)
- : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- EnumDecl *getDecl() const {
- return reinterpret_cast<EnumDecl*>(TagType::getDecl());
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
-};
-
-/// An attributed type is a type to which a type attribute has been applied.
-///
-/// The "modified type" is the fully-sugared type to which the attributed
-/// type was applied; generally it is not canonically equivalent to the
-/// attributed type. The "equivalent type" is the minimally-desugared type
-/// which the type is canonically equivalent to.
-///
-/// For example, in the following attributed type:
-/// int32_t __attribute__((vector_size(16)))
-/// - the modified type is the TypedefType for int32_t
-/// - the equivalent type is VectorType(16, int32_t)
-/// - the canonical type is VectorType(16, int)
-class AttributedType : public Type, public llvm::FoldingSetNode {
-public:
- // It is really silly to have yet another attribute-kind enum, but
- // clang::attr::Kind doesn't currently cover the pure type attrs.
- enum Kind {
- // Expression operand.
- attr_address_space,
- attr_regparm,
- attr_vector_size,
- attr_neon_vector_type,
- attr_neon_polyvector_type,
-
- FirstExprOperandKind = attr_address_space,
- LastExprOperandKind = attr_neon_polyvector_type,
-
- // Enumerated operand (string or keyword).
- attr_objc_gc,
- attr_objc_ownership,
- attr_pcs,
- attr_pcs_vfp,
-
- FirstEnumOperandKind = attr_objc_gc,
- LastEnumOperandKind = attr_pcs_vfp,
-
- // No operand.
- attr_noreturn,
- attr_cdecl,
- attr_fastcall,
- attr_stdcall,
- attr_thiscall,
- attr_pascal,
- attr_vectorcall,
- attr_inteloclbicc,
- attr_ms_abi,
- attr_sysv_abi,
- attr_ptr32,
- attr_ptr64,
- attr_sptr,
- attr_uptr,
- attr_nonnull,
- attr_nullable,
- attr_null_unspecified,
- attr_objc_kindof,
- attr_objc_inert_unsafe_unretained,
- };
-
-private:
- QualType ModifiedType;
- QualType EquivalentType;
-
- friend class ASTContext; // creates these
-
- AttributedType(QualType canon, Kind attrKind,
- QualType modified, QualType equivalent)
- : Type(Attributed, canon, canon->isDependentType(),
- canon->isInstantiationDependentType(),
- canon->isVariablyModifiedType(),
- canon->containsUnexpandedParameterPack()),
- ModifiedType(modified), EquivalentType(equivalent) {
- AttributedTypeBits.AttrKind = attrKind;
- }
-
-public:
- Kind getAttrKind() const {
- return static_cast<Kind>(AttributedTypeBits.AttrKind);
- }
-
- QualType getModifiedType() const { return ModifiedType; }
- QualType getEquivalentType() const { return EquivalentType; }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return getEquivalentType(); }
-
- /// Does this attribute behave like a type qualifier?
- ///
- /// A type qualifier adjusts a type to provide specialized rules for
- /// a specific object, like the standard const and volatile qualifiers.
- /// This includes attributes controlling things like nullability,
- /// address spaces, and ARC ownership. The value of the object is still
- /// largely described by the modified type.
- ///
- /// In contrast, many type attributes "rewrite" their modified type to
- /// produce a fundamentally different type, not necessarily related in any
- /// formalizable way to the original type. For example, calling convention
- /// and vector attributes are not simple type qualifiers.
- ///
- /// Type qualifiers are often, but not always, reflected in the canonical
- /// type.
- bool isQualifier() const;
-
- bool isMSTypeSpec() const;
-
- bool isCallingConv() const;
-
- llvm::Optional<NullabilityKind> getImmediateNullability() const;
-
- /// Retrieve the attribute kind corresponding to the given
- /// nullability kind.
- static Kind getNullabilityAttrKind(NullabilityKind kind) {
- switch (kind) {
- case NullabilityKind::NonNull:
- return attr_nonnull;
-
- case NullabilityKind::Nullable:
- return attr_nullable;
-
- case NullabilityKind::Unspecified:
- return attr_null_unspecified;
- }
- llvm_unreachable("Unknown nullability kind.");
- }
-
- /// Strip off the top-level nullability annotation on the given
- /// type, if it's there.
- ///
- /// \param T The type to strip. If the type is exactly an
- /// AttributedType specifying nullability (without looking through
- /// type sugar), the nullability is returned and this type changed
- /// to the underlying modified type.
- ///
- /// \returns the top-level nullability, if present.
- static Optional<NullabilityKind> stripOuterNullability(QualType &T);
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
- QualType modified, QualType equivalent) {
- ID.AddInteger(attrKind);
- ID.AddPointer(modified.getAsOpaquePtr());
- ID.AddPointer(equivalent.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Attributed;
- }
-};
-
-class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
- // Helper data collector for canonical types.
- struct CanonicalTTPTInfo {
- unsigned Depth : 15;
- unsigned ParameterPack : 1;
- unsigned Index : 16;
- };
-
- union {
- // Info for the canonical type.
- CanonicalTTPTInfo CanTTPTInfo;
- // Info for the non-canonical type.
- TemplateTypeParmDecl *TTPDecl;
- };
-
- /// Build a non-canonical type.
- TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
- : Type(TemplateTypeParm, Canon, /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- Canon->containsUnexpandedParameterPack()),
- TTPDecl(TTPDecl) { }
-
- /// Build the canonical type.
- TemplateTypeParmType(unsigned D, unsigned I, bool PP)
- : Type(TemplateTypeParm, QualType(this, 0),
- /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false, PP) {
- CanTTPTInfo.Depth = D;
- CanTTPTInfo.Index = I;
- CanTTPTInfo.ParameterPack = PP;
- }
-
- friend class ASTContext; // ASTContext creates these
-
- const CanonicalTTPTInfo& getCanTTPTInfo() const {
- QualType Can = getCanonicalTypeInternal();
- return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo;
- }
-
-public:
- unsigned getDepth() const { return getCanTTPTInfo().Depth; }
- unsigned getIndex() const { return getCanTTPTInfo().Index; }
- bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
-
- TemplateTypeParmDecl *getDecl() const {
- return isCanonicalUnqualified() ? nullptr : TTPDecl;
- }
-
- IdentifierInfo *getIdentifier() const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
- unsigned Index, bool ParameterPack,
- TemplateTypeParmDecl *TTPDecl) {
- ID.AddInteger(Depth);
- ID.AddInteger(Index);
- ID.AddBoolean(ParameterPack);
- ID.AddPointer(TTPDecl);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == TemplateTypeParm;
- }
-};
-
-/// \brief Represents the result of substituting a type for a template
-/// type parameter.
-///
-/// Within an instantiated template, all template type parameters have
-/// been replaced with these. They are used solely to record that a
-/// type was originally written as a template type parameter;
-/// therefore they are never canonical.
-class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
- // The original type parameter.
- const TemplateTypeParmType *Replaced;
-
- SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
- : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
- Canon->isInstantiationDependentType(),
- Canon->isVariablyModifiedType(),
- Canon->containsUnexpandedParameterPack()),
- Replaced(Param) { }
-
- friend class ASTContext;
-
-public:
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
-
- /// Gets the type that was substituted for the template
- /// parameter.
- QualType getReplacementType() const {
- return getCanonicalTypeInternal();
- }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return getReplacementType(); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReplacedParameter(), getReplacementType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
- QualType Replacement) {
- ID.AddPointer(Replaced);
- ID.AddPointer(Replacement.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == SubstTemplateTypeParm;
- }
-};
-
-/// \brief 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
-/// and those parameter packs correspond to different levels of template
-/// parameter lists, this type node is used to represent a template type
-/// parameter pack from an outer level, which has already had its argument pack
-/// substituted but that still lives within a pack expansion that itself
-/// could not be instantiated. When actually performing a substitution into
-/// that pack expansion (e.g., when all template parameters have corresponding
-/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType
-/// at the current pack substitution index.
-class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
- /// \brief The original type parameter.
- const TemplateTypeParmType *Replaced;
-
- /// \brief 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.
- unsigned NumArguments;
-
- SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
- QualType Canon,
- const TemplateArgument &ArgPack);
-
- friend class ASTContext;
-
-public:
- IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
-
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- TemplateArgument getArgumentPack() const;
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
- const TemplateArgument &ArgPack);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == SubstTemplateTypeParmPack;
- }
-};
-
-/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
-///
-/// These types are usually a placeholder for a deduced type. However, before
-/// the initializer is attached, or if the initializer is type-dependent, there
-/// is no deduced type and an auto type is canonical. In the latter case, it is
-/// also a dependent type.
-class AutoType : public Type, public llvm::FoldingSetNode {
- AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent)
- : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
- /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
- /*VariablyModified=*/false,
- /*ContainsParameterPack=*/DeducedType.isNull()
- ? false : DeducedType->containsUnexpandedParameterPack()) {
- assert((DeducedType.isNull() || !IsDependent) &&
- "auto deduced to dependent type");
- AutoTypeBits.Keyword = (unsigned)Keyword;
- }
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- bool isDecltypeAuto() const {
- return getKeyword() == AutoTypeKeyword::DecltypeAuto;
- }
- AutoTypeKeyword getKeyword() const {
- return (AutoTypeKeyword)AutoTypeBits.Keyword;
- }
-
- bool isSugared() const { return !isCanonicalUnqualified(); }
- QualType desugar() const { return getCanonicalTypeInternal(); }
-
- /// \brief Get the type deduced for this auto type, or null if it's either
- /// not been deduced or was deduced to a dependent type.
- QualType getDeducedType() const {
- return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
- }
- bool isDeduced() const {
- return !isCanonicalUnqualified() || isDependentType();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDeducedType(), getKeyword(), isDependentType());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
- AutoTypeKeyword Keyword, bool IsDependent) {
- ID.AddPointer(Deduced.getAsOpaquePtr());
- ID.AddInteger((unsigned)Keyword);
- ID.AddBoolean(IsDependent);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Auto;
- }
-};
-
-/// \brief 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
-/// specifier, is instead represented as a
-/// @c DependentTemplateSpecializationType.
-///
-/// A non-dependent template specialization type is always "sugar",
-/// typically for a \c RecordType. For example, a class template
-/// specialization type of \c vector<int> will refer to a tag type for
-/// the instantiation \c std::vector<int, std::allocator<int>>
-///
-/// Template specializations are dependent if either the template or
-/// any of the template arguments are dependent, in which case the
-/// type may also be canonical.
-///
-/// Instances of this type are allocated with a trailing array of
-/// 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
- : public Type,
- public llvm::FoldingSetNode {
- /// The name of the template being specialized. This is
- /// either a TemplateName::Template (in which case it is a
- /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
- /// TypeAliasTemplateDecl*), a
- /// TemplateName::SubstTemplateTemplateParmPack, or a
- /// TemplateName::SubstTemplateTemplateParm (in which case the
- /// replacement must, recursively, be one of these).
- TemplateName Template;
-
- /// The number of template arguments named in this class template
- /// specialization.
- unsigned NumArgs : 31;
-
- /// Whether this template specialization type is a substituted type alias.
- bool TypeAlias : 1;
-
- TemplateSpecializationType(TemplateName T,
- const TemplateArgument *Args,
- unsigned NumArgs, QualType Canon,
- QualType Aliased);
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- /// Determine whether any of the given template arguments are dependent.
- static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
- unsigned NumArgs,
- bool &InstantiationDependent);
-
- static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
- bool &InstantiationDependent);
-
- /// \brief Print a template argument list, including the '<' and '>'
- /// enclosing the template arguments.
- static void PrintTemplateArgumentList(raw_ostream &OS,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const PrintingPolicy &Policy,
- bool SkipBrackets = false);
-
- static void PrintTemplateArgumentList(raw_ostream &OS,
- const TemplateArgumentLoc *Args,
- unsigned NumArgs,
- const PrintingPolicy &Policy);
-
- static void PrintTemplateArgumentList(raw_ostream &OS,
- const TemplateArgumentListInfo &,
- const PrintingPolicy &Policy);
-
- /// True if this template specialization type matches a current
- /// instantiation in the context in which it is found.
- bool isCurrentInstantiation() const {
- return isa<InjectedClassNameType>(getCanonicalTypeInternal());
- }
-
- /// \brief 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
- /// template will be substituted. However, this is not the case when
- /// the specialization contains a pack expansion but the template alias
- /// does not have a corresponding parameter pack, e.g.,
- ///
- /// \code
- /// template<typename T, typename U, typename V> struct S;
- /// template<typename T, typename U> using A = S<T, int, U>;
- /// template<typename... Ts> struct X {
- /// typedef A<Ts...> type; // not a type alias
- /// };
- /// \endcode
- bool isTypeAlias() const { return TypeAlias; }
-
- /// Get the aliased type, if this is a specialization of a type alias
- /// template.
- QualType getAliasedType() const {
- assert(isTypeAlias() && "not a type alias template specialization");
- return *reinterpret_cast<const QualType*>(end());
- }
-
- typedef const TemplateArgument * iterator;
-
- iterator begin() const { return getArgs(); }
- iterator end() const; // defined inline in TemplateBase.h
-
- /// Retrieve the name of the template that we are specializing.
- TemplateName getTemplateName() const { return Template; }
-
- /// Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return reinterpret_cast<const TemplateArgument *>(this + 1);
- }
-
- /// Retrieve the number of template arguments.
- unsigned getNumArgs() const { return NumArgs; }
-
- /// Retrieve a specific template argument as a type.
- /// \pre \c isArgType(Arg)
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
- bool isSugared() const {
- return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
- }
- QualType desugar() const { return getCanonicalTypeInternal(); }
-
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
- Profile(ID, Template, getArgs(), NumArgs, Ctx);
- if (isTypeAlias())
- getAliasedType().Profile(ID);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const ASTContext &Context);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == TemplateSpecialization;
- }
-};
-
-/// The injected class name of a C++ class template or class
-/// template partial specialization. Used to record that a type was
-/// spelled with a bare identifier rather than as a template-id; the
-/// equivalent for non-templated classes is just RecordType.
-///
-/// Injected class name types are always dependent. Template
-/// instantiation turns these into RecordTypes.
-///
-/// Injected class name types are always canonical. This works
-/// because it is impossible to compare an injected class name type
-/// with the corresponding non-injected template type, for the same
-/// reason that it is impossible to directly compare template
-/// parameters from different dependent contexts: injected class name
-/// types can only occur within the scope of a particular templated
-/// declaration, and within that scope every template specialization
-/// will canonicalize to the injected class name (when appropriate
-/// according to the rules of the language).
-class InjectedClassNameType : public Type {
- CXXRecordDecl *Decl;
-
- /// The template specialization which this type represents.
- /// For example, in
- /// template <class T> class A { ... };
- /// this is A<T>, whereas in
- /// template <class X, class Y> class A<B<X,Y> > { ... };
- /// this is A<B<X,Y> >.
- ///
- /// It is always unqualified, always a template specialization type,
- /// and always dependent.
- QualType InjectedType;
-
- friend class ASTContext; // ASTContext creates these.
- friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
- // currently suitable for AST reading, too much
- // interdependencies.
- InjectedClassNameType(CXXRecordDecl *D, QualType TST)
- : Type(InjectedClassName, QualType(), /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(D), InjectedType(TST) {
- assert(isa<TemplateSpecializationType>(TST));
- assert(!TST.hasQualifiers());
- assert(TST->isDependentType());
- }
-
-public:
- QualType getInjectedSpecializationType() const { return InjectedType; }
- const TemplateSpecializationType *getInjectedTST() const {
- return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
- }
-
- CXXRecordDecl *getDecl() const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == InjectedClassName;
- }
-};
-
-/// \brief The kind of a tag type.
-enum TagTypeKind {
- /// \brief The "struct" keyword.
- TTK_Struct,
- /// \brief The "__interface" keyword.
- TTK_Interface,
- /// \brief The "union" keyword.
- TTK_Union,
- /// \brief The "class" keyword.
- TTK_Class,
- /// \brief The "enum" keyword.
- TTK_Enum
-};
-
-/// \brief 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.
- ETK_Struct,
- /// \brief The "__interface" keyword introduces the elaborated-type-specifier.
- ETK_Interface,
- /// \brief The "union" keyword introduces the elaborated-type-specifier.
- ETK_Union,
- /// \brief The "class" keyword introduces the elaborated-type-specifier.
- ETK_Class,
- /// \brief The "enum" keyword introduces the elaborated-type-specifier.
- ETK_Enum,
- /// \brief The "typename" keyword precedes the qualified type name, e.g.,
- /// \c typename T::type.
- ETK_Typename,
- /// \brief No keyword precedes the qualified type name.
- ETK_None
-};
-
-/// A helper class for Type nodes having an ElaboratedTypeKeyword.
-/// The keyword in stored in the free bits of the base class.
-/// Also provides a few static helpers for converting and printing
-/// elaborated type keyword and tag type kind enumerations.
-class TypeWithKeyword : public Type {
-protected:
- TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
- QualType Canonical, bool Dependent,
- bool InstantiationDependent, bool VariablyModified,
- bool ContainsUnexpandedParameterPack)
- : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
- ContainsUnexpandedParameterPack) {
- TypeWithKeywordBits.Keyword = Keyword;
- }
-
-public:
- ElaboratedTypeKeyword getKeyword() const {
- return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword);
- }
-
- /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword.
- static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
-
- /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
- /// It is an error to provide a type specifier which *isn't* a tag kind here.
- static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
-
- /// Converts a TagTypeKind into an elaborated type keyword.
- static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
-
- /// Converts an elaborated type keyword into a TagTypeKind.
- /// It is an error to provide an elaborated type keyword
- /// which *isn't* a tag kind here.
- static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
-
- static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
-
- static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
-
- static StringRef getTagTypeKindName(TagTypeKind Kind) {
- return getKeywordName(getKeywordForTagTypeKind(Kind));
- }
-
- class CannotCastToThisType {};
- static CannotCastToThisType classof(const Type *);
-};
-
-/// \brief 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.
-///
-/// This type is used to keep track of a type name as written in the
-/// source code, including tag keywords and any nested-name-specifiers.
-/// The type itself is always "sugar", used to express what was written
-/// in the source code but containing no additional semantic information.
-class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
-
- /// The nested name specifier containing the qualifier.
- NestedNameSpecifier *NNS;
-
- /// The type that this qualified name refers to.
- QualType NamedType;
-
- ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- QualType NamedType, QualType CanonType)
- : TypeWithKeyword(Keyword, Elaborated, CanonType,
- NamedType->isDependentType(),
- NamedType->isInstantiationDependentType(),
- NamedType->isVariablyModifiedType(),
- NamedType->containsUnexpandedParameterPack()),
- NNS(NNS), NamedType(NamedType) {
- assert(!(Keyword == ETK_None && NNS == nullptr) &&
- "ElaboratedType cannot have elaborated type keyword "
- "and name qualifier both null.");
- }
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- ~ElaboratedType();
-
- /// Retrieve the qualification on this type.
- NestedNameSpecifier *getQualifier() const { return NNS; }
-
- /// Retrieve the type named by the qualified-id.
- QualType getNamedType() const { return NamedType; }
-
- /// Remove a single level of sugar.
- QualType desugar() const { return getNamedType(); }
-
- /// Returns whether this type directly provides sugar.
- bool isSugared() const { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getKeyword(), NNS, NamedType);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, QualType NamedType) {
- ID.AddInteger(Keyword);
- ID.AddPointer(NNS);
- NamedType.Profile(ID);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Elaborated;
- }
-};
-
-/// \brief Represents a qualified type name for which the type name is
-/// dependent.
-///
-/// DependentNameType represents a class of dependent types that involve a
-/// possibly dependent nested-name-specifier (e.g., "T::") followed by a
-/// name of a type. The DependentNameType may start with a "typename" (for a
-/// typename-specifier), "class", "struct", "union", or "enum" (for a
-/// dependent elaborated-type-specifier), or nothing (in contexts where we
-/// know that we must be referring to a type, e.g., in a base class specifier).
-/// Typically the nested-name-specifier is dependent, but in MSVC compatibility
-/// mode, this type is used with non-dependent names to delay name lookup until
-/// instantiation.
-class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
-
- /// \brief The nested name specifier containing the qualifier.
- NestedNameSpecifier *NNS;
-
- /// \brief The type that this typename specifier refers to.
- const IdentifierInfo *Name;
-
- DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- const IdentifierInfo *Name, QualType CanonType)
- : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- NNS->containsUnexpandedParameterPack()),
- NNS(NNS), Name(Name) {}
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- /// Retrieve the qualification on this type.
- NestedNameSpecifier *getQualifier() const { return NNS; }
-
- /// Retrieve the type named by the typename specifier as an identifier.
- ///
- /// This routine will return a non-NULL identifier pointer when the
- /// form of the original typename was terminated by an identifier,
- /// e.g., "typename T::type".
- const IdentifierInfo *getIdentifier() const {
- return Name;
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getKeyword(), NNS, Name);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
- ID.AddInteger(Keyword);
- ID.AddPointer(NNS);
- ID.AddPointer(Name);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentName;
- }
-};
-
-/// 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
- : public TypeWithKeyword,
- public llvm::FoldingSetNode {
-
- /// The nested name specifier containing the qualifier.
- NestedNameSpecifier *NNS;
-
- /// The identifier of the template.
- const IdentifierInfo *Name;
-
- /// \brief The number of template arguments named in this class template
- /// specialization.
- unsigned NumArgs;
-
- const TemplateArgument *getArgBuffer() const {
- return reinterpret_cast<const TemplateArgument*>(this+1);
- }
- TemplateArgument *getArgBuffer() {
- return reinterpret_cast<TemplateArgument*>(this+1);
- }
-
- DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- unsigned NumArgs,
- const TemplateArgument *Args,
- QualType Canon);
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- NestedNameSpecifier *getQualifier() const { return NNS; }
- const IdentifierInfo *getIdentifier() const { return Name; }
-
- /// \brief Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return getArgBuffer();
- }
-
- /// \brief Retrieve the number of template arguments.
- unsigned getNumArgs() const { return NumArgs; }
-
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
- typedef const TemplateArgument * iterator;
- iterator begin() const { return getArgs(); }
- iterator end() const; // inline in TemplateBase.h
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- const ASTContext &Context,
- ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *Qualifier,
- const IdentifierInfo *Name,
- unsigned NumArgs,
- const TemplateArgument *Args);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentTemplateSpecialization;
- }
-};
-
-/// \brief 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
-/// "unexpanded" parameter packs. When instantiated, a pack expansion
-/// produces a series of types, each instantiated from the pattern of
-/// the expansion, where the Ith instantiation of the pattern uses the
-/// Ith arguments bound to each of the unexpanded parameter packs. The
-/// pack expansion is considered to "expand" these unexpanded
-/// parameter packs.
-///
-/// \code
-/// template<typename ...Types> struct tuple;
-///
-/// template<typename ...Types>
-/// struct tuple_of_references {
-/// typedef tuple<Types&...> type;
-/// };
-/// \endcode
-///
-/// Here, the pack expansion \c Types&... is represented via a
-/// PackExpansionType whose pattern is Types&.
-class PackExpansionType : public Type, public llvm::FoldingSetNode {
- /// \brief The pattern of the pack expansion.
- QualType Pattern;
-
- /// \brief 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
- /// packs that occur within the pattern have been substituted but others have
- /// not.
- unsigned NumExpansions;
-
- PackExpansionType(QualType Pattern, QualType Canon,
- Optional<unsigned> NumExpansions)
- : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/Pattern->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Pattern(Pattern),
- NumExpansions(NumExpansions? *NumExpansions + 1: 0) { }
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- /// \brief 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
- /// generate, if known.
- Optional<unsigned> getNumExpansions() const {
- if (NumExpansions)
- return NumExpansions - 1;
-
- return None;
- }
-
- bool isSugared() const { return !Pattern->isDependentType(); }
- QualType desugar() const { return isSugared() ? Pattern : QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPattern(), getNumExpansions());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
- Optional<unsigned> NumExpansions) {
- ID.AddPointer(Pattern.getAsOpaquePtr());
- ID.AddBoolean(NumExpansions.hasValue());
- if (NumExpansions)
- ID.AddInteger(*NumExpansions);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == PackExpansion;
- }
-};
-
-/// Represents a class type in Objective C.
-///
-/// Every Objective C type is a combination of a base type, a set of
-/// type arguments (optional, for parameterized classes) and a list of
-/// protocols.
-///
-/// Given the following declarations:
-/// \code
-/// \@class C<T>;
-/// \@protocol P;
-/// \endcode
-///
-/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType
-/// with base C and no protocols.
-///
-/// 'C<P>' is an unspecialized ObjCObjectType with base C and protocol list [P].
-/// 'C<C*>' is a specialized ObjCObjectType with type arguments 'C*' and no
-/// protocol list.
-/// 'C<C*><P>' is a specialized ObjCObjectType with base C, type arguments 'C*',
-/// and protocol list [P].
-///
-/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose
-/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType
-/// and no protocols.
-///
-/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType
-/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually
-/// this should get its own sugar class to better represent the source.
-class ObjCObjectType : public Type {
- // ObjCObjectType.NumTypeArgs - the number of type arguments stored
- // after the ObjCObjectPointerType node.
- // ObjCObjectType.NumProtocols - the number of protocols stored
- // after the type arguments of ObjCObjectPointerType node.
- //
- // These protocols are those written directly on the type. If
- // protocol qualifiers ever become additive, the iterators will need
- // to get kindof complicated.
- //
- // In the canonical object type, these are sorted alphabetically
- // and uniqued.
-
- /// Either a BuiltinType or an InterfaceType or sugar for either.
- QualType BaseType;
-
- /// Cached superclass type.
- mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool>
- CachedSuperClassType;
-
- ObjCProtocolDecl * const *getProtocolStorage() const {
- return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
- }
-
- QualType *getTypeArgStorage();
- const QualType *getTypeArgStorage() const {
- return const_cast<ObjCObjectType *>(this)->getTypeArgStorage();
- }
-
- ObjCProtocolDecl **getProtocolStorage();
-
-protected:
- ObjCObjectType(QualType Canonical, QualType Base,
- ArrayRef<QualType> typeArgs,
- ArrayRef<ObjCProtocolDecl *> protocols,
- bool isKindOf);
-
- enum Nonce_ObjCInterface { Nonce_ObjCInterface };
- ObjCObjectType(enum Nonce_ObjCInterface)
- : Type(ObjCInterface, QualType(), false, false, false, false),
- BaseType(QualType(this_(), 0)) {
- ObjCObjectTypeBits.NumProtocols = 0;
- ObjCObjectTypeBits.NumTypeArgs = 0;
- ObjCObjectTypeBits.IsKindOf = 0;
- }
-
- void computeSuperClassTypeSlow() const;
-
-public:
- /// Gets the base type of this object type. This is always (possibly
- /// sugar for) one of:
- /// - the 'id' builtin type (as opposed to the 'id' type visible to the
- /// user, which is a typedef for an ObjCObjectPointerType)
- /// - the 'Class' builtin type (same caveat)
- /// - an ObjCObjectType (currently always an ObjCInterfaceType)
- QualType getBaseType() const { return BaseType; }
-
- bool isObjCId() const {
- return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
- }
- bool isObjCClass() const {
- return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
- }
- bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
- bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
- bool isObjCUnqualifiedIdOrClass() const {
- if (!qual_empty()) return false;
- if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
- return T->getKind() == BuiltinType::ObjCId ||
- T->getKind() == BuiltinType::ObjCClass;
- return false;
- }
- bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
- bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
-
- /// Gets the interface declaration for this object type, if the base type
- /// really is an interface.
- ObjCInterfaceDecl *getInterface() const;
-
- /// Determine whether this object type is "specialized", meaning
- /// that it has type arguments.
- bool isSpecialized() const;
-
- /// Determine whether this object type was written with type arguments.
- bool isSpecializedAsWritten() const {
- return ObjCObjectTypeBits.NumTypeArgs > 0;
- }
-
- /// Determine whether this object type is "unspecialized", meaning
- /// that it has no type arguments.
- bool isUnspecialized() const { return !isSpecialized(); }
-
- /// Determine whether this object type is "unspecialized" as
- /// written, meaning that it has no type arguments.
- bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }
-
- /// Retrieve the type arguments of this object type (semantically).
- ArrayRef<QualType> getTypeArgs() const;
-
- /// Retrieve the type arguments of this object type as they were
- /// written.
- ArrayRef<QualType> getTypeArgsAsWritten() const {
- return llvm::makeArrayRef(getTypeArgStorage(),
- ObjCObjectTypeBits.NumTypeArgs);
- }
-
- typedef ObjCProtocolDecl * const *qual_iterator;
- typedef llvm::iterator_range<qual_iterator> qual_range;
-
- qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
- qual_iterator qual_begin() const { return getProtocolStorage(); }
- qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
-
- bool qual_empty() const { return getNumProtocols() == 0; }
-
- /// Return the number of qualifying protocols in this interface type,
- /// or 0 if there are none.
- unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; }
-
- /// Fetch a protocol by index.
- ObjCProtocolDecl *getProtocol(unsigned I) const {
- assert(I < getNumProtocols() && "Out-of-range protocol access");
- return qual_begin()[I];
- }
-
- /// Retrieve all of the protocol qualifiers.
- ArrayRef<ObjCProtocolDecl *> getProtocols() const {
- return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
- }
-
- /// Whether this is a "__kindof" type as written.
- bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; }
-
- /// Whether this ia a "__kindof" type (semantically).
- bool isKindOfType() const;
-
- /// Retrieve the type of the superclass of this object type.
- ///
- /// This operation substitutes any type arguments into the
- /// superclass of the current class type, potentially producing a
- /// specialization of the superclass type. Produces a null type if
- /// there is no superclass.
- QualType getSuperClassType() const {
- if (!CachedSuperClassType.getInt())
- computeSuperClassTypeSlow();
-
- assert(CachedSuperClassType.getInt() && "Superclass not set?");
- return QualType(CachedSuperClassType.getPointer(), 0);
- }
-
- /// Strip off the Objective-C "kindof" type and (with it) any
- /// protocol qualifiers.
- QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCObject ||
- T->getTypeClass() == ObjCInterface;
- }
-};
-
-/// A class providing a concrete implementation
-/// of ObjCObjectType, so as to not increase the footprint of
-/// ObjCInterfaceType. Code outside of ASTContext and the core type
-/// system should not reference this type.
-class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
- friend class ASTContext;
-
- // If anyone adds fields here, ObjCObjectType::getProtocolStorage()
- // will need to be modified.
-
- ObjCObjectTypeImpl(QualType Canonical, QualType Base,
- ArrayRef<QualType> typeArgs,
- ArrayRef<ObjCProtocolDecl *> protocols,
- bool isKindOf)
- : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {}
-
-public:
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- QualType Base,
- ArrayRef<QualType> typeArgs,
- ArrayRef<ObjCProtocolDecl *> protocols,
- bool isKindOf);
-};
-
-inline QualType *ObjCObjectType::getTypeArgStorage() {
- return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1);
-}
-
-inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
- return reinterpret_cast<ObjCProtocolDecl**>(
- getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs);
-}
-
-/// Interfaces are the core concept in Objective-C for object oriented design.
-/// They basically correspond to C++ classes. There are two kinds of interface
-/// types: normal interfaces like `NSString`, and qualified interfaces, which
-/// are qualified with a protocol list like `NSString<NSCopyable, NSAmazing>`.
-///
-/// ObjCInterfaceType guarantees the following properties when considered
-/// as a subtype of its superclass, ObjCObjectType:
-/// - There are no protocol qualifiers. To reinforce this, code which
-/// tries to invoke the protocol methods via an ObjCInterfaceType will
-/// fail to compile.
-/// - It is its own base type. That is, if T is an ObjCInterfaceType*,
-/// T->getBaseType() == QualType(T, 0).
-class ObjCInterfaceType : public ObjCObjectType {
- mutable ObjCInterfaceDecl *Decl;
-
- ObjCInterfaceType(const ObjCInterfaceDecl *D)
- : ObjCObjectType(Nonce_ObjCInterface),
- Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
- friend class ASTContext; // ASTContext creates these.
- friend class ASTReader;
- friend class ObjCInterfaceDecl;
-
-public:
- /// Get the declaration of this interface.
- ObjCInterfaceDecl *getDecl() const { return Decl; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCInterface;
- }
-
- // Nonsense to "hide" certain members of ObjCObjectType within this
- // class. People asking for protocols on an ObjCInterfaceType are
- // not going to get what they want: ObjCInterfaceTypes are
- // guaranteed to have no protocols.
- enum {
- qual_iterator,
- qual_begin,
- qual_end,
- getNumProtocols,
- getProtocol
- };
-};
-
-inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
- QualType baseType = getBaseType();
- while (const ObjCObjectType *ObjT = baseType->getAs<ObjCObjectType>()) {
- if (const ObjCInterfaceType *T = dyn_cast<ObjCInterfaceType>(ObjT))
- return T->getDecl();
-
- baseType = ObjT->getBaseType();
- }
-
- return nullptr;
-}
-
-/// Represents a pointer to an Objective C object.
-///
-/// These are constructed from pointer declarators when the pointee type is
-/// an ObjCObjectType (or sugar for one). In addition, the 'id' and 'Class'
-/// types are typedefs for these, and the protocol-qualified types 'id<P>'
-/// and 'Class<P>' are translated into these.
-///
-/// Pointers to pointers to Objective C objects are still PointerTypes;
-/// only the first level of pointer gets it own type implementation.
-class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
-
- ObjCObjectPointerType(QualType Canonical, QualType Pointee)
- : Type(ObjCObjectPointer, Canonical,
- Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {}
- friend class ASTContext; // ASTContext creates these.
-
-public:
- /// Gets the type pointed to by this ObjC pointer.
- /// The result will always be an ObjCObjectType or sugar thereof.
- QualType getPointeeType() const { return PointeeType; }
-
- /// Gets the type pointed to by this ObjC pointer. Always returns non-null.
- ///
- /// This method is equivalent to getPointeeType() except that
- /// it discards any typedefs (or other sugar) between this
- /// type and the "outermost" object type. So for:
- /// \code
- /// \@class A; \@protocol P; \@protocol Q;
- /// typedef A<P> AP;
- /// typedef A A1;
- /// typedef A1<P> A1P;
- /// typedef A1P<Q> A1PQ;
- /// \endcode
- /// For 'A*', getObjectType() will return 'A'.
- /// For 'A<P>*', getObjectType() will return 'A<P>'.
- /// For 'AP*', getObjectType() will return 'A<P>'.
- /// For 'A1*', getObjectType() will return 'A'.
- /// For 'A1<P>*', getObjectType() will return 'A1<P>'.
- /// For 'A1P*', getObjectType() will return 'A1<P>'.
- /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because
- /// adding protocols to a protocol-qualified base discards the
- /// old qualifiers (for now). But if it didn't, getObjectType()
- /// would return 'A1P<Q>' (and we'd have to make iterating over
- /// qualifiers more complicated).
- const ObjCObjectType *getObjectType() const {
- return PointeeType->castAs<ObjCObjectType>();
- }
-
- /// If this pointer points to an Objective C
- /// \@interface type, gets the type for that interface. Any protocol
- /// qualifiers on the interface are ignored.
- ///
- /// \return null if the base type for this pointer is 'id' or 'Class'
- const ObjCInterfaceType *getInterfaceType() const;
-
- /// If this pointer points to an Objective \@interface
- /// type, gets the declaration for that interface.
- ///
- /// \return null if the base type for this pointer is 'id' or 'Class'
- ObjCInterfaceDecl *getInterfaceDecl() const {
- return getObjectType()->getInterface();
- }
-
- /// True if this is equivalent to the 'id' type, i.e. if
- /// its object type is the primitive 'id' type with no protocols.
- bool isObjCIdType() const {
- return getObjectType()->isObjCUnqualifiedId();
- }
-
- /// True if this is equivalent to the 'Class' type,
- /// i.e. if its object tive is the primitive 'Class' type with no protocols.
- bool isObjCClassType() const {
- return getObjectType()->isObjCUnqualifiedClass();
- }
-
- /// True if this is equivalent to the 'id' or 'Class' type,
- bool isObjCIdOrClassType() const {
- return getObjectType()->isObjCUnqualifiedIdOrClass();
- }
-
- /// True if this is equivalent to 'id<P>' for some non-empty set of
- /// protocols.
- bool isObjCQualifiedIdType() const {
- return getObjectType()->isObjCQualifiedId();
- }
-
- /// True if this is equivalent to 'Class<P>' for some non-empty set of
- /// protocols.
- bool isObjCQualifiedClassType() const {
- return getObjectType()->isObjCQualifiedClass();
- }
-
- /// Whether this is a "__kindof" type.
- bool isKindOfType() const { return getObjectType()->isKindOfType(); }
-
- /// Whether this type is specialized, meaning that it has type arguments.
- bool isSpecialized() const { return getObjectType()->isSpecialized(); }
-
- /// Whether this type is specialized, meaning that it has type arguments.
- bool isSpecializedAsWritten() const {
- return getObjectType()->isSpecializedAsWritten();
- }
-
- /// Whether this type is unspecialized, meaning that is has no type arguments.
- bool isUnspecialized() const { return getObjectType()->isUnspecialized(); }
-
- /// Determine whether this object type is "unspecialized" as
- /// written, meaning that it has no type arguments.
- bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }
-
- /// Retrieve the type arguments for this type.
- ArrayRef<QualType> getTypeArgs() const {
- return getObjectType()->getTypeArgs();
- }
-
- /// Retrieve the type arguments for this type.
- ArrayRef<QualType> getTypeArgsAsWritten() const {
- return getObjectType()->getTypeArgsAsWritten();
- }
-
- /// An iterator over the qualifiers on the object type. Provided
- /// for convenience. This will always iterate over the full set of
- /// protocols on a type, not just those provided directly.
- typedef ObjCObjectType::qual_iterator qual_iterator;
- typedef llvm::iterator_range<qual_iterator> qual_range;
-
- qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
- qual_iterator qual_begin() const {
- return getObjectType()->qual_begin();
- }
- qual_iterator qual_end() const {
- return getObjectType()->qual_end();
- }
- bool qual_empty() const { return getObjectType()->qual_empty(); }
-
- /// Return the number of qualifying protocols on the object type.
- unsigned getNumProtocols() const {
- return getObjectType()->getNumProtocols();
- }
-
- /// Retrieve a qualifying protocol by index on the object type.
- ObjCProtocolDecl *getProtocol(unsigned I) const {
- return getObjectType()->getProtocol(I);
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- /// Retrieve the type of the superclass of this object pointer type.
- ///
- /// This operation substitutes any type arguments into the
- /// superclass of the current class type, potentially producing a
- /// pointer to a specialization of the superclass type. Produces a
- /// null type if there is no superclass.
- QualType getSuperClassType() const;
-
- /// Strip off the Objective-C "kindof" type and (with it) any
- /// protocol qualifiers.
- const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals(
- const ASTContext &ctx) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
- ID.AddPointer(T.getAsOpaquePtr());
- }
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCObjectPointer;
- }
-};
-
-class AtomicType : public Type, public llvm::FoldingSetNode {
- QualType ValueType;
-
- AtomicType(QualType ValTy, QualType Canonical)
- : Type(Atomic, Canonical, ValTy->isDependentType(),
- ValTy->isInstantiationDependentType(),
- ValTy->isVariablyModifiedType(),
- ValTy->containsUnexpandedParameterPack()),
- ValueType(ValTy) {}
- friend class ASTContext; // ASTContext creates these.
-
- public:
- /// Gets the type contained by this atomic type, i.e.
- /// the type returned by performing an atomic load of this atomic type.
- QualType getValueType() const { return ValueType; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getValueType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
- ID.AddPointer(T.getAsOpaquePtr());
- }
- static bool classof(const Type *T) {
- return T->getTypeClass() == Atomic;
- }
-};
-
-/// A qualifier set is used to build a set of qualifiers.
-class QualifierCollector : public Qualifiers {
-public:
- QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {}
-
- /// Collect any qualifiers on the given type and return an
- /// unqualified type. The qualifiers are assumed to be consistent
- /// with those already in the type.
- const Type *strip(QualType type) {
- addFastQualifiers(type.getLocalFastQualifiers());
- if (!type.hasLocalNonFastQualifiers())
- return type.getTypePtrUnsafe();
-
- const ExtQuals *extQuals = type.getExtQualsUnsafe();
- addConsistentQualifiers(extQuals->getQualifiers());
- return extQuals->getBaseType();
- }
-
- /// Apply the collected qualifiers to the given type.
- QualType apply(const ASTContext &Context, QualType QT) const;
-
- /// Apply the collected qualifiers to the given type.
- QualType apply(const ASTContext &Context, const Type* T) const;
-};
-
-
-// Inline function definitions.
-
-inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
- SplitQualType desugar =
- Ty->getLocallyUnqualifiedSingleStepDesugaredType().split();
- desugar.Quals.addConsistentQualifiers(Quals);
- return desugar;
-}
-
-inline const Type *QualType::getTypePtr() const {
- return getCommonPtr()->BaseType;
-}
-
-inline const Type *QualType::getTypePtrOrNull() const {
- return (isNull() ? nullptr : getCommonPtr()->BaseType);
-}
-
-inline SplitQualType QualType::split() const {
- if (!hasLocalNonFastQualifiers())
- return SplitQualType(getTypePtrUnsafe(),
- Qualifiers::fromFastMask(getLocalFastQualifiers()));
-
- const ExtQuals *eq = getExtQualsUnsafe();
- Qualifiers qs = eq->getQualifiers();
- qs.addFastQualifiers(getLocalFastQualifiers());
- return SplitQualType(eq->getBaseType(), qs);
-}
-
-inline Qualifiers QualType::getLocalQualifiers() const {
- Qualifiers Quals;
- if (hasLocalNonFastQualifiers())
- Quals = getExtQualsUnsafe()->getQualifiers();
- Quals.addFastQualifiers(getLocalFastQualifiers());
- return Quals;
-}
-
-inline Qualifiers QualType::getQualifiers() const {
- Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers();
- quals.addFastQualifiers(getLocalFastQualifiers());
- return quals;
-}
-
-inline unsigned QualType::getCVRQualifiers() const {
- unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers();
- cvr |= getLocalCVRQualifiers();
- return cvr;
-}
-
-inline QualType QualType::getCanonicalType() const {
- QualType canon = getCommonPtr()->CanonicalType;
- return canon.withFastQualifiers(getLocalFastQualifiers());
-}
-
-inline bool QualType::isCanonical() const {
- return getTypePtr()->isCanonicalUnqualified();
-}
-
-inline bool QualType::isCanonicalAsParam() const {
- if (!isCanonical()) return false;
- if (hasLocalQualifiers()) return false;
-
- const Type *T = getTypePtr();
- if (T->isVariablyModifiedType() && T->hasSizedVLAType())
- return false;
-
- return !isa<FunctionType>(T) && !isa<ArrayType>(T);
-}
-
-inline bool QualType::isConstQualified() const {
- return isLocalConstQualified() ||
- getCommonPtr()->CanonicalType.isLocalConstQualified();
-}
-
-inline bool QualType::isRestrictQualified() const {
- return isLocalRestrictQualified() ||
- getCommonPtr()->CanonicalType.isLocalRestrictQualified();
-}
-
-
-inline bool QualType::isVolatileQualified() const {
- return isLocalVolatileQualified() ||
- getCommonPtr()->CanonicalType.isLocalVolatileQualified();
-}
-
-inline bool QualType::hasQualifiers() const {
- return hasLocalQualifiers() ||
- getCommonPtr()->CanonicalType.hasLocalQualifiers();
-}
-
-inline QualType QualType::getUnqualifiedType() const {
- if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
- return QualType(getTypePtr(), 0);
-
- return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
-}
-
-inline SplitQualType QualType::getSplitUnqualifiedType() const {
- if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
- return split();
-
- return getSplitUnqualifiedTypeImpl(*this);
-}
-
-inline void QualType::removeLocalConst() {
- removeLocalFastQualifiers(Qualifiers::Const);
-}
-
-inline void QualType::removeLocalRestrict() {
- removeLocalFastQualifiers(Qualifiers::Restrict);
-}
-
-inline void QualType::removeLocalVolatile() {
- removeLocalFastQualifiers(Qualifiers::Volatile);
-}
-
-inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
- assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
- assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask);
-
- // Fast path: we don't need to touch the slow qualifiers.
- removeLocalFastQualifiers(Mask);
-}
-
-/// Return the address space of this type.
-inline unsigned QualType::getAddressSpace() const {
- return getQualifiers().getAddressSpace();
-}
-
-/// Return the gc attribute of this type.
-inline Qualifiers::GC QualType::getObjCGCAttr() const {
- return getQualifiers().getObjCGCAttr();
-}
-
-inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
- if (const PointerType *PT = t.getAs<PointerType>()) {
- if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>())
- return FT->getExtInfo();
- } else if (const FunctionType *FT = t.getAs<FunctionType>())
- return FT->getExtInfo();
-
- return FunctionType::ExtInfo();
-}
-
-inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
- return getFunctionExtInfo(*t);
-}
-
-/// Determine whether this type is more
-/// qualified than the Other type. For example, "const volatile int"
-/// is more qualified than "const int", "volatile int", and
-/// "int". However, it is not more qualified than "const volatile
-/// int".
-inline bool QualType::isMoreQualifiedThan(QualType other) const {
- Qualifiers myQuals = getQualifiers();
- Qualifiers otherQuals = other.getQualifiers();
- return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals));
-}
-
-/// Determine whether this type is at last
-/// as qualified as the Other type. For example, "const volatile
-/// int" is at least as qualified as "const int", "volatile int",
-/// "int", and "const volatile int".
-inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const {
- return getQualifiers().compatiblyIncludes(other.getQualifiers());
-}
-
-/// If Type is a reference type (e.g., const
-/// int&), returns the type that the reference refers to ("const
-/// int"). Otherwise, returns the type itself. This routine is used
-/// throughout Sema to implement C++ 5p6:
-///
-/// If an expression initially has the type "reference to T" (8.3.2,
-/// 8.5.3), the type is adjusted to "T" prior to any further
-/// 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>())
- return RefType->getPointeeType();
- else
- return *this;
-}
-
-inline bool QualType::isCForbiddenLValueType() const {
- return ((getTypePtr()->isVoidType() && !hasQualifiers()) ||
- getTypePtr()->isFunctionType());
-}
-
-/// Tests whether the type is categorized as a fundamental type.
-///
-/// \returns True for types specified in C++0x [basic.fundamental].
-inline bool Type::isFundamentalType() const {
- return isVoidType() ||
- // FIXME: It's really annoying that we don't have an
- // 'isArithmeticType()' which agrees with the standard definition.
- (isArithmeticType() && !isEnumeralType());
-}
-
-/// Tests whether the type is categorized as a compound type.
-///
-/// \returns True for types specified in C++0x [basic.compound].
-inline bool Type::isCompoundType() const {
- // C++0x [basic.compound]p1:
- // Compound types can be constructed in the following ways:
- // -- arrays of objects of a given type [...];
- return isArrayType() ||
- // -- functions, which have parameters of given types [...];
- isFunctionType() ||
- // -- pointers to void or objects or functions [...];
- isPointerType() ||
- // -- references to objects or functions of a given type. [...]
- isReferenceType() ||
- // -- classes containing a sequence of objects of various types, [...];
- isRecordType() ||
- // -- unions, which are classes capable of containing objects of different
- // types at different times;
- isUnionType() ||
- // -- enumerations, which comprise a set of named constant values. [...];
- isEnumeralType() ||
- // -- pointers to non-static class members, [...].
- isMemberPointerType();
-}
-
-inline bool Type::isFunctionType() const {
- return isa<FunctionType>(CanonicalType);
-}
-inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType);
-}
-inline bool Type::isAnyPointerType() const {
- return isPointerType() || isObjCObjectPointerType();
-}
-inline bool Type::isBlockPointerType() const {
- return isa<BlockPointerType>(CanonicalType);
-}
-inline bool Type::isReferenceType() const {
- return isa<ReferenceType>(CanonicalType);
-}
-inline bool Type::isLValueReferenceType() const {
- return isa<LValueReferenceType>(CanonicalType);
-}
-inline bool Type::isRValueReferenceType() const {
- return isa<RValueReferenceType>(CanonicalType);
-}
-inline bool Type::isFunctionPointerType() const {
- if (const PointerType *T = getAs<PointerType>())
- return T->getPointeeType()->isFunctionType();
- else
- return false;
-}
-inline bool Type::isMemberPointerType() const {
- return isa<MemberPointerType>(CanonicalType);
-}
-inline bool Type::isMemberFunctionPointerType() const {
- if (const MemberPointerType* T = getAs<MemberPointerType>())
- return T->isMemberFunctionPointer();
- else
- return false;
-}
-inline bool Type::isMemberDataPointerType() const {
- if (const MemberPointerType* T = getAs<MemberPointerType>())
- return T->isMemberDataPointer();
- else
- return false;
-}
-inline bool Type::isArrayType() const {
- return isa<ArrayType>(CanonicalType);
-}
-inline bool Type::isConstantArrayType() const {
- return isa<ConstantArrayType>(CanonicalType);
-}
-inline bool Type::isIncompleteArrayType() const {
- return isa<IncompleteArrayType>(CanonicalType);
-}
-inline bool Type::isVariableArrayType() const {
- return isa<VariableArrayType>(CanonicalType);
-}
-inline bool Type::isDependentSizedArrayType() const {
- return isa<DependentSizedArrayType>(CanonicalType);
-}
-inline bool Type::isBuiltinType() const {
- return isa<BuiltinType>(CanonicalType);
-}
-inline bool Type::isRecordType() const {
- return isa<RecordType>(CanonicalType);
-}
-inline bool Type::isEnumeralType() const {
- return isa<EnumType>(CanonicalType);
-}
-inline bool Type::isAnyComplexType() const {
- return isa<ComplexType>(CanonicalType);
-}
-inline bool Type::isVectorType() const {
- return isa<VectorType>(CanonicalType);
-}
-inline bool Type::isExtVectorType() const {
- return isa<ExtVectorType>(CanonicalType);
-}
-inline bool Type::isObjCObjectPointerType() const {
- return isa<ObjCObjectPointerType>(CanonicalType);
-}
-inline bool Type::isObjCObjectType() const {
- return isa<ObjCObjectType>(CanonicalType);
-}
-inline bool Type::isObjCObjectOrInterfaceType() const {
- return isa<ObjCInterfaceType>(CanonicalType) ||
- isa<ObjCObjectType>(CanonicalType);
-}
-inline bool Type::isAtomicType() const {
- return isa<AtomicType>(CanonicalType);
-}
-
-inline bool Type::isObjCQualifiedIdType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
- return OPT->isObjCQualifiedIdType();
- return false;
-}
-inline bool Type::isObjCQualifiedClassType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
- return OPT->isObjCQualifiedClassType();
- return false;
-}
-inline bool Type::isObjCIdType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
- return OPT->isObjCIdType();
- return false;
-}
-inline bool Type::isObjCClassType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
- return OPT->isObjCClassType();
- return false;
-}
-inline bool Type::isObjCSelType() const {
- if (const PointerType *OPT = getAs<PointerType>())
- return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
- return false;
-}
-inline bool Type::isObjCBuiltinType() const {
- return isObjCIdType() || isObjCClassType() || isObjCSelType();
-}
-
-inline bool Type::isImage1dT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage1d);
-}
-
-inline bool Type::isImage1dArrayT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage1dArray);
-}
-
-inline bool Type::isImage1dBufferT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer);
-}
-
-inline bool Type::isImage2dT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2d);
-}
-
-inline bool Type::isImage2dArrayT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dArray);
-}
-
-inline bool Type::isImage2dDepthT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dDepth);
-}
-
-inline bool Type::isImage2dArrayDepthT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayDepth);
-}
-
-inline bool Type::isImage2dMSAAT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dMSAA);
-}
-
-inline bool Type::isImage2dArrayMSAAT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayMSAA);
-}
-
-inline bool Type::isImage2dMSAATDepth() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dMSAADepth);
-}
-
-inline bool Type::isImage2dArrayMSAATDepth() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayMSAADepth);
-}
-
-inline bool Type::isImage3dT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage3d);
-}
-
-inline bool Type::isSamplerT() const {
- return isSpecificBuiltinType(BuiltinType::OCLSampler);
-}
-
-inline bool Type::isEventT() const {
- return isSpecificBuiltinType(BuiltinType::OCLEvent);
-}
-
-inline bool Type::isClkEventT() const {
- return isSpecificBuiltinType(BuiltinType::OCLClkEvent);
-}
-
-inline bool Type::isQueueT() const {
- return isSpecificBuiltinType(BuiltinType::OCLQueue);
-}
-
-inline bool Type::isNDRangeT() const {
- return isSpecificBuiltinType(BuiltinType::OCLNDRange);
-}
-
-inline bool Type::isReserveIDT() const {
- return isSpecificBuiltinType(BuiltinType::OCLReserveID);
-}
-
-inline bool Type::isImageType() const {
- return isImage3dT() || isImage2dT() || isImage2dArrayT() ||
- isImage2dDepthT() || isImage2dArrayDepthT() || isImage2dMSAAT() ||
- isImage2dArrayMSAAT() || isImage2dMSAATDepth() ||
- isImage2dArrayMSAATDepth() || isImage1dT() || isImage1dArrayT() ||
- isImage1dBufferT();
-}
-
-inline bool Type::isOpenCLSpecificType() const {
- return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
- isQueueT() || isNDRangeT() || isReserveIDT();
-}
-
-inline bool Type::isTemplateTypeParmType() const {
- return isa<TemplateTypeParmType>(CanonicalType);
-}
-
-inline bool Type::isSpecificBuiltinType(unsigned K) const {
- if (const BuiltinType *BT = getAs<BuiltinType>())
- if (BT->getKind() == (BuiltinType::Kind) K)
- return true;
- return false;
-}
-
-inline bool Type::isPlaceholderType() const {
- if (const BuiltinType *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 (BT->isPlaceholderType())
- return BT;
- return nullptr;
-}
-
-inline bool Type::isSpecificPlaceholderType(unsigned K) const {
- assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K));
- if (const BuiltinType *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))
- return BT->isNonOverloadPlaceholderType();
- return false;
-}
-
-inline bool Type::isVoidType() const {
- if (const BuiltinType *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))
- return BT->getKind() == BuiltinType::Half;
- // FIXME: Should we allow complex __fp16? Probably not.
- return false;
-}
-
-inline bool Type::isNullPtrType() const {
- if (const BuiltinType *BT = getAs<BuiltinType>())
- return BT->getKind() == BuiltinType::NullPtr;
- return false;
-}
-
-extern bool IsEnumDeclComplete(EnumDecl *);
-extern bool IsEnumDeclScoped(EnumDecl *);
-
-inline bool Type::isIntegerType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::Int128;
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
- // Incomplete enum types are not treated as integer types.
- // FIXME: In C++, enum types are never integer types.
- return IsEnumDeclComplete(ET->getDecl()) &&
- !IsEnumDeclScoped(ET->getDecl());
- }
- return false;
-}
-
-inline bool Type::isScalarType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() > BuiltinType::Void &&
- BT->getKind() <= BuiltinType::NullPtr;
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
- // Enums are scalar types, but only if they are defined. Incomplete enums
- // are not treated as scalar types.
- return IsEnumDeclComplete(ET->getDecl());
- return isa<PointerType>(CanonicalType) ||
- isa<BlockPointerType>(CanonicalType) ||
- isa<MemberPointerType>(CanonicalType) ||
- isa<ComplexType>(CanonicalType) ||
- isa<ObjCObjectPointerType>(CanonicalType);
-}
-
-inline bool Type::isIntegralOrEnumerationType() const {
- if (const BuiltinType *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))
- return IsEnumDeclComplete(ET->getDecl());
-
- return false;
-}
-
-inline bool Type::isBooleanType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Bool;
- return false;
-}
-
-inline bool Type::isUndeducedType() const {
- const AutoType *AT = getContainedAutoType();
- return AT && !AT->isDeduced();
-}
-
-/// \brief 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.
-inline bool Type::canDecayToPointerType() const {
- return isFunctionType() || isArrayType();
-}
-
-inline bool Type::hasPointerRepresentation() const {
- return (isPointerType() || isReferenceType() || isBlockPointerType() ||
- isObjCObjectPointerType() || isNullPtrType());
-}
-
-inline bool Type::hasObjCPointerRepresentation() const {
- return isObjCObjectPointerType();
-}
-
-inline const Type *Type::getBaseElementTypeUnsafe() const {
- const Type *type = this;
- while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe())
- type = arrayType->getElementType().getTypePtr();
- return type;
-}
-
-/// Insertion operator for diagnostics. This allows sending QualType's into a
-/// diagnostic with <<.
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- QualType T) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
- DiagnosticsEngine::ak_qualtype);
- return DB;
-}
-
-/// Insertion operator for partial diagnostics. This allows sending QualType's
-/// into a diagnostic with <<.
-inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- QualType T) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
- DiagnosticsEngine::ak_qualtype);
- return PD;
-}
-
-// Helper class template that is used by Type::getAs to ensure that one does
-// not try to look through a qualified type to get to an array type.
-template <typename T, bool isArrayType = (std::is_same<T, ArrayType>::value ||
- std::is_base_of<ArrayType, T>::value)>
-struct ArrayType_cannot_be_used_with_getAs {};
-
-template<typename T>
-struct ArrayType_cannot_be_used_with_getAs<T, true>;
-
-// Member-template getAs<specific type>'.
-template <typename T> const T *Type::getAs() const {
- ArrayType_cannot_be_used_with_getAs<T> at;
- (void)at;
-
- // If this is directly a T type, return it.
- if (const T *Ty = dyn_cast<T>(this))
- return Ty;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<T>(CanonicalType))
- return nullptr;
-
- // If this is a typedef for the type, strip the typedef off without
- // losing all typedef information.
- return cast<T>(getUnqualifiedDesugaredType());
-}
-
-inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
- // If this is directly an array type, return it.
- if (const ArrayType *arr = dyn_cast<ArrayType>(this))
- return arr;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<ArrayType>(CanonicalType))
- return nullptr;
-
- // If this is a typedef for the type, strip the typedef off without
- // losing all typedef information.
- return cast<ArrayType>(getUnqualifiedDesugaredType());
-}
-
-template <typename T> const T *Type::castAs() const {
- ArrayType_cannot_be_used_with_getAs<T> at;
- (void) at;
-
- if (const T *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;
- return cast<ArrayType>(getUnqualifiedDesugaredType());
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
deleted file mode 100644
index 26feda5..0000000
--- a/include/clang/AST/TypeLoc.h
+++ /dev/null
@@ -1,2039 +0,0 @@
-//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- 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::TypeLoc interface and its subclasses.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPELOC_H
-#define LLVM_CLANG_AST_TYPELOC_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/Specifiers.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
- class ASTContext;
- class ParmVarDecl;
- class TypeSourceInfo;
- class UnqualTypeLoc;
-
-// Predeclare all the type nodes.
-#define ABSTRACT_TYPELOC(Class, Base)
-#define TYPELOC(Class, Base) \
- class Class##TypeLoc;
-#include "clang/AST/TypeLocNodes.def"
-
-/// \brief 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.
-class TypeLoc {
-protected:
- // The correctness of this relies on the property that, for Type *Ty,
- // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
- const void *Ty;
- void *Data;
-
-public:
- /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
- /// is of the desired type.
- ///
- /// \pre T::isKind(*this)
- template<typename T>
- T castAs() const {
- assert(T::isKind(*this));
- T t;
- TypeLoc& tl = t;
- tl = *this;
- return t;
- }
-
- /// \brief 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();
- T t;
- TypeLoc& tl = t;
- tl = *this;
- return t;
- }
-
- /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
- /// except it also defines a Qualified enum that corresponds to the
- /// QualifiedLoc class.
- enum TypeLocClass {
-#define ABSTRACT_TYPE(Class, Base)
-#define TYPE(Class, Base) \
- Class = Type::Class,
-#include "clang/AST/TypeNodes.def"
- Qualified
- };
-
- TypeLoc() : Ty(nullptr), Data(nullptr) { }
- TypeLoc(QualType ty, void *opaqueData)
- : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
- TypeLoc(const Type *ty, void *opaqueData)
- : Ty(ty), Data(opaqueData) { }
-
- TypeLocClass getTypeLocClass() const {
- if (getType().hasLocalQualifiers()) return Qualified;
- return (TypeLocClass) getType()->getTypeClass();
- }
-
- 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.
- static unsigned getFullDataSizeForType(QualType Ty);
-
- /// \brief 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
- /// information.
- QualType getType() const {
- return QualType::getFromOpaquePtr(Ty);
- }
-
- const Type *getTypePtr() const {
- return QualType::getFromOpaquePtr(Ty).getTypePtr();
- }
-
- /// \brief Get the pointer where source information is stored.
- void *getOpaqueData() const {
- return Data;
- }
-
- /// \brief Get the begin source location.
- SourceLocation getBeginLoc() const;
-
- /// \brief Get the end source location.
- SourceLocation getEndLoc() const;
-
- /// \brief Get the full source range.
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getBeginLoc(), getEndLoc());
- }
- SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- /// \brief Get the local source range.
- SourceRange getLocalSourceRange() const {
- return getLocalSourceRangeImpl(*this);
- }
-
- /// \brief 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
- /// 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.
- UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
-
- TypeLoc IgnoreParens() const;
-
- /// \brief Find a type with the location of an explicit type qualifier.
- ///
- /// The result, if non-null, will be one of:
- /// QualifiedTypeLoc
- /// AtomicTypeLoc
- /// AttributedTypeLoc, for those type attributes that behave as qualifiers
- TypeLoc findExplicitQualifierLoc() const;
-
- /// \brief 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
- /// relies on location-less types.
- void initialize(ASTContext &Context, SourceLocation Loc) const {
- initializeImpl(Context, *this, Loc);
- }
-
- /// \brief 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
- /// TypeLoc of the same type. The given size must be the full data
- /// size.
- void initializeFullCopy(TypeLoc Other, unsigned Size) {
- assert(getType() == Other.getType());
- assert(getFullDataSize() == Size);
- copy(Other);
- }
-
- /// Copies the other type loc into this one.
- void copy(TypeLoc other);
-
- friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
- return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
- }
-
- friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
- return !(LHS == RHS);
- }
-
- /// Find the location of the nullability specifier (__nonnull,
- /// __nullable, or __null_unspecifier), if there is one.
- SourceLocation findNullabilityLoc() const;
-
-private:
- static bool isKind(const TypeLoc&) {
- return true;
- }
-
- static void initializeImpl(ASTContext &Context, TypeLoc TL,
- SourceLocation Loc);
- static TypeLoc getNextTypeLocImpl(TypeLoc TL);
- static TypeLoc IgnoreParensImpl(TypeLoc TL);
- static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
-};
-
-/// \brief 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
-/// no direct qualifiers.
-class UnqualTypeLoc : public TypeLoc {
-public:
- UnqualTypeLoc() {}
- UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
-
- const Type *getTypePtr() const {
- return reinterpret_cast<const Type*>(Ty);
- }
-
- TypeLocClass getTypeLocClass() const {
- return (TypeLocClass) getTypePtr()->getTypeClass();
- }
-
-private:
- friend class TypeLoc;
- static bool isKind(const TypeLoc &TL) {
- return !TL.getType().hasLocalQualifiers();
- }
-};
-
-/// \brief Wrapper of type source information for a type with
-/// non-trivial direct qualifiers.
-///
-/// Currently, we intentionally do not provide source location for
-/// type qualifiers.
-class QualifiedTypeLoc : public TypeLoc {
-public:
- SourceRange getLocalSourceRange() const {
- return SourceRange();
- }
-
- UnqualTypeLoc getUnqualifiedLoc() const {
- unsigned align =
- TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
- uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
- dataInt = llvm::RoundUpToAlignment(dataInt, align);
- return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
- }
-
- /// Initializes the local data of this type source info block to
- /// provide no information.
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- // do nothing
- }
-
- void copyLocal(TypeLoc other) {
- // do nothing
- }
-
- TypeLoc getNextTypeLoc() const {
- return getUnqualifiedLoc();
- }
-
- /// \brief 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
- // for qualifiers.
- return 0;
- }
-
- /// \brief 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.
- return 1;
- }
-
-private:
- friend class TypeLoc;
- static bool isKind(const TypeLoc &TL) {
- return TL.getType().hasLocalQualifiers();
- }
-};
-
-inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
- if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
- return Loc.getUnqualifiedLoc();
- return castAs<UnqualTypeLoc>();
-}
-
-/// A metaprogramming base class for TypeLoc classes which correspond
-/// to a particular Type subclass. It is accepted for a single
-/// TypeLoc class to correspond to multiple Type classes.
-///
-/// \tparam Base a class from which to derive
-/// \tparam Derived the class deriving from this one
-/// \tparam TypeClass the concrete Type subclass associated with this
-/// location type
-/// \tparam LocalData the structure type of local location data for
-/// this type
-///
-/// TypeLocs with non-constant amounts of local data should override
-/// getExtraLocalDataSize(); getExtraLocalData() will then point to
-/// this extra memory.
-///
-/// TypeLocs with an inner type should define
-/// QualType getInnerType() const
-/// and getInnerTypeLoc() will then point to this inner type's
-/// location data.
-///
-/// A word about hierarchies: this template is not designed to be
-/// derived from multiple times in a hierarchy. It is also not
-/// designed to be used for classes where subtypes might provide
-/// different amounts of source information. It should be subclassed
-/// only at the deepest portion of the hierarchy where all children
-/// have identical source information; if that's an abstract type,
-/// then further descendents should inherit from
-/// InheritingConcreteTypeLoc instead.
-template <class Base, class Derived, class TypeClass, class LocalData>
-class ConcreteTypeLoc : public Base {
-
- const Derived *asDerived() const {
- return static_cast<const Derived*>(this);
- }
-
- friend class TypeLoc;
- static bool isKind(const TypeLoc &TL) {
- return !TL.getType().hasLocalQualifiers() &&
- Derived::classofType(TL.getTypePtr());
- }
-
- static bool classofType(const Type *Ty) {
- return TypeClass::classof(Ty);
- }
-
-public:
- unsigned getLocalDataAlignment() const {
- return std::max(llvm::alignOf<LocalData>(),
- asDerived()->getExtraLocalDataAlignment());
- }
- unsigned getLocalDataSize() const {
- unsigned size = sizeof(LocalData);
- unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
- size = llvm::RoundUpToAlignment(size, extraAlign);
- size += asDerived()->getExtraLocalDataSize();
- return size;
- }
-
- void copyLocal(Derived other) {
- // Some subclasses have no data to copy.
- if (asDerived()->getLocalDataSize() == 0) return;
-
- // Copy the fixed-sized local data.
- memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
-
- // Copy the variable-sized local data. We need to do this
- // separately because the padding in the source and the padding in
- // the destination might be different.
- memcpy(getExtraLocalData(), other.getExtraLocalData(),
- asDerived()->getExtraLocalDataSize());
- }
-
- TypeLoc getNextTypeLoc() const {
- return getNextTypeLoc(asDerived()->getInnerType());
- }
-
- const TypeClass *getTypePtr() const {
- return cast<TypeClass>(Base::getTypePtr());
- }
-
-protected:
- unsigned getExtraLocalDataSize() const {
- return 0;
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return 1;
- }
-
- LocalData *getLocalData() const {
- return static_cast<LocalData*>(Base::Data);
- }
-
- /// Gets a pointer past the Info structure; useful for classes with
- /// local data that can't be captured in the Info (e.g. because it's
- /// of variable size).
- void *getExtraLocalData() const {
- unsigned size = sizeof(LocalData);
- unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
- size = llvm::RoundUpToAlignment(size, extraAlign);
- return reinterpret_cast<char*>(Base::Data) + size;
- }
-
- void *getNonLocalData() const {
- uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
- data += asDerived()->getLocalDataSize();
- data = llvm::RoundUpToAlignment(data, getNextTypeAlign());
- return reinterpret_cast<void*>(data);
- }
-
- struct HasNoInnerType {};
- HasNoInnerType getInnerType() const { return HasNoInnerType(); }
-
- TypeLoc getInnerTypeLoc() const {
- return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
- }
-
-private:
- unsigned getInnerTypeSize() const {
- return getInnerTypeSize(asDerived()->getInnerType());
- }
-
- unsigned getInnerTypeSize(HasNoInnerType _) const {
- return 0;
- }
-
- unsigned getInnerTypeSize(QualType _) const {
- return getInnerTypeLoc().getFullDataSize();
- }
-
- unsigned getNextTypeAlign() const {
- return getNextTypeAlign(asDerived()->getInnerType());
- }
-
- unsigned getNextTypeAlign(HasNoInnerType _) const {
- return 1;
- }
-
- unsigned getNextTypeAlign(QualType T) const {
- return TypeLoc::getLocalAlignmentForType(T);
- }
-
- TypeLoc getNextTypeLoc(HasNoInnerType _) const {
- return TypeLoc();
- }
-
- TypeLoc getNextTypeLoc(QualType T) const {
- return TypeLoc(T, getNonLocalData());
- }
-};
-
-/// A metaprogramming class designed for concrete subtypes of abstract
-/// types where all subtypes share equivalently-structured source
-/// information. See the note on ConcreteTypeLoc.
-template <class Base, class Derived, class TypeClass>
-class InheritingConcreteTypeLoc : public Base {
- friend class TypeLoc;
- static bool classofType(const Type *Ty) {
- return TypeClass::classof(Ty);
- }
-
- static bool isKind(const TypeLoc &TL) {
- return !TL.getType().hasLocalQualifiers() &&
- Derived::classofType(TL.getTypePtr());
- }
- static bool isKind(const UnqualTypeLoc &TL) {
- return Derived::classofType(TL.getTypePtr());
- }
-
-public:
- const TypeClass *getTypePtr() const {
- return cast<TypeClass>(Base::getTypePtr());
- }
-};
-
-
-struct TypeSpecLocInfo {
- SourceLocation NameLoc;
-};
-
-/// \brief A reasonable base class for TypeLocs that correspond to
-/// types that are written as a type-specifier.
-class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- TypeSpecTypeLoc,
- Type,
- TypeSpecLocInfo> {
-public:
- enum { LocalDataSize = sizeof(TypeSpecLocInfo),
- LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
-
- SourceLocation getNameLoc() const {
- return this->getLocalData()->NameLoc;
- }
- void setNameLoc(SourceLocation Loc) {
- this->getLocalData()->NameLoc = Loc;
- }
- SourceRange getLocalSourceRange() const {
- return SourceRange(getNameLoc(), getNameLoc());
- }
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setNameLoc(Loc);
- }
-
-private:
- friend class TypeLoc;
- static bool isKind(const TypeLoc &TL);
-};
-
-
-struct BuiltinLocInfo {
- SourceLocation BuiltinLoc;
-};
-
-/// \brief Wrapper for source info for builtin types.
-class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- BuiltinTypeLoc,
- BuiltinType,
- BuiltinLocInfo> {
-public:
- SourceLocation getBuiltinLoc() const {
- return getLocalData()->BuiltinLoc;
- }
- void setBuiltinLoc(SourceLocation Loc) {
- getLocalData()->BuiltinLoc = Loc;
- }
-
- SourceLocation getNameLoc() const { return getBuiltinLoc(); }
-
- WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
- return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
- }
- const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
- return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
- }
-
- bool needsExtraLocalData() const {
- BuiltinType::Kind bk = getTypePtr()->getKind();
- return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
- || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
- || bk == BuiltinType::UChar
- || bk == BuiltinType::SChar;
- }
-
- unsigned getExtraLocalDataSize() const {
- return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getBuiltinLoc(), getBuiltinLoc());
- }
-
- TypeSpecifierSign getWrittenSignSpec() const {
- if (needsExtraLocalData())
- return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
- else
- return TSS_unspecified;
- }
- bool hasWrittenSignSpec() const {
- return getWrittenSignSpec() != TSS_unspecified;
- }
- void setWrittenSignSpec(TypeSpecifierSign written) {
- if (needsExtraLocalData())
- getWrittenBuiltinSpecs().Sign = written;
- }
-
- TypeSpecifierWidth getWrittenWidthSpec() const {
- if (needsExtraLocalData())
- return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
- else
- return TSW_unspecified;
- }
- bool hasWrittenWidthSpec() const {
- return getWrittenWidthSpec() != TSW_unspecified;
- }
- void setWrittenWidthSpec(TypeSpecifierWidth written) {
- if (needsExtraLocalData())
- getWrittenBuiltinSpecs().Width = written;
- }
-
- TypeSpecifierType getWrittenTypeSpec() const;
- bool hasWrittenTypeSpec() const {
- return getWrittenTypeSpec() != TST_unspecified;
- }
- void setWrittenTypeSpec(TypeSpecifierType written) {
- if (needsExtraLocalData())
- getWrittenBuiltinSpecs().Type = written;
- }
-
- bool hasModeAttr() const {
- if (needsExtraLocalData())
- return getWrittenBuiltinSpecs().ModeAttr;
- else
- return false;
- }
- void setModeAttr(bool written) {
- if (needsExtraLocalData())
- getWrittenBuiltinSpecs().ModeAttr = written;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setBuiltinLoc(Loc);
- if (needsExtraLocalData()) {
- WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
- wbs.Sign = TSS_unspecified;
- wbs.Width = TSW_unspecified;
- wbs.Type = TST_unspecified;
- wbs.ModeAttr = false;
- }
- }
-};
-
-
-/// \brief Wrapper for source info for typedefs.
-class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TypedefTypeLoc,
- TypedefType> {
-public:
- TypedefNameDecl *getTypedefNameDecl() const {
- return getTypePtr()->getDecl();
- }
-};
-
-/// \brief Wrapper for source info for injected class names of class
-/// templates.
-class InjectedClassNameTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- InjectedClassNameTypeLoc,
- InjectedClassNameType> {
-public:
- CXXRecordDecl *getDecl() const {
- return getTypePtr()->getDecl();
- }
-};
-
-/// \brief Wrapper for source info for unresolved typename using decls.
-class UnresolvedUsingTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- UnresolvedUsingTypeLoc,
- UnresolvedUsingType> {
-public:
- UnresolvedUsingTypenameDecl *getDecl() const {
- return getTypePtr()->getDecl();
- }
-};
-
-/// \brief 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
-/// creating an ElaboratedType node for so many type references in C.
-class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TagTypeLoc,
- TagType> {
-public:
- TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
-
- /// \brief True if the tag was defined in this type specifier.
- bool isDefinition() const {
- TagDecl *D = getDecl();
- return D->isCompleteDefinition() &&
- (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
- }
-};
-
-/// \brief Wrapper for source info for record types.
-class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
- RecordTypeLoc,
- RecordType> {
-public:
- RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
-};
-
-/// \brief Wrapper for source info for enum types.
-class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
- EnumTypeLoc,
- EnumType> {
-public:
- EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
-};
-
-/// \brief Wrapper for template type parameters.
-class TemplateTypeParmTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TemplateTypeParmTypeLoc,
- TemplateTypeParmType> {
-public:
- TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
-};
-
-/// \brief Wrapper for substituted template type parameters.
-class SubstTemplateTypeParmTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- SubstTemplateTypeParmTypeLoc,
- SubstTemplateTypeParmType> {
-};
-
- /// \brief Wrapper for substituted template type parameters.
-class SubstTemplateTypeParmPackTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- SubstTemplateTypeParmPackTypeLoc,
- SubstTemplateTypeParmPackType> {
-};
-
-struct AttributedLocInfo {
- union {
- Expr *ExprOperand;
-
- /// A raw SourceLocation.
- unsigned EnumOperandLoc;
- };
-
- SourceRange OperandParens;
-
- SourceLocation AttrLoc;
-};
-
-/// \brief Type source information for an attributed type.
-class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- AttributedTypeLoc,
- AttributedType,
- AttributedLocInfo> {
-public:
- AttributedType::Kind getAttrKind() const {
- return getTypePtr()->getAttrKind();
- }
-
- bool hasAttrExprOperand() const {
- return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
- getAttrKind() <= AttributedType::LastExprOperandKind);
- }
-
- bool hasAttrEnumOperand() const {
- return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
- getAttrKind() <= AttributedType::LastEnumOperandKind);
- }
-
- bool hasAttrOperand() const {
- return hasAttrExprOperand() || hasAttrEnumOperand();
- }
-
- bool isQualifier() const {
- return getTypePtr()->isQualifier();
- }
-
- /// The modified type, which is generally canonically different from
- /// the attribute type.
- /// int main(int, char**) __attribute__((noreturn))
- /// ~~~ ~~~~~~~~~~~~~
- TypeLoc getModifiedLoc() const {
- return getInnerTypeLoc();
- }
-
- /// The location of the attribute name, i.e.
- /// __attribute__((regparm(1000)))
- /// ^~~~~~~
- SourceLocation getAttrNameLoc() const {
- return getLocalData()->AttrLoc;
- }
- void setAttrNameLoc(SourceLocation loc) {
- getLocalData()->AttrLoc = loc;
- }
-
- /// The attribute's expression operand, if it has one.
- /// void *cur_thread __attribute__((address_space(21)))
- /// ^~
- Expr *getAttrExprOperand() const {
- assert(hasAttrExprOperand());
- return getLocalData()->ExprOperand;
- }
- void setAttrExprOperand(Expr *e) {
- assert(hasAttrExprOperand());
- getLocalData()->ExprOperand = e;
- }
-
- /// The location of the attribute's enumerated operand, if it has one.
- /// void * __attribute__((objc_gc(weak)))
- /// ^~~~
- SourceLocation getAttrEnumOperandLoc() const {
- assert(hasAttrEnumOperand());
- return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
- }
- void setAttrEnumOperandLoc(SourceLocation loc) {
- assert(hasAttrEnumOperand());
- getLocalData()->EnumOperandLoc = loc.getRawEncoding();
- }
-
- /// The location of the parentheses around the operand, if there is
- /// an operand.
- /// void * __attribute__((objc_gc(weak)))
- /// ^ ^
- SourceRange getAttrOperandParensRange() const {
- assert(hasAttrOperand());
- return getLocalData()->OperandParens;
- }
- void setAttrOperandParensRange(SourceRange range) {
- assert(hasAttrOperand());
- getLocalData()->OperandParens = range;
- }
-
- SourceRange getLocalSourceRange() const {
- // Note that this does *not* include the range of the attribute
- // enclosure, e.g.:
- // __attribute__((foo(bar)))
- // ^~~~~~~~~~~~~~~ ~~
- // or
- // [[foo(bar)]]
- // ^~ ~~
- // That enclosure doesn't necessarily belong to a single attribute
- // anyway.
- SourceRange range(getAttrNameLoc());
- if (hasAttrOperand())
- range.setEnd(getAttrOperandParensRange().getEnd());
- return range;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation loc) {
- setAttrNameLoc(loc);
- if (hasAttrExprOperand()) {
- setAttrOperandParensRange(SourceRange(loc));
- setAttrExprOperand(nullptr);
- } else if (hasAttrEnumOperand()) {
- setAttrOperandParensRange(SourceRange(loc));
- setAttrEnumOperandLoc(loc);
- }
- }
-
- QualType getInnerType() const {
- return getTypePtr()->getModifiedType();
- }
-};
-
-
-struct ObjCObjectTypeLocInfo {
- SourceLocation TypeArgsLAngleLoc;
- SourceLocation TypeArgsRAngleLoc;
- SourceLocation ProtocolLAngleLoc;
- SourceLocation ProtocolRAngleLoc;
- bool HasBaseTypeAsWritten;
-};
-
-// A helper class for defining ObjC TypeLocs that can qualified with
-// protocols.
-//
-// TypeClass basically has to be either ObjCInterfaceType or
-// ObjCObjectPointerType.
-class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- ObjCObjectTypeLoc,
- ObjCObjectType,
- ObjCObjectTypeLocInfo> {
- // TypeSourceInfo*'s are stored after Info, one for each type argument.
- TypeSourceInfo **getTypeArgLocArray() const {
- return (TypeSourceInfo**)this->getExtraLocalData();
- }
-
- // SourceLocations are stored after the type argument information, one for
- // each Protocol.
- SourceLocation *getProtocolLocArray() const {
- return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
- }
-
-public:
- SourceLocation getTypeArgsLAngleLoc() const {
- return this->getLocalData()->TypeArgsLAngleLoc;
- }
- void setTypeArgsLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->TypeArgsLAngleLoc = Loc;
- }
-
- SourceLocation getTypeArgsRAngleLoc() const {
- return this->getLocalData()->TypeArgsRAngleLoc;
- }
- void setTypeArgsRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->TypeArgsRAngleLoc = Loc;
- }
-
- unsigned getNumTypeArgs() const {
- return this->getTypePtr()->getTypeArgsAsWritten().size();
- }
-
- TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
- assert(i < getNumTypeArgs() && "Index is out of bounds!");
- return getTypeArgLocArray()[i];
- }
-
- void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
- assert(i < getNumTypeArgs() && "Index is out of bounds!");
- getTypeArgLocArray()[i] = TInfo;
- }
-
- SourceLocation getProtocolLAngleLoc() const {
- return this->getLocalData()->ProtocolLAngleLoc;
- }
- void setProtocolLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->ProtocolLAngleLoc = Loc;
- }
-
- SourceLocation getProtocolRAngleLoc() const {
- return this->getLocalData()->ProtocolRAngleLoc;
- }
- void setProtocolRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->ProtocolRAngleLoc = Loc;
- }
-
- unsigned getNumProtocols() const {
- return this->getTypePtr()->getNumProtocols();
- }
-
- SourceLocation getProtocolLoc(unsigned i) const {
- assert(i < getNumProtocols() && "Index is out of bounds!");
- return getProtocolLocArray()[i];
- }
- void setProtocolLoc(unsigned i, SourceLocation Loc) {
- assert(i < getNumProtocols() && "Index is out of bounds!");
- getProtocolLocArray()[i] = Loc;
- }
-
- ObjCProtocolDecl *getProtocol(unsigned i) const {
- assert(i < getNumProtocols() && "Index is out of bounds!");
- return *(this->getTypePtr()->qual_begin() + i);
- }
-
-
- ArrayRef<SourceLocation> getProtocolLocs() const {
- return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
- }
-
- bool hasBaseTypeAsWritten() const {
- return getLocalData()->HasBaseTypeAsWritten;
- }
-
- void setHasBaseTypeAsWritten(bool HasBaseType) {
- getLocalData()->HasBaseTypeAsWritten = HasBaseType;
- }
-
- TypeLoc getBaseLoc() const {
- return getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- SourceLocation start = getTypeArgsLAngleLoc();
- if (start.isInvalid())
- start = getProtocolLAngleLoc();
- SourceLocation end = getProtocolRAngleLoc();
- if (end.isInvalid())
- end = getTypeArgsRAngleLoc();
- return SourceRange(start, end);
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
- + this->getNumProtocols() * sizeof(SourceLocation);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- assert(llvm::alignOf<ObjCObjectTypeLoc>()
- >= llvm::alignOf<TypeSourceInfo *>() &&
- "not enough alignment for tail-allocated data");
- return llvm::alignOf<TypeSourceInfo *>();
- }
-
- QualType getInnerType() const {
- return getTypePtr()->getBaseType();
- }
-};
-
-
-struct ObjCInterfaceLocInfo {
- SourceLocation NameLoc;
- SourceLocation NameEndLoc;
-};
-
-/// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
- ObjCInterfaceTypeLoc,
- ObjCInterfaceType,
- ObjCInterfaceLocInfo> {
-public:
- ObjCInterfaceDecl *getIFaceDecl() const {
- return getTypePtr()->getDecl();
- }
-
- SourceLocation getNameLoc() const {
- return getLocalData()->NameLoc;
- }
-
- void setNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getNameLoc(), getNameEndLoc());
- }
-
- SourceLocation getNameEndLoc() const {
- return getLocalData()->NameEndLoc;
- }
-
- void setNameEndLoc(SourceLocation Loc) {
- getLocalData()->NameEndLoc = Loc;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setNameLoc(Loc);
- setNameEndLoc(Loc);
- }
-};
-
-struct ParenLocInfo {
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
-};
-
-class ParenTypeLoc
- : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
- ParenLocInfo> {
-public:
- SourceLocation getLParenLoc() const {
- return this->getLocalData()->LParenLoc;
- }
- SourceLocation getRParenLoc() const {
- return this->getLocalData()->RParenLoc;
- }
- void setLParenLoc(SourceLocation Loc) {
- this->getLocalData()->LParenLoc = Loc;
- }
- void setRParenLoc(SourceLocation Loc) {
- this->getLocalData()->RParenLoc = Loc;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setLParenLoc(Loc);
- setRParenLoc(Loc);
- }
-
- TypeLoc getInnerLoc() const {
- return getInnerTypeLoc();
- }
-
- QualType getInnerType() const {
- return this->getTypePtr()->getInnerType();
- }
-};
-
-inline TypeLoc TypeLoc::IgnoreParens() const {
- if (ParenTypeLoc::isKind(*this))
- return IgnoreParensImpl(*this);
- return *this;
-}
-
-
-struct AdjustedLocInfo { }; // Nothing.
-
-class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
- AdjustedType, AdjustedLocInfo> {
-public:
- TypeLoc getOriginalLoc() const {
- return getInnerTypeLoc();
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- // do nothing
- }
-
- QualType getInnerType() const {
- // The inner type is the undecayed type, since that's what we have source
- // location information for.
- return getTypePtr()->getOriginalType();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange();
- }
-
- unsigned getLocalDataSize() const {
- // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
- // anyway. TypeLocBuilder can't handle data sizes of 1.
- return 0; // No data.
- }
-};
-
-/// \brief Wrapper for source info for pointers decayed from arrays and
-/// functions.
-class DecayedTypeLoc : public InheritingConcreteTypeLoc<
- AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
-};
-
-struct PointerLikeLocInfo {
- SourceLocation StarLoc;
-};
-
-/// A base class for
-template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
-class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
- TypeClass, LocalData> {
-public:
- SourceLocation getSigilLoc() const {
- return this->getLocalData()->StarLoc;
- }
- void setSigilLoc(SourceLocation Loc) {
- this->getLocalData()->StarLoc = Loc;
- }
-
- TypeLoc getPointeeLoc() const {
- return this->getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getSigilLoc(), getSigilLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-
- QualType getInnerType() const {
- return this->getTypePtr()->getPointeeType();
- }
-};
-
-
-/// \brief Wrapper for source info for pointers.
-class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
- PointerType> {
-public:
- SourceLocation getStarLoc() const {
- return getSigilLoc();
- }
- void setStarLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-
-/// \brief Wrapper for source info for block pointers.
-class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
- BlockPointerType> {
-public:
- SourceLocation getCaretLoc() const {
- return getSigilLoc();
- }
- void setCaretLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-struct MemberPointerLocInfo : public PointerLikeLocInfo {
- TypeSourceInfo *ClassTInfo;
-};
-
-/// \brief Wrapper for source info for member pointers.
-class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
- MemberPointerType,
- MemberPointerLocInfo> {
-public:
- SourceLocation getStarLoc() const {
- return getSigilLoc();
- }
- void setStarLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-
- const Type *getClass() const {
- return getTypePtr()->getClass();
- }
- TypeSourceInfo *getClassTInfo() const {
- return getLocalData()->ClassTInfo;
- }
- void setClassTInfo(TypeSourceInfo* TI) {
- getLocalData()->ClassTInfo = TI;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setSigilLoc(Loc);
- setClassTInfo(nullptr);
- }
-
- SourceRange getLocalSourceRange() const {
- if (TypeSourceInfo *TI = getClassTInfo())
- return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
- else
- return SourceRange(getStarLoc());
- }
-};
-
-/// Wraps an ObjCPointerType with source location information.
-class ObjCObjectPointerTypeLoc :
- public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
- ObjCObjectPointerType> {
-public:
- SourceLocation getStarLoc() const {
- return getSigilLoc();
- }
-
- void setStarLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-
-class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
- ReferenceType> {
-public:
- QualType getInnerType() const {
- return getTypePtr()->getPointeeTypeAsWritten();
- }
-};
-
-class LValueReferenceTypeLoc :
- public InheritingConcreteTypeLoc<ReferenceTypeLoc,
- LValueReferenceTypeLoc,
- LValueReferenceType> {
-public:
- SourceLocation getAmpLoc() const {
- return getSigilLoc();
- }
- void setAmpLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-class RValueReferenceTypeLoc :
- public InheritingConcreteTypeLoc<ReferenceTypeLoc,
- RValueReferenceTypeLoc,
- RValueReferenceType> {
-public:
- SourceLocation getAmpAmpLoc() const {
- return getSigilLoc();
- }
- void setAmpAmpLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-
-struct FunctionLocInfo {
- SourceLocation LocalRangeBegin;
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
- SourceLocation LocalRangeEnd;
-};
-
-/// \brief Wrapper for source info for functions.
-class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- FunctionTypeLoc,
- FunctionType,
- FunctionLocInfo> {
-public:
- SourceLocation getLocalRangeBegin() const {
- return getLocalData()->LocalRangeBegin;
- }
- void setLocalRangeBegin(SourceLocation L) {
- getLocalData()->LocalRangeBegin = L;
- }
-
- SourceLocation getLocalRangeEnd() const {
- return getLocalData()->LocalRangeEnd;
- }
- void setLocalRangeEnd(SourceLocation L) {
- getLocalData()->LocalRangeEnd = L;
- }
-
- SourceLocation getLParenLoc() const {
- return this->getLocalData()->LParenLoc;
- }
- void setLParenLoc(SourceLocation Loc) {
- this->getLocalData()->LParenLoc = Loc;
- }
-
- SourceLocation getRParenLoc() const {
- return this->getLocalData()->RParenLoc;
- }
- void setRParenLoc(SourceLocation Loc) {
- this->getLocalData()->RParenLoc = Loc;
- }
-
- SourceRange getParensRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
-
- ArrayRef<ParmVarDecl *> getParams() const {
- return llvm::makeArrayRef(getParmArray(), getNumParams());
- }
-
- // ParmVarDecls* are stored after Info, one for each parameter.
- ParmVarDecl **getParmArray() const {
- return (ParmVarDecl**) getExtraLocalData();
- }
-
- unsigned getNumParams() const {
- if (isa<FunctionNoProtoType>(getTypePtr()))
- return 0;
- return cast<FunctionProtoType>(getTypePtr())->getNumParams();
- }
- ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
- void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
-
- TypeLoc getReturnLoc() const {
- return getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setLocalRangeBegin(Loc);
- setLParenLoc(Loc);
- setRParenLoc(Loc);
- setLocalRangeEnd(Loc);
- for (unsigned i = 0, e = getNumParams(); i != e; ++i)
- setParam(i, nullptr);
- }
-
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getExtraLocalDataSize() const {
- return getNumParams() * sizeof(ParmVarDecl *);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<ParmVarDecl*>();
- }
-
- QualType getInnerType() const { return getTypePtr()->getReturnType(); }
-};
-
-class FunctionProtoTypeLoc :
- public InheritingConcreteTypeLoc<FunctionTypeLoc,
- FunctionProtoTypeLoc,
- FunctionProtoType> {
-};
-
-class FunctionNoProtoTypeLoc :
- public InheritingConcreteTypeLoc<FunctionTypeLoc,
- FunctionNoProtoTypeLoc,
- FunctionNoProtoType> {
-};
-
-
-struct ArrayLocInfo {
- SourceLocation LBracketLoc, RBracketLoc;
- Expr *Size;
-};
-
-/// \brief Wrapper for source info for arrays.
-class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- ArrayTypeLoc,
- ArrayType,
- ArrayLocInfo> {
-public:
- SourceLocation getLBracketLoc() const {
- return getLocalData()->LBracketLoc;
- }
- void setLBracketLoc(SourceLocation Loc) {
- getLocalData()->LBracketLoc = Loc;
- }
-
- SourceLocation getRBracketLoc() const {
- return getLocalData()->RBracketLoc;
- }
- void setRBracketLoc(SourceLocation Loc) {
- getLocalData()->RBracketLoc = Loc;
- }
-
- SourceRange getBracketsRange() const {
- return SourceRange(getLBracketLoc(), getRBracketLoc());
- }
-
- Expr *getSizeExpr() const {
- return getLocalData()->Size;
- }
- void setSizeExpr(Expr *Size) {
- getLocalData()->Size = Size;
- }
-
- TypeLoc getElementLoc() const {
- return getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getLBracketLoc(), getRBracketLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setLBracketLoc(Loc);
- setRBracketLoc(Loc);
- setSizeExpr(nullptr);
- }
-
- QualType getInnerType() const { return getTypePtr()->getElementType(); }
-};
-
-class ConstantArrayTypeLoc :
- public InheritingConcreteTypeLoc<ArrayTypeLoc,
- ConstantArrayTypeLoc,
- ConstantArrayType> {
-};
-
-class IncompleteArrayTypeLoc :
- public InheritingConcreteTypeLoc<ArrayTypeLoc,
- IncompleteArrayTypeLoc,
- IncompleteArrayType> {
-};
-
-class DependentSizedArrayTypeLoc :
- public InheritingConcreteTypeLoc<ArrayTypeLoc,
- DependentSizedArrayTypeLoc,
- DependentSizedArrayType> {
-
-};
-
-class VariableArrayTypeLoc :
- public InheritingConcreteTypeLoc<ArrayTypeLoc,
- VariableArrayTypeLoc,
- VariableArrayType> {
-};
-
-
-// Location information for a TemplateName. Rudimentary for now.
-struct TemplateNameLocInfo {
- SourceLocation NameLoc;
-};
-
-struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
- SourceLocation TemplateKWLoc;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
-};
-
-class TemplateSpecializationTypeLoc :
- public ConcreteTypeLoc<UnqualTypeLoc,
- TemplateSpecializationTypeLoc,
- TemplateSpecializationType,
- TemplateSpecializationLocInfo> {
-public:
- SourceLocation getTemplateKeywordLoc() const {
- return getLocalData()->TemplateKWLoc;
- }
- void setTemplateKeywordLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
- }
-
- SourceLocation getLAngleLoc() const {
- return getLocalData()->LAngleLoc;
- }
- void setLAngleLoc(SourceLocation Loc) {
- getLocalData()->LAngleLoc = Loc;
- }
-
- SourceLocation getRAngleLoc() const {
- return getLocalData()->RAngleLoc;
- }
- void setRAngleLoc(SourceLocation Loc) {
- getLocalData()->RAngleLoc = Loc;
- }
-
- unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
- }
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
- }
-
- TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
- }
-
- SourceLocation getTemplateNameLoc() const {
- return getLocalData()->NameLoc;
- }
- void setTemplateNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
- }
-
- /// \brief - Copy the location information from the given info.
- void copy(TemplateSpecializationTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
-
- // We're potentially copying Expr references here. We don't
- // bother retaining them because TypeSourceInfos live forever, so
- // as long as the Expr was retained when originally written into
- // the TypeLoc, we're okay.
- memcpy(Data, Loc.Data, size);
- }
-
- SourceRange getLocalSourceRange() const {
- if (getTemplateKeywordLoc().isValid())
- return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
- else
- return SourceRange(getTemplateNameLoc(), getRAngleLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setTemplateKeywordLoc(Loc);
- setTemplateNameLoc(Loc);
- setLAngleLoc(Loc);
- setRAngleLoc(Loc);
- initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
- getArgInfos(), Loc);
- }
-
- static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
- const TemplateArgument *Args,
- TemplateArgumentLocInfo *ArgInfos,
- SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(TemplateArgumentLocInfo);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<TemplateArgumentLocInfo>();
- }
-
-private:
- TemplateArgumentLocInfo *getArgInfos() const {
- return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
- }
-};
-
-//===----------------------------------------------------------------------===//
-//
-// All of these need proper implementations.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: size expression and attribute locations (or keyword if we
-// ever fully support altivec syntax).
-class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- VectorTypeLoc,
- VectorType> {
-};
-
-// FIXME: size expression and attribute locations.
-class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
- ExtVectorTypeLoc,
- ExtVectorType> {
-};
-
-// FIXME: attribute locations.
-// For some reason, this isn't a subtype of VectorType.
-class DependentSizedExtVectorTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- DependentSizedExtVectorTypeLoc,
- DependentSizedExtVectorType> {
-};
-
-// FIXME: location of the '_Complex' keyword.
-class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- ComplexTypeLoc,
- ComplexType> {
-};
-
-struct TypeofLocInfo {
- SourceLocation TypeofLoc;
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
-};
-
-struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
-};
-
-struct TypeOfTypeLocInfo : public TypeofLocInfo {
- TypeSourceInfo* UnderlyingTInfo;
-};
-
-template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
-class TypeofLikeTypeLoc
- : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
-public:
- SourceLocation getTypeofLoc() const {
- return this->getLocalData()->TypeofLoc;
- }
- void setTypeofLoc(SourceLocation Loc) {
- this->getLocalData()->TypeofLoc = Loc;
- }
-
- SourceLocation getLParenLoc() const {
- return this->getLocalData()->LParenLoc;
- }
- void setLParenLoc(SourceLocation Loc) {
- this->getLocalData()->LParenLoc = Loc;
- }
-
- SourceLocation getRParenLoc() const {
- return this->getLocalData()->RParenLoc;
- }
- void setRParenLoc(SourceLocation Loc) {
- this->getLocalData()->RParenLoc = Loc;
- }
-
- SourceRange getParensRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
- void setParensRange(SourceRange range) {
- setLParenLoc(range.getBegin());
- setRParenLoc(range.getEnd());
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getTypeofLoc(), getRParenLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setTypeofLoc(Loc);
- setLParenLoc(Loc);
- setRParenLoc(Loc);
- }
-};
-
-class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
- TypeOfExprType,
- TypeOfExprTypeLocInfo> {
-public:
- Expr* getUnderlyingExpr() const {
- return getTypePtr()->getUnderlyingExpr();
- }
- // Reimplemented to account for GNU/C++ extension
- // typeof unary-expression
- // where there are no parentheses.
- SourceRange getLocalSourceRange() const;
-};
-
-class TypeOfTypeLoc
- : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
-public:
- QualType getUnderlyingType() const {
- return this->getTypePtr()->getUnderlyingType();
- }
- TypeSourceInfo* getUnderlyingTInfo() const {
- return this->getLocalData()->UnderlyingTInfo;
- }
- void setUnderlyingTInfo(TypeSourceInfo* TI) const {
- this->getLocalData()->UnderlyingTInfo = TI;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-};
-
-// FIXME: location of the 'decltype' and parens.
-class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- DecltypeTypeLoc,
- DecltypeType> {
-public:
- Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
-};
-
-struct UnaryTransformTypeLocInfo {
- // FIXME: While there's only one unary transform right now, future ones may
- // need different representations
- SourceLocation KWLoc, LParenLoc, RParenLoc;
- TypeSourceInfo *UnderlyingTInfo;
-};
-
-class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- UnaryTransformTypeLoc,
- UnaryTransformType,
- UnaryTransformTypeLocInfo> {
-public:
- SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
- void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
-
- SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
- void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
-
- SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
- void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
-
- TypeSourceInfo* getUnderlyingTInfo() const {
- return getLocalData()->UnderlyingTInfo;
- }
- void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
- getLocalData()->UnderlyingTInfo = TInfo;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getKWLoc(), getRParenLoc());
- }
-
- SourceRange getParensRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
- void setParensRange(SourceRange Range) {
- setLParenLoc(Range.getBegin());
- setRParenLoc(Range.getEnd());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKWLoc(Loc);
- setRParenLoc(Loc);
- setLParenLoc(Loc);
- }
-};
-
-class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- AutoTypeLoc,
- AutoType> {
-};
-
-struct ElaboratedLocInfo {
- SourceLocation ElaboratedKWLoc;
- /// \brief Data associated with the nested-name-specifier location.
- void *QualifierData;
-};
-
-class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- ElaboratedTypeLoc,
- ElaboratedType,
- ElaboratedLocInfo> {
-public:
- SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
- }
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
- }
-
- NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
- }
-
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier()
- == getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- if (getQualifierLoc())
- return SourceRange(getElaboratedKeywordLoc(),
- getQualifierLoc().getEndLoc());
- else
- return SourceRange(getElaboratedKeywordLoc());
- else
- return getQualifierLoc().getSourceRange();
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- TypeLoc getNamedTypeLoc() const {
- return getInnerTypeLoc();
- }
-
- QualType getInnerType() const {
- return getTypePtr()->getNamedType();
- }
-
- void copy(ElaboratedTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
-};
-
-// This is exactly the structure of an ElaboratedTypeLoc whose inner
-// type is some sort of TypeDeclTypeLoc.
-struct DependentNameLocInfo : ElaboratedLocInfo {
- SourceLocation NameLoc;
-};
-
-class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- DependentNameTypeLoc,
- DependentNameType,
- DependentNameLocInfo> {
-public:
- SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
- }
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
- }
-
- NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
- }
-
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier()
- == getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceLocation getNameLoc() const {
- return this->getLocalData()->NameLoc;
- }
- void setNameLoc(SourceLocation Loc) {
- this->getLocalData()->NameLoc = Loc;
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
- else
- return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
- }
-
- void copy(DependentNameTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-};
-
-struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
- SourceLocation TemplateKWLoc;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
- // followed by a TemplateArgumentLocInfo[]
-};
-
-class DependentTemplateSpecializationTypeLoc :
- public ConcreteTypeLoc<UnqualTypeLoc,
- DependentTemplateSpecializationTypeLoc,
- DependentTemplateSpecializationType,
- DependentTemplateSpecializationLocInfo> {
-public:
- SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
- }
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
- }
-
- NestedNameSpecifierLoc getQualifierLoc() const {
- if (!getLocalData()->QualifierData)
- return NestedNameSpecifierLoc();
-
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
- }
-
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- if (!QualifierLoc) {
- // Even if we have a nested-name-specifier in the dependent
- // template specialization type, we won't record the nested-name-specifier
- // location information when this type-source location information is
- // part of a nested-name-specifier.
- getLocalData()->QualifierData = nullptr;
- return;
- }
-
- assert(QualifierLoc.getNestedNameSpecifier()
- == getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceLocation getTemplateKeywordLoc() const {
- return getLocalData()->TemplateKWLoc;
- }
- void setTemplateKeywordLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
- }
-
- SourceLocation getTemplateNameLoc() const {
- return this->getLocalData()->NameLoc;
- }
- void setTemplateNameLoc(SourceLocation Loc) {
- this->getLocalData()->NameLoc = Loc;
- }
-
- SourceLocation getLAngleLoc() const {
- return this->getLocalData()->LAngleLoc;
- }
- void setLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->LAngleLoc = Loc;
- }
-
- SourceLocation getRAngleLoc() const {
- return this->getLocalData()->RAngleLoc;
- }
- void setRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->RAngleLoc = Loc;
- }
-
- unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
- }
-
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
- }
-
- TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
- else if (getQualifierLoc())
- return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
- else if (getTemplateKeywordLoc().isValid())
- return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
- else
- return SourceRange(getTemplateNameLoc(), getRAngleLoc());
- }
-
- void copy(DependentTemplateSpecializationTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(TemplateArgumentLocInfo);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<TemplateArgumentLocInfo>();
- }
-
-private:
- TemplateArgumentLocInfo *getArgInfos() const {
- return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
- }
-};
-
-
-struct PackExpansionTypeLocInfo {
- SourceLocation EllipsisLoc;
-};
-
-class PackExpansionTypeLoc
- : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
- PackExpansionType, PackExpansionTypeLocInfo> {
-public:
- SourceLocation getEllipsisLoc() const {
- return this->getLocalData()->EllipsisLoc;
- }
-
- void setEllipsisLoc(SourceLocation Loc) {
- this->getLocalData()->EllipsisLoc = Loc;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getEllipsisLoc(), getEllipsisLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setEllipsisLoc(Loc);
- }
-
- TypeLoc getPatternLoc() const {
- return getInnerTypeLoc();
- }
-
- QualType getInnerType() const {
- return this->getTypePtr()->getPattern();
- }
-};
-
-struct AtomicTypeLocInfo {
- SourceLocation KWLoc, LParenLoc, RParenLoc;
-};
-
-class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
- AtomicType, AtomicTypeLocInfo> {
-public:
- TypeLoc getValueLoc() const {
- return this->getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getKWLoc(), getRParenLoc());
- }
-
- SourceLocation getKWLoc() const {
- return this->getLocalData()->KWLoc;
- }
- void setKWLoc(SourceLocation Loc) {
- this->getLocalData()->KWLoc = Loc;
- }
-
- SourceLocation getLParenLoc() const {
- return this->getLocalData()->LParenLoc;
- }
- void setLParenLoc(SourceLocation Loc) {
- this->getLocalData()->LParenLoc = Loc;
- }
-
- SourceLocation getRParenLoc() const {
- return this->getLocalData()->RParenLoc;
- }
- void setRParenLoc(SourceLocation Loc) {
- this->getLocalData()->RParenLoc = Loc;
- }
-
- SourceRange getParensRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
- void setParensRange(SourceRange Range) {
- setLParenLoc(Range.getBegin());
- setRParenLoc(Range.getEnd());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKWLoc(Loc);
- setLParenLoc(Loc);
- setRParenLoc(Loc);
- }
-
- QualType getInnerType() const {
- return this->getTypePtr()->getValueType();
- }
-};
-
-
-}
-
-#endif
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
deleted file mode 100644
index 4590e48..0000000
--- a/include/clang/AST/TypeLocNodes.def
+++ /dev/null
@@ -1,41 +0,0 @@
-//===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- 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 TypeLoc info database. Each node is
-// enumerated by providing its core name (e.g., "Pointer" for "PointerTypeLoc")
-// and base class (e.g., "DeclaratorLoc"). All nodes except QualifiedTypeLoc
-// are associated
-//
-// TYPELOC(Class, Base) - A TypeLoc subclass. If UNQUAL_TYPELOC is
-// provided, there will be exactly one of these, Qualified.
-//
-// UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass.
-//
-// ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef UNQUAL_TYPELOC
-# define UNQUAL_TYPELOC(Class, Base) TYPELOC(Class, Base)
-#endif
-
-#ifndef ABSTRACT_TYPELOC
-# define ABSTRACT_TYPELOC(Class, Base) UNQUAL_TYPELOC(Class, Base)
-#endif
-
-TYPELOC(Qualified, TypeLoc)
-#define TYPE(Class, Base) UNQUAL_TYPELOC(Class, Base##Loc)
-#define ABSTRACT_TYPE(Class, Base) ABSTRACT_TYPELOC(Class, Base##Loc)
-#include "clang/AST/TypeNodes.def"
-
-#undef DECLARATOR_TYPELOC
-#undef TYPESPEC_TYPELOC
-#undef ABSTRACT_TYPELOC
-#undef UNQUAL_TYPELOC
-#undef TYPELOC
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
deleted file mode 100644
index db5775a..0000000
--- a/include/clang/AST/TypeLocVisitor.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===--- TypeLocVisitor.h - Visitor for TypeLoc subclasses ------*- 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 TypeLocVisitor interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_TYPELOCVISITOR_H
-#define LLVM_CLANG_AST_TYPELOCVISITOR_H
-
-#include "clang/AST/TypeLoc.h"
-#include "clang/AST/TypeVisitor.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-
-#define DISPATCH(CLASSNAME) \
- return static_cast<ImplClass*>(this)-> \
- Visit##CLASSNAME(TyLoc.castAs<CLASSNAME>())
-
-template<typename ImplClass, typename RetTy=void>
-class TypeLocVisitor {
-public:
- RetTy Visit(TypeLoc TyLoc) {
- switch (TyLoc.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
- case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
-#include "clang/AST/TypeLocNodes.def"
- }
- llvm_unreachable("unexpected type loc class!");
- }
-
- RetTy Visit(UnqualTypeLoc TyLoc) {
- switch (TyLoc.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
- case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
-#include "clang/AST/TypeLocNodes.def"
- }
- llvm_unreachable("unexpected type loc class!");
- }
-
-#define TYPELOC(CLASS, PARENT) \
- RetTy Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- DISPATCH(PARENT); \
- }
-#include "clang/AST/TypeLocNodes.def"
-
- RetTy VisitTypeLoc(TypeLoc TyLoc) { return RetTy(); }
-};
-
-#undef DISPATCH
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_TYPELOCVISITOR_H
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
deleted file mode 100644
index 2549f0b..0000000
--- a/include/clang/AST/TypeNodes.def
+++ /dev/null
@@ -1,129 +0,0 @@
-//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- 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 AST type info database. Each type node is
-// enumerated by providing its name (e.g., "Builtin" or "Enum") and
-// base class (e.g., "Type" or "TagType"). Depending on where in the
-// abstract syntax tree the type will show up, the enumeration uses
-// one of five different macros:
-//
-// TYPE(Class, Base) - A type that can show up anywhere in the AST,
-// and might be dependent, canonical, or non-canonical. All clients
-// will need to understand these types.
-//
-// ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
-// the type hierarchy but has no concrete instances.
-//
-// NON_CANONICAL_TYPE(Class, Base) - A type that can show up
-// anywhere in the AST but will never be a part of a canonical
-// type. Clients that only need to deal with canonical types
-// (ignoring, e.g., typedefs and other type alises used for
-// pretty-printing) can ignore these types.
-//
-// DEPENDENT_TYPE(Class, Base) - A type that will only show up
-// within a C++ template that has not been instantiated, e.g., a
-// type that is always dependent. Clients that do not need to deal
-// with uninstantiated C++ templates can ignore these types.
-//
-// NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
-// is non-canonical unless it is dependent. Defaults to TYPE because
-// it is neither reliably dependent nor reliably non-canonical.
-//
-// There is a sixth macro, independent of the others. Most clients
-// will not need to use it.
-//
-// LEAF_TYPE(Class) - A type that never has inner types. Clients
-// which can operate on such types more efficiently may wish to do so.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ABSTRACT_TYPE
-# define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base)
-#endif
-
-#ifndef NON_CANONICAL_TYPE
-# define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base)
-#endif
-
-#ifndef DEPENDENT_TYPE
-# define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
-#endif
-
-#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
-# define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
-#endif
-
-TYPE(Builtin, Type)
-TYPE(Complex, Type)
-TYPE(Pointer, Type)
-TYPE(BlockPointer, Type)
-ABSTRACT_TYPE(Reference, Type)
-TYPE(LValueReference, ReferenceType)
-TYPE(RValueReference, ReferenceType)
-TYPE(MemberPointer, Type)
-ABSTRACT_TYPE(Array, Type)
-TYPE(ConstantArray, ArrayType)
-TYPE(IncompleteArray, ArrayType)
-TYPE(VariableArray, ArrayType)
-DEPENDENT_TYPE(DependentSizedArray, ArrayType)
-DEPENDENT_TYPE(DependentSizedExtVector, Type)
-TYPE(Vector, Type)
-TYPE(ExtVector, VectorType)
-ABSTRACT_TYPE(Function, Type)
-TYPE(FunctionProto, FunctionType)
-TYPE(FunctionNoProto, FunctionType)
-DEPENDENT_TYPE(UnresolvedUsing, Type)
-NON_CANONICAL_TYPE(Paren, Type)
-NON_CANONICAL_TYPE(Typedef, Type)
-NON_CANONICAL_TYPE(Adjusted, Type)
-NON_CANONICAL_TYPE(Decayed, AdjustedType)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type)
-ABSTRACT_TYPE(Tag, Type)
-TYPE(Record, TagType)
-TYPE(Enum, TagType)
-NON_CANONICAL_TYPE(Elaborated, Type)
-NON_CANONICAL_TYPE(Attributed, Type)
-DEPENDENT_TYPE(TemplateTypeParm, Type)
-NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
-DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
-TYPE(Auto, Type)
-DEPENDENT_TYPE(InjectedClassName, Type)
-DEPENDENT_TYPE(DependentName, Type)
-DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)
-TYPE(ObjCObject, Type)
-TYPE(ObjCInterface, ObjCObjectType)
-TYPE(ObjCObjectPointer, Type)
-TYPE(Atomic, Type)
-
-#ifdef LAST_TYPE
-LAST_TYPE(Atomic)
-#undef LAST_TYPE
-#endif
-
-// These types are always leaves in the type hierarchy.
-#ifdef LEAF_TYPE
-LEAF_TYPE(Enum)
-LEAF_TYPE(Builtin)
-LEAF_TYPE(Record)
-LEAF_TYPE(InjectedClassName)
-LEAF_TYPE(ObjCInterface)
-LEAF_TYPE(TemplateTypeParm)
-#undef LEAF_TYPE
-#endif
-
-#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
-#undef DEPENDENT_TYPE
-#undef NON_CANONICAL_TYPE
-#undef ABSTRACT_TYPE
-#undef TYPE
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
deleted file mode 100644
index 392e544..0000000
--- a/include/clang/AST/TypeOrdering.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-------------- TypeOrdering.h - Total ordering for types -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief 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
-/// std::maps, std::sets, llvm::DenseMaps, and llvm::DenseSets.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPEORDERING_H
-#define LLVM_CLANG_AST_TYPEORDERING_H
-
-#include "clang/AST/CanonicalType.h"
-#include "clang/AST/Type.h"
-#include <functional>
-
-namespace clang {
-
-/// \brief Function object that provides a total ordering on QualType values.
-struct QualTypeOrdering : std::binary_function<QualType, QualType, bool> {
- bool operator()(QualType T1, QualType T2) const {
- return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr());
- }
-};
-
-}
-
-namespace llvm {
- template<class> struct DenseMapInfo;
-
- template<> struct DenseMapInfo<clang::QualType> {
- static inline clang::QualType getEmptyKey() { return clang::QualType(); }
-
- static inline clang::QualType getTombstoneKey() {
- using clang::QualType;
- return QualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
- }
-
- static unsigned getHashValue(clang::QualType Val) {
- return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
- ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
- }
-
- static bool isEqual(clang::QualType LHS, clang::QualType RHS) {
- return LHS == RHS;
- }
- };
-
- template<> struct DenseMapInfo<clang::CanQualType> {
- static inline clang::CanQualType getEmptyKey() {
- return clang::CanQualType();
- }
-
- static inline clang::CanQualType getTombstoneKey() {
- using clang::CanQualType;
- return CanQualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
- }
-
- static unsigned getHashValue(clang::CanQualType Val) {
- return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
- ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
- }
-
- static bool isEqual(clang::CanQualType LHS, clang::CanQualType RHS) {
- return LHS == RHS;
- }
- };
-}
-
-#endif
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
deleted file mode 100644
index 11e5a47..0000000
--- a/include/clang/AST/TypeVisitor.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- 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 TypeVisitor interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPEVISITOR_H
-#define LLVM_CLANG_AST_TYPEVISITOR_H
-
-#include "clang/AST/Type.h"
-
-namespace clang {
-
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass*>(this)-> \
- Visit##CLASS(static_cast<const CLASS*>(T))
-
-/// \brief An operation on a type.
-///
-/// \tparam ImplClass Class implementing the operation. Must be inherited from
-/// TypeVisitor.
-/// \tparam RetTy %Type of result produced by the operation.
-///
-/// The class implements polymorphic operation on an object of type derived
-/// from Type. The operation is performed by calling method Visit. It then
-/// dispatches the call to function \c VisitFooType, if actual argument type
-/// is \c FooType.
-///
-/// The class implements static polymorphism using Curiously Recurring
-/// Template Pattern. It is designed to be a base class for some concrete
-/// class:
-///
-/// \code
-/// class SomeVisitor : public TypeVisitor<SomeVisitor,sometype> { ... };
-/// ...
-/// Type *atype = ...
-/// ...
-/// SomeVisitor avisitor;
-/// sometype result = avisitor.Visit(atype);
-/// \endcode
-///
-/// Actual treatment is made by methods of the derived class, TypeVisitor only
-/// dispatches call to the appropriate method. If the implementation class
-/// \c ImplClass provides specific action for some type, say
-/// \c ConstantArrayType, it should define method
-/// <tt>VisitConstantArrayType(const ConstantArrayType*)</tt>. Otherwise
-/// \c TypeVisitor dispatches call to the method that handles parent type. In
-/// this example handlers are tried in the sequence:
-///
-/// \li <tt>ImplClass::VisitConstantArrayType(const ConstantArrayType*)</tt>
-/// \li <tt>ImplClass::VisitArrayType(const ArrayType*)</tt>
-/// \li <tt>ImplClass::VisitType(const Type*)</tt>
-/// \li <tt>TypeVisitor::VisitType(const Type*)</tt>
-///
-/// The first function of this sequence that is defined will handle object of
-/// type \c ConstantArrayType.
-template<typename ImplClass, typename RetTy=void>
-class TypeVisitor {
-public:
-
- /// \brief 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()) {
-#define ABSTRACT_TYPE(CLASS, PARENT)
-#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
-#include "clang/AST/TypeNodes.def"
- }
- llvm_unreachable("Unknown type class!");
- }
-
- // If the implementation chooses not to implement a certain visit method, fall
- // back on superclass.
-#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \
- DISPATCH(PARENT); \
-}
-#include "clang/AST/TypeNodes.def"
-
- /// \brief Method called if \c ImpClass doesn't provide specific handler
- /// for some type class.
- RetTy VisitType(const Type*) { return RetTy(); }
-};
-
-#undef DISPATCH
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
deleted file mode 100644
index 26ee1cf..0000000
--- a/include/clang/AST/UnresolvedSet.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- 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 UnresolvedSet class, which is used to store
-// collections of declarations in the AST.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
-#define LLVM_CLANG_AST_UNRESOLVEDSET_H
-
-#include "clang/AST/DeclAccessPair.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator.h"
-
-namespace clang {
-
-/// The iterator over UnresolvedSets. Serves as both the const and
-/// non-const iterator.
-class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
- UnresolvedSetIterator, DeclAccessPair *,
- std::random_access_iterator_tag, NamedDecl *,
- std::ptrdiff_t, NamedDecl *, NamedDecl *> {
- friend class UnresolvedSetImpl;
- friend class ASTUnresolvedSet;
- friend class OverloadExpr;
-
- explicit UnresolvedSetIterator(DeclAccessPair *Iter)
- : iterator_adaptor_base(Iter) {}
- explicit UnresolvedSetIterator(const DeclAccessPair *Iter)
- : iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {}
-
-public:
- UnresolvedSetIterator() {}
-
- NamedDecl *getDecl() const { return I->getDecl(); }
- void setDecl(NamedDecl *ND) const { return I->setDecl(ND); }
- AccessSpecifier getAccess() const { return I->getAccess(); }
- void setAccess(AccessSpecifier AS) { I->setAccess(AS); }
- const DeclAccessPair &getPair() const { return *I; }
-
- NamedDecl *operator*() const { return getDecl(); }
- NamedDecl *operator->() const { return **this; }
-};
-
-/// \brief A set of unresolved declarations.
-class UnresolvedSetImpl {
- typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
-
- // Don't allow direct construction, and only permit subclassing by
- // UnresolvedSet.
-private:
- template <unsigned N> friend class UnresolvedSet;
- UnresolvedSetImpl() {}
- UnresolvedSetImpl(const UnresolvedSetImpl &) {}
-
-public:
- // We don't currently support assignment through this iterator, so we might
- // as well use the same implementation twice.
- typedef UnresolvedSetIterator iterator;
- typedef UnresolvedSetIterator const_iterator;
-
- iterator begin() { return iterator(decls().begin()); }
- iterator end() { return iterator(decls().end()); }
-
- const_iterator begin() const { return const_iterator(decls().begin()); }
- const_iterator end() const { return const_iterator(decls().end()); }
-
- void addDecl(NamedDecl *D) {
- addDecl(D, AS_none);
- }
-
- void addDecl(NamedDecl *D, AccessSpecifier AS) {
- decls().push_back(DeclAccessPair::make(D, AS));
- }
-
- /// Replaces the given declaration with the new one, once.
- ///
- /// \return true if the set changed
- bool replace(const NamedDecl* Old, NamedDecl *New) {
- for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
- if (I->getDecl() == Old)
- return (I->setDecl(New), true);
- return false;
- }
-
- /// Replaces the declaration at the given iterator with the new one,
- /// preserving the original access bits.
- void replace(iterator I, NamedDecl *New) { I.I->setDecl(New); }
-
- void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
- I.I->set(New, AS);
- }
-
- void erase(unsigned I) { decls()[I] = decls().pop_back_val(); }
-
- void erase(iterator I) { *I.I = decls().pop_back_val(); }
-
- void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); }
-
- void clear() { decls().clear(); }
- void set_size(unsigned N) { decls().set_size(N); }
-
- bool empty() const { return decls().empty(); }
- unsigned size() const { return decls().size(); }
-
- void append(iterator I, iterator E) { decls().append(I.I, E.I); }
-
- DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
- const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
-
-private:
- // These work because the only permitted subclass is UnresolvedSetImpl
-
- DeclsTy &decls() {
- return *reinterpret_cast<DeclsTy*>(this);
- }
- const DeclsTy &decls() const {
- return *reinterpret_cast<const DeclsTy*>(this);
- }
-};
-
-/// \brief A set of unresolved declarations.
-template <unsigned InlineCapacity> class UnresolvedSet :
- public UnresolvedSetImpl {
- SmallVector<DeclAccessPair, InlineCapacity> Decls;
-};
-
-
-} // namespace clang
-
-#endif
diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h
deleted file mode 100644
index 727bf51..0000000
--- a/include/clang/AST/VTTBuilder.h
+++ /dev/null
@@ -1,162 +0,0 @@
-//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with generation of the layout of virtual table
-// tables (VTT).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_VTTBUILDER_H
-#define LLVM_CLANG_AST_VTTBUILDER_H
-
-#include "clang/AST/BaseSubobject.h"
-#include "clang/AST/CXXInheritance.h"
-#include "clang/AST/GlobalDecl.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/ABI.h"
-#include "llvm/ADT/SetVector.h"
-#include <utility>
-
-namespace clang {
-
-class VTTVTable {
- llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
- CharUnits BaseOffset;
-
-public:
- VTTVTable() {}
- VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
- : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
- VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
- : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
- BaseOffset(Base.getBaseOffset()) {}
-
- const CXXRecordDecl *getBase() const {
- return BaseAndIsVirtual.getPointer();
- }
-
- CharUnits getBaseOffset() const {
- return BaseOffset;
- }
-
- bool isVirtual() const {
- return BaseAndIsVirtual.getInt();
- }
-
- BaseSubobject getBaseSubobject() const {
- return BaseSubobject(getBase(), getBaseOffset());
- }
-};
-
-struct VTTComponent {
- uint64_t VTableIndex;
- BaseSubobject VTableBase;
-
- VTTComponent() {}
- VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
- : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
-};
-
-/// \brief Class for building VTT layout information.
-class VTTBuilder {
-
- ASTContext &Ctx;
-
- /// \brief The most derived class for which we're building this vtable.
- const CXXRecordDecl *MostDerivedClass;
-
- typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
-
- /// \brief The VTT vtables.
- VTTVTablesVectorTy VTTVTables;
-
- typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
-
- /// \brief The VTT components.
- VTTComponentsVectorTy VTTComponents;
-
- /// \brief The AST record layout of the most derived class.
- const ASTRecordLayout &MostDerivedClassLayout;
-
- typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
-
- typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
-
- /// \brief 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 most derived class.
- llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
-
- /// \brief Whether the VTT builder should generate LLVM IR for the VTT.
- bool GenerateDefinition;
-
- /// \brief 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.
- void LayoutSecondaryVTTs(BaseSubobject Base);
-
- /// \brief Lay out the secondary virtual pointers for the given base
- /// subobject.
- ///
- /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
- /// or a direct or indirect base of a virtual base.
- void LayoutSecondaryVirtualPointers(BaseSubobject Base,
- bool BaseIsMorallyVirtual,
- uint64_t VTableIndex,
- const CXXRecordDecl *VTableClass,
- VisitedVirtualBasesSetTy &VBases);
-
- /// \brief 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
- /// record declaration.
- void LayoutVirtualVTTs(const CXXRecordDecl *RD,
- VisitedVirtualBasesSetTy &VBases);
-
- /// \brief Lay out the VTT for the given subobject, including any
- /// secondary VTTs, secondary virtual pointers and virtual VTTs.
- void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
-
-public:
- VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
- bool GenerateDefinition);
-
- // \brief Returns a reference to the VTT components.
- const VTTComponentsVectorTy &getVTTComponents() const {
- return VTTComponents;
- }
-
- // \brief Returns a reference to the VTT vtables.
- const VTTVTablesVectorTy &getVTTVTables() const {
- return VTTVTables;
- }
-
- /// \brief 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.
- const llvm::DenseMap<BaseSubobject, uint64_t> &
- getSecondaryVirtualPointerIndices() const {
- return SecondaryVirtualPointerIndices;
- }
-
-};
-
-}
-
-#endif
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
deleted file mode 100644
index 481fd11..0000000
--- a/include/clang/AST/VTableBuilder.h
+++ /dev/null
@@ -1,566 +0,0 @@
-//===--- VTableBuilder.h - C++ vtable layout builder --------------*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with generation of the layout of virtual tables.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_VTABLEBUILDER_H
-#define LLVM_CLANG_AST_VTABLEBUILDER_H
-
-#include "clang/AST/BaseSubobject.h"
-#include "clang/AST/CXXInheritance.h"
-#include "clang/AST/GlobalDecl.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/ABI.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SetVector.h"
-#include <memory>
-#include <utility>
-
-namespace clang {
- class CXXRecordDecl;
-
-/// \brief Represents a single component in a vtable.
-class VTableComponent {
-public:
- enum Kind {
- CK_VCallOffset,
- CK_VBaseOffset,
- CK_OffsetToTop,
- CK_RTTI,
- CK_FunctionPointer,
-
- /// \brief A pointer to the complete destructor.
- CK_CompleteDtorPointer,
-
- /// \brief A pointer to the deleting destructor.
- CK_DeletingDtorPointer,
-
- /// \brief 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
- /// CK_UnusedFunctionPointer.
- CK_UnusedFunctionPointer
- };
-
- VTableComponent() = default;
-
- static VTableComponent MakeVCallOffset(CharUnits Offset) {
- return VTableComponent(CK_VCallOffset, Offset);
- }
-
- static VTableComponent MakeVBaseOffset(CharUnits Offset) {
- return VTableComponent(CK_VBaseOffset, Offset);
- }
-
- static VTableComponent MakeOffsetToTop(CharUnits Offset) {
- return VTableComponent(CK_OffsetToTop, Offset);
- }
-
- static VTableComponent MakeRTTI(const CXXRecordDecl *RD) {
- return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD));
- }
-
- static VTableComponent MakeFunction(const CXXMethodDecl *MD) {
- assert(!isa<CXXDestructorDecl>(MD) &&
- "Don't use MakeFunction with destructors!");
-
- return VTableComponent(CK_FunctionPointer,
- reinterpret_cast<uintptr_t>(MD));
- }
-
- static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) {
- return VTableComponent(CK_CompleteDtorPointer,
- reinterpret_cast<uintptr_t>(DD));
- }
-
- static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) {
- return VTableComponent(CK_DeletingDtorPointer,
- reinterpret_cast<uintptr_t>(DD));
- }
-
- static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD) {
- assert(!isa<CXXDestructorDecl>(MD) &&
- "Don't use MakeUnusedFunction with destructors!");
- return VTableComponent(CK_UnusedFunctionPointer,
- reinterpret_cast<uintptr_t>(MD));
- }
-
- static VTableComponent getFromOpaqueInteger(uint64_t I) {
- return VTableComponent(I);
- }
-
- /// \brief Get the kind of this vtable component.
- Kind getKind() const {
- return (Kind)(Value & 0x7);
- }
-
- CharUnits getVCallOffset() const {
- assert(getKind() == CK_VCallOffset && "Invalid component kind!");
-
- return getOffset();
- }
-
- CharUnits getVBaseOffset() const {
- assert(getKind() == CK_VBaseOffset && "Invalid component kind!");
-
- return getOffset();
- }
-
- CharUnits getOffsetToTop() const {
- assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
-
- return getOffset();
- }
-
- const CXXRecordDecl *getRTTIDecl() const {
- assert(isRTTIKind() && "Invalid component kind!");
- return reinterpret_cast<CXXRecordDecl *>(getPointer());
- }
-
- const CXXMethodDecl *getFunctionDecl() const {
- assert(isFunctionPointerKind() && "Invalid component kind!");
- if (isDestructorKind())
- return getDestructorDecl();
- return reinterpret_cast<CXXMethodDecl *>(getPointer());
- }
-
- const CXXDestructorDecl *getDestructorDecl() const {
- assert(isDestructorKind() && "Invalid component kind!");
- return reinterpret_cast<CXXDestructorDecl *>(getPointer());
- }
-
- const CXXMethodDecl *getUnusedFunctionDecl() const {
- assert(getKind() == CK_UnusedFunctionPointer && "Invalid component kind!");
- return reinterpret_cast<CXXMethodDecl *>(getPointer());
- }
-
- bool isDestructorKind() const { return isDestructorKind(getKind()); }
-
- bool isUsedFunctionPointerKind() const {
- return isUsedFunctionPointerKind(getKind());
- }
-
- bool isFunctionPointerKind() const {
- return isFunctionPointerKind(getKind());
- }
-
- bool isRTTIKind() const { return isRTTIKind(getKind()); }
-
-private:
- static bool isFunctionPointerKind(Kind ComponentKind) {
- return isUsedFunctionPointerKind(ComponentKind) ||
- ComponentKind == CK_UnusedFunctionPointer;
- }
- static bool isUsedFunctionPointerKind(Kind ComponentKind) {
- return ComponentKind == CK_FunctionPointer ||
- isDestructorKind(ComponentKind);
- }
- static bool isDestructorKind(Kind ComponentKind) {
- return ComponentKind == CK_CompleteDtorPointer ||
- ComponentKind == CK_DeletingDtorPointer;
- }
- static bool isRTTIKind(Kind ComponentKind) {
- return ComponentKind == CK_RTTI;
- }
-
- VTableComponent(Kind ComponentKind, CharUnits Offset) {
- assert((ComponentKind == CK_VCallOffset ||
- ComponentKind == CK_VBaseOffset ||
- ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
- assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!");
- assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!");
-
- Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind;
- }
-
- VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
- assert((isRTTIKind(ComponentKind) || isFunctionPointerKind(ComponentKind)) &&
- "Invalid component kind!");
-
- assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
-
- Value = Ptr | ComponentKind;
- }
-
- CharUnits getOffset() const {
- assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset ||
- getKind() == CK_OffsetToTop) && "Invalid component kind!");
-
- return CharUnits::fromQuantity(Value >> 3);
- }
-
- uintptr_t getPointer() const {
- assert((getKind() == CK_RTTI || isFunctionPointerKind()) &&
- "Invalid component kind!");
-
- 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.
- /// (The reason that we're not simply using a PointerIntPair here is that we
- /// need the offsets to be 64-bit, even when on a 32-bit machine).
- int64_t Value;
-};
-
-class VTableLayout {
-public:
- typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
-
- typedef const VTableComponent *vtable_component_iterator;
- typedef const VTableThunkTy *vtable_thunk_iterator;
- typedef llvm::iterator_range<vtable_component_iterator>
- vtable_component_range;
-
- typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
-
-private:
- uint64_t NumVTableComponents;
- std::unique_ptr<VTableComponent[]> VTableComponents;
-
- /// \brief Contains thunks needed by vtables, sorted by indices.
- uint64_t NumVTableThunks;
- std::unique_ptr<VTableThunkTy[]> VTableThunks;
-
- /// \brief Address points for all vtables.
- AddressPointsMapTy AddressPoints;
-
- bool IsMicrosoftABI;
-
-public:
- VTableLayout(uint64_t NumVTableComponents,
- const VTableComponent *VTableComponents,
- uint64_t NumVTableThunks,
- const VTableThunkTy *VTableThunks,
- const AddressPointsMapTy &AddressPoints,
- bool IsMicrosoftABI);
- ~VTableLayout();
-
- uint64_t getNumVTableComponents() const {
- return NumVTableComponents;
- }
-
- vtable_component_range vtable_components() const {
- return vtable_component_range(vtable_component_begin(),
- vtable_component_end());
- }
-
- vtable_component_iterator vtable_component_begin() const {
- return VTableComponents.get();
- }
-
- vtable_component_iterator vtable_component_end() const {
- return VTableComponents.get() + NumVTableComponents;
- }
-
- uint64_t getNumVTableThunks() const { return NumVTableThunks; }
-
- vtable_thunk_iterator vtable_thunk_begin() const {
- return VTableThunks.get();
- }
-
- vtable_thunk_iterator vtable_thunk_end() const {
- return VTableThunks.get() + NumVTableThunks;
- }
-
- uint64_t getAddressPoint(BaseSubobject Base) const {
- assert(AddressPoints.count(Base) &&
- "Did not find address point!");
-
- uint64_t AddressPoint = AddressPoints.lookup(Base);
- assert(AddressPoint != 0 || IsMicrosoftABI);
- (void)IsMicrosoftABI;
-
- return AddressPoint;
- }
-
- const AddressPointsMapTy &getAddressPoints() const {
- return AddressPoints;
- }
-};
-
-class VTableContextBase {
-public:
- typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
-
- bool isMicrosoft() const { return IsMicrosoftABI; }
-
- virtual ~VTableContextBase() {}
-
-protected:
- typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
-
- /// \brief Contains all thunks that a given method decl will need.
- ThunksMapTy Thunks;
-
- /// Compute and store all vtable related information (vtable layout, vbase
- /// offset offsets, thunks etc) for the given record decl.
- virtual void computeVTableRelatedInformation(const CXXRecordDecl *RD) = 0;
-
- VTableContextBase(bool MS) : IsMicrosoftABI(MS) {}
-
-public:
- virtual const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()->getCanonicalDecl());
- computeVTableRelatedInformation(MD->getParent());
-
- // This assumes that all the destructors present in the vtable
- // use exactly the same set of thunks.
- ThunksMapTy::const_iterator I = Thunks.find(MD);
- if (I == Thunks.end()) {
- // We did not find a thunk for this method.
- return nullptr;
- }
-
- return &I->second;
- }
-
- bool IsMicrosoftABI;
-};
-
-class ItaniumVTableContext : public VTableContextBase {
-private:
-
- /// \brief 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;
-
- typedef llvm::DenseMap<const CXXRecordDecl *, const VTableLayout *>
- VTableLayoutMapTy;
- VTableLayoutMapTy VTableLayouts;
-
- typedef std::pair<const CXXRecordDecl *,
- const CXXRecordDecl *> ClassPairTy;
-
- /// \brief 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.
- typedef llvm::DenseMap<ClassPairTy, CharUnits>
- VirtualBaseClassOffsetOffsetsMapTy;
- VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
-
- void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
-
-public:
- ItaniumVTableContext(ASTContext &Context);
- ~ItaniumVTableContext() override;
-
- const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) {
- computeVTableRelatedInformation(RD);
- assert(VTableLayouts.count(RD) && "No layout for this record decl!");
-
- return *VTableLayouts[RD];
- }
-
- VTableLayout *
- createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass,
- CharUnits MostDerivedClassOffset,
- bool MostDerivedClassIsVirtual,
- const CXXRecordDecl *LayoutClass);
-
- /// \brief 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.
- uint64_t getMethodVTableIndex(GlobalDecl GD);
-
- /// Return the offset in chars (relative to the vtable address point) where
- /// the offset of the virtual base that contains the given base is stored,
- /// otherwise, if no virtual base contains the given class, return 0.
- ///
- /// Base must be a virtual base class or an unambiguous base.
- CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
- const CXXRecordDecl *VBase);
-
- static bool classof(const VTableContextBase *VT) {
- return !VT->isMicrosoft();
- }
-};
-
-/// Holds information about the inheritance path to a virtual base or function
-/// table pointer. A record may contain as many vfptrs or vbptrs as there are
-/// base subobjects.
-struct VPtrInfo {
- typedef SmallVector<const CXXRecordDecl *, 1> BasePath;
-
- VPtrInfo(const CXXRecordDecl *RD)
- : ReusingBase(RD), BaseWithVPtr(RD), NextBaseToMangle(RD) {}
-
- /// The vtable will hold all of the virtual bases or virtual methods of
- /// ReusingBase. This may or may not be the same class as VPtrSubobject.Base.
- /// A derived class will reuse the vptr of the first non-virtual base
- /// subobject that has one.
- const CXXRecordDecl *ReusingBase;
-
- /// BaseWithVPtr is at this offset from its containing complete object or
- /// virtual base.
- CharUnits NonVirtualOffset;
-
- /// The vptr is stored inside this subobject.
- const CXXRecordDecl *BaseWithVPtr;
-
- /// The bases from the inheritance path that got used to mangle the vbtable
- /// name. This is not really a full path like a CXXBasePath. It holds the
- /// subset of records that need to be mangled into the vbtable symbol name in
- /// order to get a unique name.
- BasePath MangledPath;
-
- /// The next base to push onto the mangled path if this path is ambiguous in a
- /// derived class. If it's null, then it's already been pushed onto the path.
- const CXXRecordDecl *NextBaseToMangle;
-
- /// The set of possibly indirect vbases that contain this vbtable. When a
- /// derived class indirectly inherits from the same vbase twice, we only keep
- /// vtables and their paths from the first instance.
- BasePath ContainingVBases;
-
- /// This holds the base classes path from the complete type to the first base
- /// with the given vfptr offset, in the base-to-derived order. Only used for
- /// vftables.
- BasePath PathToBaseWithVPtr;
-
- /// Static offset from the top of the most derived class to this vfptr,
- /// including any virtual base offset. Only used for vftables.
- CharUnits FullOffsetInMDC;
-
- /// The vptr is stored inside the non-virtual component of this virtual base.
- const CXXRecordDecl *getVBaseWithVPtr() const {
- return ContainingVBases.empty() ? nullptr : ContainingVBases.front();
- }
-};
-
-typedef SmallVector<VPtrInfo *, 2> VPtrInfoVector;
-
-/// All virtual base related information about a given record decl. Includes
-/// information on all virtual base tables and the path components that are used
-/// to mangle them.
-struct VirtualBaseInfo {
- ~VirtualBaseInfo() { llvm::DeleteContainerPointers(VBPtrPaths); }
-
- /// A map from virtual base to vbtable index for doing a conversion from the
- /// the derived class to the a base.
- llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
-
- /// Information on all virtual base tables used when this record is the most
- /// derived class.
- VPtrInfoVector VBPtrPaths;
-};
-
-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;
-
- typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
- MethodVFTableLocationsTy;
- MethodVFTableLocationsTy MethodVFTableLocations;
-
- typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector *>
- VFPtrLocationsMapTy;
- VFPtrLocationsMapTy VFPtrLocations;
-
- typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
- typedef llvm::DenseMap<VFTableIdTy, const VTableLayout *> VFTableLayoutMapTy;
- VFTableLayoutMapTy VFTableLayouts;
-
- llvm::DenseMap<const CXXRecordDecl *, VirtualBaseInfo *> VBaseInfo;
-
- void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
-
- void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
-
- void dumpMethodLocations(const CXXRecordDecl *RD,
- const MethodVFTableLocationsTy &NewMethods,
- raw_ostream &);
-
- const VirtualBaseInfo *
- computeVBTableRelatedInformation(const CXXRecordDecl *RD);
-
- void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,
- VPtrInfoVector &Paths);
-
-public:
- MicrosoftVTableContext(ASTContext &Context)
- : VTableContextBase(/*MS=*/true), Context(Context) {}
-
- ~MicrosoftVTableContext() override;
-
- const VPtrInfoVector &getVFPtrOffsets(const CXXRecordDecl *RD);
-
- const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD,
- CharUnits VFPtrOffset);
-
- const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD);
-
- const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) override {
- // Complete destructors don't have a slot in a vftable, so no thunks needed.
- if (isa<CXXDestructorDecl>(GD.getDecl()) &&
- GD.getDtorType() == Dtor_Complete)
- return nullptr;
- return VTableContextBase::getThunkInfo(GD);
- }
-
- /// \brief 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.
- unsigned getVBTableIndex(const CXXRecordDecl *Derived,
- const CXXRecordDecl *VBase);
-
- const VPtrInfoVector &enumerateVBTables(const CXXRecordDecl *RD);
-
- static bool classof(const VTableContextBase *VT) { return VT->isMicrosoft(); }
-};
-
-} // namespace clang
-
-#endif
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
deleted file mode 100644
index 92ec92c..0000000
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ /dev/null
@@ -1,294 +0,0 @@
-//===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Provides a way to construct an ASTConsumer that runs given matchers
-// over the AST and invokes a given callback on every match.
-//
-// The general idea is to construct a matcher expression that describes a
-// subtree match on the AST. Next, a callback that is executed every time the
-// expression matches is registered, and the matcher is run over the AST of
-// some code. Matched subexpressions can be bound to string IDs and easily
-// be accessed from the registered callback. The callback can than use the
-// AST nodes that the subexpressions matched on to output information about
-// the match or construct changes that can be applied to the code.
-//
-// Example:
-// class HandleMatch : public MatchFinder::MatchCallback {
-// public:
-// virtual void Run(const MatchFinder::MatchResult &Result) {
-// const CXXRecordDecl *Class =
-// Result.Nodes.GetDeclAs<CXXRecordDecl>("id");
-// ...
-// }
-// };
-//
-// int main(int argc, char **argv) {
-// ClangTool Tool(argc, argv);
-// MatchFinder finder;
-// finder.AddMatcher(Id("id", record(hasName("::a_namespace::AClass"))),
-// new HandleMatch);
-// return Tool.Run(newFrontendActionFactory(&finder));
-// }
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H
-#define LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H
-
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/Timer.h"
-
-namespace clang {
-
-namespace ast_matchers {
-
-/// \brief A class to allow finding matches over the Clang AST.
-///
-/// After creation, you can add multiple matchers to the MatchFinder via
-/// calls to addMatcher(...).
-///
-/// Once all matchers are added, newASTConsumer() returns an ASTConsumer
-/// that will trigger the callbacks specified via addMatcher(...) when a match
-/// is found.
-///
-/// The order of matches is guaranteed to be equivalent to doing a pre-order
-/// traversal on the AST, and applying the matchers in the order in which they
-/// were added to the MatchFinder.
-///
-/// See ASTMatchers.h for more information about how to create matchers.
-///
-/// Not intended to be subclassed.
-class MatchFinder {
-public:
- /// \brief 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.
- ///
- /// This allows user code to easily extract matched AST nodes.
- const BoundNodes Nodes;
-
- /// \brief 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
- /// in the AST.
- class MatchCallback {
- public:
- virtual ~MatchCallback();
-
- /// \brief Called on every match by the \c MatchFinder.
- virtual void run(const MatchResult &Result) = 0;
-
- /// \brief 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.
- ///
- /// Optionally override to do per translation unit tasks.
- virtual void onEndOfTranslationUnit() {}
-
- /// \brief 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.
- class ParsingDoneTestCallback {
- public:
- virtual ~ParsingDoneTestCallback();
- virtual void run() = 0;
- };
-
- struct MatchFinderOptions {
- struct Profiling {
- Profiling(llvm::StringMap<llvm::TimeRecord> &Records)
- : Records(Records) {}
-
- /// \brief Per bucket timing information.
- llvm::StringMap<llvm::TimeRecord> &Records;
- };
-
- /// \brief Enables per-check timers.
- ///
- /// It prints a report after match.
- llvm::Optional<Profiling> CheckProfiling;
- };
-
- MatchFinder(MatchFinderOptions Options = MatchFinderOptions());
- ~MatchFinder();
-
- /// \brief 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
- /// single pass over the AST.
- ///
- /// Does not take ownership of 'Action'.
- /// @{
- void addMatcher(const DeclarationMatcher &NodeMatch,
- MatchCallback *Action);
- void addMatcher(const TypeMatcher &NodeMatch,
- MatchCallback *Action);
- void addMatcher(const StatementMatcher &NodeMatch,
- MatchCallback *Action);
- void addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
- MatchCallback *Action);
- void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
- MatchCallback *Action);
- void addMatcher(const TypeLocMatcher &NodeMatch,
- MatchCallback *Action);
- /// @}
-
- /// \brief 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
- /// a matcher that cannot match anything.
- ///
- /// \returns \c true if the matcher is a valid top-level matcher, \c false
- /// otherwise.
- bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
- MatchCallback *Action);
-
- /// \brief 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.
- ///
- /// Note that there can be multiple matches on a single node, for
- /// example when using decl(forEachDescendant(stmt())).
- ///
- /// @{
- template <typename T> void match(const T &Node, ASTContext &Context) {
- match(clang::ast_type_traits::DynTypedNode::create(Node), Context);
- }
- void match(const clang::ast_type_traits::DynTypedNode &Node,
- ASTContext &Context);
- /// @}
-
- /// \brief Finds all matches in the given AST.
- void matchAST(ASTContext &Context);
-
- /// \brief 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
- /// when it matches.
- struct MatchersByType {
- std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *>>
- DeclOrStmt;
- std::vector<std::pair<TypeMatcher, MatchCallback *>> Type;
- std::vector<std::pair<NestedNameSpecifierMatcher, MatchCallback *>>
- NestedNameSpecifier;
- std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>>
- NestedNameSpecifierLoc;
- std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
- /// \brief All the callbacks in one container to simplify iteration.
- llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
- };
-
-private:
- MatchersByType Matchers;
-
- MatchFinderOptions Options;
-
- /// \brief Called when parsing is done.
- ParsingDoneTestCallback *ParsingDone;
-};
-
-/// \brief 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.
-///
-/// Multiple results occur when using matchers like \c forEachDescendant,
-/// which generate a result for each sub-match.
-///
-/// \see selectFirst
-/// @{
-template <typename MatcherT, typename NodeT>
-SmallVector<BoundNodes, 1>
-match(MatcherT Matcher, const NodeT &Node, ASTContext &Context);
-
-template <typename MatcherT>
-SmallVector<BoundNodes, 1>
-match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
- ASTContext &Context);
-/// @}
-
-/// \brief 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.
-///
-/// This is useful in combanation with \c match():
-/// \code
-/// const Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
-/// Node, Context));
-/// \endcode
-template <typename NodeT>
-const NodeT *
-selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) {
- for (const BoundNodes &N : Results) {
- if (const NodeT *Node = N.getNodeAs<NodeT>(BoundTo))
- return Node;
- }
- return nullptr;
-}
-
-namespace internal {
-class CollectMatchesCallback : public MatchFinder::MatchCallback {
-public:
- void run(const MatchFinder::MatchResult &Result) override {
- Nodes.push_back(Result.Nodes);
- }
- SmallVector<BoundNodes, 1> Nodes;
-};
-}
-
-template <typename MatcherT>
-SmallVector<BoundNodes, 1>
-match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
- ASTContext &Context) {
- internal::CollectMatchesCallback Callback;
- MatchFinder Finder;
- Finder.addMatcher(Matcher, &Callback);
- Finder.match(Node, Context);
- return std::move(Callback.Nodes);
-}
-
-template <typename MatcherT, typename NodeT>
-SmallVector<BoundNodes, 1>
-match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
- return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context);
-}
-
-} // end namespace ast_matchers
-} // end namespace clang
-
-#endif
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
deleted file mode 100644
index e6ba877..0000000
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ /dev/null
@@ -1,4671 +0,0 @@
-//===--- ASTMatchers.h - Structural query framework -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements matchers to be used together with the MatchFinder to
-// match AST nodes.
-//
-// Matchers are created by generator functions, which can be combined in
-// a functional in-language DSL to express queries over the C++ AST.
-//
-// For example, to match a class with a certain name, one would call:
-// cxxRecordDecl(hasName("MyClass"))
-// which returns a matcher that can be used to find all AST nodes that declare
-// a class named 'MyClass'.
-//
-// For more complicated match expressions we're often interested in accessing
-// multiple parts of the matched AST nodes once a match is found. In that case,
-// use the id(...) matcher around the match expressions that match the nodes
-// you want to access.
-//
-// For example, when we're interested in child classes of a certain class, we
-// would write:
-// cxxRecordDecl(hasName("MyClass"), hasChild(id("child", recordDecl())))
-// When the match is found via the MatchFinder, a user provided callback will
-// be called with a BoundNodes instance that contains a mapping from the
-// strings that we provided for the id(...) calls to the nodes that were
-// matched.
-// In the given example, each time our matcher finds a match we get a callback
-// where "child" is bound to the RecordDecl node of the matching child
-// class declaration.
-//
-// See ASTMatchersInternal.h for a more in-depth explanation of the
-// implementation details of the matcher framework.
-//
-// See ASTMatchFinder.h for how to use the generated matchers to run over
-// an AST.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
-#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "clang/ASTMatchers/ASTMatchersMacros.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/Regex.h"
-#include <iterator>
-
-namespace clang {
-namespace ast_matchers {
-
-/// \brief 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.
-///
-/// The instances of BoundNodes are created by \c MatchFinder when the user's
-/// callbacks are executed every time a match is found.
-class BoundNodes {
-public:
- /// \brief 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.
- template <typename T>
- const T *getNodeAs(StringRef ID) const {
- return MyBoundNodes.getNodeAs<T>(ID);
- }
-
- /// \brief Deprecated. Please use \c getNodeAs instead.
- /// @{
- template <typename T>
- const T *getDeclAs(StringRef ID) const {
- return getNodeAs<T>(ID);
- }
- template <typename T>
- const T *getStmtAs(StringRef ID) const {
- return getNodeAs<T>(ID);
- }
- /// @}
-
- /// \brief 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
- typedef internal::BoundNodesMap::IDToNodeMap IDToNodeMap;
-
- /// \brief Retrieve mapping from binding identifiers to bound nodes.
- const IDToNodeMap &getMap() const {
- return MyBoundNodes.getMap();
- }
-
-private:
- /// \brief Create BoundNodes from a pre-filled map of bindings.
- BoundNodes(internal::BoundNodesMap &MyBoundNodes)
- : MyBoundNodes(MyBoundNodes) {}
-
- internal::BoundNodesMap MyBoundNodes;
-
- friend class internal::BoundNodesTreeBuilder;
-};
-
-/// \brief 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>
-internal::Matcher<T> id(StringRef ID,
- const internal::BindableMatcher<T> &InnerMatcher) {
- return InnerMatcher.bind(ID);
-}
-
-/// \brief Types of matchers for the top-level classes in the AST class
-/// hierarchy.
-/// @{
-typedef internal::Matcher<Decl> DeclarationMatcher;
-typedef internal::Matcher<Stmt> StatementMatcher;
-typedef internal::Matcher<QualType> TypeMatcher;
-typedef internal::Matcher<TypeLoc> TypeLocMatcher;
-typedef internal::Matcher<NestedNameSpecifier> NestedNameSpecifierMatcher;
-typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher;
-/// @}
-
-/// \brief 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
-/// to an \c internal::Matcher<> type such as \c TypeMatcher.
-///
-/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
-/// \code
-/// "int* p" and "void f()" in
-/// int* p;
-/// void f();
-/// \endcode
-///
-/// Usable as: Any Matcher
-inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
-
-/// \brief Matches the top declaration context.
-///
-/// Given
-/// \code
-/// int X;
-/// namespace NS {
-/// int Y;
-/// } // namespace NS
-/// \endcode
-/// decl(hasDeclContext(translationUnitDecl()))
-/// matches "int X", but not "int Y".
-const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
- translationUnitDecl;
-
-/// \brief Matches typedef declarations.
-///
-/// Given
-/// \code
-/// typedef int X;
-/// \endcode
-/// typedefDecl()
-/// matches "typedef int X"
-const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
-
-/// \brief Matches AST nodes that were expanded within the main-file.
-///
-/// Example matches X but not Y
-/// (matcher = cxxRecordDecl(isExpansionInMainFile())
-/// \code
-/// #include <Y.h>
-/// class X {};
-/// \endcode
-/// Y.h:
-/// \code
-/// class Y {};
-/// \endcode
-///
-/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
- AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
- auto &SourceManager = Finder->getASTContext().getSourceManager();
- return SourceManager.isInMainFile(
- SourceManager.getExpansionLoc(Node.getLocStart()));
-}
-
-/// \brief Matches AST nodes that were expanded within system-header-files.
-///
-/// Example matches Y but not X
-/// (matcher = cxxRecordDecl(isExpansionInSystemHeader())
-/// \code
-/// #include <SystemHeader.h>
-/// class X {};
-/// \endcode
-/// SystemHeader.h:
-/// \code
-/// class Y {};
-/// \endcode
-///
-/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
- AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
- auto &SourceManager = Finder->getASTContext().getSourceManager();
- auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
- if (ExpansionLoc.isInvalid()) {
- return false;
- }
- return SourceManager.isInSystemHeader(ExpansionLoc);
-}
-
-/// \brief Matches AST nodes that were expanded within files whose name is
-/// partially matching a given regex.
-///
-/// Example matches Y but not X
-/// (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
-/// \code
-/// #include "ASTMatcher.h"
-/// class X {};
-/// \endcode
-/// ASTMatcher.h:
-/// \code
-/// class Y {};
-/// \endcode
-///
-/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
- AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
- std::string, RegExp) {
- auto &SourceManager = Finder->getASTContext().getSourceManager();
- auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
- if (ExpansionLoc.isInvalid()) {
- return false;
- }
- auto FileEntry =
- SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
- if (!FileEntry) {
- return false;
- }
-
- auto Filename = FileEntry->getName();
- llvm::Regex RE(RegExp);
- return RE.match(Filename);
-}
-
-/// \brief Matches declarations.
-///
-/// Examples matches \c X, \c C, and the friend declaration inside \c C;
-/// \code
-/// void X();
-/// class C {
-/// friend X;
-/// };
-/// \endcode
-const internal::VariadicAllOfMatcher<Decl> decl;
-
-/// \brief Matches a declaration of a linkage specification.
-///
-/// Given
-/// \code
-/// extern "C" {}
-/// \endcode
-/// linkageSpecDecl()
-/// matches "extern "C" {}"
-const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
- linkageSpecDecl;
-
-/// \brief 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
-/// typedef int X;
-/// struct S {
-/// union {
-/// int i;
-/// } U;
-/// };
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
-
-/// \brief Matches a declaration of a namespace.
-///
-/// Given
-/// \code
-/// namespace {}
-/// namespace test {}
-/// \endcode
-/// namespaceDecl()
-/// matches "namespace {}" and "namespace test {}"
-const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
-
-/// \brief Matches a declaration of a namespace alias.
-///
-/// Given
-/// \code
-/// namespace test {}
-/// namespace alias = ::test;
-/// \endcode
-/// namespaceAliasDecl()
-/// matches "namespace alias" but not "namespace test"
-const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
- namespaceAliasDecl;
-
-/// \brief Matches class, struct, and union declarations.
-///
-/// Example matches \c X, \c Z, \c U, and \c S
-/// \code
-/// class X;
-/// template<class T> class Z {};
-/// struct S {};
-/// union U {};
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- RecordDecl> recordDecl;
-
-/// \brief Matches C++ class declarations.
-///
-/// Example matches \c X, \c Z
-/// \code
-/// class X;
-/// template<class T> class Z {};
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- CXXRecordDecl> cxxRecordDecl;
-
-/// \brief Matches C++ class template declarations.
-///
-/// Example matches \c Z
-/// \code
-/// template<class T> class Z {};
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ClassTemplateDecl> classTemplateDecl;
-
-/// \brief Matches C++ class template specializations.
-///
-/// Given
-/// \code
-/// template<typename T> class A {};
-/// template<> class A<double> {};
-/// A<int> a;
-/// \endcode
-/// classTemplateSpecializationDecl()
-/// matches the specializations \c A<int> and \c A<double>
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ClassTemplateSpecializationDecl> classTemplateSpecializationDecl;
-
-/// \brief Matches declarator declarations (field, variable, function
-/// and non-type template parameter declarations).
-///
-/// Given
-/// \code
-/// class X { int y; };
-/// \endcode
-/// declaratorDecl()
-/// matches \c int y.
-const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
- declaratorDecl;
-
-/// \brief Matches parameter variable declarations.
-///
-/// Given
-/// \code
-/// void f(int x);
-/// \endcode
-/// parmVarDecl()
-/// matches \c int x.
-const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
-
-/// \brief Matches C++ access specifier declarations.
-///
-/// Given
-/// \code
-/// class C {
-/// public:
-/// int a;
-/// };
-/// \endcode
-/// accessSpecDecl()
-/// matches 'public:'
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- AccessSpecDecl> accessSpecDecl;
-
-/// \brief Matches constructor initializers.
-///
-/// Examples matches \c i(42).
-/// \code
-/// class C {
-/// C() : i(42) {}
-/// int i;
-/// };
-/// \endcode
-const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
-
-/// \brief Matches template arguments.
-///
-/// Given
-/// \code
-/// template <typename T> struct C {};
-/// C<int> c;
-/// \endcode
-/// templateArgument()
-/// matches 'int' in C<int>.
-const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
-
-/// \brief Matches non-type template parameter declarations.
-///
-/// Given
-/// \code
-/// template <typename T, int N> struct C {};
-/// \endcode
-/// nonTypeTemplateParmDecl()
-/// matches 'N', but not 'T'.
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- NonTypeTemplateParmDecl> nonTypeTemplateParmDecl;
-
-/// \brief Matches template type parameter declarations.
-///
-/// Given
-/// \code
-/// template <typename T, int N> struct C {};
-/// \endcode
-/// templateTypeParmDecl()
-/// matches 'T', but not 'N'.
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- TemplateTypeParmDecl> templateTypeParmDecl;
-
-/// \brief Matches public C++ declarations.
-///
-/// Given
-/// \code
-/// class C {
-/// public: int a;
-/// protected: int b;
-/// private: int c;
-/// };
-/// \endcode
-/// fieldDecl(isPublic())
-/// matches 'int a;'
-AST_MATCHER(Decl, isPublic) {
- return Node.getAccess() == AS_public;
-}
-
-/// \brief Matches protected C++ declarations.
-///
-/// Given
-/// \code
-/// class C {
-/// public: int a;
-/// protected: int b;
-/// private: int c;
-/// };
-/// \endcode
-/// fieldDecl(isProtected())
-/// matches 'int b;'
-AST_MATCHER(Decl, isProtected) {
- return Node.getAccess() == AS_protected;
-}
-
-/// \brief Matches private C++ declarations.
-///
-/// Given
-/// \code
-/// class C {
-/// public: int a;
-/// protected: int b;
-/// private: int c;
-/// };
-/// \endcode
-/// fieldDecl(isPrivate())
-/// matches 'int c;'
-AST_MATCHER(Decl, isPrivate) {
- return Node.getAccess() == AS_private;
-}
-
-/// \brief 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 that have at least one
-/// TemplateArgument matching the given InnerMatcher.
-///
-/// Given
-/// \code
-/// template<typename T> class A {};
-/// template<> class A<double> {};
-/// A<int> a;
-/// \endcode
-/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToType(asString("int"))))
-/// matches the specialization \c A<int>
-AST_POLYMORPHIC_MATCHER_P(
- hasAnyTemplateArgument,
- AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
- TemplateSpecializationType),
- internal::Matcher<TemplateArgument>, InnerMatcher) {
- ArrayRef<TemplateArgument> List =
- internal::getTemplateSpecializationArgs(Node);
- return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
- Builder);
-}
-
-/// \brief Matches expressions that match InnerMatcher after any implicit casts
-/// are stripped off.
-///
-/// Parentheses and explicit casts are not discarded.
-/// Given
-/// \code
-/// int arr[5];
-/// int a = 0;
-/// char b = 0;
-/// const int c = a;
-/// int *d = arr;
-/// long e = (long) 0l;
-/// \endcode
-/// The matchers
-/// \code
-/// varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))
-/// varDecl(hasInitializer(ignoringImpCasts(declRefExpr())))
-/// \endcode
-/// would match the declarations for a, b, c, and d, but not e.
-/// While
-/// \code
-/// varDecl(hasInitializer(integerLiteral()))
-/// varDecl(hasInitializer(declRefExpr()))
-/// \endcode
-/// only match the declarations for b, c, and d.
-AST_MATCHER_P(Expr, ignoringImpCasts,
- internal::Matcher<Expr>, InnerMatcher) {
- return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
-}
-
-/// \brief Matches expressions that match InnerMatcher after parentheses and
-/// casts are stripped off.
-///
-/// Implicit and non-C Style casts are also discarded.
-/// Given
-/// \code
-/// int a = 0;
-/// char b = (0);
-/// void* c = reinterpret_cast<char*>(0);
-/// char d = char(0);
-/// \endcode
-/// The matcher
-/// varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))
-/// would match the declarations for a, b, c, and d.
-/// while
-/// varDecl(hasInitializer(integerLiteral()))
-/// only match the declaration for a.
-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
-/// parentheses are stripped off.
-///
-/// Explicit casts are not discarded.
-/// Given
-/// \code
-/// int arr[5];
-/// int a = 0;
-/// char b = (0);
-/// const int c = a;
-/// int *d = (arr);
-/// long e = ((long) 0l);
-/// \endcode
-/// The matchers
-/// varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral())))
-/// varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr())))
-/// would match the declarations for a, b, c, and d, but not e.
-/// while
-/// varDecl(hasInitializer(integerLiteral()))
-/// varDecl(hasInitializer(declRefExpr()))
-/// would only match the declaration for a.
-AST_MATCHER_P(Expr, ignoringParenImpCasts,
- internal::Matcher<Expr>, InnerMatcher) {
- return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
-}
-
-/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
-/// matches the given InnerMatcher.
-///
-/// Given
-/// \code
-/// template<typename T, typename U> class A {};
-/// A<bool, int> b;
-/// A<int, bool> c;
-/// \endcode
-/// classTemplateSpecializationDecl(hasTemplateArgument(
-/// 1, refersToType(asString("int"))))
-/// matches the specialization \c A<bool, int>
-AST_POLYMORPHIC_MATCHER_P2(
- hasTemplateArgument,
- AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
- TemplateSpecializationType),
- unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
- ArrayRef<TemplateArgument> List =
- internal::getTemplateSpecializationArgs(Node);
- if (List.size() <= N)
- return false;
- return InnerMatcher.matches(List[N], Finder, Builder);
-}
-
-/// \brief Matches if the number of template arguments equals \p N.
-///
-/// Given
-/// \code
-/// template<typename T> struct C {};
-/// C<int> c;
-/// \endcode
-/// classTemplateSpecializationDecl(templateArgumentCountIs(1))
-/// matches C<int>.
-AST_POLYMORPHIC_MATCHER_P(
- templateArgumentCountIs,
- AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
- TemplateSpecializationType),
- unsigned, N) {
- return internal::getTemplateSpecializationArgs(Node).size() == N;
-}
-
-/// \brief Matches a TemplateArgument that refers to a certain type.
-///
-/// Given
-/// \code
-/// struct X {};
-/// template<typename T> struct A {};
-/// A<X> a;
-/// \endcode
-/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToType(class(hasName("X")))))
-/// matches the specialization \c A<X>
-AST_MATCHER_P(TemplateArgument, refersToType,
- internal::Matcher<QualType>, InnerMatcher) {
- if (Node.getKind() != TemplateArgument::Type)
- return false;
- return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
-}
-
-/// \brief Matches a canonical TemplateArgument that refers to a certain
-/// declaration.
-///
-/// Given
-/// \code
-/// template<typename T> struct A {};
-/// struct B { B* next; };
-/// A<&B::next> a;
-/// \endcode
-/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToDeclaration(fieldDecl(hasName("next"))))
-/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
-/// \c B::next
-AST_MATCHER_P(TemplateArgument, refersToDeclaration,
- internal::Matcher<Decl>, InnerMatcher) {
- if (Node.getKind() == TemplateArgument::Declaration)
- return InnerMatcher.matches(*Node.getAsDecl(), Finder, Builder);
- return false;
-}
-
-/// \brief Matches a sugar TemplateArgument that refers to a certain expression.
-///
-/// Given
-/// \code
-/// template<typename T> struct A {};
-/// struct B { B* next; };
-/// A<&B::next> a;
-/// \endcode
-/// templateSpecializationType(hasAnyTemplateArgument(
-/// isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
-/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
-/// \c B::next
-AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher) {
- if (Node.getKind() == TemplateArgument::Expression)
- return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
- return false;
-}
-
-/// \brief Matches a TemplateArgument that is an integral value.
-///
-/// Given
-/// \code
-/// template<int T> struct A {};
-/// C<42> c;
-/// \endcode
-/// classTemplateSpecializationDecl(
-/// hasAnyTemplateArgument(isIntegral()))
-/// matches the implicit instantiation of C in C<42>
-/// with isIntegral() matching 42.
-AST_MATCHER(TemplateArgument, isIntegral) {
- return Node.getKind() == TemplateArgument::Integral;
-}
-
-/// \brief Matches a TemplateArgument that referes to an integral type.
-///
-/// Given
-/// \code
-/// template<int T> struct A {};
-/// C<42> c;
-/// \endcode
-/// classTemplateSpecializationDecl(
-/// hasAnyTemplateArgument(refersToIntegralType(asString("int"))))
-/// matches the implicit instantiation of C in C<42>.
-AST_MATCHER_P(TemplateArgument, refersToIntegralType,
- internal::Matcher<QualType>, InnerMatcher) {
- if (Node.getKind() != TemplateArgument::Integral)
- return false;
- return InnerMatcher.matches(Node.getIntegralType(), Finder, Builder);
-}
-
-/// \brief 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
-/// representation of that integral value in base 10.
-///
-/// Given
-/// \code
-/// template<int T> struct A {};
-/// C<42> c;
-/// \endcode
-/// classTemplateSpecializationDecl(
-/// hasAnyTemplateArgument(equalsIntegralValue("42")))
-/// matches the implicit instantiation of C in C<42>.
-AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
- std::string, Value) {
- if (Node.getKind() != TemplateArgument::Integral)
- return false;
- return Node.getAsIntegral().toString(10) == Value;
-}
-
-/// \brief Matches any value declaration.
-///
-/// Example matches A, B, C and F
-/// \code
-/// enum X { A, B, C };
-/// void F();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
-
-/// \brief Matches C++ constructor declarations.
-///
-/// Example matches Foo::Foo() and Foo::Foo(int)
-/// \code
-/// class Foo {
-/// public:
-/// Foo();
-/// Foo(int);
-/// int DoSomething();
-/// };
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- CXXConstructorDecl> cxxConstructorDecl;
-
-/// \brief Matches explicit C++ destructor declarations.
-///
-/// Example matches Foo::~Foo()
-/// \code
-/// class Foo {
-/// public:
-/// virtual ~Foo();
-/// };
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- CXXDestructorDecl> cxxDestructorDecl;
-
-/// \brief Matches enum declarations.
-///
-/// Example matches X
-/// \code
-/// enum X {
-/// A, B, C
-/// };
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
-
-/// \brief Matches enum constants.
-///
-/// Example matches A, B, C
-/// \code
-/// enum X {
-/// A, B, C
-/// };
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- EnumConstantDecl> enumConstantDecl;
-
-/// \brief Matches method declarations.
-///
-/// Example matches y
-/// \code
-/// class X { void y(); };
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
-
-/// \brief Matches conversion operator declarations.
-///
-/// Example matches the operator.
-/// \code
-/// class X { operator int() const; };
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
- cxxConversionDecl;
-
-/// \brief Matches variable declarations.
-///
-/// Note: this does not match declarations of member variables, which are
-/// "field" declarations in Clang parlance.
-///
-/// Example matches a
-/// \code
-/// int a;
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
-
-/// \brief Matches field declarations.
-///
-/// Given
-/// \code
-/// class X { int m; };
-/// \endcode
-/// fieldDecl()
-/// matches 'm'.
-const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
-
-/// \brief Matches function declarations.
-///
-/// Example matches f
-/// \code
-/// void f();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
-
-/// \brief Matches C++ function template declarations.
-///
-/// Example matches f
-/// \code
-/// template<class T> void f(T t) {}
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- FunctionTemplateDecl> functionTemplateDecl;
-
-/// \brief Matches friend declarations.
-///
-/// Given
-/// \code
-/// class X { friend void foo(); };
-/// \endcode
-/// friendDecl()
-/// matches 'friend void foo()'.
-const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
-
-/// \brief Matches statements.
-///
-/// Given
-/// \code
-/// { ++a; }
-/// \endcode
-/// stmt()
-/// matches both the compound statement '{ ++a; }' and '++a'.
-const internal::VariadicAllOfMatcher<Stmt> stmt;
-
-/// \brief Matches declaration statements.
-///
-/// Given
-/// \code
-/// int a;
-/// \endcode
-/// declStmt()
-/// matches 'int a'.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- DeclStmt> declStmt;
-
-/// \brief Matches member expressions.
-///
-/// Given
-/// \code
-/// class Y {
-/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
-/// int a; static int b;
-/// };
-/// \endcode
-/// memberExpr()
-/// matches this->x, x, y.x, a, this->b
-const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
-
-/// \brief Matches call expressions.
-///
-/// Example matches x.y() and y()
-/// \code
-/// X x;
-/// x.y();
-/// y();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
-
-/// \brief Matches lambda expressions.
-///
-/// Example matches [&](){return 5;}
-/// \code
-/// [&](){return 5;}
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
-
-/// \brief Matches member call expressions.
-///
-/// Example matches x.y()
-/// \code
-/// X x;
-/// x.y();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXMemberCallExpr> cxxMemberCallExpr;
-
-/// \brief 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
-/// "initWithString" instance method on the object returned from
-/// NSString's "alloc". This matcher should match both message sends.
-/// \code
-/// [[NSString alloc] initWithString:@"Hello"]
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ObjCMessageExpr> objcMessageExpr;
-
-/// \brief Matches Objective-C interface declarations.
-///
-/// Example matches Foo
-/// \code
-/// @interface Foo
-/// @end
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ObjCInterfaceDecl> objcInterfaceDecl;
-
-/// \brief Matches expressions that introduce cleanups to be run at the end
-/// of the sub-expression's evaluation.
-///
-/// Example matches std::string()
-/// \code
-/// const std::string str = std::string();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ExprWithCleanups> exprWithCleanups;
-
-/// \brief Matches init list expressions.
-///
-/// Given
-/// \code
-/// int a[] = { 1, 2 };
-/// struct B { int x, y; };
-/// B b = { 5, 6 };
-/// \endcode
-/// initListExpr()
-/// matches "{ 1, 2 }" and "{ 5, 6 }"
-const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
-
-/// \brief Matches substitutions of non-type template parameters.
-///
-/// Given
-/// \code
-/// template <int N>
-/// struct A { static const int n = N; };
-/// struct B : public A<42> {};
-/// \endcode
-/// substNonTypeTemplateParmExpr()
-/// matches "N" in the right-hand side of "static const int n = N;"
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- SubstNonTypeTemplateParmExpr> substNonTypeTemplateParmExpr;
-
-/// \brief Matches using declarations.
-///
-/// Given
-/// \code
-/// namespace X { int x; }
-/// using X::x;
-/// \endcode
-/// usingDecl()
-/// matches \code using X::x \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
-
-/// \brief Matches using namespace declarations.
-///
-/// Given
-/// \code
-/// namespace X { int x; }
-/// using namespace X;
-/// \endcode
-/// usingDirectiveDecl()
-/// matches \code using namespace X \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- UsingDirectiveDecl> usingDirectiveDecl;
-
-/// \brief Matches unresolved using value declarations.
-///
-/// Given
-/// \code
-/// template<typename X>
-/// class C : private X {
-/// using X::x;
-/// };
-/// \endcode
-/// unresolvedUsingValueDecl()
-/// matches \code using X::x \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- UnresolvedUsingValueDecl> unresolvedUsingValueDecl;
-
-/// \brief Matches unresolved using value declarations that involve the
-/// typename.
-///
-/// Given
-/// \code
-/// template <typename T>
-/// struct Base { typedef T Foo; };
-///
-/// template<typename T>
-/// struct S : private Base<T> {
-/// using typename Base<T>::Foo;
-/// };
-/// \endcode
-/// unresolvedUsingTypenameDecl()
-/// matches \code using Base<T>::Foo \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl;
-
-/// \brief Matches constructor call expressions (including implicit ones).
-///
-/// Example matches string(ptr, n) and ptr within arguments of f
-/// (matcher = cxxConstructExpr())
-/// \code
-/// void f(const string &a, const string &b);
-/// char *ptr;
-/// int n;
-/// f(string(ptr, n), ptr);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXConstructExpr> cxxConstructExpr;
-
-/// \brief Matches unresolved constructor call expressions.
-///
-/// Example matches T(t) in return statement of f
-/// (matcher = cxxUnresolvedConstructExpr())
-/// \code
-/// template <typename T>
-/// void f(const T& t) { return T(t); }
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXUnresolvedConstructExpr> cxxUnresolvedConstructExpr;
-
-/// \brief Matches implicit and explicit this expressions.
-///
-/// Example matches the implicit this expression in "return i".
-/// (matcher = cxxThisExpr())
-/// \code
-/// struct foo {
-/// int i;
-/// int f() { return i; }
-/// };
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
-
-/// \brief Matches nodes where temporaries are created.
-///
-/// Example matches FunctionTakesString(GetStringByValue())
-/// (matcher = cxxBindTemporaryExpr())
-/// \code
-/// FunctionTakesString(GetStringByValue());
-/// FunctionTakesStringByPointer(GetStringPointer());
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXBindTemporaryExpr> cxxBindTemporaryExpr;
-
-/// \brief Matches nodes where temporaries are materialized.
-///
-/// Example: Given
-/// \code
-/// struct T {void func()};
-/// T f();
-/// void g(T);
-/// \endcode
-/// materializeTemporaryExpr() matches 'f()' in these statements
-/// \code
-/// T u(f());
-/// g(f());
-/// \endcode
-/// but does not match
-/// \code
-/// f();
-/// f().func();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- MaterializeTemporaryExpr> materializeTemporaryExpr;
-
-/// \brief Matches new expressions.
-///
-/// Given
-/// \code
-/// new X;
-/// \endcode
-/// cxxNewExpr()
-/// matches 'new X'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
-
-/// \brief Matches delete expressions.
-///
-/// Given
-/// \code
-/// delete X;
-/// \endcode
-/// cxxDeleteExpr()
-/// matches 'delete X'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
-
-/// \brief Matches array subscript expressions.
-///
-/// Given
-/// \code
-/// int i = a[1];
-/// \endcode
-/// arraySubscriptExpr()
-/// matches "a[1]"
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ArraySubscriptExpr> arraySubscriptExpr;
-
-/// \brief 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)
-/// (matcher = cxxDefaultArgExpr())
-/// \code
-/// void f(int x, int y = 0);
-/// f(42);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXDefaultArgExpr> cxxDefaultArgExpr;
-
-/// \brief Matches overloaded operator calls.
-///
-/// Note that if an operator isn't overloaded, it won't match. Instead, use
-/// binaryOperator matcher.
-/// Currently it does not match operators such as new delete.
-/// FIXME: figure out why these do not match?
-///
-/// Example matches both operator<<((o << b), c) and operator<<(o, b)
-/// (matcher = cxxOperatorCallExpr())
-/// \code
-/// ostream &operator<< (ostream &out, int i) { };
-/// ostream &o; int b = 1, c = 1;
-/// o << b << c;
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXOperatorCallExpr> cxxOperatorCallExpr;
-
-/// \brief Matches expressions.
-///
-/// Example matches x()
-/// \code
-/// void f() { x(); }
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
-
-/// \brief Matches expressions that refer to declarations.
-///
-/// Example matches x in if (x)
-/// \code
-/// bool x;
-/// if (x) {}
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
-
-/// \brief Matches if statements.
-///
-/// Example matches 'if (x) {}'
-/// \code
-/// if (x) {}
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
-
-/// \brief Matches for statements.
-///
-/// Example matches 'for (;;) {}'
-/// \code
-/// for (;;) {}
-/// int i[] = {1, 2, 3}; for (auto a : i);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
-
-/// \brief Matches the increment statement of a for loop.
-///
-/// Example:
-/// forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
-/// matches '++x' in
-/// \code
-/// for (x; x < N; ++x) { }
-/// \endcode
-AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
- InnerMatcher) {
- const Stmt *const Increment = Node.getInc();
- return (Increment != nullptr &&
- InnerMatcher.matches(*Increment, Finder, Builder));
-}
-
-/// \brief Matches the initialization statement of a for loop.
-///
-/// Example:
-/// forStmt(hasLoopInit(declStmt()))
-/// matches 'int x = 0' in
-/// \code
-/// for (int x = 0; x < N; ++x) { }
-/// \endcode
-AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
- InnerMatcher) {
- const Stmt *const Init = Node.getInit();
- return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
-}
-
-/// \brief Matches range-based for statements.
-///
-/// cxxForRangeStmt() matches 'for (auto a : i)'
-/// \code
-/// int i[] = {1, 2, 3}; for (auto a : i);
-/// for(int j = 0; j < 5; ++j);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXForRangeStmt> cxxForRangeStmt;
-
-/// \brief Matches the initialization statement of a for loop.
-///
-/// Example:
-/// forStmt(hasLoopVariable(anything()))
-/// matches 'int x' in
-/// \code
-/// for (int x : a) { }
-/// \endcode
-AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>,
- InnerMatcher) {
- const VarDecl *const Var = Node.getLoopVariable();
- return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder));
-}
-
-/// \brief Matches the range initialization statement of a for loop.
-///
-/// Example:
-/// forStmt(hasRangeInit(anything()))
-/// matches 'a' in
-/// \code
-/// for (int x : a) { }
-/// \endcode
-AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,
- InnerMatcher) {
- const Expr *const Init = Node.getRangeInit();
- return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
-}
-
-/// \brief Matches while statements.
-///
-/// Given
-/// \code
-/// while (true) {}
-/// \endcode
-/// whileStmt()
-/// matches 'while (true) {}'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
-
-/// \brief Matches do statements.
-///
-/// Given
-/// \code
-/// do {} while (true);
-/// \endcode
-/// doStmt()
-/// matches 'do {} while(true)'
-const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
-
-/// \brief Matches break statements.
-///
-/// Given
-/// \code
-/// while (true) { break; }
-/// \endcode
-/// breakStmt()
-/// matches 'break'
-const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
-
-/// \brief Matches continue statements.
-///
-/// Given
-/// \code
-/// while (true) { continue; }
-/// \endcode
-/// continueStmt()
-/// matches 'continue'
-const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
-
-/// \brief Matches return statements.
-///
-/// Given
-/// \code
-/// return 1;
-/// \endcode
-/// returnStmt()
-/// matches 'return 1'
-const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
-
-/// \brief Matches goto statements.
-///
-/// Given
-/// \code
-/// goto FOO;
-/// FOO: bar();
-/// \endcode
-/// gotoStmt()
-/// matches 'goto FOO'
-const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
-
-/// \brief Matches label statements.
-///
-/// Given
-/// \code
-/// goto FOO;
-/// FOO: bar();
-/// \endcode
-/// labelStmt()
-/// matches 'FOO:'
-const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
-
-/// \brief Matches switch statements.
-///
-/// Given
-/// \code
-/// switch(a) { case 42: break; default: break; }
-/// \endcode
-/// switchStmt()
-/// matches 'switch(a)'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
-
-/// \brief 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;'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
-
-/// \brief Matches case statements inside switch statements.
-///
-/// Given
-/// \code
-/// switch(a) { case 42: break; default: break; }
-/// \endcode
-/// caseStmt()
-/// matches 'case 42: break;'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
-
-/// \brief Matches default statements inside switch statements.
-///
-/// Given
-/// \code
-/// switch(a) { case 42: break; default: break; }
-/// \endcode
-/// defaultStmt()
-/// matches 'default: break;'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
-
-/// \brief Matches compound statements.
-///
-/// Example matches '{}' and '{{}}'in 'for (;;) {{}}'
-/// \code
-/// for (;;) {{}}
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
-
-/// \brief Matches catch statements.
-///
-/// \code
-/// try {} catch(int i) {}
-/// \endcode
-/// cxxCatchStmt()
-/// matches 'catch(int i)'
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
-
-/// \brief Matches try statements.
-///
-/// \code
-/// try {} catch(int i) {}
-/// \endcode
-/// cxxTryStmt()
-/// matches 'try {}'
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
-
-/// \brief Matches throw expressions.
-///
-/// \code
-/// try { throw 5; } catch(int i) {}
-/// \endcode
-/// cxxThrowExpr()
-/// matches 'throw 5'
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
-
-/// \brief Matches null statements.
-///
-/// \code
-/// foo();;
-/// \endcode
-/// nullStmt()
-/// matches the second ';'
-const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
-
-/// \brief Matches asm statements.
-///
-/// \code
-/// int i = 100;
-/// __asm("mov al, 2");
-/// \endcode
-/// asmStmt()
-/// matches '__asm("mov al, 2")'
-const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
-
-/// \brief Matches bool literals.
-///
-/// Example matches true
-/// \code
-/// true
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXBoolLiteralExpr> cxxBoolLiteral;
-
-/// \brief Matches string literals (also matches wide string literals).
-///
-/// Example matches "abcd", L"abcd"
-/// \code
-/// char *s = "abcd"; wchar_t *ws = L"abcd"
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- StringLiteral> stringLiteral;
-
-/// \brief Matches character literals (also matches wchar_t).
-///
-/// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
-/// though.
-///
-/// Example matches 'a', L'a'
-/// \code
-/// char ch = 'a'; wchar_t chw = L'a';
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CharacterLiteral> characterLiteral;
-
-/// \brief Matches integer literals of all sizes / encodings, e.g.
-/// 1, 1L, 0x1 and 1U.
-///
-/// Does not match character-encoded integers such as L'a'.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- IntegerLiteral> integerLiteral;
-
-/// \brief Matches float literals of all sizes / encodings, e.g.
-/// 1.0, 1.0f, 1.0L and 1e10.
-///
-/// Does not match implicit conversions such as
-/// \code
-/// float a = 10;
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- FloatingLiteral> floatLiteral;
-
-/// \brief Matches user defined literal operator call.
-///
-/// Example match: "foo"_suffix
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- UserDefinedLiteral> userDefinedLiteral;
-
-/// \brief Matches compound (i.e. non-scalar) literals
-///
-/// Example match: {1}, (1, 2)
-/// \code
-/// int array[4] = {1}; vector int myvec = (vector int)(1, 2);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CompoundLiteralExpr> compoundLiteralExpr;
-
-/// \brief Matches nullptr literal.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr;
-
-/// \brief Matches GNU __null expression.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- GNUNullExpr> gnuNullExpr;
-
-/// \brief Matches binary operator expressions.
-///
-/// Example matches a || b
-/// \code
-/// !(a || b)
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- BinaryOperator> binaryOperator;
-
-/// \brief Matches unary operator expressions.
-///
-/// Example matches !a
-/// \code
-/// !a || b
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- UnaryOperator> unaryOperator;
-
-/// \brief Matches conditional operator expressions.
-///
-/// Example matches a ? b : c
-/// \code
-/// (a ? b : c) + 42
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ConditionalOperator> conditionalOperator;
-
-/// \brief Matches a C++ static_assert declaration.
-///
-/// Example:
-/// staticAssertExpr()
-/// matches
-/// static_assert(sizeof(S) == sizeof(int))
-/// in
-/// \code
-/// struct S {
-/// int x;
-/// };
-/// static_assert(sizeof(S) == sizeof(int));
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- StaticAssertDecl> staticAssertDecl;
-
-/// \brief 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
-/// more readable.
-///
-/// Example matches reinterpret_cast<char*>(&p) in
-/// \code
-/// void* p = reinterpret_cast<char*>(&p);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXReinterpretCastExpr> cxxReinterpretCastExpr;
-
-/// \brief Matches a C++ static_cast expression.
-///
-/// \see hasDestinationType
-/// \see reinterpretCast
-///
-/// Example:
-/// cxxStaticCastExpr()
-/// matches
-/// static_cast<long>(8)
-/// in
-/// \code
-/// long eight(static_cast<long>(8));
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXStaticCastExpr> cxxStaticCastExpr;
-
-/// \brief Matches a dynamic_cast expression.
-///
-/// Example:
-/// cxxDynamicCastExpr()
-/// matches
-/// dynamic_cast<D*>(&b);
-/// in
-/// \code
-/// struct B { virtual ~B() {} }; struct D : B {};
-/// B b;
-/// D* p = dynamic_cast<D*>(&b);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXDynamicCastExpr> cxxDynamicCastExpr;
-
-/// \brief Matches a const_cast expression.
-///
-/// Example: Matches const_cast<int*>(&r) in
-/// \code
-/// int n = 42;
-/// const int &r(n);
-/// int* p = const_cast<int*>(&r);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXConstCastExpr> cxxConstCastExpr;
-
-/// \brief Matches a C-style cast expression.
-///
-/// Example: Matches (int*) 2.2f in
-/// \code
-/// int i = (int) 2.2f;
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CStyleCastExpr> cStyleCastExpr;
-
-/// \brief 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.
-///
-/// Does not match implicit conversions.
-///
-/// Note: the name "explicitCast" is chosen to match Clang's terminology, as
-/// Clang uses the term "cast" to apply to implicit conversions as well as to
-/// actual cast expressions.
-///
-/// \see hasDestinationType.
-///
-/// Example: matches all five of the casts in
-/// \code
-/// int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42)))))
-/// \endcode
-/// but does not match the implicit conversion in
-/// \code
-/// long ell = 42;
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ExplicitCastExpr> explicitCastExpr;
-
-/// \brief 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.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ImplicitCastExpr> implicitCastExpr;
-
-/// \brief Matches any cast nodes of Clang's AST.
-///
-/// Example: castExpr() matches each of the following:
-/// \code
-/// (int) 3;
-/// const_cast<Expr *>(SubExpr);
-/// char c = 0;
-/// \endcode
-/// but does not match
-/// \code
-/// int i = (0);
-/// int k = 0;
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
-
-/// \brief Matches functional cast expressions
-///
-/// Example: Matches Foo(bar);
-/// \code
-/// Foo f = bar;
-/// Foo g = (Foo) bar;
-/// Foo h = Foo(bar);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXFunctionalCastExpr> cxxFunctionalCastExpr;
-
-/// \brief Matches functional cast expressions having N != 1 arguments
-///
-/// Example: Matches Foo(bar, bar)
-/// \code
-/// Foo h = Foo(bar, bar);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXTemporaryObjectExpr> cxxTemporaryObjectExpr;
-
-/// \brief Matches \c QualTypes in the clang AST.
-const internal::VariadicAllOfMatcher<QualType> qualType;
-
-/// \brief Matches \c Types in the clang AST.
-const internal::VariadicAllOfMatcher<Type> type;
-
-/// \brief Matches \c TypeLocs in the clang AST.
-const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
-
-/// \brief Matches if any of the given matchers matches.
-///
-/// Unlike \c anyOf, \c eachOf will generate a match result for each
-/// matching submatcher.
-///
-/// For example, in:
-/// \code
-/// class A { int a; int b; };
-/// \endcode
-/// The matcher:
-/// \code
-/// cxxRecordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
-/// has(fieldDecl(hasName("b")).bind("v"))))
-/// \endcode
-/// will generate two results binding "v", the first of which binds
-/// the field declaration of \c a, the second the field declaration of
-/// \c b.
-///
-/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
- internal::DynTypedMatcher::VO_EachOf
-};
-
-/// \brief Matches if any of the given matchers matches.
-///
-/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
- internal::DynTypedMatcher::VO_AnyOf
-};
-
-/// \brief Matches if all given matchers match.
-///
-/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
- internal::DynTypedMatcher::VO_AllOf
-};
-
-/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
-///
-/// Given
-/// \code
-/// Foo x = bar;
-/// int y = sizeof(x) + alignof(x);
-/// \endcode
-/// unaryExprOrTypeTraitExpr()
-/// matches \c sizeof(x) and \c alignof(x)
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- UnaryExprOrTypeTraitExpr> unaryExprOrTypeTraitExpr;
-
-/// \brief Matches unary expressions that have a specific type of argument.
-///
-/// Given
-/// \code
-/// int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
-/// \endcode
-/// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
-/// matches \c sizeof(a) and \c alignof(c)
-AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
- internal::Matcher<QualType>, InnerMatcher) {
- const QualType ArgumentType = Node.getTypeOfArgument();
- return InnerMatcher.matches(ArgumentType, Finder, Builder);
-}
-
-/// \brief Matches unary expressions of a certain kind.
-///
-/// Given
-/// \code
-/// int x;
-/// int s = sizeof(x) + alignof(x)
-/// \endcode
-/// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
-/// matches \c sizeof(x)
-AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
- return Node.getKind() == Kind;
-}
-
-/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
-/// alignof.
-inline internal::Matcher<Stmt> alignOfExpr(
- const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
- return stmt(unaryExprOrTypeTraitExpr(allOf(
- ofKind(UETT_AlignOf), InnerMatcher)));
-}
-
-/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
-/// sizeof.
-inline internal::Matcher<Stmt> sizeOfExpr(
- const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
- return stmt(unaryExprOrTypeTraitExpr(
- allOf(ofKind(UETT_SizeOf), InnerMatcher)));
-}
-
-/// \brief Matches NamedDecl nodes that have the specified name.
-///
-/// Supports specifying enclosing namespaces or classes by prefixing the name
-/// with '<enclosing>::'.
-/// Does not match typedefs of an underlying type with the given name.
-///
-/// Example matches X (Name == "X")
-/// \code
-/// class X;
-/// \endcode
-///
-/// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
-/// \code
-/// namespace a { namespace b { class X; } }
-/// \endcode
-inline internal::Matcher<NamedDecl> hasName(const std::string &Name) {
- return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Name));
-}
-
-/// \brief Matches NamedDecl nodes whose fully qualified names contain
-/// a substring matched by the given RegExp.
-///
-/// Supports specifying enclosing namespaces or classes by
-/// prefixing the name with '<enclosing>::'. Does not match typedefs
-/// of an underlying type with the given name.
-///
-/// Example matches X (regexp == "::X")
-/// \code
-/// class X;
-/// \endcode
-///
-/// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
-/// \code
-/// namespace foo { namespace bar { class X; } }
-/// \endcode
-AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
- assert(!RegExp.empty());
- std::string FullNameString = "::" + Node.getQualifiedNameAsString();
- llvm::Regex RE(RegExp);
- return RE.match(FullNameString);
-}
-
-/// \brief Matches overloaded operator names.
-///
-/// Matches overloaded operator names specified in strings without the
-/// "operator" prefix: e.g. "<<".
-///
-/// Given:
-/// \code
-/// class A { int operator*(); };
-/// const A &operator<<(const A &a, const A &b);
-/// A a;
-/// a << a; // <-- This matches
-/// \endcode
-///
-/// \c cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the
-/// specified line and
-/// \c cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")))
-/// matches the declaration of \c A.
-///
-/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
-inline internal::PolymorphicMatcherWithParam1<
- internal::HasOverloadedOperatorNameMatcher, StringRef,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>
-hasOverloadedOperatorName(StringRef Name) {
- return internal::PolymorphicMatcherWithParam1<
- internal::HasOverloadedOperatorNameMatcher, StringRef,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(Name);
-}
-
-/// \brief 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.
-///
-/// Example matches Y, Z, C (Base == hasName("X"))
-/// \code
-/// class X;
-/// class Y : public X {}; // directly derived
-/// class Z : public Y {}; // indirectly derived
-/// typedef X A;
-/// typedef A B;
-/// class C : public B {}; // derived from a typedef of X
-/// \endcode
-///
-/// In the following example, Bar matches isDerivedFrom(hasName("X")):
-/// \code
-/// class Foo;
-/// typedef Foo X;
-/// class Bar : public Foo {}; // derived from a type that X is a typedef of
-/// \endcode
-AST_MATCHER_P(CXXRecordDecl, isDerivedFrom,
- internal::Matcher<NamedDecl>, Base) {
- return Finder->classIsDerivedFrom(&Node, Base, Builder);
-}
-
-/// \brief 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
-/// match \c Base.
-AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom,
- internal::Matcher<NamedDecl>, Base, 0) {
- return Matcher<CXXRecordDecl>(anyOf(Base, isDerivedFrom(Base)))
- .matches(Node, Finder, Builder);
-}
-
-/// \brief Overloaded method as shortcut for
-/// \c isSameOrDerivedFrom(hasName(...)).
-AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, std::string,
- BaseName, 1) {
- assert(!BaseName.empty());
- return isSameOrDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
-}
-
-/// \brief Matches the first method of a class or struct that satisfies \c
-/// InnerMatcher.
-///
-/// Given:
-/// \code
-/// class A { void func(); };
-/// class B { void member(); };
-/// \endcode
-///
-/// \c cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of
-/// \c A but not \c B.
-AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>,
- InnerMatcher) {
- return matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
- Node.method_end(), Finder, Builder);
-}
-
-/// \brief Matches AST nodes that have child AST nodes that match the
-/// provided matcher.
-///
-/// Example matches X, Y
-/// (matcher = cxxRecordDecl(has(cxxRecordDecl(hasName("X")))
-/// \code
-/// class X {}; // Matches X, because X::X is a class of name X inside X.
-/// class Y { class X {}; };
-/// class Z { class Y { class X {}; }; }; // Does not match Z.
-/// \endcode
-///
-/// ChildT must be an AST base type.
-///
-/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher>
-LLVM_ATTRIBUTE_UNUSED has = {};
-
-/// \brief Matches AST nodes that have descendant AST nodes that match the
-/// provided matcher.
-///
-/// Example matches X, Y, Z
-/// (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(hasName("X")))))
-/// \code
-/// class X {}; // Matches X, because X::X is a class of name X inside X.
-/// class Y { class X {}; };
-/// class Z { class Y { class X {}; }; };
-/// \endcode
-///
-/// DescendantT must be an AST base type.
-///
-/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
-LLVM_ATTRIBUTE_UNUSED hasDescendant = {};
-
-/// \brief Matches AST nodes that have child AST nodes that match the
-/// provided matcher.
-///
-/// Example matches X, Y
-/// (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 Z { class Y { class X {}; }; }; // Does not match Z.
-/// \endcode
-///
-/// ChildT must be an AST base type.
-///
-/// As opposed to 'has', 'forEach' will cause a match for each result that
-/// matches instead of only on the first one.
-///
-/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
-LLVM_ATTRIBUTE_UNUSED forEach = {};
-
-/// \brief Matches AST nodes that have descendant AST nodes that match the
-/// provided matcher.
-///
-/// Example matches X, A, B, C
-/// (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 B { class C { class X {}; }; };
-/// \endcode
-///
-/// DescendantT must be an AST base type.
-///
-/// As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for
-/// each result that matches instead of only on the first one.
-///
-/// Note: Recursively combined ForEachDescendant can cause many matches:
-/// cxxRecordDecl(forEachDescendant(cxxRecordDecl(
-/// forEachDescendant(cxxRecordDecl())
-/// )))
-/// will match 10 times (plus injected class name matches) on:
-/// \code
-/// class A { class B { class C { class D { class E {}; }; }; }; };
-/// \endcode
-///
-/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
-LLVM_ATTRIBUTE_UNUSED forEachDescendant = {};
-
-/// \brief Matches if the node or any descendant matches.
-///
-/// Generates results for each match.
-///
-/// For example, in:
-/// \code
-/// class A { class B {}; class C {}; };
-/// \endcode
-/// The matcher:
-/// \code
-/// cxxRecordDecl(hasName("::A"),
-/// findAll(cxxRecordDecl(isDefinition()).bind("m")))
-/// \endcode
-/// will generate results for \c A, \c B and \c C.
-///
-/// Usable as: Any Matcher
-template <typename T>
-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
-/// matcher.
-///
-/// Given
-/// \code
-/// void f() { for (;;) { int x = 42; if (true) { int x = 43; } } }
-/// \endcode
-/// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }".
-///
-/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<
- internal::HasParentMatcher,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
- LLVM_ATTRIBUTE_UNUSED hasParent = {};
-
-/// \brief Matches AST nodes that have an ancestor that matches the provided
-/// matcher.
-///
-/// Given
-/// \code
-/// void f() { if (true) { int x = 42; } }
-/// void g() { for (;;) { int x = 43; } }
-/// \endcode
-/// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43.
-///
-/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<
- internal::HasAncestorMatcher,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
- LLVM_ATTRIBUTE_UNUSED hasAncestor = {};
-
-/// \brief Matches if the provided matcher does not match.
-///
-/// Example matches Y (matcher = cxxRecordDecl(unless(hasName("X"))))
-/// \code
-/// class X {};
-/// class Y {};
-/// \endcode
-///
-/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
- internal::DynTypedMatcher::VO_UnaryNot
-};
-
-/// \brief Matches a node if the declaration associated with that node
-/// matches the given matcher.
-///
-/// The associated declaration is:
-/// - for type nodes, the declaration of the underlying type
-/// - for CallExpr, the declaration of the callee
-/// - for MemberExpr, the declaration of the referenced member
-/// - for CXXConstructExpr, the declaration of the constructor
-///
-/// Also usable as Matcher<T> for any T supporting the getDecl() member
-/// function. e.g. various subtypes of clang::Type and various expressions.
-///
-/// Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-/// Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
-/// Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
-/// Matcher<RecordType>, Matcher<TagType>,
-/// Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
-/// Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-inline internal::PolymorphicMatcherWithParam1<
- internal::HasDeclarationMatcher, internal::Matcher<Decl>,
- void(internal::HasDeclarationSupportedTypes)>
-hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
- return internal::PolymorphicMatcherWithParam1<
- internal::HasDeclarationMatcher, internal::Matcher<Decl>,
- void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
-}
-
-/// \brief 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(); }",
-/// \endcode
-///
-/// FIXME: Overload to allow directly matching types?
-AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
- InnerMatcher) {
- const Expr *ExprNode = Node.getImplicitObjectArgument()
- ->IgnoreParenImpCasts();
- return (ExprNode != nullptr &&
- InnerMatcher.matches(*ExprNode, Finder, Builder));
-}
-
-
-/// \brief Matches on the receiver of an ObjectiveC Message expression.
-///
-/// Example
-/// matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *")));
-/// matches the [webView ...] message invocation.
-/// \code
-/// NSString *webViewJavaScript = ...
-/// UIWebView *webView = ...
-/// [webView stringByEvaluatingJavaScriptFromString:webViewJavascript];
-/// \endcode
-AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>,
- InnerMatcher) {
- const QualType TypeDecl = Node.getReceiverType();
- return InnerMatcher.matches(TypeDecl, Finder, Builder);
-}
-
-/// \brief Matches when BaseName == Selector.getAsString()
-///
-/// matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:"));
-/// matches the outer message expr in the code below, but NOT the message
-/// invocation for self.bodyView.
-/// \code
-/// [self.bodyView loadHTMLString:html baseURL:NULL];
-/// \endcode
-AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) {
- Selector Sel = Node.getSelector();
- return BaseName.compare(Sel.getAsString()) == 0;
-}
-
-
-/// \brief 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
-/// invocation for self.bodyView.
-/// \code
-/// [self.bodyView loadHTMLString:html baseURL:NULL];
-/// \endcode
-AST_MATCHER_P(ObjCMessageExpr, matchesSelector, std::string, RegExp) {
- assert(!RegExp.empty());
- std::string SelectorString = Node.getSelector().getAsString();
- llvm::Regex RE(RegExp);
- return RE.match(SelectorString);
-}
-
-/// \brief 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!
-AST_MATCHER(ObjCMessageExpr, hasNullSelector) {
- return Node.getSelector().isNull();
-}
-
-/// \brief Matches when the selector is a Unary Selector
-///
-/// matcher = objCMessageExpr(matchesSelector(hasUnarySelector());
-/// matches self.bodyView in the code below, but NOT the outer message
-/// invocation of "loadHTMLString:baseURL:".
-/// \code
-/// [self.bodyView loadHTMLString:html baseURL:NULL];
-/// \endcode
-AST_MATCHER(ObjCMessageExpr, hasUnarySelector) {
- return Node.getSelector().isUnarySelector();
-}
-
-/// \brief Matches when the selector is a keyword selector
-///
-/// objCMessageExpr(hasKeywordSelector()) matches the generated setFrame
-/// message expression in
-///
-/// \code
-/// UIWebView *webView = ...;
-/// CGRect bodyFrame = webView.frame;
-/// bodyFrame.size.height = self.bodyContentHeight;
-/// webView.frame = bodyFrame;
-/// // ^---- matches here
-/// \endcode
-AST_MATCHER(ObjCMessageExpr, hasKeywordSelector) {
- return Node.getSelector().isKeywordSelector();
-}
-
-/// \brief Matches when the selector has the specified number of arguments
-///
-/// matcher = objCMessageExpr(numSelectorArgs(0));
-/// matches self.bodyView in the code below
-///
-/// matcher = objCMessageExpr(numSelectorArgs(2));
-/// matches the invocation of "loadHTMLString:baseURL:" but not that
-/// of self.bodyView
-/// \code
-/// [self.bodyView loadHTMLString:html baseURL:NULL];
-/// \endcode
-AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
- return Node.getSelector().getNumArgs() == N;
-}
-
-/// \brief Matches if the call expression's callee expression matches.
-///
-/// Given
-/// \code
-/// class Y { void x() { this->x(); x(); Y y; y.x(); } };
-/// void f() { f(); }
-/// \endcode
-/// callExpr(callee(expr()))
-/// matches this->x(), x(), y.x(), f()
-/// with callee(...)
-/// matching this->x, x, y.x, f respectively
-///
-/// Note: Callee cannot take the more general internal::Matcher<Expr>
-/// because this introduces ambiguous overloads with calls to Callee taking a
-/// internal::Matcher<Decl>, as the matcher hierarchy is purely
-/// implemented in terms of implicit casts.
-AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
- InnerMatcher) {
- const Expr *ExprNode = Node.getCallee();
- return (ExprNode != nullptr &&
- InnerMatcher.matches(*ExprNode, Finder, Builder));
-}
-
-/// \brief Matches if the call expression's callee's declaration matches the
-/// given matcher.
-///
-/// Example matches y.x() (matcher = callExpr(callee(
-/// cxxMethodDecl(hasName("x")))))
-/// \code
-/// class Y { public: void x(); };
-/// void z() { Y y; y.x(); }
-/// \endcode
-AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
- 1) {
- return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
-}
-
-/// \brief 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")))))
-/// \code
-/// class X {};
-/// void y(X &x) { x; X z; }
-/// \endcode
-AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
- hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, ValueDecl),
- internal::Matcher<QualType>, InnerMatcher, 0) {
- return InnerMatcher.matches(Node.getType(), Finder, Builder);
-}
-
-/// \brief 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),
-/// this resolves one layer of indirection. For example, in the value
-/// declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of
-/// X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
-/// declaration of x.
-///
-/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
-/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
-/// \code
-/// class X {};
-/// void y(X &x) { x; X z; }
-/// \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);
-}
-
-/// \brief Matches if the type location of the declarator decl's type matches
-/// the inner matcher.
-///
-/// Given
-/// \code
-/// int x;
-/// \endcode
-/// declaratorDecl(hasTypeLoc(loc(asString("int"))))
-/// matches int x
-AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher<TypeLoc>, Inner) {
- if (!Node.getTypeSourceInfo())
- // This happens for example for implicit destructors.
- return false;
- return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder);
-}
-
-/// \brief Matches if the matched type is represented by the given string.
-///
-/// Given
-/// \code
-/// class Y { public: void x(); };
-/// void z() { Y* y; y->x(); }
-/// \endcode
-/// cxxMemberCallExpr(on(hasType(asString("class Y *"))))
-/// matches y->x()
-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 the specified matcher.
-///
-/// Example matches y->x()
-/// (matcher = cxxMemberCallExpr(on(hasType(pointsTo
-/// cxxRecordDecl(hasName("Y")))))))
-/// \code
-/// class Y { public: void x(); };
-/// void z() { Y *y; y->x(); }
-/// \endcode
-AST_MATCHER_P(
- QualType, pointsTo, internal::Matcher<QualType>,
- InnerMatcher) {
- return (!Node.isNull() && Node->isAnyPointerType() &&
- InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
-}
-
-/// \brief 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 is a reference type and the referenced
-/// type matches the specified matcher.
-///
-/// Example matches X &x and const X &y
-/// (matcher = varDecl(hasType(references(cxxRecordDecl(hasName("X"))))))
-/// \code
-/// class X {
-/// void a(X b) {
-/// X &x = b;
-/// const X &y = b;
-/// }
-/// };
-/// \endcode
-AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
- InnerMatcher) {
- return (!Node.isNull() && Node->isReferenceType() &&
- InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
-}
-
-/// \brief Matches QualTypes whose canonical type matches InnerMatcher.
-///
-/// Given:
-/// \code
-/// typedef int &int_ref;
-/// int a;
-/// int_ref b = a;
-/// \endcode
-///
-/// \c varDecl(hasType(qualType(referenceType()))))) will not match the
-/// declaration of b but \c
-/// varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does.
-AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher<QualType>,
- InnerMatcher) {
- if (Node.isNull())
- return false;
- return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder);
-}
-
-/// \brief Overloaded to match the referenced type's declaration.
-AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>,
- InnerMatcher, 1) {
- return references(qualType(hasDeclaration(InnerMatcher)))
- .matches(Node, Finder, Builder);
-}
-
-AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr *ExprNode = Node.getImplicitObjectArgument();
- return (ExprNode != nullptr &&
- InnerMatcher.matches(*ExprNode, Finder, Builder));
-}
-
-/// \brief 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) {
- return onImplicitObjectArgument(
- anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
- .matches(Node, Finder, Builder);
-}
-
-/// \brief Overloaded to match the type's declaration.
-AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
- internal::Matcher<Decl>, InnerMatcher, 1) {
- return onImplicitObjectArgument(
- anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
- .matches(Node, Finder, Builder);
-}
-
-/// \brief Matches a DeclRefExpr that refers to a declaration that matches the
-/// specified matcher.
-///
-/// Example matches x in if(x)
-/// (matcher = declRefExpr(to(varDecl(hasName("x")))))
-/// \code
-/// bool x;
-/// if (x) {}
-/// \endcode
-AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
- InnerMatcher) {
- const Decl *DeclNode = Node.getDecl();
- return (DeclNode != nullptr &&
- InnerMatcher.matches(*DeclNode, Finder, Builder));
-}
-
-/// \brief Matches a \c DeclRefExpr that refers to a declaration through a
-/// specific using shadow declaration.
-///
-/// Given
-/// \code
-/// namespace a { void f() {} }
-/// using a::f;
-/// void g() {
-/// f(); // Matches this ..
-/// a::f(); // .. but not this.
-/// }
-/// \endcode
-/// declRefExpr(throughUsingDecl(anything()))
-/// matches \c f()
-AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
- internal::Matcher<UsingShadowDecl>, InnerMatcher) {
- const NamedDecl *FoundDecl = Node.getFoundDecl();
- if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
- return InnerMatcher.matches(*UsingDecl, Finder, Builder);
- return false;
-}
-
-/// \brief Matches the Decl of a DeclStmt which has a single declaration.
-///
-/// Given
-/// \code
-/// int a, b;
-/// int c;
-/// \endcode
-/// declStmt(hasSingleDecl(anything()))
-/// matches 'int c;' but not 'int a, b;'.
-AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) {
- if (Node.isSingleDecl()) {
- const Decl *FoundDecl = Node.getSingleDecl();
- return InnerMatcher.matches(*FoundDecl, Finder, Builder);
- }
- return false;
-}
-
-/// \brief Matches a variable declaration that has an initializer expression
-/// that matches the given matcher.
-///
-/// Example matches x (matcher = varDecl(hasInitializer(callExpr())))
-/// \code
-/// bool y() { return true; }
-/// bool x = y();
-/// \endcode
-AST_MATCHER_P(
- VarDecl, hasInitializer, internal::Matcher<Expr>,
- InnerMatcher) {
- const Expr *Initializer = Node.getAnyInitializer();
- return (Initializer != nullptr &&
- InnerMatcher.matches(*Initializer, Finder, Builder));
-}
-
-/// \brief Matches a variable declaration that has function scope and is a
-/// non-static local variable.
-///
-/// Example matches x (matcher = varDecl(hasLocalStorage())
-/// \code
-/// void f() {
-/// int x;
-/// static int y;
-/// }
-/// int z;
-/// \endcode
-AST_MATCHER(VarDecl, hasLocalStorage) {
- return Node.hasLocalStorage();
-}
-
-/// \brief Matches a variable declaration that does not have local storage.
-///
-/// Example matches y and z (matcher = varDecl(hasGlobalStorage())
-/// \code
-/// void f() {
-/// int x;
-/// static int y;
-/// }
-/// int z;
-/// \endcode
-AST_MATCHER(VarDecl, hasGlobalStorage) {
- return Node.hasGlobalStorage();
-}
-
-/// \brief Matches a variable declaration that has automatic storage duration.
-///
-/// Example matches x, but not y, z, or a.
-/// (matcher = varDecl(hasAutomaticStorageDuration())
-/// \code
-/// void f() {
-/// int x;
-/// static int y;
-/// thread_local int z;
-/// }
-/// int a;
-/// \endcode
-AST_MATCHER(VarDecl, hasAutomaticStorageDuration) {
- return Node.getStorageDuration() == SD_Automatic;
-}
-
-/// \brief Matches a variable declaration that has static storage duration.
-///
-/// Example matches y and a, but not x or z.
-/// (matcher = varDecl(hasStaticStorageDuration())
-/// \code
-/// void f() {
-/// int x;
-/// static int y;
-/// thread_local int z;
-/// }
-/// int a;
-/// \endcode
-AST_MATCHER(VarDecl, hasStaticStorageDuration) {
- return Node.getStorageDuration() == SD_Static;
-}
-
-/// \brief Matches a variable declaration that has thread storage duration.
-///
-/// Example matches z, but not x, z, or a.
-/// (matcher = varDecl(hasThreadStorageDuration())
-/// \code
-/// void f() {
-/// int x;
-/// static int y;
-/// thread_local int z;
-/// }
-/// int a;
-/// \endcode
-AST_MATCHER(VarDecl, hasThreadStorageDuration) {
- return Node.getStorageDuration() == SD_Thread;
-}
-
-/// \brief 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())
-/// \code
-/// void f(int y) {
-/// try {
-/// } catch (int x) {
-/// }
-/// }
-/// \endcode
-AST_MATCHER(VarDecl, isExceptionVariable) {
- return Node.isExceptionVariable();
-}
-
-/// \brief 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)))
-/// \code
-/// void f(int x, int y);
-/// f(0, 0);
-/// \endcode
-AST_POLYMORPHIC_MATCHER_P(argumentCountIs,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
- CXXConstructExpr,
- ObjCMessageExpr),
- unsigned, N) {
- return Node.getNumArgs() == N;
-}
-
-/// \brief Matches the n'th argument of a call expression or a constructor
-/// call expression.
-///
-/// Example matches y in x(y)
-/// (matcher = callExpr(hasArgument(0, declRefExpr())))
-/// \code
-/// void x(int) { int y; x(y); }
-/// \endcode
-AST_POLYMORPHIC_MATCHER_P2(hasArgument,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
- CXXConstructExpr,
- ObjCMessageExpr),
- unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
- return (N < Node.getNumArgs() &&
- InnerMatcher.matches(
- *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
-}
-
-/// \brief Matches declaration statements that contain a specific number of
-/// declarations.
-///
-/// Example: Given
-/// \code
-/// int a, b;
-/// int c;
-/// int d = 2, e;
-/// \endcode
-/// declCountIs(2)
-/// matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
-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.
-///
-/// Note that this does not work for global declarations because the AST
-/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
-/// DeclStmt's.
-/// Example: Given non-global declarations
-/// \code
-/// int a, b = 0;
-/// int c;
-/// int d = 2, e;
-/// \endcode
-/// declStmt(containsDeclaration(
-/// 0, varDecl(hasInitializer(anything()))))
-/// matches only 'int d = 2, e;', and
-/// declStmt(containsDeclaration(1, varDecl()))
-/// \code
-/// matches 'int a, b = 0' as well as 'int d = 2, e;'
-/// but 'int c;' is not matched.
-/// \endcode
-AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
- internal::Matcher<Decl>, InnerMatcher) {
- const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end());
- if (N >= NumDecls)
- return false;
- DeclStmt::const_decl_iterator Iterator = Node.decl_begin();
- std::advance(Iterator, N);
- return InnerMatcher.matches(**Iterator, Finder, Builder);
-}
-
-/// \brief Matches a C++ catch statement that has a catch-all handler.
-///
-/// Given
-/// \code
-/// try {
-/// // ...
-/// } catch (int) {
-/// // ...
-/// } catch (...) {
-/// // ...
-/// }
-/// /endcode
-/// cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).
-AST_MATCHER(CXXCatchStmt, isCatchAll) {
- return Node.getExceptionDecl() == nullptr;
-}
-
-/// \brief Matches a constructor initializer.
-///
-/// Given
-/// \code
-/// struct Foo {
-/// Foo() : foo_(1) { }
-/// int foo_;
-/// };
-/// \endcode
-/// cxxRecordDecl(has(cxxConstructorDecl(
-/// hasAnyConstructorInitializer(anything())
-/// )))
-/// record matches Foo, hasAnyConstructorInitializer matches foo_(1)
-AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
- internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
- return matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
- Node.init_end(), Finder, Builder);
-}
-
-/// \brief Matches the field declaration of a constructor initializer.
-///
-/// Given
-/// \code
-/// struct Foo {
-/// Foo() : foo_(1) { }
-/// int foo_;
-/// };
-/// \endcode
-/// cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer(
-/// forField(hasName("foo_"))))))
-/// matches Foo
-/// with forField matching foo_
-AST_MATCHER_P(CXXCtorInitializer, forField,
- internal::Matcher<FieldDecl>, InnerMatcher) {
- const FieldDecl *NodeAsDecl = Node.getMember();
- return (NodeAsDecl != nullptr &&
- InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
-}
-
-/// \brief Matches the initializer expression of a constructor initializer.
-///
-/// Given
-/// \code
-/// struct Foo {
-/// Foo() : foo_(1) { }
-/// int foo_;
-/// };
-/// \endcode
-/// cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer(
-/// withInitializer(integerLiteral(equals(1)))))))
-/// matches Foo
-/// with withInitializer matching (1)
-AST_MATCHER_P(CXXCtorInitializer, withInitializer,
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr* NodeAsExpr = Node.getInit();
- return (NodeAsExpr != nullptr &&
- InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
-}
-
-/// \brief Matches a constructor initializer if it is explicitly written in
-/// code (as opposed to implicitly added by the compiler).
-///
-/// Given
-/// \code
-/// struct Foo {
-/// Foo() { }
-/// Foo(int) : foo_("A") { }
-/// string foo_;
-/// };
-/// \endcode
-/// cxxConstructorDecl(hasAnyConstructorInitializer(isWritten()))
-/// will match Foo(int), but not Foo()
-AST_MATCHER(CXXCtorInitializer, isWritten) {
- return Node.isWritten();
-}
-
-/// \brief Matches a constructor initializer if it is initializing a base, as
-/// opposed to a member.
-///
-/// Given
-/// \code
-/// struct B {};
-/// struct D : B {
-/// int I;
-/// D(int i) : I(i) {}
-/// };
-/// struct E : B {
-/// E() : B() {}
-/// };
-/// \endcode
-/// cxxConstructorDecl(hasAnyConstructorInitializer(isBaseInitializer()))
-/// will match E(), but not match D(int).
-AST_MATCHER(CXXCtorInitializer, isBaseInitializer) {
- return Node.isBaseInitializer();
-}
-
-/// \brief Matches a constructor initializer if it is initializing a member, as
-/// opposed to a base.
-///
-/// Given
-/// \code
-/// struct B {};
-/// struct D : B {
-/// int I;
-/// D(int i) : I(i) {}
-/// };
-/// struct E : B {
-/// E() : B() {}
-/// };
-/// \endcode
-/// cxxConstructorDecl(hasAnyConstructorInitializer(isMemberInitializer()))
-/// will match D(int), but not match E().
-AST_MATCHER(CXXCtorInitializer, isMemberInitializer) {
- return Node.isMemberInitializer();
-}
-
-/// \brief Matches any argument of a call expression or a constructor call
-/// expression.
-///
-/// Given
-/// \code
-/// void x(int, int, int) { int y; x(1, y, 42); }
-/// \endcode
-/// callExpr(hasAnyArgument(declRefExpr()))
-/// matches x(1, y, 42)
-/// with hasAnyArgument(...)
-/// matching y
-///
-/// FIXME: Currently this will ignore parentheses and implicit casts on
-/// the argument before applying the inner matcher. We'll want to remove
-/// this to allow for greater control by the user once \c ignoreImplicit()
-/// has been implemented.
-AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
- CXXConstructExpr),
- internal::Matcher<Expr>, InnerMatcher) {
- for (const Expr *Arg : Node.arguments()) {
- BoundNodesTreeBuilder Result(*Builder);
- if (InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, &Result)) {
- *Builder = std::move(Result);
- return true;
- }
- }
- return false;
-}
-
-/// \brief Matches a constructor call expression which uses list initialization.
-AST_MATCHER(CXXConstructExpr, isListInitialization) {
- return Node.isListInitialization();
-}
-
-/// \brief Matches the n'th parameter of a function declaration.
-///
-/// Given
-/// \code
-/// class X { void f(int x) {} };
-/// \endcode
-/// cxxMethodDecl(hasParameter(0, hasType(varDecl())))
-/// 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));
-}
-
-/// \brief Matches any parameter of a function declaration.
-///
-/// Does not match the 'this' parameter of a method.
-///
-/// Given
-/// \code
-/// class X { void f(int x, int y, int z) {} };
-/// \endcode
-/// cxxMethodDecl(hasAnyParameter(hasName("y")))
-/// matches f(int x, int y, int z) {}
-/// with hasAnyParameter(...)
-/// matching int y
-AST_MATCHER_P(FunctionDecl, hasAnyParameter,
- internal::Matcher<ParmVarDecl>, InnerMatcher) {
- return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
- Node.param_end(), Finder, Builder);
-}
-
-/// \brief Matches \c FunctionDecls that have a specific parameter count.
-///
-/// Given
-/// \code
-/// void f(int i) {}
-/// void g(int i, int j) {}
-/// \endcode
-/// functionDecl(parameterCountIs(2))
-/// matches g(int i, int j) {}
-AST_MATCHER_P(FunctionDecl, parameterCountIs, unsigned, N) {
- return Node.getNumParams() == N;
-}
-
-/// \brief Matches the return type of a function declaration.
-///
-/// Given:
-/// \code
-/// class X { int f() { return 1; } };
-/// \endcode
-/// cxxMethodDecl(returns(asString("int")))
-/// matches int f() { return 1; }
-AST_MATCHER_P(FunctionDecl, returns,
- internal::Matcher<QualType>, InnerMatcher) {
- return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
-}
-
-/// \brief Matches extern "C" function declarations.
-///
-/// Given:
-/// \code
-/// extern "C" void f() {}
-/// extern "C" { void g() {} }
-/// void h() {}
-/// \endcode
-/// functionDecl(isExternC())
-/// matches the declaration of f and g, but not the declaration h
-AST_MATCHER(FunctionDecl, isExternC) {
- return Node.isExternC();
-}
-
-/// \brief Matches deleted function declarations.
-///
-/// Given:
-/// \code
-/// void Func();
-/// void DeletedFunc() = delete;
-/// \endcode
-/// functionDecl(isDeleted())
-/// matches the declaration of DeletedFunc, but not Func.
-AST_MATCHER(FunctionDecl, isDeleted) {
- return Node.isDeleted();
-}
-
-/// \brief Matches functions that have a non-throwing exception specification.
-///
-/// Given:
-/// \code
-/// void f();
-/// void g() noexcept;
-/// void h() throw();
-/// void i() throw(int);
-/// void j() noexcept(false);
-/// \endcode
-/// functionDecl(isNoThrow())
-/// matches the declarations of g, and h, but not f, i or j.
-AST_MATCHER(FunctionDecl, isNoThrow) {
- const auto *FnTy = Node.getType()->getAs<FunctionProtoType>();
-
- // If the function does not have a prototype, then it is assumed to be a
- // throwing function (as it would if the function did not have any exception
- // specification).
- if (!FnTy)
- return false;
-
- // Assume the best for any unresolved exception specification.
- if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
- return true;
-
- return FnTy->isNothrow(Node.getASTContext());
-}
-
-/// \brief Matches constexpr variable and function declarations.
-///
-/// Given:
-/// \code
-/// constexpr int foo = 42;
-/// constexpr int bar();
-/// \endcode
-/// varDecl(isConstexpr())
-/// matches the declaration of foo.
-/// functionDecl(isConstexpr())
-/// matches the declaration of bar.
-AST_POLYMORPHIC_MATCHER(isConstexpr,
- AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl,
- FunctionDecl)) {
- return Node.isConstexpr();
-}
-
-/// \brief Matches the condition expression of an if statement, for loop,
-/// or conditional operator.
-///
-/// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
-/// \code
-/// if (true) {}
-/// \endcode
-AST_POLYMORPHIC_MATCHER_P(hasCondition,
- AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt,
- WhileStmt, DoStmt,
- ConditionalOperator),
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr *const Condition = Node.getCond();
- return (Condition != nullptr &&
- InnerMatcher.matches(*Condition, Finder, Builder));
-}
-
-/// \brief Matches the then-statement of an if statement.
-///
-/// Examples matches the if statement
-/// (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true)))))
-/// \code
-/// if (false) true; else false;
-/// \endcode
-AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher) {
- const Stmt *const Then = Node.getThen();
- return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder));
-}
-
-/// \brief Matches the else-statement of an if statement.
-///
-/// Examples matches the if statement
-/// (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true)))))
-/// \code
-/// if (false) false; else true;
-/// \endcode
-AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) {
- const Stmt *const Else = Node.getElse();
- return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder));
-}
-
-/// \brief Matches if a node equals a previously bound node.
-///
-/// Matches a node if it equals the node previously bound to \p ID.
-///
-/// Given
-/// \code
-/// class X { int a; int b; };
-/// \endcode
-/// cxxRecordDecl(
-/// has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
-/// has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
-/// matches the class \c X, as \c a and \c b have the same type.
-///
-/// Note that when multiple matches are involved via \c forEach* matchers,
-/// \c equalsBoundNodes acts as a filter.
-/// For example:
-/// compoundStmt(
-/// forEachDescendant(varDecl().bind("d")),
-/// forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
-/// will trigger a match for each combination of variable declaration
-/// and reference to that variable declaration within a compound statement.
-AST_POLYMORPHIC_MATCHER_P(equalsBoundNode,
- AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl, Type,
- QualType),
- std::string, ID) {
- // FIXME: Figure out whether it makes sense to allow this
- // on any other node types.
- // For *Loc it probably does not make sense, as those seem
- // unique. For NestedNameSepcifier it might make sense, as
- // those also have pointer identity, but I'm not sure whether
- // they're ever reused.
- internal::NotEqualsBoundNodePredicate Predicate;
- Predicate.ID = ID;
- Predicate.Node = ast_type_traits::DynTypedNode::create(Node);
- return Builder->removeBindings(Predicate);
-}
-
-/// \brief Matches the condition variable statement in an if statement.
-///
-/// Given
-/// \code
-/// if (A* a = GetAPointer()) {}
-/// \endcode
-/// hasConditionVariableStatement(...)
-/// matches 'A* a = GetAPointer()'.
-AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
- internal::Matcher<DeclStmt>, InnerMatcher) {
- const DeclStmt* const DeclarationStatement =
- Node.getConditionVariableDeclStmt();
- return DeclarationStatement != nullptr &&
- InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
-}
-
-/// \brief Matches the index expression of an array subscript expression.
-///
-/// Given
-/// \code
-/// int i[5];
-/// void f() { i[1] = 42; }
-/// \endcode
-/// arraySubscriptExpression(hasIndex(integerLiteral()))
-/// matches \c i[1] with the \c integerLiteral() matching \c 1
-AST_MATCHER_P(ArraySubscriptExpr, hasIndex,
- internal::Matcher<Expr>, InnerMatcher) {
- if (const Expr* Expression = Node.getIdx())
- return InnerMatcher.matches(*Expression, Finder, Builder);
- return false;
-}
-
-/// \brief Matches the base expression of an array subscript expression.
-///
-/// Given
-/// \code
-/// int i[5];
-/// void f() { i[1] = 42; }
-/// \endcode
-/// arraySubscriptExpression(hasBase(implicitCastExpr(
-/// hasSourceExpression(declRefExpr()))))
-/// matches \c i[1] with the \c declRefExpr() matching \c i
-AST_MATCHER_P(ArraySubscriptExpr, hasBase,
- internal::Matcher<Expr>, InnerMatcher) {
- if (const Expr* Expression = Node.getBase())
- return InnerMatcher.matches(*Expression, Finder, Builder);
- return false;
-}
-
-/// \brief Matches a 'for', 'while', or 'do while' statement that has
-/// a given body.
-///
-/// Given
-/// \code
-/// for (;;) {}
-/// \endcode
-/// hasBody(compoundStmt())
-/// matches 'for (;;) {}'
-/// with compoundStmt()
-/// matching '{}'
-AST_POLYMORPHIC_MATCHER_P(hasBody,
- AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
- WhileStmt,
- CXXForRangeStmt),
- internal::Matcher<Stmt>, InnerMatcher) {
- const Stmt *const Statement = Node.getBody();
- return (Statement != nullptr &&
- InnerMatcher.matches(*Statement, Finder, Builder));
-}
-
-/// \brief Matches compound statements where at least one substatement matches
-/// a given matcher.
-///
-/// Given
-/// \code
-/// { {}; 1+2; }
-/// \endcode
-/// hasAnySubstatement(compoundStmt())
-/// matches '{ {}; 1+2; }'
-/// with compoundStmt()
-/// matching '{}'
-AST_MATCHER_P(CompoundStmt, hasAnySubstatement,
- internal::Matcher<Stmt>, InnerMatcher) {
- return matchesFirstInPointerRange(InnerMatcher, Node.body_begin(),
- Node.body_end(), Finder, Builder);
-}
-
-/// \brief Checks that a compound statement contains a specific number of
-/// child statements.
-///
-/// Example: Given
-/// \code
-/// { for (;;) {} }
-/// \endcode
-/// compoundStmt(statementCountIs(0)))
-/// matches '{}'
-/// but does not match the outer compound statement.
-AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
- return Node.size() == N;
-}
-
-/// \brief Matches literals that are equal to the given value.
-///
-/// Example matches true (matcher = cxxBoolLiteral(equals(true)))
-/// \code
-/// true
-/// \endcode
-///
-/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
-/// Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
-template <typename ValueT>
-internal::PolymorphicMatcherWithParam1<internal::ValueEqualsMatcher, ValueT>
-equals(const ValueT &Value) {
- return internal::PolymorphicMatcherWithParam1<
- internal::ValueEqualsMatcher,
- ValueT>(Value);
-}
-
-/// \brief Matches the operator Name of operator expressions (binary or
-/// unary).
-///
-/// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
-/// \code
-/// !(a || b)
-/// \endcode
-AST_POLYMORPHIC_MATCHER_P(hasOperatorName,
- AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
- UnaryOperator),
- std::string, Name) {
- return Name == Node.getOpcodeStr(Node.getOpcode());
-}
-
-/// \brief Matches the left hand side of binary operator expressions.
-///
-/// Example matches a (matcher = binaryOperator(hasLHS()))
-/// \code
-/// a || b
-/// \endcode
-AST_POLYMORPHIC_MATCHER_P(hasLHS,
- AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
- ArraySubscriptExpr),
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr *LeftHandSide = Node.getLHS();
- return (LeftHandSide != nullptr &&
- InnerMatcher.matches(*LeftHandSide, Finder, Builder));
-}
-
-/// \brief Matches the right hand side of binary operator expressions.
-///
-/// Example matches b (matcher = binaryOperator(hasRHS()))
-/// \code
-/// a || b
-/// \endcode
-AST_POLYMORPHIC_MATCHER_P(hasRHS,
- AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
- ArraySubscriptExpr),
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr *RightHandSide = Node.getRHS();
- return (RightHandSide != nullptr &&
- InnerMatcher.matches(*RightHandSide, Finder, Builder));
-}
-
-/// \brief 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.
-///
-/// Example matches true (matcher = hasUnaryOperand(
-/// cxxBoolLiteral(equals(true))))
-/// \code
-/// !true
-/// \endcode
-AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr * const Operand = Node.getSubExpr();
- return (Operand != nullptr &&
- InnerMatcher.matches(*Operand, Finder, Builder));
-}
-
-/// \brief Matches if the cast's source expression matches the given matcher.
-///
-/// Example: matches "a string" (matcher =
-/// hasSourceExpression(cxxConstructExpr()))
-/// \code
-/// class URL { URL(string); };
-/// URL url = "a string";
-/// \endcode
-AST_MATCHER_P(CastExpr, hasSourceExpression,
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr* const SubExpression = Node.getSubExpr();
- return (SubExpression != nullptr &&
- InnerMatcher.matches(*SubExpression, Finder, Builder));
-}
-
-/// \brief 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.)
-AST_MATCHER_P(ExplicitCastExpr, hasDestinationType,
- internal::Matcher<QualType>, InnerMatcher) {
- const QualType NodeType = Node.getTypeAsWritten();
- return InnerMatcher.matches(NodeType, Finder, Builder);
-}
-
-/// \brief Matches implicit casts whose destination type matches a given
-/// matcher.
-///
-/// FIXME: Unit test this matcher
-AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,
- internal::Matcher<QualType>, InnerMatcher) {
- return InnerMatcher.matches(Node.getType(), Finder, Builder);
-}
-
-/// \brief Matches RecordDecl object that are spelled with "struct."
-///
-/// Example matches S, but not C or U.
-/// \code
-/// struct S {};
-/// class C {};
-/// union U {};
-/// \endcode
-AST_MATCHER(RecordDecl, isStruct) {
- return Node.isStruct();
-}
-
-/// \brief Matches RecordDecl object that are spelled with "union."
-///
-/// Example matches U, but not C or S.
-/// \code
-/// struct S {};
-/// class C {};
-/// union U {};
-/// \endcode
-AST_MATCHER(RecordDecl, isUnion) {
- return Node.isUnion();
-}
-
-/// \brief Matches RecordDecl object that are spelled with "class."
-///
-/// Example matches C, but not S or U.
-/// \code
-/// struct S {};
-/// class C {};
-/// union U {};
-/// \endcode
-AST_MATCHER(RecordDecl, isClass) {
- return Node.isClass();
-}
-
-/// \brief Matches the true branch expression of a conditional operator.
-///
-/// Example matches a
-/// \code
-/// condition ? a : b
-/// \endcode
-AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr *Expression = Node.getTrueExpr();
- return (Expression != nullptr &&
- InnerMatcher.matches(*Expression, Finder, Builder));
-}
-
-/// \brief Matches the false branch expression of a conditional operator.
-///
-/// Example matches b
-/// \code
-/// condition ? a : b
-/// \endcode
-AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
- internal::Matcher<Expr>, InnerMatcher) {
- const Expr *Expression = Node.getFalseExpr();
- return (Expression != nullptr &&
- InnerMatcher.matches(*Expression, Finder, Builder));
-}
-
-/// \brief Matches if a declaration has a body attached.
-///
-/// Example matches A, va, fa
-/// \code
-/// class A {};
-/// class B; // Doesn't match, as it has no body.
-/// int va;
-/// extern int vb; // Doesn't match, as it doesn't define the variable.
-/// void fa() {}
-/// void fb(); // Doesn't match, as it has no body.
-/// \endcode
-///
-/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
-AST_POLYMORPHIC_MATCHER(isDefinition,
- AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl,
- FunctionDecl)) {
- return Node.isThisDeclarationADefinition();
-}
-
-/// \brief 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.
-/// \code
-/// void f(...);
-/// void g(int);
-/// template <typename... Ts> void h(Ts...);
-/// void i();
-/// \endcode
-AST_MATCHER(FunctionDecl, isVariadic) {
- return Node.isVariadic();
-}
-
-/// \brief Matches the class declaration that the given method declaration
-/// belongs to.
-///
-/// FIXME: Generalize this for other kinds of declarations.
-/// FIXME: What other kind of declarations would we need to generalize
-/// this to?
-///
-/// Example matches A() in the last line
-/// (matcher = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
-/// ofClass(hasName("A"))))))
-/// \code
-/// class A {
-/// public:
-/// A();
-/// };
-/// A a = A();
-/// \endcode
-AST_MATCHER_P(CXXMethodDecl, ofClass,
- internal::Matcher<CXXRecordDecl>, InnerMatcher) {
- const CXXRecordDecl *Parent = Node.getParent();
- return (Parent != nullptr &&
- InnerMatcher.matches(*Parent, Finder, Builder));
-}
-
-/// \brief Matches if the given method declaration is virtual.
-///
-/// Given
-/// \code
-/// class A {
-/// public:
-/// virtual void x();
-/// };
-/// \endcode
-/// matches A::x
-AST_MATCHER(CXXMethodDecl, isVirtual) {
- return Node.isVirtual();
-}
-
-/// \brief Matches if the given method or class declaration is final.
-///
-/// Given:
-/// \code
-/// class A final {};
-///
-/// struct B {
-/// virtual void f();
-/// };
-///
-/// struct C : B {
-/// void f() final;
-/// };
-/// \endcode
-/// matches A and C::f, but not B, C, or B::f
-AST_POLYMORPHIC_MATCHER(isFinal,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl,
- CXXMethodDecl)) {
- return Node.template hasAttr<FinalAttr>();
-}
-
-/// \brief Matches if the given method declaration is pure.
-///
-/// Given
-/// \code
-/// class A {
-/// public:
-/// virtual void x() = 0;
-/// };
-/// \endcode
-/// matches A::x
-AST_MATCHER(CXXMethodDecl, isPure) {
- return Node.isPure();
-}
-
-/// \brief Matches if the given method declaration is const.
-///
-/// Given
-/// \code
-/// struct A {
-/// void foo() const;
-/// void bar();
-/// };
-/// \endcode
-///
-/// cxxMethodDecl(isConst()) matches A::foo() but not A::bar()
-AST_MATCHER(CXXMethodDecl, isConst) {
- return Node.isConst();
-}
-
-/// \brief Matches if the given method declaration declares a copy assignment
-/// operator.
-///
-/// Given
-/// \code
-/// struct A {
-/// A &operator=(const A &);
-/// A &operator=(A &&);
-/// };
-/// \endcode
-///
-/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not
-/// the second one.
-AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) {
- return Node.isCopyAssignmentOperator();
-}
-
-/// \brief Matches if the given method declaration overrides another method.
-///
-/// Given
-/// \code
-/// class A {
-/// public:
-/// virtual void x();
-/// };
-/// class B : public A {
-/// public:
-/// virtual void x();
-/// };
-/// \endcode
-/// matches B::x
-AST_MATCHER(CXXMethodDecl, isOverride) {
- return Node.size_overridden_methods() > 0 || Node.hasAttr<OverrideAttr>();
-}
-
-/// \brief Matches member expressions that are called with '->' as opposed
-/// to '.'.
-///
-/// Member calls on the implicit this pointer match as called with '->'.
-///
-/// Given
-/// \code
-/// class Y {
-/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
-/// int a;
-/// static int b;
-/// };
-/// \endcode
-/// memberExpr(isArrow())
-/// matches this->x, x, y.x, a, this->b
-AST_MATCHER(MemberExpr, isArrow) {
- return Node.isArrow();
-}
-
-/// \brief Matches QualType nodes that are of integer type.
-///
-/// Given
-/// \code
-/// void a(int);
-/// void b(long);
-/// void c(double);
-/// \endcode
-/// functionDecl(hasAnyParameter(hasType(isInteger())))
-/// matches "a(int)", "b(long)", but not "c(double)".
-AST_MATCHER(QualType, isInteger) {
- return Node->isIntegerType();
-}
-
-/// \brief Matches QualType nodes that are of character type.
-///
-/// Given
-/// \code
-/// void a(char);
-/// void b(wchar_t);
-/// void c(double);
-/// \endcode
-/// functionDecl(hasAnyParameter(hasType(isAnyCharacter())))
-/// matches "a(char)", "b(wchar_t)", but not "c(double)".
-AST_MATCHER(QualType, isAnyCharacter) {
- return Node->isAnyCharacterType();
-}
-
-/// \brief Matches QualType nodes that are const-qualified, i.e., that
-/// include "top-level" const.
-///
-/// Given
-/// \code
-/// void a(int);
-/// void b(int const);
-/// void c(const int);
-/// void d(const int*);
-/// void e(int const) {};
-/// \endcode
-/// functionDecl(hasAnyParameter(hasType(isConstQualified())))
-/// matches "void b(int const)", "void c(const int)" and
-/// "void e(int const) {}". It does not match d as there
-/// is no top-level const on the parameter type "const int *".
-AST_MATCHER(QualType, isConstQualified) {
- return Node.isConstQualified();
-}
-
-/// \brief Matches QualType nodes that are volatile-qualified, i.e., that
-/// include "top-level" volatile.
-///
-/// Given
-/// \code
-/// void a(int);
-/// void b(int volatile);
-/// void c(volatile int);
-/// void d(volatile int*);
-/// void e(int volatile) {};
-/// \endcode
-/// functionDecl(hasAnyParameter(hasType(isVolatileQualified())))
-/// matches "void b(int volatile)", "void c(volatile int)" and
-/// "void e(int volatile) {}". It does not match d as there
-/// is no top-level volatile on the parameter type "volatile int *".
-AST_MATCHER(QualType, isVolatileQualified) {
- return Node.isVolatileQualified();
-}
-
-/// \brief Matches QualType nodes that have local CV-qualifiers attached to
-/// the node, not hidden within a typedef.
-///
-/// Given
-/// \code
-/// typedef const int const_int;
-/// const_int i;
-/// int *const j;
-/// int *volatile k;
-/// int m;
-/// \endcode
-/// \c varDecl(hasType(hasLocalQualifiers())) matches only \c j and \c k.
-/// \c i is const-qualified but the qualifier is not local.
-AST_MATCHER(QualType, hasLocalQualifiers) {
- return Node.hasLocalQualifiers();
-}
-
-/// \brief Matches a member expression where the member is matched by a
-/// given matcher.
-///
-/// Given
-/// \code
-/// struct { int first, second; } first, second;
-/// int i(second.first);
-/// int j(first.second);
-/// \endcode
-/// memberExpr(member(hasName("first")))
-/// matches second.first
-/// but not first.second (because the member name there is "second").
-AST_MATCHER_P(MemberExpr, member,
- internal::Matcher<ValueDecl>, InnerMatcher) {
- return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
-}
-
-/// \brief Matches a member expression where the object expression is
-/// matched by a given matcher.
-///
-/// Given
-/// \code
-/// struct X { int m; };
-/// void f(X x) { x.m; m; }
-/// \endcode
-/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
-/// matches "x.m" and "m"
-/// with hasObjectExpression(...)
-/// matching "x" and the implicit object expression of "m" which has type X*.
-AST_MATCHER_P(MemberExpr, hasObjectExpression,
- internal::Matcher<Expr>, InnerMatcher) {
- return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
-}
-
-/// \brief Matches any using shadow declaration.
-///
-/// Given
-/// \code
-/// namespace X { void b(); }
-/// using X::b;
-/// \endcode
-/// usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
-/// matches \code using X::b \endcode
-AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
- internal::Matcher<UsingShadowDecl>, InnerMatcher) {
- return matchesFirstInPointerRange(InnerMatcher, Node.shadow_begin(),
- Node.shadow_end(), Finder, Builder);
-}
-
-/// \brief Matches a using shadow declaration where the target declaration is
-/// matched by the given matcher.
-///
-/// Given
-/// \code
-/// namespace X { int a; void b(); }
-/// using X::a;
-/// using X::b;
-/// \endcode
-/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl())))
-/// matches \code using X::b \endcode
-/// but not \code using X::a \endcode
-AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
- internal::Matcher<NamedDecl>, InnerMatcher) {
- return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder);
-}
-
-/// \brief Matches template instantiations of function, class, or static
-/// member variable template instantiations.
-///
-/// Given
-/// \code
-/// template <typename T> class X {}; class A {}; X<A> x;
-/// \endcode
-/// or
-/// \code
-/// template <typename T> class X {}; class A {}; template class X<A>;
-/// \endcode
-/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
-/// matches the template instantiation of X<A>.
-///
-/// But given
-/// \code
-/// template <typename T> class X {}; class A {};
-/// template <> class X<A> {}; X<A> x;
-/// \endcode
-/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
-/// does not match, as X<A> is an explicit template specialization.
-///
-/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,
- AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
- CXXRecordDecl)) {
- return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
- Node.getTemplateSpecializationKind() ==
- TSK_ExplicitInstantiationDefinition);
-}
-
-/// \brief Matches declarations that are template instantiations or are inside
-/// template instantiations.
-///
-/// Given
-/// \code
-/// template<typename T> void A(T t) { T i; }
-/// A(0);
-/// A(0U);
-/// \endcode
-/// functionDecl(isInstantiated())
-/// matches 'A(int) {...};' and 'A(unsigned) {...}'.
-AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) {
- auto IsInstantiation = decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
- functionDecl(isTemplateInstantiation())));
- return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
-}
-
-/// \brief Matches statements inside of a template instantiation.
-///
-/// Given
-/// \code
-/// int j;
-/// template<typename T> void A(T t) { T i; j += 42;}
-/// A(0);
-/// A(0U);
-/// \endcode
-/// declStmt(isInTemplateInstantiation())
-/// matches 'int i;' and 'unsigned i'.
-/// unless(stmt(isInTemplateInstantiation()))
-/// will NOT match j += 42; as it's shared between the template definition and
-/// instantiation.
-AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) {
- return stmt(
- hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
- functionDecl(isTemplateInstantiation())))));
-}
-
-/// \brief Matches explicit template specializations of function, class, or
-/// static member variable template instantiations.
-///
-/// Given
-/// \code
-/// template<typename T> void A(T t) { }
-/// template<> void A(int N) { }
-/// \endcode
-/// functionDecl(isExplicitTemplateSpecialization())
-/// matches the specialization A<int>().
-///
-/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization,
- AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
- CXXRecordDecl)) {
- return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
-}
-
-/// \brief 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) {
- return internal::BindableMatcher<TypeLoc>(
- new internal::TypeLocTypeMatcher(InnerMatcher));
-}
-
-/// \brief Matches type \c bool.
-///
-/// Given
-/// \code
-/// struct S { bool func(); };
-/// \endcode
-/// functionDecl(returns(booleanType()))
-/// matches "bool func();"
-AST_MATCHER(Type, booleanType) {
- return Node.isBooleanType();
-}
-
-/// \brief Matches type \c void.
-///
-/// Given
-/// \code
-/// struct S { void func(); };
-/// \endcode
-/// functionDecl(returns(voidType()))
-/// matches "void func();"
-AST_MATCHER(Type, voidType) {
- return Node.isVoidType();
-}
-
-/// \brief Matches builtin Types.
-///
-/// Given
-/// \code
-/// struct A {};
-/// A a;
-/// int b;
-/// float c;
-/// bool d;
-/// \endcode
-/// builtinType()
-/// matches "int b", "float c" and "bool d"
-AST_TYPE_MATCHER(BuiltinType, builtinType);
-
-/// \brief Matches all kinds of arrays.
-///
-/// Given
-/// \code
-/// int a[] = { 2, 3 };
-/// int b[4];
-/// void f() { int c[a[0]]; }
-/// \endcode
-/// arrayType()
-/// matches "int a[]", "int b[4]" and "int c[a[0]]";
-AST_TYPE_MATCHER(ArrayType, arrayType);
-
-/// \brief Matches C99 complex types.
-///
-/// Given
-/// \code
-/// _Complex float f;
-/// \endcode
-/// complexType()
-/// matches "_Complex float f"
-AST_TYPE_MATCHER(ComplexType, complexType);
-
-/// \brief Matches arrays and C99 complex types that have a specific element
-/// type.
-///
-/// Given
-/// \code
-/// struct A {};
-/// A a[7];
-/// int b[7];
-/// \endcode
-/// arrayType(hasElementType(builtinType()))
-/// matches "int b[7]"
-///
-/// Usable as: Matcher<ArrayType>, Matcher<ComplexType>
-AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement,
- AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
- ComplexType));
-
-/// \brief Matches C arrays with a specified constant size.
-///
-/// Given
-/// \code
-/// void() {
-/// int a[2];
-/// int b[] = { 2, 3 };
-/// int c[b[0]];
-/// }
-/// \endcode
-/// constantArrayType()
-/// matches "int a[2]"
-AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
-
-/// \brief Matches \c ConstantArrayType nodes that have the specified size.
-///
-/// Given
-/// \code
-/// int a[42];
-/// int b[2 * 21];
-/// int c[41], d[43];
-/// \endcode
-/// constantArrayType(hasSize(42))
-/// matches "int a[42]" and "int b[2 * 21]"
-AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
- return Node.getSize() == N;
-}
-
-/// \brief Matches C++ arrays whose size is a value-dependent expression.
-///
-/// Given
-/// \code
-/// template<typename T, int Size>
-/// class array {
-/// T data[Size];
-/// };
-/// \endcode
-/// dependentSizedArrayType
-/// matches "T data[Size]"
-AST_TYPE_MATCHER(DependentSizedArrayType, dependentSizedArrayType);
-
-/// \brief Matches C arrays with unspecified size.
-///
-/// Given
-/// \code
-/// int a[] = { 2, 3 };
-/// int b[42];
-/// void f(int c[]) { int d[a[0]]; };
-/// \endcode
-/// incompleteArrayType()
-/// matches "int a[]" and "int c[]"
-AST_TYPE_MATCHER(IncompleteArrayType, incompleteArrayType);
-
-/// \brief Matches C arrays with a specified size that is not an
-/// integer-constant-expression.
-///
-/// Given
-/// \code
-/// void f() {
-/// int a[] = { 2, 3 }
-/// int b[42];
-/// int c[a[0]];
-/// }
-/// \endcode
-/// variableArrayType()
-/// matches "int c[a[0]]"
-AST_TYPE_MATCHER(VariableArrayType, variableArrayType);
-
-/// \brief Matches \c VariableArrayType nodes that have a specific size
-/// expression.
-///
-/// Given
-/// \code
-/// void f(int b) {
-/// int a[b];
-/// }
-/// \endcode
-/// variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
-/// varDecl(hasName("b")))))))
-/// matches "int a[b]"
-AST_MATCHER_P(VariableArrayType, hasSizeExpr,
- internal::Matcher<Expr>, InnerMatcher) {
- return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder);
-}
-
-/// \brief Matches atomic types.
-///
-/// Given
-/// \code
-/// _Atomic(int) i;
-/// \endcode
-/// atomicType()
-/// matches "_Atomic(int) i"
-AST_TYPE_MATCHER(AtomicType, atomicType);
-
-/// \brief Matches atomic types with a specific value type.
-///
-/// Given
-/// \code
-/// _Atomic(int) i;
-/// _Atomic(float) f;
-/// \endcode
-/// atomicType(hasValueType(isInteger()))
-/// matches "_Atomic(int) i"
-///
-/// Usable as: Matcher<AtomicType>
-AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue,
- AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
-
-/// \brief Matches types nodes representing C++11 auto types.
-///
-/// Given:
-/// \code
-/// auto n = 4;
-/// int v[] = { 2, 3 }
-/// for (auto i : v) { }
-/// \endcode
-/// autoType()
-/// matches "auto n" and "auto i"
-AST_TYPE_MATCHER(AutoType, autoType);
-
-/// \brief 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.
-///
-/// Given
-/// \code
-/// auto a = 1;
-/// auto b = 2.0;
-/// \endcode
-/// autoType(hasDeducedType(isInteger()))
-/// matches "auto a"
-///
-/// Usable as: Matcher<AutoType>
-AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
- AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
-
-/// \brief Matches \c FunctionType nodes.
-///
-/// Given
-/// \code
-/// int (*f)(int);
-/// void g();
-/// \endcode
-/// functionType()
-/// matches "int (*f)(int)" and the type of "g".
-AST_TYPE_MATCHER(FunctionType, functionType);
-
-/// \brief Matches \c ParenType nodes.
-///
-/// Given
-/// \code
-/// int (*ptr_to_array)[4];
-/// int *array_of_ptrs[4];
-/// \endcode
-///
-/// \c varDecl(hasType(pointsTo(parenType()))) matches \c ptr_to_array but not
-/// \c array_of_ptrs.
-AST_TYPE_MATCHER(ParenType, parenType);
-
-/// \brief Matches \c ParenType nodes where the inner type is a specific type.
-///
-/// Given
-/// \code
-/// int (*ptr_to_array)[4];
-/// int (*ptr_to_func)(int);
-/// \endcode
-///
-/// \c varDecl(hasType(pointsTo(parenType(innerType(functionType()))))) matches
-/// \c ptr_to_func but not \c ptr_to_array.
-///
-/// Usable as: Matcher<ParenType>
-AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType,
- AST_POLYMORPHIC_SUPPORTED_TYPES(ParenType));
-
-/// \brief Matches block pointer types, i.e. types syntactically represented as
-/// "void (^)(int)".
-///
-/// The \c pointee is always required to be a \c FunctionType.
-AST_TYPE_MATCHER(BlockPointerType, blockPointerType);
-
-/// \brief Matches member pointer types.
-/// Given
-/// \code
-/// struct A { int i; }
-/// A::* ptr = A::i;
-/// \endcode
-/// memberPointerType()
-/// matches "A::* ptr"
-AST_TYPE_MATCHER(MemberPointerType, memberPointerType);
-
-/// \brief Matches pointer types, but does not match Objective-C object pointer
-/// types.
-///
-/// Given
-/// \code
-/// int *a;
-/// int &b = *a;
-/// int c = 5;
-///
-/// @interface Foo
-/// @end
-/// Foo *f;
-/// \endcode
-/// pointerType()
-/// matches "int *a", but does not match "Foo *f".
-AST_TYPE_MATCHER(PointerType, pointerType);
-
-/// \brief Matches an Objective-C object pointer type, which is different from
-/// a pointer type, despite being syntactically similar.
-///
-/// Given
-/// \code
-/// int *a;
-///
-/// @interface Foo
-/// @end
-/// Foo *f;
-/// \endcode
-/// pointerType()
-/// matches "Foo *f", but does not match "int *a".
-AST_TYPE_MATCHER(ObjCObjectPointerType, objcObjectPointerType);
-
-/// \brief Matches both lvalue and rvalue reference types.
-///
-/// Given
-/// \code
-/// int *a;
-/// int &b = *a;
-/// int &&c = 1;
-/// auto &d = b;
-/// auto &&e = c;
-/// auto &&f = 2;
-/// int g = 5;
-/// \endcode
-///
-/// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f.
-AST_TYPE_MATCHER(ReferenceType, referenceType);
-
-/// \brief Matches lvalue reference types.
-///
-/// Given:
-/// \code
-/// int *a;
-/// int &b = *a;
-/// int &&c = 1;
-/// auto &d = b;
-/// auto &&e = c;
-/// auto &&f = 2;
-/// int g = 5;
-/// \endcode
-///
-/// \c lValueReferenceType() matches the types of \c b, \c d, and \c e. \c e is
-/// matched since the type is deduced as int& by reference collapsing rules.
-AST_TYPE_MATCHER(LValueReferenceType, lValueReferenceType);
-
-/// \brief Matches rvalue reference types.
-///
-/// Given:
-/// \code
-/// int *a;
-/// int &b = *a;
-/// int &&c = 1;
-/// auto &d = b;
-/// auto &&e = c;
-/// auto &&f = 2;
-/// int g = 5;
-/// \endcode
-///
-/// \c rValueReferenceType() matches the types of \c c and \c f. \c e is not
-/// matched as it is deduced to int& by reference collapsing rules.
-AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType);
-
-/// \brief Narrows PointerType (and similar) matchers to those where the
-/// \c pointee matches a given matcher.
-///
-/// Given
-/// \code
-/// int *a;
-/// int const *b;
-/// float const *f;
-/// \endcode
-/// pointerType(pointee(isConstQualified(), isInteger()))
-/// matches "int const *b"
-///
-/// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
-/// Matcher<PointerType>, Matcher<ReferenceType>
-AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee,
- AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType,
- MemberPointerType,
- PointerType,
- ReferenceType));
-
-/// \brief Matches typedef types.
-///
-/// Given
-/// \code
-/// typedef int X;
-/// \endcode
-/// typedefType()
-/// matches "typedef int X"
-AST_TYPE_MATCHER(TypedefType, typedefType);
-
-/// \brief Matches template specialization types.
-///
-/// Given
-/// \code
-/// template <typename T>
-/// class C { };
-///
-/// template class C<int>; // A
-/// C<char> var; // B
-/// \endcode
-///
-/// \c templateSpecializationType() matches the type of the explicit
-/// instantiation in \c A and the type of the variable declaration in \c B.
-AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType);
-
-/// \brief Matches types nodes representing unary type transformations.
-///
-/// Given:
-/// \code
-/// typedef __underlying_type(T) type;
-/// \endcode
-/// unaryTransformType()
-/// matches "__underlying_type(T)"
-AST_TYPE_MATCHER(UnaryTransformType, unaryTransformType);
-
-/// \brief Matches record types (e.g. structs, classes).
-///
-/// Given
-/// \code
-/// class C {};
-/// struct S {};
-///
-/// C c;
-/// S s;
-/// \endcode
-///
-/// \c recordType() matches the type of the variable declarations of both \c c
-/// and \c s.
-AST_TYPE_MATCHER(RecordType, recordType);
-
-/// \brief Matches types specified with an elaborated type keyword or with a
-/// qualified name.
-///
-/// Given
-/// \code
-/// namespace N {
-/// namespace M {
-/// class D {};
-/// }
-/// }
-/// class C {};
-///
-/// class C c;
-/// N::M::D d;
-/// \endcode
-///
-/// \c elaboratedType() matches the type of the variable declarations of both
-/// \c c and \c d.
-AST_TYPE_MATCHER(ElaboratedType, elaboratedType);
-
-/// \brief Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
-/// matches \c InnerMatcher if the qualifier exists.
-///
-/// Given
-/// \code
-/// namespace N {
-/// namespace M {
-/// class D {};
-/// }
-/// }
-/// N::M::D d;
-/// \endcode
-///
-/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
-/// matches the type of the variable declaration of \c d.
-AST_MATCHER_P(ElaboratedType, hasQualifier,
- internal::Matcher<NestedNameSpecifier>, InnerMatcher) {
- if (const NestedNameSpecifier *Qualifier = Node.getQualifier())
- return InnerMatcher.matches(*Qualifier, Finder, Builder);
-
- return false;
-}
-
-/// \brief Matches ElaboratedTypes whose named type matches \c InnerMatcher.
-///
-/// Given
-/// \code
-/// namespace N {
-/// namespace M {
-/// class D {};
-/// }
-/// }
-/// N::M::D d;
-/// \endcode
-///
-/// \c elaboratedType(namesType(recordType(
-/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable
-/// declaration of \c d.
-AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
- InnerMatcher) {
- return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
-}
-
-/// \brief Matches types that represent the result of substituting a type for a
-/// template type parameter.
-///
-/// Given
-/// \code
-/// template <typename T>
-/// void F(T t) {
-/// int i = 1 + t;
-/// }
-/// \endcode
-///
-/// \c substTemplateTypeParmType() matches the type of 't' but not '1'
-AST_TYPE_MATCHER(SubstTemplateTypeParmType, substTemplateTypeParmType);
-
-/// \brief Matches template type parameter types.
-///
-/// Example matches T, but not int.
-/// (matcher = templateTypeParmType())
-/// \code
-/// template <typename T> void f(int i);
-/// \endcode
-AST_TYPE_MATCHER(TemplateTypeParmType, templateTypeParmType);
-
-/// \brief Matches injected class name types.
-///
-/// Example matches S s, but not S<T> s.
-/// (matcher = parmVarDecl(hasType(injectedClassNameType())))
-/// \code
-/// template <typename T> struct S {
-/// void f(S s);
-/// void g(S<T> s);
-/// };
-/// \endcode
-AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType);
-
-/// \brief Matches decayed type
-/// Example matches i[] in declaration of f.
-/// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))
-/// Example matches i[1].
-/// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())))))
-/// \code
-/// void f(int i[]) {
-/// i[1] = 0;
-/// }
-/// \endcode
-AST_TYPE_MATCHER(DecayedType, decayedType);
-
-/// \brief 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
-/// Decl, matches \c InnerMatcher.
-///
-/// Given
-/// \code
-/// namespace N {
-/// namespace M {
-/// class D {};
-/// }
-/// }
-/// \endcode
-///
-/// \c cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the
-/// declaration of \c class \c D.
-AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {
- const DeclContext *DC = Node.getDeclContext();
- if (!DC) return false;
- return InnerMatcher.matches(*Decl::castFromDeclContext(DC), Finder, Builder);
-}
-
-/// \brief Matches nested name specifiers.
-///
-/// Given
-/// \code
-/// namespace ns {
-/// struct A { static void f(); };
-/// void A::f() {}
-/// void g() { A::f(); }
-/// }
-/// ns::A a;
-/// \endcode
-/// nestedNameSpecifier()
-/// matches "ns::" and both "A::"
-const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
-
-/// \brief Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc.
-const internal::VariadicAllOfMatcher<
- NestedNameSpecifierLoc> nestedNameSpecifierLoc;
-
-/// \brief Matches \c NestedNameSpecifierLocs for which the given inner
-/// NestedNameSpecifier-matcher matches.
-AST_MATCHER_FUNCTION_P_OVERLOAD(
- internal::BindableMatcher<NestedNameSpecifierLoc>, loc,
- internal::Matcher<NestedNameSpecifier>, InnerMatcher, 1) {
- return internal::BindableMatcher<NestedNameSpecifierLoc>(
- new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>(
- InnerMatcher));
-}
-
-/// \brief Matches nested name specifiers that specify a type matching the
-/// given \c QualType matcher without qualifiers.
-///
-/// Given
-/// \code
-/// struct A { struct B { struct C {}; }; };
-/// A::B::C c;
-/// \endcode
-/// nestedNameSpecifier(specifiesType(
-/// hasDeclaration(cxxRecordDecl(hasName("A")))
-/// ))
-/// matches "A::"
-AST_MATCHER_P(NestedNameSpecifier, specifiesType,
- internal::Matcher<QualType>, InnerMatcher) {
- if (!Node.getAsType())
- return false;
- return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
-}
-
-/// \brief Matches nested name specifier locs that specify a type matching the
-/// given \c TypeLoc.
-///
-/// Given
-/// \code
-/// struct A { struct B { struct C {}; }; };
-/// A::B::C c;
-/// \endcode
-/// nestedNameSpecifierLoc(specifiesTypeLoc(loc(type(
-/// hasDeclaration(cxxRecordDecl(hasName("A")))))))
-/// matches "A::"
-AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
- internal::Matcher<TypeLoc>, InnerMatcher) {
- return Node && InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
-}
-
-/// \brief Matches on the prefix of a \c NestedNameSpecifier.
-///
-/// Given
-/// \code
-/// struct A { struct B { struct C {}; }; };
-/// A::B::C c;
-/// \endcode
-/// nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))) and
-/// matches "A::"
-AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
- internal::Matcher<NestedNameSpecifier>, InnerMatcher,
- 0) {
- const NestedNameSpecifier *NextNode = Node.getPrefix();
- if (!NextNode)
- return false;
- return InnerMatcher.matches(*NextNode, Finder, Builder);
-}
-
-/// \brief Matches on the prefix of a \c NestedNameSpecifierLoc.
-///
-/// Given
-/// \code
-/// struct A { struct B { struct C {}; }; };
-/// A::B::C c;
-/// \endcode
-/// nestedNameSpecifierLoc(hasPrefix(loc(specifiesType(asString("struct A")))))
-/// matches "A::"
-AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
- internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,
- 1) {
- NestedNameSpecifierLoc NextNode = Node.getPrefix();
- if (!NextNode)
- return false;
- return InnerMatcher.matches(NextNode, Finder, Builder);
-}
-
-/// \brief Matches nested name specifiers that specify a namespace matching the
-/// given namespace matcher.
-///
-/// Given
-/// \code
-/// namespace ns { struct A {}; }
-/// ns::A a;
-/// \endcode
-/// nestedNameSpecifier(specifiesNamespace(hasName("ns")))
-/// matches "ns::"
-AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
- internal::Matcher<NamespaceDecl>, InnerMatcher) {
- if (!Node.getAsNamespace())
- return false;
- return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
-}
-
-/// \brief Overloads for the \c equalsNode matcher.
-/// FIXME: Implement for other node types.
-/// @{
-
-/// \brief 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.
-///
-/// \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.
-///
-/// \c Type has pointer identity in the AST.
-AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) {
- return &Node == Other;
-}
-
-/// @}
-
-/// \brief Matches each case or default statement belonging to the given switch
-/// statement. This matcher may produce multiple matches.
-///
-/// Given
-/// \code
-/// switch (1) { case 1: case 2: default: switch (2) { case 3: case 4: ; } }
-/// \endcode
-/// switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s")
-/// matches four times, with "c" binding each of "case 1:", "case 2:",
-/// "case 3:" and "case 4:", and "s" respectively binding "switch (1)",
-/// "switch (1)", "switch (2)" and "switch (2)".
-AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>,
- InnerMatcher) {
- BoundNodesTreeBuilder Result;
- // FIXME: getSwitchCaseList() does not necessarily guarantee a stable
- // iteration order. We should use the more general iterating matchers once
- // they are capable of expressing this matcher (for example, it should ignore
- // case statements belonging to nested switch statements).
- bool Matched = false;
- for (const SwitchCase *SC = Node.getSwitchCaseList(); SC;
- SC = SC->getNextSwitchCase()) {
- BoundNodesTreeBuilder CaseBuilder(*Builder);
- bool CaseMatched = InnerMatcher.matches(*SC, Finder, &CaseBuilder);
- if (CaseMatched) {
- Matched = true;
- Result.addMatch(CaseBuilder);
- }
- }
- *Builder = std::move(Result);
- return Matched;
-}
-
-/// \brief Matches each constructor initializer in a constructor definition.
-///
-/// Given
-/// \code
-/// class A { A() : i(42), j(42) {} int i; int j; };
-/// \endcode
-/// cxxConstructorDecl(forEachConstructorInitializer(
-/// forField(decl().bind("x"))
-/// ))
-/// will trigger two matches, binding for 'i' and 'j' respectively.
-AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer,
- internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
- BoundNodesTreeBuilder Result;
- bool Matched = false;
- for (const auto *I : Node.inits()) {
- BoundNodesTreeBuilder InitBuilder(*Builder);
- if (InnerMatcher.matches(*I, Finder, &InitBuilder)) {
- Matched = true;
- Result.addMatch(InitBuilder);
- }
- }
- *Builder = std::move(Result);
- return Matched;
-}
-
-/// \brief Matches constructor declarations that are copy constructors.
-///
-/// Given
-/// \code
-/// struct S {
-/// S(); // #1
-/// S(const S &); // #2
-/// S(S &&); // #3
-/// };
-/// \endcode
-/// cxxConstructorDecl(isCopyConstructor()) will match #2, but not #1 or #3.
-AST_MATCHER(CXXConstructorDecl, isCopyConstructor) {
- return Node.isCopyConstructor();
-}
-
-/// \brief Matches constructor declarations that are move constructors.
-///
-/// Given
-/// \code
-/// struct S {
-/// S(); // #1
-/// S(const S &); // #2
-/// S(S &&); // #3
-/// };
-/// \endcode
-/// cxxConstructorDecl(isMoveConstructor()) will match #3, but not #1 or #2.
-AST_MATCHER(CXXConstructorDecl, isMoveConstructor) {
- return Node.isMoveConstructor();
-}
-
-/// \brief Matches constructor declarations that are default constructors.
-///
-/// Given
-/// \code
-/// struct S {
-/// S(); // #1
-/// S(const S &); // #2
-/// S(S &&); // #3
-/// };
-/// \endcode
-/// cxxConstructorDecl(isDefaultConstructor()) will match #1, but not #2 or #3.
-AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) {
- return Node.isDefaultConstructor();
-}
-
-/// \brief Matches constructor and conversion declarations that are marked with
-/// the explicit keyword.
-///
-/// Given
-/// \code
-/// struct S {
-/// S(int); // #1
-/// explicit S(double); // #2
-/// operator int(); // #3
-/// explicit operator bool(); // #4
-/// };
-/// \endcode
-/// cxxConstructorDecl(isExplicit()) will match #2, but not #1.
-/// cxxConversionDecl(isExplicit()) will match #4, but not #3.
-AST_POLYMORPHIC_MATCHER(isExplicit,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl,
- CXXConversionDecl)) {
- return Node.isExplicit();
-}
-
-/// \brief Matches function and namespace declarations that are marked with
-/// the inline keyword.
-///
-/// Given
-/// \code
-/// inline void f();
-/// void g();
-/// namespace n {
-/// inline namespace m {}
-/// }
-/// \endcode
-/// functionDecl(isInline()) will match ::f().
-/// namespaceDecl(isInline()) will match n::m.
-AST_POLYMORPHIC_MATCHER(isInline,
- AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,
- FunctionDecl)) {
- // This is required because the spelling of the function used to determine
- // whether inline is specified or not differs between the polymorphic types.
- if (const auto *FD = dyn_cast<FunctionDecl>(&Node))
- return FD->isInlineSpecified();
- else if (const auto *NSD = dyn_cast<NamespaceDecl>(&Node))
- return NSD->isInline();
- llvm_unreachable("Not a valid polymorphic type");
-}
-
-/// \brief Matches anonymous namespace declarations.
-///
-/// Given
-/// \code
-/// namespace n {
-/// namespace {} // #1
-/// }
-/// \endcode
-/// namespaceDecl(isAnonymous()) will match #1 but not ::n.
-AST_MATCHER(NamespaceDecl, isAnonymous) {
- return Node.isAnonymousNamespace();
-}
-
-/// \brief If the given case statement does not use the GNU case range
-/// extension, matches the constant given in the statement.
-///
-/// Given
-/// \code
-/// switch (1) { case 1: case 1+1: case 3 ... 4: ; }
-/// \endcode
-/// caseStmt(hasCaseConstant(integerLiteral()))
-/// matches "case 1:"
-AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>,
- InnerMatcher) {
- if (Node.getRHS())
- return false;
-
- return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
-}
-
-/// \brief Matches declaration that has a given attribute.
-///
-/// Given
-/// \code
-/// __attribute__((device)) void f() { ... }
-/// \endcode
-/// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
-/// f. If the matcher is use from clang-query, attr::Kind parameter should be
-/// passed as a quoted string. e.g., hasAttr("attr::CUDADevice").
-AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) {
- for (const auto *Attr : Node.attrs()) {
- if (Attr->getKind() == AttrKind)
- return true;
- }
- return false;
-}
-
-/// \brief Matches CUDA kernel call expression.
-///
-/// Example matches,
-/// \code
-/// kernel<<<i,j>>>();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CUDAKernelCallExpr> cudaKernelCallExpr;
-
-} // end namespace ast_matchers
-} // end namespace clang
-
-#endif
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
deleted file mode 100644
index d499091..0000000
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ /dev/null
@@ -1,1591 +0,0 @@
-//===--- ASTMatchersInternal.h - Structural query framework -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Implements the base layer of the matcher framework.
-//
-// Matchers are methods that return a Matcher<T> which provides a method
-// Matches(...) which is a predicate on an AST node. The Matches method's
-// parameters define the context of the match, which allows matchers to recurse
-// or store the current node as bound to a specific string, so that it can be
-// retrieved later.
-//
-// In general, matchers have two parts:
-// 1. A function Matcher<T> MatcherName(<arguments>) which returns a Matcher<T>
-// based on the arguments and optionally on template type deduction based
-// on the arguments. Matcher<T>s form an implicit reverse hierarchy
-// to clang's AST class hierarchy, meaning that you can use a Matcher<Base>
-// everywhere a Matcher<Derived> is required.
-// 2. An implementation of a class derived from MatcherInterface<T>.
-//
-// The matcher functions are defined in ASTMatchers.h. To make it possible
-// to implement both the matcher function and the implementation of the matcher
-// interface in one place, ASTMatcherMacros.h defines macros that allow
-// implementing a matcher in a single place.
-//
-// This file contains the base classes needed to construct the actual matchers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
-#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
-
-#include "clang/AST/ASTTypeTraits.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-#include "clang/AST/Type.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/VariadicFunction.h"
-#include "llvm/Support/ManagedStatic.h"
-#include <map>
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace ast_matchers {
-
-class BoundNodes;
-
-namespace internal {
-
-/// \brief Internal version of BoundNodes. Holds all the bound nodes.
-class BoundNodesMap {
-public:
- /// \brief 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 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.
- template <typename T>
- const T *getNodeAs(StringRef ID) const {
- IDToNodeMap::const_iterator It = NodeMap.find(ID);
- if (It == NodeMap.end()) {
- return nullptr;
- }
- return It->second.get<T>();
- }
-
- ast_type_traits::DynTypedNode getNode(StringRef ID) const {
- IDToNodeMap::const_iterator It = NodeMap.find(ID);
- if (It == NodeMap.end()) {
- return ast_type_traits::DynTypedNode();
- }
- return It->second;
- }
-
- /// \brief Imposes an order on BoundNodesMaps.
- bool operator<(const BoundNodesMap &Other) const {
- return NodeMap < Other.NodeMap;
- }
-
- /// \brief A map from IDs to the bound nodes.
- ///
- /// Note that we're using std::map here, as for memoization:
- /// - we need a comparison operator
- /// - we need an assignment operator
- typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap;
-
- const IDToNodeMap &getMap() const {
- return NodeMap;
- }
-
- /// \brief 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) {
- if (!IDAndNode.second.getMemoizationData())
- return false;
- }
- return true;
- }
-
-private:
- IDToNodeMap NodeMap;
-};
-
-/// \brief 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
- /// BoundNodesTree.
- class Visitor {
- public:
- virtual ~Visitor() {}
-
- /// \brief 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.
- void setBinding(StringRef Id, const ast_type_traits::DynTypedNode &DynNode) {
- if (Bindings.empty())
- Bindings.emplace_back();
- for (BoundNodesMap &Binding : Bindings)
- Binding.addNode(Id, DynNode);
- }
-
- /// \brief Adds a branch in the tree.
- void addMatch(const BoundNodesTreeBuilder &Bindings);
-
- /// \brief Visits all matches that this BoundNodesTree represents.
- ///
- /// The ownership of 'ResultVisitor' remains at the caller.
- void visitMatches(Visitor* ResultVisitor);
-
- template <typename ExcludePredicate>
- bool removeBindings(const ExcludePredicate &Predicate) {
- Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate),
- Bindings.end());
- return !Bindings.empty();
- }
-
- /// \brief 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,
- /// i.e. all stored node maps have memoization data.
- bool isComparable() const {
- for (const BoundNodesMap &NodesMap : Bindings) {
- if (!NodesMap.isComparable())
- return false;
- }
- return true;
- }
-
-private:
- SmallVector<BoundNodesMap, 16> Bindings;
-};
-
-class ASTMatchFinder;
-
-/// \brief Generic interface for all matchers.
-///
-/// Used by the implementation of Matcher<T> and DynTypedMatcher.
-/// In general, implement MatcherInterface<T> or SingleNodeMatcherInterface<T>
-/// instead.
-class DynMatcherInterface
- : public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
-public:
- virtual ~DynMatcherInterface() {}
-
- /// \brief 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.
- virtual bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const = 0;
-};
-
-/// \brief 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
-/// writing a simple matcher that only inspects properties of the
-/// current node and doesn't care about its children or descendants,
-/// implement SingleNodeMatcherInterface instead.
-template <typename T>
-class MatcherInterface : public DynMatcherInterface {
-public:
- /// \brief Returns true if 'Node' can be matched.
- ///
- /// May bind 'Node' to an ID via 'Builder', or recurse into
- /// the AST via 'Finder'.
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const = 0;
-
- bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return matches(DynNode.getUnchecked<T>(), Finder, Builder);
- }
-};
-
-/// \brief 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.
- ///
- /// A subclass must implement this instead of Matches().
- virtual bool matchesNode(const T &Node) const = 0;
-
-private:
- /// Implements MatcherInterface::Matches.
- bool matches(const T &Node,
- ASTMatchFinder * /* Finder */,
- BoundNodesTreeBuilder * /* Builder */) const override {
- return matchesNode(Node);
- }
-};
-
-template <typename> class Matcher;
-
-/// \brief Matcher that works on a \c DynTypedNode.
-///
-/// It is constructed from a \c Matcher<T> object and redirects most calls to
-/// underlying matcher.
-/// It checks whether the \c DynTypedNode is convertible into the type of the
-/// underlying matcher and then do the actual match on the actual node, or
-/// return false if it is not convertible.
-class DynTypedMatcher {
-public:
- /// \brief Takes ownership of the provided implementation pointer.
- template <typename T>
- DynTypedMatcher(MatcherInterface<T> *Implementation)
- : AllowBind(false),
- SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
- RestrictKind(SupportedKind), Implementation(Implementation) {}
-
- /// \brief Construct from a variadic function.
- enum VariadicOperator {
- /// \brief Matches nodes for which all provided matchers match.
- VO_AllOf,
- /// \brief 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, but doesn't stop at the first match.
- VO_EachOf,
- /// \brief Matches nodes that do not match the provided matcher.
- ///
- /// Uses the variadic matcher interface, but fails if
- /// InnerMatchers.size() != 1.
- VO_UnaryNot
- };
- static DynTypedMatcher
- constructVariadic(VariadicOperator Op,
- ast_type_traits::ASTNodeKind SupportedKind,
- std::vector<DynTypedMatcher> InnerMatchers);
-
- /// \brief 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.
- /// \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
- /// 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.
- bool matches(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const;
-
- /// \brief 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.
- bool matchesNoKindCheck(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const;
-
- /// \brief 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.
- ///
- /// Casting a Matcher<T> to Matcher<U> creates a matcher that has the
- /// same \c Implementation pointer, but different \c RestrictKind. We need to
- /// include both in the ID to make it unique.
- ///
- /// \c MatcherIDType supports operator< and provides strict weak ordering.
- typedef std::pair<ast_type_traits::ASTNodeKind, uint64_t> MatcherIDType;
- MatcherIDType getID() const {
- /// FIXME: Document the requirements this imposes on matcher
- /// implementations (no new() implementation_ during a Matches()).
- return std::make_pair(RestrictKind,
- reinterpret_cast<uint64_t>(Implementation.get()));
- }
-
- /// \brief Returns the type this matcher works on.
- ///
- /// \c matches() will always return false unless the node passed is of this
- /// or a derived type.
- ast_type_traits::ASTNodeKind getSupportedKind() const {
- return SupportedKind;
- }
-
- /// \brief 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
- /// nodes of types T.
- template <typename T> bool canConvertTo() const {
- return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
- }
- bool canConvertTo(ast_type_traits::ASTNodeKind To) const;
-
- /// \brief 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
- /// compatible with T.
- template <typename T> Matcher<T> convertTo() const {
- assert(canConvertTo<T>());
- return unconditionalConvertTo<T>();
- }
-
- /// \brief 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.
- template <typename T> Matcher<T> unconditionalConvertTo() const;
-
-private:
- DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
- ast_type_traits::ASTNodeKind RestrictKind,
- IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
- : AllowBind(false),
- SupportedKind(SupportedKind),
- RestrictKind(RestrictKind),
- Implementation(std::move(Implementation)) {}
-
- bool AllowBind;
- ast_type_traits::ASTNodeKind SupportedKind;
- /// \brief A potentially stricter node kind.
- ///
- /// It allows to perform implicit and dynamic cast of matchers without
- /// needing to change \c Implementation.
- ast_type_traits::ASTNodeKind RestrictKind;
- IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
-};
-
-/// \brief 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.
-template <typename T>
-class WrapperMatcherInterface : public MatcherInterface<T> {
-protected:
- explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher)
- : InnerMatcher(std::move(InnerMatcher)) {}
-
- const DynTypedMatcher InnerMatcher;
-};
-
-/// \brief 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
-/// to the AST hierarchy. In other words, Matcher<T> is contravariant
-/// with respect to T. The relationship is built via a type conversion
-/// operator rather than a type hierarchy to be able to templatize the
-/// type hierarchy instead of spelling it out.
-template <typename T>
-class Matcher {
-public:
- /// \brief Takes ownership of the provided implementation pointer.
- explicit Matcher(MatcherInterface<T> *Implementation)
- : Implementation(Implementation) {}
-
- /// \brief Implicitly converts \c Other to a Matcher<T>.
- ///
- /// Requires \c T to be derived from \c From.
- template <typename From>
- Matcher(const Matcher<From> &Other,
- typename std::enable_if<std::is_base_of<From, T>::value &&
- !std::is_same<From, T>::value>::type * = 0)
- : Implementation(restrictMatcher(Other.Implementation)) {
- assert(Implementation.getSupportedKind().isSame(
- ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
- }
-
- /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
- ///
- /// The resulting matcher is not strict, i.e. ignores qualifiers.
- template <typename TypeT>
- Matcher(const Matcher<TypeT> &Other,
- typename std::enable_if<
- std::is_same<T, QualType>::value &&
- std::is_same<TypeT, Type>::value>::type* = 0)
- : Implementation(new TypeToQualType<TypeT>(Other)) {}
-
- /// \brief 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>
- Matcher<To> dynCastTo() const {
- static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
- return Matcher<To>(Implementation);
- }
-
- /// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
- bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return Implementation.matches(ast_type_traits::DynTypedNode::create(Node),
- Finder, Builder);
- }
-
- /// \brief Returns an ID that uniquely identifies the matcher.
- DynTypedMatcher::MatcherIDType getID() const {
- return Implementation.getID();
- }
-
- /// \brief 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
- /// Matcher<QualType>.
- ///
- /// Depending on the constructor argument, the matcher is either strict, i.e.
- /// does only matches in the absence of qualifiers, or not, i.e. simply
- /// ignores any qualifiers.
- template <typename TypeT>
- class TypeToQualType : public WrapperMatcherInterface<QualType> {
- public:
- TypeToQualType(const Matcher<TypeT> &InnerMatcher)
- : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {}
-
- bool matches(const QualType &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- if (Node.isNull())
- return false;
- return this->InnerMatcher.matches(
- ast_type_traits::DynTypedNode::create(*Node), Finder, Builder);
- }
- };
-
-private:
- // For Matcher<T> <=> Matcher<U> conversions.
- template <typename U> friend class Matcher;
- // For DynTypedMatcher::unconditionalConvertTo<T>.
- friend class DynTypedMatcher;
-
- static DynTypedMatcher restrictMatcher(const DynTypedMatcher &Other) {
- return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
- }
-
- explicit Matcher(const DynTypedMatcher &Implementation)
- : Implementation(restrictMatcher(Implementation)) {
- assert(this->Implementation.getSupportedKind()
- .isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
- }
-
- DynTypedMatcher Implementation;
-}; // class Matcher
-
-/// \brief 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.
-///
-/// This specialization provides the Matcher<Type>->Matcher<QualType>
-/// conversion that the static API does.
-template <>
-inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
- assert(canConvertTo<QualType>());
- const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
- if (SourceKind.isSame(
- ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
- // We support implicit conversion from Matcher<Type> to Matcher<QualType>
- return unconditionalConvertTo<Type>();
- }
- return unconditionalConvertTo<QualType>();
-}
-
-/// \brief 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,
- BoundNodesTreeBuilder *Builder) {
- for (IteratorT I = Start; I != End; ++I) {
- BoundNodesTreeBuilder Result(*Builder);
- if (Matcher.matches(*I, Finder, &Result)) {
- *Builder = std::move(Result);
- return true;
- }
- }
- return false;
-}
-
-/// \brief 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,
- IteratorT End, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) {
- for (IteratorT I = Start; I != End; ++I) {
- BoundNodesTreeBuilder Result(*Builder);
- if (Matcher.matches(**I, Finder, &Result)) {
- *Builder = std::move(Result);
- return true;
- }
- }
- return false;
-}
-
-// Metafunction to determine if type T has a member called
-// getDecl.
-#if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(__clang__)
-// For old versions of MSVC, we use a weird nonstandard __if_exists
-// statement, since before MSVC2015, it was not standards-conformant
-// enough to compile the usual code below.
-template <typename T> struct has_getDecl {
- __if_exists(T::getDecl) {
- enum { value = 1 };
- }
- __if_not_exists(T::getDecl) {
- enum { value = 0 };
- }
-};
-#else
-// There is a default template inheriting from "false_type". Then, a
-// partial specialization inherits from "true_type". However, this
-// specialization will only exist when the call to getDecl() isn't an
-// error -- it vanishes by SFINAE when the member doesn't exist.
-template <typename> struct type_sink_to_void { typedef void type; };
-template <typename T, typename = void> struct has_getDecl : std::false_type {};
-template <typename T>
-struct has_getDecl<
- T, typename type_sink_to_void<decltype(std::declval<T>().getDecl())>::type>
- : std::true_type {};
-#endif
-
-/// \brief 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.
-template <typename T, typename ArgT>
-class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
- static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
- std::is_base_of<FunctionDecl, T>::value,
- "unsupported class for matcher");
- static_assert(std::is_same<ArgT, StringRef>::value,
- "argument type must be StringRef");
-
-public:
- explicit HasOverloadedOperatorNameMatcher(const StringRef Name)
- : SingleNodeMatcherInterface<T>(), Name(Name) {}
-
- bool matchesNode(const T &Node) const override {
- return matchesSpecialized(Node);
- }
-
-private:
-
- /// \brief 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
- /// operator and has the given operator name.
- bool matchesSpecialized(const FunctionDecl &Node) const {
- return Node.isOverloadedOperator() &&
- getOperatorSpelling(Node.getOverloadedOperator()) == Name;
- }
-
- std::string Name;
-};
-
-/// \brief Matches named declarations with a specific name.
-///
-/// See \c hasName() in ASTMatchers.h for details.
-class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
- public:
- explicit HasNameMatcher(StringRef Name);
-
- bool matchesNode(const NamedDecl &Node) const override;
-
- private:
- /// \brief 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
- ///
- /// It generates the fully qualified name of the declaration (which is
- /// expensive) before trying to match.
- /// It is slower but simple and works on all cases.
- bool matchesNodeFull(const NamedDecl &Node) const;
-
- const bool UseUnqualifiedMatch;
- const std::string Name;
-};
-
-/// \brief Matches declarations for QualType and CallExpr.
-///
-/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
-/// not actually used.
-template <typename T, typename DeclMatcherT>
-class HasDeclarationMatcher : public WrapperMatcherInterface<T> {
- static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
- "instantiated with wrong types");
-
-public:
- explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
- : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return matchesSpecialized(Node, Finder, Builder);
- }
-
-private:
- /// \brief If getDecl exists as a member of U, returns whether the inner
- /// matcher matches Node.getDecl().
- template <typename U>
- bool matchesSpecialized(
- const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
- typename std::enable_if<has_getDecl<U>::value, int>::type = 0) const {
- return matchesDecl(Node.getDecl(), Finder, Builder);
- }
-
- /// \brief Extracts the TagDecl of a QualType and returns whether the inner
- /// matcher matches on it.
- bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- if (Node.isNull())
- return false;
-
- if (auto *TD = Node->getAsTagDecl())
- return matchesDecl(TD, Finder, Builder);
- else if (auto *TT = Node->getAs<TypedefType>())
- return matchesDecl(TT->getDecl(), Finder, Builder);
- // Do not use getAs<TemplateTypeParmType> instead of the direct dyn_cast.
- // Calling getAs will return the canonical type, but that type does not
- // store a TemplateTypeParmDecl. We *need* the uncanonical type, if it is
- // available, and using dyn_cast ensures that.
- else if (auto *TTP = dyn_cast<TemplateTypeParmType>(Node.getTypePtr()))
- return matchesDecl(TTP->getDecl(), Finder, Builder);
- else if (auto *OCIT = Node->getAs<ObjCInterfaceType>())
- return matchesDecl(OCIT->getDecl(), Finder, Builder);
- else if (auto *UUT = Node->getAs<UnresolvedUsingType>())
- return matchesDecl(UUT->getDecl(), Finder, Builder);
- else if (auto *ICNT = Node->getAs<InjectedClassNameType>())
- return matchesDecl(ICNT->getDecl(), Finder, Builder);
- return false;
- }
-
- /// \brief Gets the TemplateDecl from a TemplateSpecializationType
- /// and returns whether the inner matches on it.
- bool matchesSpecialized(const TemplateSpecializationType &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return matchesDecl(Node.getTemplateName().getAsTemplateDecl(),
- Finder, Builder);
- }
-
- /// \brief 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
- /// inner matcher matches on it.
- bool matchesSpecialized(const CXXConstructExpr &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return matchesDecl(Node.getConstructor(), Finder, Builder);
- }
-
- /// \brief 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,
- BoundNodesTreeBuilder *Builder) const {
- return matchesDecl(Node.getMemberDecl(), Finder, Builder);
- }
-
- /// \brief 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 {
- return Node != nullptr &&
- this->InnerMatcher.matches(
- ast_type_traits::DynTypedNode::create(*Node), Finder, Builder);
- }
-};
-
-/// \brief IsBaseType<T>::value is true if T is a "base" type in the AST
-/// node class hierarchies.
-template <typename T>
-struct IsBaseType {
- static const bool value =
- std::is_same<T, Decl>::value ||
- std::is_same<T, Stmt>::value ||
- std::is_same<T, QualType>::value ||
- std::is_same<T, Type>::value ||
- std::is_same<T, TypeLoc>::value ||
- std::is_same<T, NestedNameSpecifier>::value ||
- std::is_same<T, NestedNameSpecifierLoc>::value ||
- std::is_same<T, CXXCtorInitializer>::value;
-};
-template <typename T>
-const bool IsBaseType<T>::value;
-
-/// \brief 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:
-/// - \c matchesChildOf:
-/// Matches a matcher on every child node of the given node. Returns true
-/// if at least one child node could be matched.
-/// - \c matchesDescendantOf:
-/// Matches a matcher on all descendant nodes of the given node. Returns true
-/// if at least one descendant matched.
-/// - \c matchesAncestorOf:
-/// Matches a matcher on all ancestors of the given node. Returns true if
-/// at least one ancestor matched.
-///
-/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal.
-/// In the future, we want to implement this for all nodes for which it makes
-/// sense. In the case of matchesAncestorOf, we'll want to implement it for
-/// all nodes, as all nodes have ancestors.
-class ASTMatchFinder {
-public:
- /// \brief Defines how we descend a level in the AST when we pass
- /// through expressions.
- enum TraversalKind {
- /// Will traverse any child nodes.
- TK_AsIs,
- /// Will not traverse implicit casts and parentheses.
- TK_IgnoreImplicitCastsAndParentheses
- };
-
- /// \brief Defines how bindings are processed on recursive matches.
- enum BindKind {
- /// Stop at the first match and only bind the first match.
- BK_First,
- /// Create results for all combinations of bindings that match.
- BK_All
- };
-
- /// \brief Defines which ancestors are considered for a match.
- enum AncestorMatchMode {
- /// All ancestors.
- AMM_All,
- /// Direct parent only.
- AMM_ParentOnly
- };
-
- virtual ~ASTMatchFinder() {}
-
- /// \brief 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.
- virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
- const Matcher<NamedDecl> &Base,
- BoundNodesTreeBuilder *Builder) = 0;
-
- template <typename T>
- bool matchesChildOf(const T &Node,
- const DynTypedMatcher &Matcher,
- BoundNodesTreeBuilder *Builder,
- TraversalKind Traverse,
- BindKind Bind) {
- static_assert(std::is_base_of<Decl, T>::value ||
- std::is_base_of<Stmt, T>::value ||
- std::is_base_of<NestedNameSpecifier, T>::value ||
- std::is_base_of<NestedNameSpecifierLoc, T>::value ||
- std::is_base_of<TypeLoc, T>::value ||
- std::is_base_of<QualType, T>::value,
- "unsupported type for recursive matching");
- return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
- Matcher, Builder, Traverse, Bind);
- }
-
- template <typename T>
- bool matchesDescendantOf(const T &Node,
- const DynTypedMatcher &Matcher,
- BoundNodesTreeBuilder *Builder,
- BindKind Bind) {
- static_assert(std::is_base_of<Decl, T>::value ||
- std::is_base_of<Stmt, T>::value ||
- std::is_base_of<NestedNameSpecifier, T>::value ||
- std::is_base_of<NestedNameSpecifierLoc, T>::value ||
- std::is_base_of<TypeLoc, T>::value ||
- std::is_base_of<QualType, T>::value,
- "unsupported type for recursive matching");
- return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
- Matcher, Builder, Bind);
- }
-
- // FIXME: Implement support for BindKind.
- template <typename T>
- bool matchesAncestorOf(const T &Node,
- const DynTypedMatcher &Matcher,
- BoundNodesTreeBuilder *Builder,
- AncestorMatchMode MatchMode) {
- static_assert(std::is_base_of<Decl, T>::value ||
- std::is_base_of<NestedNameSpecifierLoc, T>::value ||
- std::is_base_of<Stmt, T>::value ||
- std::is_base_of<TypeLoc, T>::value,
- "type not allowed for recursive matching");
- return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
- Matcher, Builder, MatchMode);
- }
-
- virtual ASTContext &getASTContext() const = 0;
-
-protected:
- virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
- const DynTypedMatcher &Matcher,
- BoundNodesTreeBuilder *Builder,
- TraversalKind Traverse,
- BindKind Bind) = 0;
-
- virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
- const DynTypedMatcher &Matcher,
- BoundNodesTreeBuilder *Builder,
- BindKind Bind) = 0;
-
- virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
- const DynTypedMatcher &Matcher,
- BoundNodesTreeBuilder *Builder,
- AncestorMatchMode MatchMode) = 0;
-};
-
-/// \brief 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.
- typedef T1 head;
-
- /// \brief 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.
- typedef TypeList<Ts...> tail;
-};
-
-/// \brief The empty type list.
-typedef TypeList<> EmptyTypeList;
-
-/// \brief 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 {
- static const bool value =
- std::is_base_of<typename AnyTypeList::head, T>::value ||
- TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
-};
-template <typename T>
-struct TypeListContainsSuperOf<EmptyTypeList, T> {
- static const bool value = false;
-};
-
-/// \brief A "type list" that contains all types.
-///
-/// Useful for matchers like \c anything and \c unless.
-typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
- QualType, Type, TypeLoc, CXXCtorInitializer> AllNodeBaseTypes;
-
-/// \brief Helper meta-function to extract the argument out of a function of
-/// type void(Arg).
-///
-/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
-template <class T> struct ExtractFunctionArgMeta;
-template <class T> struct ExtractFunctionArgMeta<void(T)> {
- typedef T type;
-};
-
-/// \brief Default type lists for ArgumentAdaptingMatcher matchers.
-typedef AllNodeBaseTypes AdaptativeDefaultFromTypes;
-typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
- TypeLoc, QualType> AdaptativeDefaultToTypes;
-
-/// \brief All types that are supported by HasDeclarationMatcher above.
-typedef TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType,
- InjectedClassNameType, LabelStmt, MemberExpr, QualType,
- RecordType, TagType, TemplateSpecializationType,
- TemplateTypeParmType, TypedefType,
- UnresolvedUsingType> HasDeclarationSupportedTypes;
-
-/// \brief 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.
-///
-/// For example:
-/// \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher);
-/// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher
-/// that is convertible into any matcher of type \c To by constructing
-/// \c HasMatcher<To, T>(InnerMatcher).
-///
-/// If a matcher does not need knowledge about the inner type, prefer to use
-/// PolymorphicMatcherWithParam1.
-template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
- typename FromTypes = AdaptativeDefaultFromTypes,
- typename ToTypes = AdaptativeDefaultToTypes>
-struct ArgumentAdaptingMatcherFunc {
- template <typename T> class Adaptor {
- public:
- explicit Adaptor(const Matcher<T> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- typedef ToTypes ReturnTypes;
-
- template <typename To> operator Matcher<To>() const {
- return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
- }
-
- private:
- const Matcher<T> InnerMatcher;
- };
-
- template <typename T>
- static Adaptor<T> create(const Matcher<T> &InnerMatcher) {
- return Adaptor<T>(InnerMatcher);
- }
-
- template <typename T>
- Adaptor<T> operator()(const Matcher<T> &InnerMatcher) const {
- return create(InnerMatcher);
- }
-};
-
-/// \brief 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.
-///
-/// For example:
-/// - PolymorphicMatcherWithParam0<IsDefinitionMatcher>()
-/// creates an object that can be used as a Matcher<T> for any type T
-/// where an IsDefinitionMatcher<T>() can be constructed.
-/// - PolymorphicMatcherWithParam1<ValueEqualsMatcher, int>(42)
-/// creates an object that can be used as a Matcher<T> for any type T
-/// where a ValueEqualsMatcher<T, int>(42) can be constructed.
-template <template <typename T> class MatcherT,
- typename ReturnTypesF = void(AllNodeBaseTypes)>
-class PolymorphicMatcherWithParam0 {
-public:
- typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
- template <typename T>
- operator Matcher<T>() const {
- static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
- "right polymorphic conversion");
- return Matcher<T>(new MatcherT<T>());
- }
-};
-
-template <template <typename T, typename P1> class MatcherT,
- typename P1,
- typename ReturnTypesF = void(AllNodeBaseTypes)>
-class PolymorphicMatcherWithParam1 {
-public:
- explicit PolymorphicMatcherWithParam1(const P1 &Param1)
- : Param1(Param1) {}
-
- typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
-
- template <typename T>
- operator Matcher<T>() const {
- static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
- "right polymorphic conversion");
- return Matcher<T>(new MatcherT<T, P1>(Param1));
- }
-
-private:
- const P1 Param1;
-};
-
-template <template <typename T, typename P1, typename P2> class MatcherT,
- typename P1, typename P2,
- typename ReturnTypesF = void(AllNodeBaseTypes)>
-class PolymorphicMatcherWithParam2 {
-public:
- PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
- : Param1(Param1), Param2(Param2) {}
-
- typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
-
- template <typename T>
- operator Matcher<T>() const {
- static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
- "right polymorphic conversion");
- return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
- }
-
-private:
- const P1 Param1;
- const P2 Param2;
-};
-
-/// \brief 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().
-class TrueMatcher {
- public:
- typedef AllNodeBaseTypes ReturnTypes;
-
- template <typename T>
- operator Matcher<T>() const {
- return DynTypedMatcher::trueMatcher(
- ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
- .template unconditionalConvertTo<T>();
- }
-};
-
-/// \brief 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.
-template <typename T>
-class BindableMatcher : public Matcher<T> {
-public:
- explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {}
- explicit BindableMatcher(MatcherInterface<T> *Implementation)
- : Matcher<T>(Implementation) {}
-
- /// \brief 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.
- Matcher<T> bind(StringRef ID) const {
- return DynTypedMatcher(*this)
- .tryBind(ID)
- ->template unconditionalConvertTo<T>();
- }
-
- /// \brief 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);
- Result.setAllowBind(true);
- return Result;
- }
-};
-
-/// \brief 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.
-template <typename T, typename ChildT>
-class HasMatcher : public WrapperMatcherInterface<T> {
- static_assert(IsBaseType<ChildT>::value,
- "has only accepts base type matcher");
-
-public:
- explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
- : HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return Finder->matchesChildOf(
- Node, this->InnerMatcher, Builder,
- ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
- ASTMatchFinder::BK_First);
- }
-};
-
-/// \brief 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
-/// for each child that matches.
-template <typename T, typename ChildT>
-class ForEachMatcher : public WrapperMatcherInterface<T> {
- static_assert(IsBaseType<ChildT>::value,
- "for each only accepts base type matcher");
-
- public:
- explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher)
- : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {}
-
- bool matches(const T& Node, ASTMatchFinder* Finder,
- BoundNodesTreeBuilder* Builder) const override {
- return Finder->matchesChildOf(
- Node, this->InnerMatcher, Builder,
- ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
- ASTMatchFinder::BK_All);
- }
-};
-
-/// \brief VariadicOperatorMatcher related types.
-/// @{
-
-/// \brief Polymorphic matcher object that uses a \c
-/// DynTypedMatcher::VariadicOperator operator.
-///
-/// Input matchers can have any type (including other polymorphic matcher
-/// types), and the actual Matcher<T> is generated on demand with an implicit
-/// coversion operator.
-template <typename... Ps> class VariadicOperatorMatcher {
-public:
- VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
- : Op(Op), Params(std::forward<Ps>(Params)...) {}
-
- template <typename T> operator Matcher<T>() const {
- return DynTypedMatcher::constructVariadic(
- Op, ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
- getMatchers<T>(llvm::index_sequence_for<Ps...>()))
- .template unconditionalConvertTo<T>();
- }
-
-private:
- // Helper method to unpack the tuple into a vector.
- template <typename T, std::size_t... Is>
- std::vector<DynTypedMatcher> getMatchers(llvm::index_sequence<Is...>) const {
- return {Matcher<T>(std::get<Is>(Params))...};
- }
-
- const DynTypedMatcher::VariadicOperator Op;
- std::tuple<Ps...> Params;
-};
-
-/// \brief Overloaded function object to generate VariadicOperatorMatcher
-/// objects from arbitrary matchers.
-template <unsigned MinCount, unsigned MaxCount>
-struct VariadicOperatorMatcherFunc {
- DynTypedMatcher::VariadicOperator Op;
-
- template <typename... Ms>
- VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const {
- static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount,
- "invalid number of parameters for variadic matcher");
- return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
- }
-};
-
-/// @}
-
-template <typename T>
-inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
- return Matcher<T>(*this);
-}
-
-/// \brief Creates a Matcher<T> that matches if all inner matchers match.
-template<typename T>
-BindableMatcher<T> makeAllOfComposite(
- ArrayRef<const Matcher<T> *> InnerMatchers) {
- // For the size() == 0 case, we return a "true" matcher.
- if (InnerMatchers.size() == 0) {
- return BindableMatcher<T>(TrueMatcher());
- }
- // For the size() == 1 case, we simply return that one matcher.
- // No need to wrap it in a variadic operation.
- if (InnerMatchers.size() == 1) {
- return BindableMatcher<T>(*InnerMatchers[0]);
- }
-
- typedef llvm::pointee_iterator<const Matcher<T> *const *> PI;
- std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
- PI(InnerMatchers.end()));
- return BindableMatcher<T>(
- DynTypedMatcher::constructVariadic(
- DynTypedMatcher::VO_AllOf,
- ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
- std::move(DynMatchers))
- .template unconditionalConvertTo<T>());
-}
-
-/// \brief 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
-/// the same object both to match on and to run submatchers on,
-/// so there is no ambiguity with what gets bound.
-template<typename T, typename InnerT>
-BindableMatcher<T> makeDynCastAllOfComposite(
- ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
- return BindableMatcher<T>(
- makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
-}
-
-/// \brief 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.
-template <typename T, typename DescendantT>
-class HasDescendantMatcher : public WrapperMatcherInterface<T> {
- static_assert(IsBaseType<DescendantT>::value,
- "has descendant only accepts base type matcher");
-
-public:
- explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
- : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
- ASTMatchFinder::BK_First);
- }
-};
-
-/// \brief 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.
-template <typename T, typename ParentT>
-class HasParentMatcher : public WrapperMatcherInterface<T> {
- static_assert(IsBaseType<ParentT>::value,
- "has parent only accepts base type matcher");
-
-public:
- explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
- : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
- ASTMatchFinder::AMM_ParentOnly);
- }
-};
-
-/// \brief 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.
-template <typename T, typename AncestorT>
-class HasAncestorMatcher : public WrapperMatcherInterface<T> {
- static_assert(IsBaseType<AncestorT>::value,
- "has ancestor only accepts base type matcher");
-
-public:
- explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
- : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
- ASTMatchFinder::AMM_All);
- }
-};
-
-/// \brief 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.
-/// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match
-/// for each descendant node that matches instead of only for the first.
-template <typename T, typename DescendantT>
-class ForEachDescendantMatcher : public WrapperMatcherInterface<T> {
- static_assert(IsBaseType<DescendantT>::value,
- "for each descendant only accepts base type matcher");
-
-public:
- explicit ForEachDescendantMatcher(
- const Matcher<DescendantT> &DescendantMatcher)
- : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
- ASTMatchFinder::BK_All);
- }
-};
-
-/// \brief 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> {
- static_assert(std::is_base_of<CharacterLiteral, T>::value ||
- std::is_base_of<CXXBoolLiteralExpr, T>::value ||
- std::is_base_of<FloatingLiteral, T>::value ||
- std::is_base_of<IntegerLiteral, T>::value,
- "the node must have a getValue method");
-
-public:
- explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
- : ExpectedValue(ExpectedValue) {}
-
- bool matchesNode(const T &Node) const override {
- return Node.getValue() == ExpectedValue;
- }
-
-private:
- const ValueT ExpectedValue;
-};
-
-/// \brief Template specializations to easily write matchers for floating point
-/// literals.
-template <>
-inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
- const FloatingLiteral &Node) const {
- if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
- return Node.getValue().convertToFloat() == ExpectedValue;
- if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
- return Node.getValue().convertToDouble() == ExpectedValue;
- return false;
-}
-template <>
-inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
- const FloatingLiteral &Node) const {
- if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
- return Node.getValue().convertToFloat() == ExpectedValue;
- if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
- return Node.getValue().convertToDouble() == ExpectedValue;
- return false;
-}
-template <>
-inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
- const FloatingLiteral &Node) const {
- return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
-}
-
-/// \brief 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.
-///
-/// For example:
-/// const VariadicDynCastAllOfMatcher<
-/// Decl, CXXRecordDecl> record;
-/// Creates a functor record(...) that creates a Matcher<Decl> given
-/// a variable number of arguments of type Matcher<CXXRecordDecl>.
-/// The returned matcher matches if the given Decl can by dynamically
-/// casted to CXXRecordDecl and all given matchers match.
-template <typename SourceT, typename TargetT>
-class VariadicDynCastAllOfMatcher
- : public llvm::VariadicFunction<
- BindableMatcher<SourceT>, Matcher<TargetT>,
- makeDynCastAllOfComposite<SourceT, TargetT> > {
-public:
- VariadicDynCastAllOfMatcher() {}
-};
-
-/// \brief 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.
-///
-/// For example:
-/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
-/// Creates a functor nestedNameSpecifier(...) that creates a
-/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
-/// \c Matcher<NestedNameSpecifier>.
-/// The returned matcher matches if all given matchers match.
-template <typename T>
-class VariadicAllOfMatcher : public llvm::VariadicFunction<
- BindableMatcher<T>, Matcher<T>,
- makeAllOfComposite<T> > {
-public:
- VariadicAllOfMatcher() {}
-};
-
-/// \brief Matches nodes of type \c TLoc for which the inner
-/// \c Matcher<T> matches.
-template <typename TLoc, typename T>
-class LocMatcher : public WrapperMatcherInterface<TLoc> {
-public:
- explicit LocMatcher(const Matcher<T> &InnerMatcher)
- : LocMatcher::WrapperMatcherInterface(InnerMatcher) {}
-
- bool matches(const TLoc &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- if (!Node)
- return false;
- return this->InnerMatcher.matches(extract(Node), Finder, Builder);
- }
-
-private:
- static ast_type_traits::DynTypedNode
- extract(const NestedNameSpecifierLoc &Loc) {
- return ast_type_traits::DynTypedNode::create(*Loc.getNestedNameSpecifier());
- }
-};
-
-/// \brief Matches \c TypeLocs based on an inner matcher matching a certain
-/// \c QualType.
-///
-/// Used to implement the \c loc() matcher.
-class TypeLocTypeMatcher : public WrapperMatcherInterface<TypeLoc> {
-public:
- explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
- : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {}
-
- bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- if (!Node)
- return false;
- return this->InnerMatcher.matches(
- ast_type_traits::DynTypedNode::create(Node.getType()), Finder, Builder);
- }
-};
-
-/// \brief 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>
-class TypeTraverseMatcher : public WrapperMatcherInterface<T> {
-public:
- explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
- QualType (T::*TraverseFunction)() const)
- : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
- TraverseFunction(TraverseFunction) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- QualType NextNode = (Node.*TraverseFunction)();
- if (NextNode.isNull())
- return false;
- return this->InnerMatcher.matches(
- ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder);
- }
-
-private:
- QualType (T::*TraverseFunction)() const;
-};
-
-/// \brief 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>
-class TypeLocTraverseMatcher : public WrapperMatcherInterface<T> {
-public:
- explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
- TypeLoc (T::*TraverseFunction)() const)
- : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
- TraverseFunction(TraverseFunction) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- TypeLoc NextNode = (Node.*TraverseFunction)();
- if (!NextNode)
- return false;
- return this->InnerMatcher.matches(
- ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder);
- }
-
-private:
- TypeLoc (T::*TraverseFunction)() const;
-};
-
-/// \brief 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
-/// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT
-/// object into a \c InnerT
-template <typename InnerTBase,
- template <typename OuterT> class Getter,
- template <typename OuterT> class MatcherImpl,
- typename ReturnTypesF>
-class TypeTraversePolymorphicMatcher {
-private:
- typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
- ReturnTypesF> Self;
- static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
-
-public:
- typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
-
- explicit TypeTraversePolymorphicMatcher(
- ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
- : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
-
- template <typename OuterT> operator Matcher<OuterT>() const {
- return Matcher<OuterT>(
- new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
- }
-
- struct Func : public llvm::VariadicFunction<Self, Matcher<InnerTBase>,
- &Self::create> {
- Func() {}
- };
-
-private:
- const Matcher<InnerTBase> InnerMatcher;
-};
-
-/// \brief A simple memoizer of T(*)() functions.
-///
-/// It will call the passed 'Func' template parameter at most once.
-/// Used to support AST_MATCHER_FUNCTION() macro.
-template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
- struct Wrapper {
- Wrapper() : M(Func()) {}
- Matcher M;
- };
-
-public:
- static const Matcher &getInstance() {
- static llvm::ManagedStatic<Wrapper> Instance;
- return Instance->M;
- }
-};
-
-// Define the create() method out of line to silence a GCC warning about
-// the struct "Func" having greater visibility than its base, which comes from
-// using the flag -fvisibility-inlines-hidden.
-template <typename InnerTBase, template <typename OuterT> class Getter,
- template <typename OuterT> class MatcherImpl, typename ReturnTypesF>
-TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
-TypeTraversePolymorphicMatcher<
- InnerTBase, Getter, MatcherImpl,
- ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) {
- return Self(InnerMatchers);
-}
-
-// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
-// APIs for accessing the template argument list.
-inline ArrayRef<TemplateArgument>
-getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
- return D.getTemplateArgs().asArray();
-}
-
-inline ArrayRef<TemplateArgument>
-getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
- return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
-}
-
-struct NotEqualsBoundNodePredicate {
- bool operator()(const internal::BoundNodesMap &Nodes) const {
- return Nodes.getNode(ID) != Node;
- }
- std::string ID;
- ast_type_traits::DynTypedNode Node;
-};
-
-} // end namespace internal
-} // end namespace ast_matchers
-} // end namespace clang
-
-#endif
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
deleted file mode 100644
index 8ad0c16..0000000
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ /dev/null
@@ -1,404 +0,0 @@
-//===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines macros that enable us to define new matchers in a single place.
-// Since a matcher is a function which returns a Matcher<T> object, where
-// T is the type of the actual implementation of the matcher, the macros allow
-// us to write matchers like functions and take care of the definition of the
-// class boilerplate.
-//
-// Note that when you define a matcher with an AST_MATCHER* macro, only the
-// function which creates the matcher goes into the current namespace - the
-// class that implements the actual matcher, which gets returned by the
-// generator function, is put into the 'internal' namespace. This allows us
-// to only have the functions (which is all the user cares about) in the
-// 'ast_matchers' namespace and hide the boilerplate.
-//
-// To define a matcher in user code, put it into your own namespace. This would
-// help to prevent ODR violations in case a matcher with the same name is
-// defined in multiple translation units:
-//
-// namespace my_matchers {
-// AST_MATCHER_P(clang::MemberExpr, Member,
-// clang::ast_matchers::internal::Matcher<clang::ValueDecl>,
-// InnerMatcher) {
-// return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
-// }
-// } // namespace my_matchers
-//
-// Alternatively, an unnamed namespace may be used:
-//
-// namespace clang {
-// namespace ast_matchers {
-// namespace {
-// AST_MATCHER_P(MemberExpr, Member,
-// internal::Matcher<ValueDecl>, InnerMatcher) {
-// return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
-// }
-// } // namespace
-// } // namespace ast_matchers
-// } // namespace clang
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
-#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
-
-/// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... }
-/// defines a zero parameter function named DefineMatcher() that returns a
-/// ReturnType object.
-#define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \
- inline ReturnType DefineMatcher##_getInstance(); \
- inline ReturnType DefineMatcher() { \
- return ::clang::ast_matchers::internal::MemoizedMatcher< \
- ReturnType, DefineMatcher##_getInstance>::getInstance(); \
- } \
- inline ReturnType DefineMatcher##_getInstance()
-
-/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
-/// ... }
-/// defines a single-parameter function named DefineMatcher() that returns a
-/// ReturnType object.
-///
-/// The code between the curly braces has access to the following variables:
-///
-/// Param: the parameter passed to the function; its type
-/// is ParamType.
-///
-/// The code should return an instance of ReturnType.
-#define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) \
- AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
- 0)
-#define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \
- Param, OverloadId) \
- inline ReturnType DefineMatcher(ParamType const &Param); \
- typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \
- inline ReturnType DefineMatcher(ParamType const &Param)
-
-/// \brief AST_MATCHER(Type, DefineMatcher) { ... }
-/// defines a zero parameter function named DefineMatcher() that returns a
-/// Matcher<Type> object.
-///
-/// The code between the curly braces has access to the following variables:
-///
-/// Node: the AST node being matched; its type is Type.
-/// Finder: an ASTMatchFinder*.
-/// Builder: a BoundNodesTreeBuilder*.
-///
-/// The code should return true if 'Node' matches.
-#define AST_MATCHER(Type, DefineMatcher) \
- namespace internal { \
- class matcher_##DefineMatcher##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
- public: \
- explicit matcher_##DefineMatcher##Matcher() {} \
- bool matches(const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() { \
- return ::clang::ast_matchers::internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##Matcher()); \
- } \
- inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
- const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
-
-/// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
-/// defines a single-parameter function named DefineMatcher() that returns a
-/// Matcher<Type> object.
-///
-/// The code between the curly braces has access to the following variables:
-///
-/// Node: the AST node being matched; its type is Type.
-/// Param: the parameter passed to the function; its type
-/// is ParamType.
-/// Finder: an ASTMatchFinder*.
-/// Builder: a BoundNodesTreeBuilder*.
-///
-/// The code should return true if 'Node' matches.
-#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \
- AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
-
-#define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \
- OverloadId) \
- namespace internal { \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
- public: \
- explicit matcher_##DefineMatcher##OverloadId##Matcher( \
- ParamType const &A##Param) \
- : Param(A##Param) {} \
- bool matches(const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- ParamType const Param; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
- ParamType const &Param) { \
- return ::clang::ast_matchers::internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
- } \
- typedef ::clang::ast_matchers::internal::Matcher<Type>( \
- &DefineMatcher##_Type##OverloadId)(ParamType const &Param); \
- inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
- const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
-
-/// \brief AST_MATCHER_P2(
-/// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
-/// defines a two-parameter function named DefineMatcher() that returns a
-/// Matcher<Type> object.
-///
-/// The code between the curly braces has access to the following variables:
-///
-/// Node: the AST node being matched; its type is Type.
-/// Param1, Param2: the parameters passed to the function; their types
-/// are ParamType1 and ParamType2.
-/// Finder: an ASTMatchFinder*.
-/// Builder: a BoundNodesTreeBuilder*.
-///
-/// The code should return true if 'Node' matches.
-#define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
- Param2) \
- AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
- Param2, 0)
-
-#define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \
- ParamType2, Param2, OverloadId) \
- namespace internal { \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
- public: \
- matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
- ParamType2 const &A##Param2) \
- : Param1(A##Param1), Param2(A##Param2) {} \
- bool matches(const Type &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- ParamType1 const Param1; \
- ParamType2 const Param2; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
- ParamType1 const &Param1, ParamType2 const &Param2) { \
- return ::clang::ast_matchers::internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
- Param2)); \
- } \
- typedef ::clang::ast_matchers::internal::Matcher<Type>( \
- &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \
- ParamType2 const &Param2); \
- inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
- const Type &Node, \
- ::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*
-/// macros.
-///
-/// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
-/// will look at that as two arguments. However, you can pass
-/// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
-/// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
-/// extract the TypeList object.
-#define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \
- void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>)
-
-/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
-/// defines a single-parameter function named DefineMatcher() that is
-/// polymorphic in the return type.
-///
-/// The variables are the same as for AST_MATCHER, but NodeType will be deduced
-/// from the calling context.
-#define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \
- namespace internal { \
- template <typename NodeType> \
- class matcher_##DefineMatcher##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
- public: \
- bool matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \
- internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \
- DefineMatcher() { \
- return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \
- internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \
- } \
- template <typename NodeType> \
- bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \
- const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
-
-/// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
-/// defines a single-parameter function named DefineMatcher() that is
-/// polymorphic in the return type.
-///
-/// The variables are the same as for
-/// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
-/// of the matcher Matcher<NodeType> returned by the function matcher().
-///
-/// FIXME: Pull out common code with above macro?
-#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \
- Param) \
- AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \
- Param, 0)
-
-#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \
- ParamType, Param, OverloadId) \
- namespace internal { \
- template <typename NodeType, typename ParamT> \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
- public: \
- explicit matcher_##DefineMatcher##OverloadId##Matcher( \
- ParamType const &A##Param) \
- : Param(A##Param) {} \
- bool matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- ParamType const Param; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
- ReturnTypesF> \
- DefineMatcher(ParamType const &Param) { \
- return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
- ReturnTypesF>(Param); \
- } \
- typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
- ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
- ParamType const &Param); \
- template <typename NodeType, typename ParamT> \
- bool internal:: \
- matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
- const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
- const
-
-/// \brief AST_POLYMORPHIC_MATCHER_P2(
-/// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
-/// defines a two-parameter function named matcher() that is polymorphic in
-/// the return type.
-///
-/// The variables are the same as for AST_MATCHER_P2, with the
-/// addition of NodeType, which specifies the node type of the matcher
-/// Matcher<NodeType> returned by the function DefineMatcher().
-#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \
- Param1, ParamType2, Param2) \
- AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
- Param1, ParamType2, Param2, 0)
-
-#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \
- ParamType1, Param1, ParamType2, \
- Param2, OverloadId) \
- namespace internal { \
- template <typename NodeType, typename ParamT1, typename ParamT2> \
- class matcher_##DefineMatcher##OverloadId##Matcher \
- : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
- public: \
- matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
- ParamType2 const &A##Param2) \
- : Param1(A##Param1), Param2(A##Param2) {} \
- bool matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
- *Builder) const override; \
- \
- private: \
- ParamType1 const Param1; \
- ParamType2 const Param2; \
- }; \
- } \
- inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
- ParamType2, ReturnTypesF> \
- DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \
- return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
- ParamType2, ReturnTypesF>(Param1, Param2); \
- } \
- typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
- internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
- ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
- ParamType1 const &Param1, ParamType2 const &Param2); \
- template <typename NodeType, typename ParamT1, typename ParamT2> \
- bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
- NodeType, ParamT1, ParamT2>:: \
- matches(const NodeType &Node, \
- ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
- ::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
-
-/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
-/// the matcher \c MatcherName that can be used to traverse from one \c Type
-/// to another.
-///
-/// For a specific \c SpecificType, the traversal is done using
-/// \c SpecificType::FunctionName. The existence of such a function determines
-/// whether a corresponding matcher can be used on \c SpecificType.
-#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
- namespace internal { \
- template <typename T> struct TypeMatcher##MatcherName##Getter { \
- static QualType (T::*value())() const { return &T::FunctionName; } \
- }; \
- } \
- const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
- QualType, \
- ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
- ::clang::ast_matchers::internal::TypeTraverseMatcher, \
- ReturnTypesF>::Func MatcherName
-
-/// \brief 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 { \
- template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
- static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
- }; \
- } \
- const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
- TypeLoc, \
- ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \
- ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
- ReturnTypesF>::Func MatcherName##Loc; \
- AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
-
-#endif
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
deleted file mode 100644
index 2c76dda..0000000
--- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ /dev/null
@@ -1,185 +0,0 @@
-//===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Diagnostics class to manage error messages.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
-#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
-
-#include "clang/ASTMatchers/Dynamic/VariantValue.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/raw_ostream.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace ast_matchers {
-namespace dynamic {
-
-struct SourceLocation {
- SourceLocation() : Line(), Column() {}
- unsigned Line;
- unsigned Column;
-};
-
-struct SourceRange {
- SourceLocation Start;
- SourceLocation End;
-};
-
-/// \brief A VariantValue instance annotated with its parser context.
-struct ParserValue {
- ParserValue() : Text(), Range(), Value() {}
- StringRef Text;
- SourceRange Range;
- VariantValue Value;
-};
-
-/// \brief Helper class to manage error messages.
-class Diagnostics {
-public:
- /// \brief Parser context types.
- enum ContextType {
- CT_MatcherArg = 0,
- CT_MatcherConstruct = 1
- };
-
- /// \brief All errors from the system.
- enum ErrorType {
- ET_None = 0,
-
- ET_RegistryMatcherNotFound = 1,
- ET_RegistryWrongArgCount = 2,
- ET_RegistryWrongArgType = 3,
- ET_RegistryNotBindable = 4,
- ET_RegistryAmbiguousOverload = 5,
- ET_RegistryValueNotFound = 6,
-
- ET_ParserStringError = 100,
- ET_ParserNoOpenParen = 101,
- ET_ParserNoCloseParen = 102,
- ET_ParserNoComma = 103,
- ET_ParserNoCode = 104,
- ET_ParserNotAMatcher = 105,
- ET_ParserInvalidToken = 106,
- ET_ParserMalformedBindExpr = 107,
- ET_ParserTrailingCode = 108,
- ET_ParserUnsignedError = 109,
- ET_ParserOverloadedType = 110
- };
-
- /// \brief Helper stream class.
- class ArgStream {
- public:
- ArgStream(std::vector<std::string> *Out) : Out(Out) {}
- template <class T> ArgStream &operator<<(const T &Arg) {
- return operator<<(Twine(Arg));
- }
- ArgStream &operator<<(const Twine &Arg);
-
- private:
- std::vector<std::string> *Out;
- };
-
- /// \brief 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
- /// keep information about the context chain.
- /// This class should be used as a RAII instance in the stack.
- struct Context {
- public:
- /// \brief 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.
- enum MatcherArgEnum { MatcherArg };
- Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName,
- SourceRange MatcherRange, unsigned ArgNumber);
- ~Context();
-
- private:
- Diagnostics *const Error;
- };
-
- /// \brief 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.
- struct OverloadContext {
- public:
- OverloadContext(Diagnostics* Error);
- ~OverloadContext();
-
- /// \brief Revert all errors that happened within this context.
- void revertErrors();
-
- private:
- Diagnostics *const Error;
- unsigned BeginIndex;
- };
-
- /// \brief 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.
- struct ContextFrame {
- ContextType Type;
- SourceRange Range;
- std::vector<std::string> Args;
- };
-
- /// \brief Information stored for each error found.
- struct ErrorContent {
- std::vector<ContextFrame> ContextStack;
- struct Message {
- SourceRange Range;
- ErrorType Type;
- std::vector<std::string> Args;
- };
- std::vector<Message> Messages;
- };
- ArrayRef<ErrorContent> errors() const { return Errors; }
-
- /// \brief 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.
- ///
- /// 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.
- ArgStream pushContextFrame(ContextType Type, SourceRange Range);
-
- std::vector<ContextFrame> ContextStack;
- std::vector<ErrorContent> Errors;
-};
-
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
-
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
deleted file mode 100644
index 76926f0..0000000
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ /dev/null
@@ -1,257 +0,0 @@
-//===--- Parser.h - Matcher expression parser -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Simple matcher expression parser.
-///
-/// The parser understands matcher expressions of the form:
-/// MatcherName(Arg0, Arg1, ..., ArgN)
-/// as well as simple types like strings.
-/// The parser does not know how to process the matchers. It delegates this task
-/// to a Sema object received as an argument.
-///
-/// \code
-/// Grammar for the expressions supported:
-/// <Expression> := <Literal> | <NamedValue> | <MatcherExpression>
-/// <Literal> := <StringLiteral> | <Unsigned>
-/// <StringLiteral> := "quoted string"
-/// <Unsigned> := [0-9]+
-/// <NamedValue> := <Identifier>
-/// <MatcherExpression> := <Identifier>(<ArgumentList>) |
-/// <Identifier>(<ArgumentList>).bind(<StringLiteral>)
-/// <Identifier> := [a-zA-Z]+
-/// <ArgumentList> := <Expression> | <Expression>,<ArgumentList>
-/// \endcode
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
-#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
-
-#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
-#include "clang/ASTMatchers/Dynamic/Registry.h"
-#include "clang/ASTMatchers/Dynamic/VariantValue.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace ast_matchers {
-namespace dynamic {
-
-/// \brief Matcher expression parser.
-class Parser {
-public:
- /// \brief 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
- /// processor implementation would simply call into the registry to create
- /// the matchers.
- /// However, a more complex processor might decide to intercept the matcher
- /// creation and do some extra work. For example, it could apply some
- /// transformation to the matcher by adding some id() nodes, or could detect
- /// specific matcher nodes for more efficient lookup.
- class Sema {
- public:
- virtual ~Sema();
-
- /// \brief Process a matcher expression.
- ///
- /// All the arguments passed here have already been processed.
- ///
- /// \param Ctor A matcher constructor looked up by lookupMatcherCtor.
- ///
- /// \param NameRange The location of the name in the matcher source.
- /// Useful for error reporting.
- ///
- /// \param BindID The ID to use to bind the matcher, or a null \c StringRef
- /// if no ID is specified.
- ///
- /// \param Args The argument list for the matcher.
- ///
- /// \return The matcher objects constructed by the processor, or a null
- /// matcher if an error occurred. In that case, \c Error will contain a
- /// description of the error.
- virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
- SourceRange NameRange,
- StringRef BindID,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error) = 0;
-
- /// \brief Look up a matcher by name.
- ///
- /// \param MatcherName The matcher name found by the parser.
- ///
- /// \return The matcher constructor, or Optional<MatcherCtor>() if not
- /// found.
- virtual llvm::Optional<MatcherCtor>
- lookupMatcherCtor(StringRef MatcherName) = 0;
-
- /// \brief 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
- /// the matcher constructor and the index of the next element in the
- /// argument list of that matcher (or for the last element, the index of
- /// the completion point in the argument list). An empty list requests
- /// completion for the root matcher.
- virtual std::vector<ArgKind> getAcceptedCompletionTypes(
- llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
-
- /// \brief Compute the list of completions that match any of
- /// \p AcceptedTypes.
- ///
- /// \param AcceptedTypes All types accepted for this completion.
- ///
- /// \return All completions for the specified types.
- /// Completions should be valid when used in \c lookupMatcherCtor().
- /// The matcher constructed from the return of \c lookupMatcherCtor()
- /// should be convertible to some type in \p AcceptedTypes.
- virtual std::vector<MatcherCompletion>
- getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes);
- };
-
- /// \brief Sema implementation that uses the matcher registry to process the
- /// tokens.
- class RegistrySema : public Parser::Sema {
- public:
- ~RegistrySema() override;
-
- llvm::Optional<MatcherCtor>
- lookupMatcherCtor(StringRef MatcherName) override;
-
- VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
- SourceRange NameRange,
- StringRef BindID,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error) override;
-
- std::vector<ArgKind> getAcceptedCompletionTypes(
- llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) override;
-
- std::vector<MatcherCompletion>
- getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override;
- };
-
- typedef llvm::StringMap<VariantValue> NamedValueMap;
-
- /// \brief Parse a matcher expression.
- ///
- /// \param MatcherCode The matcher expression to parse.
- ///
- /// \param S The Sema instance that will help the parser
- /// construct the matchers. If null, it uses the default registry.
- ///
- /// \param NamedValues A map of precomputed named values. This provides
- /// the dictionary for the <NamedValue> rule of the grammar.
- /// If null, it is ignored.
- ///
- /// \return The matcher object constructed by the processor, or an empty
- /// Optional if an error occurred. In that case, \c Error will contain a
- /// description of the error.
- /// The caller takes ownership of the DynTypedMatcher object returned.
- static llvm::Optional<DynTypedMatcher>
- parseMatcherExpression(StringRef MatcherCode, Sema *S,
- const NamedValueMap *NamedValues,
- Diagnostics *Error);
- static llvm::Optional<DynTypedMatcher>
- parseMatcherExpression(StringRef MatcherCode, Sema *S,
- Diagnostics *Error) {
- return parseMatcherExpression(MatcherCode, S, nullptr, Error);
- }
- static llvm::Optional<DynTypedMatcher>
- parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error) {
- return parseMatcherExpression(MatcherCode, nullptr, Error);
- }
-
- /// \brief Parse an expression.
- ///
- /// Parses any expression supported by this parser. In general, the
- /// \c parseMatcherExpression function is a better approach to get a matcher
- /// object.
- ///
- /// \param S The Sema instance that will help the parser
- /// construct the matchers. If null, it uses the default registry.
- ///
- /// \param NamedValues A map of precomputed named values. This provides
- /// the dictionary for the <NamedValue> rule of the grammar.
- /// If null, it is ignored.
- static bool parseExpression(StringRef Code, Sema *S,
- const NamedValueMap *NamedValues,
- VariantValue *Value, Diagnostics *Error);
- static bool parseExpression(StringRef Code, Sema *S,
- VariantValue *Value, Diagnostics *Error) {
- return parseExpression(Code, S, nullptr, Value, Error);
- }
- static bool parseExpression(StringRef Code, VariantValue *Value,
- Diagnostics *Error) {
- return parseExpression(Code, nullptr, Value, Error);
- }
-
- /// \brief 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.
- ///
- /// \param NamedValues A map of precomputed named values. This provides
- /// the dictionary for the <NamedValue> rule of the grammar.
- /// If null, it is ignored.
- ///
- /// \return The list of completions, which may be empty if there are no
- /// available completions or if an error occurred.
- static std::vector<MatcherCompletion>
- completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S,
- const NamedValueMap *NamedValues);
- static std::vector<MatcherCompletion>
- completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S) {
- return completeExpression(Code, CompletionOffset, S, nullptr);
- }
- static std::vector<MatcherCompletion>
- completeExpression(StringRef Code, unsigned CompletionOffset) {
- return completeExpression(Code, CompletionOffset, nullptr);
- }
-
-private:
- class CodeTokenizer;
- struct ScopedContextEntry;
- struct TokenInfo;
-
- Parser(CodeTokenizer *Tokenizer, Sema *S,
- const NamedValueMap *NamedValues,
- Diagnostics *Error);
-
- bool parseExpressionImpl(VariantValue *Value);
- bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
- VariantValue *Value);
- bool parseIdentifierPrefixImpl(VariantValue *Value);
-
- void addCompletion(const TokenInfo &CompToken,
- const MatcherCompletion &Completion);
- void addExpressionCompletions();
-
- std::vector<MatcherCompletion>
- getNamedValueCompletions(ArrayRef<ArgKind> AcceptedTypes);
-
- CodeTokenizer *const Tokenizer;
- Sema *const S;
- const NamedValueMap *const NamedValues;
- Diagnostics *const Error;
-
- typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy;
- ContextStackTy ContextStack;
- std::vector<MatcherCompletion> Completions;
-};
-
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
-
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
deleted file mode 100644
index 3808adb..0000000
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ /dev/null
@@ -1,133 +0,0 @@
-//===--- Registry.h - Matcher registry -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Registry of all known matchers.
-///
-/// The registry provides a generic interface to construct any matcher by name.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
-#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
-
-#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
-#include "clang/ASTMatchers/Dynamic/VariantValue.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace ast_matchers {
-namespace dynamic {
-
-namespace internal {
-class MatcherDescriptor;
-}
-
-typedef const internal::MatcherDescriptor *MatcherCtor;
-
-struct MatcherCompletion {
- MatcherCompletion() {}
- MatcherCompletion(StringRef TypedText, StringRef MatcherDecl,
- unsigned Specificity)
- : TypedText(TypedText), MatcherDecl(MatcherDecl),
- Specificity(Specificity) {}
-
- /// \brief The text to type to select this matcher.
- std::string TypedText;
-
- /// \brief The "declaration" of the matcher, with type information.
- std::string MatcherDecl;
-
- /// \brief 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.
- /// Such matchers are excluded from code completion results.
- unsigned Specificity;
-
- bool operator==(const MatcherCompletion &Other) const {
- return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
- }
-};
-
-class Registry {
-public:
- /// \brief 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.
- ///
- /// Each element of \p Context represents a matcher invocation, going from
- /// outermost to innermost. Elements are pairs consisting of a reference to
- /// the matcher constructor and the index of the next element in the
- /// argument list of that matcher (or for the last element, the index of
- /// the completion point in the argument list). An empty list requests
- /// completion for the root matcher.
- static std::vector<ArgKind> getAcceptedCompletionTypes(
- llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
-
- /// \brief Compute the list of completions that match any of
- /// \p AcceptedTypes.
- ///
- /// \param AcceptedTypes All types accepted for this completion.
- ///
- /// \return All completions for the specified types.
- /// Completions should be valid when used in \c lookupMatcherCtor().
- /// The matcher constructed from the return of \c lookupMatcherCtor()
- /// should be convertible to some type in \p AcceptedTypes.
- static std::vector<MatcherCompletion>
- getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes);
-
- /// \brief Construct a matcher from the registry.
- ///
- /// \param Ctor The matcher constructor to instantiate.
- ///
- /// \param NameRange The location of the name in the matcher source.
- /// Useful for error reporting.
- ///
- /// \param Args The argument list for the matcher. The number and types of the
- /// values must be valid for the matcher requested. Otherwise, the function
- /// will return an error.
- ///
- /// \return The matcher object constructed if no error was found.
- /// A null matcher if the number of arguments or argument types do not match
- /// the signature. In that case \c Error will contain the description of
- /// the error.
- static VariantMatcher constructMatcher(MatcherCtor Ctor,
- SourceRange NameRange,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error);
-
- /// \brief 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.
- /// If the matcher is not bindable, it sets an error in \c Error and returns
- /// a null matcher.
- static VariantMatcher constructBoundMatcher(MatcherCtor Ctor,
- SourceRange NameRange,
- StringRef BindID,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error);
-
-private:
- Registry() = delete;
-};
-
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
-
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
deleted file mode 100644
index c391b24..0000000
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ /dev/null
@@ -1,326 +0,0 @@
-//===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Polymorphic value type.
-///
-/// Supports all the types required for dynamic Matcher construction.
-/// Used by the registry to construct matchers in a generic way.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
-#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
-
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/Twine.h"
-#include <memory>
-#include <vector>
-
-namespace clang {
-namespace ast_matchers {
-namespace dynamic {
-
-/// \brief Kind identifier.
-///
-/// It supports all types that VariantValue can contain.
-class ArgKind {
- public:
- enum Kind {
- AK_Matcher,
- AK_Unsigned,
- AK_String
- };
- /// \brief Constructor for non-matcher types.
- ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
-
- /// \brief Constructor for matcher types.
- ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
- : K(AK_Matcher), MatcherKind(MatcherKind) {}
-
- Kind getArgKind() const { return K; }
- ast_type_traits::ASTNodeKind getMatcherKind() const {
- assert(K == AK_Matcher);
- return MatcherKind;
- }
-
- /// \brief Determines if this type can be converted to \p To.
- ///
- /// \param To the requested destination type.
- ///
- /// \param Specificity value corresponding to the "specificity" of the
- /// convertion.
- bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
-
- bool operator<(const ArgKind &Other) const {
- if (K == AK_Matcher && Other.K == AK_Matcher)
- return MatcherKind < Other.MatcherKind;
- return K < Other.K;
- }
-
- /// \brief String representation of the type.
- std::string asString() const;
-
-private:
- Kind K;
- ast_type_traits::ASTNodeKind MatcherKind;
-};
-
-using ast_matchers::internal::DynTypedMatcher;
-
-/// \brief A variant matcher object.
-///
-/// The purpose of this object is to abstract simple and polymorphic matchers
-/// into a single object type.
-/// Polymorphic matchers might be implemented as a list of all the possible
-/// overloads of the matcher. \c VariantMatcher knows how to select the
-/// appropriate overload when needed.
-/// To get a real matcher object out of a \c VariantMatcher you can do:
-/// - getSingleMatcher() which returns a matcher, only if it is not ambiguous
-/// to decide which matcher to return. Eg. it contains only a single
-/// matcher, or a polymorphic one with only one overload.
-/// - 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.
- class MatcherOps {
- public:
- MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
-
- bool canConstructFrom(const DynTypedMatcher &Matcher,
- bool &IsExactMatch) const;
-
- /// \brief 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.
- /// Will try to convert each inner matcher to the destination type and
- /// return llvm::None if it fails to do so.
- llvm::Optional<DynTypedMatcher>
- constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
- ArrayRef<VariantMatcher> InnerMatchers) const;
-
- protected:
- ~MatcherOps() = default;
-
- private:
- ast_type_traits::ASTNodeKind NodeKind;
- };
-
- /// \brief Payload interface to be specialized by each matcher type.
- ///
- /// It follows a similar interface as VariantMatcher itself.
- class Payload : public RefCountedBaseVPTR {
- public:
- ~Payload() override;
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
- virtual std::string getTypeAsString() const = 0;
- virtual llvm::Optional<DynTypedMatcher>
- getTypedMatcher(const MatcherOps &Ops) const = 0;
- virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
- unsigned *Specificity) const = 0;
- };
-
-public:
- /// \brief A null matcher.
- VariantMatcher();
-
- /// \brief Clones the provided matcher.
- static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
-
- /// \brief 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.
- ///
- /// 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.
- void reset();
-
- /// \brief Whether the matcher is null.
- bool isNull() const { return !Value; }
-
- /// \brief 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
- /// \c Matcher<T>.
- ///
- /// For the Single case, it returns true if it can be converted to
- /// \c Matcher<T>.
- /// For the Polymorphic case, it returns true if one, and only one, of the
- /// overloads can be converted to \c Matcher<T>. If there are more than one
- /// that can, the result would be ambiguous and false is returned.
- template <class T>
- bool hasTypedMatcher() const {
- if (!Value) return false;
- return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue();
- }
-
- /// \brief Determines if the contained matcher can be converted to \p Kind.
- ///
- /// \param Kind the requested destination type.
- ///
- /// \param Specificity value corresponding to the "specificity" of the
- /// convertion.
- bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
- unsigned *Specificity) const {
- if (Value)
- return Value->isConvertibleTo(Kind, Specificity);
- return false;
- }
-
- /// \brief Return this matcher as a \c Matcher<T>.
- ///
- /// Handles the different types (Single, Polymorphic) accordingly.
- /// Asserts that \c hasTypedMatcher<T>() is true.
- template <class T>
- ast_matchers::internal::Matcher<T> getTypedMatcher() const {
- assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false");
- return Value->getTypedMatcher(TypedMatcherOps<T>())
- ->template convertTo<T>();
- }
-
- /// \brief String representation of the type of the value.
- ///
- /// If the underlying matcher is a polymorphic one, the string will show all
- /// the types.
- std::string getTypeAsString() const;
-
-private:
- explicit VariantMatcher(Payload *Value) : Value(Value) {}
-
- template <typename T> struct TypedMatcherOps;
-
- class SinglePayload;
- class PolymorphicPayload;
- class VariadicOpPayload;
-
- IntrusiveRefCntPtr<const Payload> Value;
-};
-
-template <typename T>
-struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps {
- TypedMatcherOps()
- : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {}
- typedef ast_matchers::internal::Matcher<T> MatcherT;
-
- DynTypedMatcher
- convertMatcher(const DynTypedMatcher &Matcher) const override {
- return DynTypedMatcher(Matcher.convertTo<T>());
- }
-};
-
-/// \brief 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
-/// matcher factory methods.
-/// It can be constructed from any of the supported types. It supports
-/// copy/assignment.
-///
-/// Supported types:
-/// - \c unsigned
-/// - \c llvm::StringRef
-/// - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
-class VariantValue {
-public:
- VariantValue() : Type(VT_Nothing) {}
-
- VariantValue(const VariantValue &Other);
- ~VariantValue();
- VariantValue &operator=(const VariantValue &Other);
-
- /// \brief Specific constructors for each supported type.
- VariantValue(unsigned Unsigned);
- VariantValue(StringRef String);
- VariantValue(const VariantMatcher &Matchers);
-
- /// \brief Returns true iff this is not an empty value.
- explicit operator bool() const { return hasValue(); }
- bool hasValue() const { return Type != VT_Nothing; }
-
- /// \brief Unsigned value functions.
- bool isUnsigned() const;
- unsigned getUnsigned() const;
- void setUnsigned(unsigned Unsigned);
-
- /// \brief String value functions.
- bool isString() const;
- const std::string &getString() const;
- void setString(StringRef String);
-
- /// \brief 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.
- ///
- /// \param Kind the requested destination type.
- ///
- /// \param Specificity value corresponding to the "specificity" of the
- /// convertion.
- bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
-
- /// \brief Determines if the contained value can be converted to any kind
- /// in \p Kinds.
- ///
- /// \param Kinds the requested destination types.
- ///
- /// \param Specificity value corresponding to the "specificity" of the
- /// convertion. It is the maximum specificity of all the possible
- /// conversions.
- bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
-
- /// \brief String representation of the type of the value.
- std::string getTypeAsString() const;
-
-private:
- void reset();
-
- /// \brief All supported value types.
- enum ValueType {
- VT_Nothing,
- VT_Unsigned,
- VT_String,
- VT_Matcher
- };
-
- /// \brief All supported value types.
- union AllValues {
- unsigned Unsigned;
- std::string *String;
- VariantMatcher *Matcher;
- };
-
- ValueType Type;
- AllValues Value;
-};
-
-} // end namespace dynamic
-} // end namespace ast_matchers
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
diff --git a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
deleted file mode 100644
index cc14c7b..0000000
--- a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//==- CFGReachabilityAnalysis.h - Basic reachability analysis ----*- 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 flow-sensitive, (mostly) path-insensitive reachability
-// analysis based on Clang's CFGs. Clients can query if a given basic block
-// is reachable within the CFG.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CFGREACHABILITYANALYSIS_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_CFGREACHABILITYANALYSIS_H
-
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-
-class CFG;
-class CFGBlock;
-
-// A class that performs reachability queries for CFGBlocks. Several internal
-// checks in this checker require reachability information. The requests all
-// tend to have a common destination, so we lazily do a predecessor search
-// from the destination node and cache the results to prevent work
-// duplication.
-class CFGReverseBlockReachabilityAnalysis {
- typedef llvm::BitVector ReachableSet;
- typedef llvm::DenseMap<unsigned, ReachableSet> ReachableMap;
- ReachableSet analyzed;
- ReachableMap reachable;
-public:
- CFGReverseBlockReachabilityAnalysis(const CFG &cfg);
-
- /// Returns true if the block 'Dst' can be reached from block 'Src'.
- bool isReachable(const CFGBlock *Src, const CFGBlock *Dst);
-
-private:
- void mapReachability(const CFGBlock *Dst);
-};
-
-}
-
-#endif
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
deleted file mode 100644
index 1f5aa12..0000000
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ /dev/null
@@ -1,269 +0,0 @@
-//===- Consumed.h ----------------------------------------------*- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// A intra-procedural analysis for checking consumed properties. This is based,
-// in part, on research on linear types.
-//
-//===----------------------------------------------------------------------===//
-
-#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/AnalysisContext.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-namespace consumed {
-
- enum ConsumedState {
- // No state information for the given variable.
- CS_None,
-
- CS_Unknown,
- CS_Unconsumed,
- CS_Consumed
- };
-
- class ConsumedStmtVisitor;
-
- typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
- typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
- typedef std::list<DelayedDiag> DiagList;
-
- class ConsumedWarningsHandlerBase {
-
- public:
-
- virtual ~ConsumedWarningsHandlerBase();
-
- /// \brief 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
- /// of a loop.
- ///
- /// \param Loc -- The location of the end of the loop.
- ///
- /// \param VariableName -- The name of the variable that has a mismatched
- /// state.
- virtual void warnLoopStateMismatch(SourceLocation Loc,
- StringRef VariableName) {}
-
- /// \brief Warn about parameter typestate mismatches upon return.
- ///
- /// \param Loc -- The SourceLocation of the return statement.
- ///
- /// \param ExpectedState -- The state the return value was expected to be
- /// in.
- ///
- /// \param ObservedState -- The state the return value was observed to be
- /// in.
- virtual void warnParamReturnTypestateMismatch(SourceLocation Loc,
- StringRef VariableName,
- StringRef ExpectedState,
- StringRef ObservedState) {}
-
- // FIXME: Add documentation.
- virtual void warnParamTypestateMismatch(SourceLocation LOC,
- StringRef ExpectedState,
- StringRef ObservedState) {}
-
- // FIXME: This can be removed when the attr propagation fix for templated
- // classes lands.
- /// \brief Warn about return typestates set for unconsumable types.
- ///
- /// \param Loc -- The location of the attributes.
- ///
- /// \param TypeName -- The name of the unconsumable type.
- virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
- StringRef TypeName) {}
-
- /// \brief Warn about return typestate mismatches.
- ///
- /// \param Loc -- The SourceLocation of the return statement.
- ///
- /// \param ExpectedState -- The state the return value was expected to be
- /// in.
- ///
- /// \param ObservedState -- The state the return value was observed to be
- /// in.
- virtual void warnReturnTypestateMismatch(SourceLocation Loc,
- StringRef ExpectedState,
- StringRef ObservedState) {}
-
- /// \brief Warn about use-while-consumed errors.
- /// \param MethodName -- The name of the method that was incorrectly
- /// invoked.
- ///
- /// \param State -- The state the object was used in.
- ///
- /// \param Loc -- The SourceLocation of the method invocation.
- virtual void warnUseOfTempInInvalidState(StringRef MethodName,
- StringRef State,
- SourceLocation Loc) {}
-
- /// \brief Warn about use-while-consumed errors.
- /// \param MethodName -- The name of the method that was incorrectly
- /// invoked.
- ///
- /// \param State -- The state the object was used in.
- ///
- /// \param VariableName -- The name of the variable that holds the unique
- /// value.
- ///
- /// \param Loc -- The SourceLocation of the method invocation.
- virtual void warnUseInInvalidState(StringRef MethodName,
- StringRef VariableName,
- StringRef State,
- SourceLocation Loc) {}
- };
-
- class ConsumedStateMap {
-
- typedef llvm::DenseMap<const VarDecl *, ConsumedState> VarMapType;
- typedef llvm::DenseMap<const CXXBindTemporaryExpr *, ConsumedState>
- TmpMapType;
-
- protected:
-
- bool Reachable;
- const Stmt *From;
- VarMapType VarMap;
- TmpMapType TmpMap;
-
- public:
- ConsumedStateMap() : Reachable(true), From(nullptr) {}
- ConsumedStateMap(const ConsumedStateMap &Other)
- : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap),
- TmpMap() {}
-
- /// \brief 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.
- void clearTemporaries();
-
- /// \brief Get the consumed state of a given variable.
- ConsumedState getState(const VarDecl *Var) const;
-
- /// \brief Get the consumed state of a given temporary value.
- ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const;
-
- /// \brief 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.
- bool isReachable() const { return Reachable; }
-
- /// \brief Mark the block as unreachable.
- void markUnreachable();
-
- /// \brief 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.
- void setState(const VarDecl *Var, ConsumedState State);
-
- /// \brief 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.
- void remove(const CXXBindTemporaryExpr *Tmp);
-
- /// \brief Tests to see if there is a mismatch in the states stored in two
- /// maps.
- ///
- /// \param Other -- The second map to compare against.
- bool operator!=(const ConsumedStateMap *Other) const;
- };
-
- class ConsumedBlockInfo {
- std::vector<std::unique_ptr<ConsumedStateMap>> StateMapsArray;
- std::vector<unsigned int> VisitOrder;
-
- public:
- ConsumedBlockInfo() = default;
- ConsumedBlockInfo &operator=(ConsumedBlockInfo &&Other) {
- StateMapsArray = std::move(Other.StateMapsArray);
- VisitOrder = std::move(Other.VisitOrder);
- return *this;
- }
-
- 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++;
- }
- }
-
- bool allBackEdgesVisited(const CFGBlock *CurrBlock,
- const CFGBlock *TargetBlock);
-
- void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap,
- std::unique_ptr<ConsumedStateMap> &OwnedStateMap);
- void addInfo(const CFGBlock *Block,
- std::unique_ptr<ConsumedStateMap> StateMap);
-
- ConsumedStateMap* borrowInfo(const CFGBlock *Block);
-
- void discardInfo(const CFGBlock *Block);
-
- std::unique_ptr<ConsumedStateMap> getInfo(const CFGBlock *Block);
-
- bool isBackEdge(const CFGBlock *From, const CFGBlock *To);
- bool isBackEdgeTarget(const CFGBlock *Block);
- };
-
- /// A class that handles the analysis of uniqueness violations.
- class ConsumedAnalyzer {
-
- ConsumedBlockInfo BlockInfo;
- std::unique_ptr<ConsumedStateMap> CurrStates;
-
- ConsumedState ExpectedReturnState;
-
- void determineExpectedReturnState(AnalysisDeclContext &AC,
- const FunctionDecl *D);
- bool splitState(const CFGBlock *CurrBlock,
- const ConsumedStmtVisitor &Visitor);
-
- public:
-
- ConsumedWarningsHandlerBase &WarningsHandler;
-
- ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler)
- : WarningsHandler(WarningsHandler) {}
-
- ConsumedState getExpectedReturnState() const { return ExpectedReturnState; }
-
- /// \brief 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
- /// the wrong state a warning is issued. Each block in the CFG is traversed
- /// exactly once.
- void run(AnalysisDeclContext &AC);
- };
-}} // end namespace clang::consumed
-
-#endif
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
deleted file mode 100644
index 4524aeb..0000000
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ /dev/null
@@ -1,210 +0,0 @@
-//==- Dominators.h - Implementation of dominators tree for Clang CFG C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the dominators tree functionality for Clang CFGs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
-
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Analysis/CFG.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/Support/GenericDomTree.h"
-#include "llvm/Support/GenericDomTreeConstruction.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 clang {
-
-class CFGBlock;
-typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
-
-/// \brief 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::DominatorTreeBase<CFGBlock>* DT;
-
- DominatorTree() {
- DT = new llvm::DominatorTreeBase<CFGBlock>(false);
- }
-
- ~DominatorTree() override { delete DT; }
-
- llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; }
-
- /// \brief This method returns the root CFGBlock of the dominators tree.
- ///
- inline CFGBlock *getRoot() const {
- return DT->getRoot();
- }
-
- /// \brief This method returns the root DomTreeNode, which is the wrapper
- /// for CFGBlock.
- inline DomTreeNode *getRootNode() const {
- return DT->getRootNode();
- }
-
- /// \brief 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 {
- DomTreeNode *R = getRootNode();
- DomTreeNode *OtherR = Other.getRootNode();
-
- if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
- return true;
-
- if (DT->compare(Other.getBase()))
- return true;
-
- return false;
- }
-
- /// \brief 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,
- /// mainly used for debug purposes.
- ///
- void dump() {
- llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
- for (CFG::const_iterator I = cfg->begin(),
- E = cfg->end(); I != E; ++I) {
- if(DT->getNode(*I)->getIDom())
- llvm::errs() << "(" << (*I)->getBlockID()
- << ","
- << DT->getNode(*I)->getIDom()->getBlock()->getBlockID()
- << ")\n";
- else llvm::errs() << "(" << (*I)->getBlockID()
- << "," << (*I)->getBlockID() << ")\n";
- }
- }
-
- /// \brief 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 {
- return DT->dominates(A, B);
- }
-
- /// \brief 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 {
- return DT->properlyDominates(A, B);
- }
-
- /// \brief 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) {
- return DT->findNearestCommonDominator(A, B);
- }
-
- inline const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
- const CFGBlock *B) {
- return DT->findNearestCommonDominator(A, B);
- }
-
- /// \brief This method is used to update the dominator
- /// tree information when a node's immediate dominator changes.
- ///
- inline void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
- DT->changeImmediateDominator(N, NewIDom);
- }
-
- /// \brief 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.
- ///
- virtual void releaseMemory() {
- DT->releaseMemory();
- }
-
- /// \brief 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);
- }
-
-private:
- CFG *cfg;
-};
-
-} // end 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 NodeType;
- typedef NodeType::iterator ChildIteratorType;
-
- static NodeType *getEntryNode(NodeType *N) {
- return N;
- }
- static inline ChildIteratorType child_begin(NodeType *N) {
- return N->begin();
- }
- static inline ChildIteratorType child_end(NodeType *N) {
- return N->end();
- }
-
- typedef df_iterator< ::clang::DomTreeNode* > nodes_iterator;
-
- static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
- return df_begin(getEntryNode(N));
- }
-
- static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
- return df_end(getEntryNode(N));
- }
-};
-
-template <> struct GraphTraits< ::clang::DominatorTree* >
- : public GraphTraits< ::clang::DomTreeNode* > {
- static NodeType *getEntryNode(::clang::DominatorTree *DT) {
- return DT->getRootNode();
- }
-
- static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
- return df_begin(getEntryNode(N));
- }
-
- static nodes_iterator nodes_end(::clang::DominatorTree *N) {
- return df_end(getEntryNode(N));
- }
-};
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
deleted file mode 100644
index 4471311..0000000
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ /dev/null
@@ -1,679 +0,0 @@
-//= FormatString.h - Analysis of printf/fprintf format strings --*- 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 APIs for analyzing the format strings of printf, fscanf,
-// and friends.
-//
-// The structure of format strings for fprintf are described in C99 7.19.6.1.
-//
-// The structure of format strings for fscanf are described in C99 7.19.6.2.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
-
-#include "clang/AST/CanonicalType.h"
-
-namespace clang {
-
-class TargetInfo;
-
-//===----------------------------------------------------------------------===//
-/// Common components of both fprintf and fscanf format strings.
-namespace analyze_format_string {
-
-/// Class representing optional flags with location and representation
-/// information.
-class OptionalFlag {
-public:
- OptionalFlag(const char *Representation)
- : representation(Representation), flag(false) {}
- bool isSet() { return flag; }
- void set() { flag = true; }
- void clear() { flag = false; }
- void setPosition(const char *position) {
- assert(position);
- flag = true;
- this->position = position;
- }
- const char *getPosition() const {
- assert(position);
- return position;
- }
- const char *toString() const { return representation; }
-
- // Overloaded operators for bool like qualities
- explicit operator bool() const { return flag; }
- OptionalFlag& operator=(const bool &rhs) {
- flag = rhs;
- return *this; // Return a reference to myself.
- }
-private:
- const char *representation;
- const char *position;
- bool flag;
-};
-
-/// Represents the length modifier in a format string in scanf/printf.
-class LengthModifier {
-public:
- enum Kind {
- None,
- AsChar, // 'hh'
- AsShort, // 'h'
- AsLong, // 'l'
- AsLongLong, // 'll'
- AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types)
- AsIntMax, // 'j'
- AsSizeT, // 'z'
- AsPtrDiff, // 't'
- AsInt32, // 'I32' (MSVCRT, like __int32)
- AsInt3264, // 'I' (MSVCRT, like __int3264 from MIDL)
- AsInt64, // 'I64' (MSVCRT, like __int64)
- AsLongDouble, // 'L'
- AsAllocate, // for '%as', GNU extension to C90 scanf
- AsMAllocate, // for '%ms', GNU extension to scanf
- AsWide, // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
- AsWideChar = AsLong // for '%ls', only makes sense for printf
- };
-
- LengthModifier()
- : Position(nullptr), kind(None) {}
- LengthModifier(const char *pos, Kind k)
- : Position(pos), kind(k) {}
-
- const char *getStart() const {
- return Position;
- }
-
- unsigned getLength() const {
- switch (kind) {
- default:
- return 1;
- case AsLongLong:
- case AsChar:
- return 2;
- case AsInt32:
- case AsInt64:
- return 3;
- case None:
- return 0;
- }
- }
-
- Kind getKind() const { return kind; }
- void setKind(Kind k) { kind = k; }
-
- const char *toString() const;
-
-private:
- const char *Position;
- Kind kind;
-};
-
-class ConversionSpecifier {
-public:
- enum Kind {
- InvalidSpecifier = 0,
- // C99 conversion specifiers.
- cArg,
- dArg,
- DArg, // Apple extension
- iArg,
- IntArgBeg = dArg, IntArgEnd = iArg,
-
- oArg,
- OArg, // Apple extension
- uArg,
- UArg, // Apple extension
- xArg,
- XArg,
- UIntArgBeg = oArg, UIntArgEnd = XArg,
-
- fArg,
- FArg,
- eArg,
- EArg,
- gArg,
- GArg,
- aArg,
- AArg,
- DoubleArgBeg = fArg, DoubleArgEnd = AArg,
-
- sArg,
- pArg,
- nArg,
- PercentArg,
- CArg,
- SArg,
-
- // ** Printf-specific **
-
- ZArg, // MS extension
-
- // Objective-C specific specifiers.
- ObjCObjArg, // '@'
- ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
-
- // FreeBSD kernel specific specifiers.
- FreeBSDbArg,
- FreeBSDDArg,
- FreeBSDrArg,
- FreeBSDyArg,
-
- // GlibC specific specifiers.
- PrintErrno, // 'm'
-
- PrintfConvBeg = ObjCObjArg, PrintfConvEnd = PrintErrno,
-
- // ** Scanf-specific **
- ScanListArg, // '['
- ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg
- };
-
- ConversionSpecifier(bool isPrintf = true)
- : IsPrintf(isPrintf), Position(nullptr), EndScanList(nullptr),
- kind(InvalidSpecifier) {}
-
- ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
- : IsPrintf(isPrintf), Position(pos), EndScanList(nullptr), kind(k) {}
-
- const char *getStart() const {
- return Position;
- }
-
- StringRef getCharacters() const {
- return StringRef(getStart(), getLength());
- }
-
- bool consumesDataArgument() const {
- switch (kind) {
- case PrintErrno:
- assert(IsPrintf);
- return false;
- case PercentArg:
- return false;
- default:
- return true;
- }
- }
-
- Kind getKind() const { return kind; }
- void setKind(Kind k) { kind = k; }
- unsigned getLength() const {
- return EndScanList ? EndScanList - Position : 1;
- }
-
- bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) ||
- kind == FreeBSDrArg || kind == FreeBSDyArg; }
- bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
- bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; }
- const char *toString() const;
-
- bool isPrintfKind() const { return IsPrintf; }
-
- Optional<ConversionSpecifier> getStandardSpecifier() const;
-
-protected:
- bool IsPrintf;
- const char *Position;
- const char *EndScanList;
- Kind kind;
-};
-
-class ArgType {
-public:
- enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
- AnyCharTy, CStrTy, WCStrTy, WIntTy };
-
- enum MatchKind { NoMatch = 0, Match = 1, NoMatchPedantic };
-
-private:
- const Kind K;
- QualType T;
- const char *Name;
- bool Ptr;
-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) {}
-
- static ArgType Invalid() { return ArgType(InvalidTy); }
- bool isValid() const { return K != InvalidTy; }
-
- /// 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");
- ArgType Res = A;
- Res.Ptr = true;
- return Res;
- }
-
- MatchKind matchesType(ASTContext &C, QualType argTy) const;
-
- QualType getRepresentativeType(ASTContext &C) const;
-
- std::string getRepresentativeTypeName(ASTContext &C) const;
-};
-
-class OptionalAmount {
-public:
- enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
-
- OptionalAmount(HowSpecified howSpecified,
- unsigned amount,
- const char *amountStart,
- unsigned amountLength,
- bool usesPositionalArg)
- : start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
- UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
-
- OptionalAmount(bool valid = true)
- : start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
- UsesPositionalArg(0), UsesDotPrefix(0) {}
-
- bool isInvalid() const {
- return hs == Invalid;
- }
-
- HowSpecified getHowSpecified() const { return hs; }
- void setHowSpecified(HowSpecified h) { hs = h; }
-
- bool hasDataArgument() const { return hs == Arg; }
-
- unsigned getArgIndex() const {
- assert(hasDataArgument());
- return amt;
- }
-
- unsigned getConstantAmount() const {
- assert(hs == Constant);
- return amt;
- }
-
- const char *getStart() const {
- // We include the . character if it is given.
- return start - UsesDotPrefix;
- }
-
- unsigned getConstantLength() const {
- assert(hs == Constant);
- return length + UsesDotPrefix;
- }
-
- ArgType getArgType(ASTContext &Ctx) const;
-
- void toString(raw_ostream &os) const;
-
- bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
- unsigned getPositionalArgIndex() const {
- assert(hasDataArgument());
- return amt + 1;
- }
-
- bool usesDotPrefix() const { return UsesDotPrefix; }
- void setUsesDotPrefix() { UsesDotPrefix = true; }
-
-private:
- const char *start;
- unsigned length;
- HowSpecified hs;
- unsigned amt;
- bool UsesPositionalArg : 1;
- bool UsesDotPrefix;
-};
-
-
-class FormatSpecifier {
-protected:
- LengthModifier LM;
- OptionalAmount FieldWidth;
- ConversionSpecifier CS;
- /// Positional arguments, an IEEE extension:
- /// IEEE Std 1003.1, 2004 Edition
- /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
- bool UsesPositionalArg;
- unsigned argIndex;
-public:
- FormatSpecifier(bool isPrintf)
- : CS(isPrintf), UsesPositionalArg(false), argIndex(0) {}
-
- void setLengthModifier(LengthModifier lm) {
- LM = lm;
- }
-
- void setUsesPositionalArg() { UsesPositionalArg = true; }
-
- void setArgIndex(unsigned i) {
- argIndex = i;
- }
-
- unsigned getArgIndex() const {
- return argIndex;
- }
-
- unsigned getPositionalArgIndex() const {
- return argIndex + 1;
- }
-
- const LengthModifier &getLengthModifier() const {
- return LM;
- }
-
- const OptionalAmount &getFieldWidth() const {
- return FieldWidth;
- }
-
- void setFieldWidth(const OptionalAmount &Amt) {
- FieldWidth = Amt;
- }
-
- bool usesPositionalArg() const { return UsesPositionalArg; }
-
- bool hasValidLengthModifier(const TargetInfo &Target) const;
-
- bool hasStandardLengthModifier() const;
-
- Optional<LengthModifier> getCorrectedLengthModifier() const;
-
- bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
-
- bool hasStandardLengthConversionCombination() const;
-
- /// For a TypedefType QT, if it is a named integer type such as size_t,
- /// assign the appropriate value to LM and return true.
- static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM);
-};
-
-} // end analyze_format_string namespace
-
-//===----------------------------------------------------------------------===//
-/// Pieces specific to fprintf format strings.
-
-namespace analyze_printf {
-
-class PrintfConversionSpecifier :
- public analyze_format_string::ConversionSpecifier {
-public:
- PrintfConversionSpecifier()
- : ConversionSpecifier(true, nullptr, InvalidSpecifier) {}
-
- PrintfConversionSpecifier(const char *pos, Kind k)
- : ConversionSpecifier(true, pos, k) {}
-
- bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
- bool isDoubleArg() const { return kind >= DoubleArgBeg &&
- kind <= DoubleArgEnd; }
- unsigned getLength() const {
- // Conversion specifiers currently only are represented by
- // single characters, but we be flexible.
- return 1;
- }
-
- static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
- return CS->isPrintfKind();
- }
-};
-
-using analyze_format_string::ArgType;
-using analyze_format_string::LengthModifier;
-using analyze_format_string::OptionalAmount;
-using analyze_format_string::OptionalFlag;
-
-class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
- OptionalFlag HasThousandsGrouping; // ''', POSIX extension.
- OptionalFlag IsLeftJustified; // '-'
- OptionalFlag HasPlusPrefix; // '+'
- OptionalFlag HasSpacePrefix; // ' '
- OptionalFlag HasAlternativeForm; // '#'
- OptionalFlag HasLeadingZeroes; // '0'
- OptionalFlag HasObjCTechnicalTerm; // '[tt]'
- OptionalAmount Precision;
-public:
- PrintfSpecifier() :
- FormatSpecifier(/* isPrintf = */ true),
- HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"),
- HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0"),
- HasObjCTechnicalTerm("tt") {}
-
- static PrintfSpecifier Parse(const char *beg, const char *end);
-
- // Methods for incrementally constructing the PrintfSpecifier.
- void setConversionSpecifier(const PrintfConversionSpecifier &cs) {
- CS = cs;
- }
- void setHasThousandsGrouping(const char *position) {
- HasThousandsGrouping.setPosition(position);
- }
- void setIsLeftJustified(const char *position) {
- IsLeftJustified.setPosition(position);
- }
- void setHasPlusPrefix(const char *position) {
- HasPlusPrefix.setPosition(position);
- }
- void setHasSpacePrefix(const char *position) {
- HasSpacePrefix.setPosition(position);
- }
- void setHasAlternativeForm(const char *position) {
- HasAlternativeForm.setPosition(position);
- }
- void setHasLeadingZeros(const char *position) {
- HasLeadingZeroes.setPosition(position);
- }
- void setHasObjCTechnicalTerm(const char *position) {
- HasObjCTechnicalTerm.setPosition(position);
- }
- void setUsesPositionalArg() { UsesPositionalArg = true; }
-
- // Methods for querying the format specifier.
-
- const PrintfConversionSpecifier &getConversionSpecifier() const {
- return cast<PrintfConversionSpecifier>(CS);
- }
-
- void setPrecision(const OptionalAmount &Amt) {
- Precision = Amt;
- Precision.setUsesDotPrefix();
- }
-
- const OptionalAmount &getPrecision() const {
- return Precision;
- }
-
- bool consumesDataArgument() const {
- return getConversionSpecifier().consumesDataArgument();
- }
-
- /// \brief 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
- /// more than one type.
- ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
-
- const OptionalFlag &hasThousandsGrouping() const {
- return HasThousandsGrouping;
- }
- const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
- const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
- const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
- const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
- const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
- const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; }
- bool usesPositionalArg() const { return UsesPositionalArg; }
-
- /// Changes the specifier and length according to a QualType, retaining any
- /// flags or options. Returns true on success, or false when a conversion
- /// was not successful.
- bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx,
- bool IsObjCLiteral);
-
- void toString(raw_ostream &os) const;
-
- // Validation methods - to check if any element results in undefined behavior
- bool hasValidPlusPrefix() const;
- bool hasValidAlternativeForm() const;
- bool hasValidLeadingZeros() const;
- bool hasValidSpacePrefix() const;
- bool hasValidLeftJustified() const;
- bool hasValidThousandsGroupingPrefix() const;
-
- bool hasValidPrecision() const;
- bool hasValidFieldWidth() const;
-};
-} // end analyze_printf namespace
-
-//===----------------------------------------------------------------------===//
-/// Pieces specific to fscanf format strings.
-
-namespace analyze_scanf {
-
-class ScanfConversionSpecifier :
- public analyze_format_string::ConversionSpecifier {
-public:
- ScanfConversionSpecifier()
- : ConversionSpecifier(false, nullptr, InvalidSpecifier) {}
-
- ScanfConversionSpecifier(const char *pos, Kind k)
- : ConversionSpecifier(false, pos, k) {}
-
- void setEndScanList(const char *pos) { EndScanList = pos; }
-
- static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
- return !CS->isPrintfKind();
- }
-};
-
-using analyze_format_string::ArgType;
-using analyze_format_string::LengthModifier;
-using analyze_format_string::OptionalAmount;
-using analyze_format_string::OptionalFlag;
-
-class ScanfSpecifier : public analyze_format_string::FormatSpecifier {
- OptionalFlag SuppressAssignment; // '*'
-public:
- ScanfSpecifier() :
- FormatSpecifier(/* isPrintf = */ false),
- SuppressAssignment("*") {}
-
- void setSuppressAssignment(const char *position) {
- SuppressAssignment.setPosition(position);
- }
-
- const OptionalFlag &getSuppressAssignment() const {
- return SuppressAssignment;
- }
-
- void setConversionSpecifier(const ScanfConversionSpecifier &cs) {
- CS = cs;
- }
-
- const ScanfConversionSpecifier &getConversionSpecifier() const {
- return cast<ScanfConversionSpecifier>(CS);
- }
-
- bool consumesDataArgument() const {
- return CS.consumesDataArgument() && !SuppressAssignment;
- }
-
- ArgType getArgType(ASTContext &Ctx) const;
-
- bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt,
- ASTContext &Ctx);
-
- void toString(raw_ostream &os) const;
-
- static ScanfSpecifier Parse(const char *beg, const char *end);
-};
-
-} // end analyze_scanf namespace
-
-//===----------------------------------------------------------------------===//
-// Parsing and processing of format strings (both fprintf and fscanf).
-
-namespace analyze_format_string {
-
-enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
-
-class FormatStringHandler {
-public:
- FormatStringHandler() {}
- virtual ~FormatStringHandler();
-
- virtual void HandleNullChar(const char *nullCharacter) {}
-
- virtual void HandlePosition(const char *startPos, unsigned posLen) {}
-
- virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
- PositionContext p) {}
-
- virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
-
- virtual void HandleIncompleteSpecifier(const char *startSpecifier,
- unsigned specifierLen) {}
-
- virtual void HandleEmptyObjCModifierFlag(const char *startFlags,
- unsigned flagsLen) {}
-
- virtual void HandleInvalidObjCModifierFlag(const char *startFlag,
- unsigned flagLen) {}
-
- virtual void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart,
- const char *flagsEnd,
- const char *conversionPosition) {}
- // Printf-specific handlers.
-
- virtual bool HandleInvalidPrintfConversionSpecifier(
- const analyze_printf::PrintfSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen) {
- return true;
- }
-
- virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen) {
- return true;
- }
-
- // Scanf-specific handlers.
-
- virtual bool HandleInvalidScanfConversionSpecifier(
- const analyze_scanf::ScanfSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen) {
- return true;
- }
-
- virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen) {
- return true;
- }
-
- virtual void HandleIncompleteScanList(const char *start, const char *end) {}
-};
-
-bool ParsePrintfString(FormatStringHandler &H,
- const char *beg, const char *end, const LangOptions &LO,
- const TargetInfo &Target, bool isFreeBSDKPrintf);
-
-bool ParseFormatStringHasSArg(const char *beg, const char *end,
- const LangOptions &LO, const TargetInfo &Target);
-
-bool ParseScanfString(FormatStringHandler &H,
- const char *beg, const char *end, const LangOptions &LO,
- const TargetInfo &Target);
-
-} // end analyze_format_string namespace
-} // end clang namespace
-#endif
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
deleted file mode 100644
index e17f73a6..0000000
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements Live Variables analysis for source-level CFGs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Analysis/AnalysisContext.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/ImmutableSet.h"
-
-namespace clang {
-
-class CFG;
-class CFGBlock;
-class Stmt;
-class DeclRefExpr;
-class SourceManager;
-
-class LiveVariables : public ManagedAnalysis {
-public:
- class LivenessValues {
- public:
-
- llvm::ImmutableSet<const Stmt *> liveStmts;
- llvm::ImmutableSet<const VarDecl *> liveDecls;
-
- bool equals(const LivenessValues &V) const;
-
- LivenessValues()
- : liveStmts(nullptr), liveDecls(nullptr) {}
-
- LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts,
- llvm::ImmutableSet<const VarDecl *> LiveDecls)
- : liveStmts(LiveStmts), liveDecls(LiveDecls) {}
-
- bool isLive(const Stmt *S) const;
- bool isLive(const VarDecl *D) const;
-
- friend class LiveVariables;
- };
-
- class Observer {
- virtual void anchor();
- public:
- virtual ~Observer() {}
-
- /// A callback invoked right before invoking the
- /// liveness transfer function on the given statement.
- virtual void observeStmt(const Stmt *S,
- const CFGBlock *currentBlock,
- const LivenessValues& V) {}
-
- /// Called when the live variables analysis registers
- /// that a variable is killed.
- virtual void observerKill(const DeclRefExpr *DR) {}
- };
-
- ~LiveVariables() override;
-
- /// Compute the liveness information for a given CFG.
- static LiveVariables *computeLiveness(AnalysisDeclContext &analysisContext,
- bool killAtAssign);
-
- /// Return true if a variable is live at the end of a
- /// specified block.
- bool isLive(const CFGBlock *B, const VarDecl *D);
-
- /// Returns true if a variable is live at the beginning of the
- /// the statement. This query only works if liveness information
- /// has been recorded at the statement level (see runOnAllBlocks), and
- /// only returns liveness information for block-level expressions.
- bool isLive(const Stmt *S, const VarDecl *D);
-
- /// Returns true the block-level expression "value" is live
- /// before the given block-level expression (see runOnAllBlocks).
- bool isLive(const Stmt *Loc, const Stmt *StmtVal);
-
- /// Print to stderr the liveness information associated with
- /// each basic block.
- void dumpBlockLiveness(const SourceManager& M);
-
- void runOnAllBlocks(Observer &obs);
-
- static LiveVariables *create(AnalysisDeclContext &analysisContext) {
- return computeLiveness(analysisContext, true);
- }
-
- static const void *getTag();
-
-private:
- LiveVariables(void *impl);
- void *impl;
-};
-
-class RelaxedLiveVariables : public LiveVariables {
-public:
- static LiveVariables *create(AnalysisDeclContext &analysisContext) {
- return computeLiveness(analysisContext, false);
- }
-
- static const void *getTag();
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
deleted file mode 100644
index a1c6504..0000000
--- a/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ /dev/null
@@ -1,115 +0,0 @@
-//===- PostOrderCFGView.h - Post order view of CFG blocks ---------*- C++ --*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements post order view of the blocks in a CFG.
-//
-//===----------------------------------------------------------------------===//
-
-#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/AnalysisContext.h"
-#include "clang/Analysis/CFG.h"
-
-namespace clang {
-
-class PostOrderCFGView : public ManagedAnalysis {
- virtual void anchor();
-public:
- /// \brief 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
- /// external storage. We also use this set to keep track of which CFGBlocks we
- /// 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; };
-
- CFGBlockSet() {}
- CFGBlockSet(const CFG *G) : VisitedBlockIDs(G->getNumBlockIDs(), false) {}
-
- /// \brief 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
- // make sure that Block is non-null. Moreover, the CFGBlock iterator will
- // occasionally hand out null pointers for pruned edges, so we catch those
- // here.
- if (!Block)
- return std::make_pair(None, false); // if an edge is trivially false.
- if (VisitedBlockIDs.test(Block->getBlockID()))
- return std::make_pair(None, false);
- VisitedBlockIDs.set(Block->getBlockID());
- return std::make_pair(None, true);
- }
-
- /// \brief 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) {
- return VisitedBlockIDs.test(Block->getBlockID());
- }
- };
-
-private:
- typedef llvm::po_iterator<const CFG*, CFGBlockSet, true> po_iterator;
- std::vector<const CFGBlock*> Blocks;
-
- typedef llvm::DenseMap<const CFGBlock *, unsigned> BlockOrderTy;
- BlockOrderTy BlockOrder;
-
-public:
- typedef std::vector<const CFGBlock *>::reverse_iterator iterator;
- typedef std::vector<const CFGBlock *>::const_reverse_iterator const_iterator;
-
- PostOrderCFGView(const CFG *cfg);
-
- iterator begin() { return Blocks.rbegin(); }
- 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;
- };
-
- BlockOrderCompare getComparator() const {
- return BlockOrderCompare(*this);
- }
-
- // Used by AnalyisContext to construct this object.
- static const void *getTag();
-
- static PostOrderCFGView *create(AnalysisDeclContext &analysisContext);
-};
-
-} // end clang namespace
-
-#endif
-
diff --git a/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h b/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
deleted file mode 100644
index c4ec2f2..0000000
--- a/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//== PseudoConstantAnalysis.h - Find Pseudo-constants in the AST -*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file tracks the usage of variables in a Decl body to see if they are
-// never written to, implying that they constant. This is useful in static
-// analysis to see if a developer might have intended a variable to be const.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
-
-#include "clang/AST/Stmt.h"
-
-namespace clang {
-
-class PseudoConstantAnalysis {
-public:
- PseudoConstantAnalysis(const Stmt *DeclBody);
- ~PseudoConstantAnalysis();
-
- bool isPseudoConstant(const VarDecl *VD);
- bool wasReferenced(const VarDecl *VD);
-
-private:
- void RunAnalysis();
- inline static const Decl *getDecl(const Expr *E);
-
- // for storing the result of analyzed ValueDecls
- void *NonConstantsImpl;
- void *UsedVarsImpl;
-
- const Stmt *DeclBody;
- bool Analyzed;
-};
-
-}
-
-#endif
diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h
deleted file mode 100644
index 4c523bf..0000000
--- a/include/clang/Analysis/Analyses/ReachableCode.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===- ReachableCode.h -----------------------------------------*- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// A flow-sensitive, path-insensitive analysis of unreachable code.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_REACHABLECODE_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_REACHABLECODE_H
-
-#include "clang/Basic/SourceLocation.h"
-
-//===----------------------------------------------------------------------===//
-// Forward declarations.
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
- class BitVector;
-}
-
-namespace clang {
- class AnalysisDeclContext;
- class CFGBlock;
- class Preprocessor;
-}
-
-//===----------------------------------------------------------------------===//
-// API.
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-namespace reachable_code {
-
-/// Classifications of unreachable code.
-enum UnreachableKind {
- UK_Return,
- UK_Break,
- UK_Loop_Increment,
- UK_Other
-};
-
-class Callback {
- virtual void anchor();
-public:
- virtual ~Callback() {}
- virtual void HandleUnreachable(UnreachableKind UK,
- SourceLocation L,
- SourceRange ConditionVal,
- SourceRange R1,
- SourceRange R2) = 0;
-};
-
-/// ScanReachableFromBlock - Mark all blocks reachable from Start.
-/// Returns the total number of blocks that were marked reachable.
-unsigned ScanReachableFromBlock(const CFGBlock *Start,
- llvm::BitVector &Reachable);
-
-void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP,
- Callback &CB);
-
-}} // end namespace clang::reachable_code
-
-#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
deleted file mode 100644
index 22694a7..0000000
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ /dev/null
@@ -1,226 +0,0 @@
-//===- ThreadSafety.h ------------------------------------------*- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-// A intra-procedural analysis for thread safety (e.g. deadlocks and race
-// conditions), based off of an annotation system.
-//
-// See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking
-// for more information.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
-
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace threadSafety {
-
-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.
-};
-
-/// 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
-};
-
-/// 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.
-};
-
-/// This enum distinguishes between different situations where we warn due to
-/// inconsistent locking.
-/// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all
-/// loop iterations.
-/// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all
-/// predecessors of a CFGBlock.
-/// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a
-/// function.
-enum LockErrorKind {
- LEK_LockedSomeLoopIterations,
- LEK_LockedSomePredecessors,
- LEK_LockedAtEndOfFunction,
- LEK_NotLockedAtEndOfFunction
-};
-
-/// Handler class for thread safety warnings.
-class ThreadSafetyHandler {
-public:
- typedef StringRef Name;
- ThreadSafetyHandler() : IssueBetaWarnings(false) { }
- virtual ~ThreadSafetyHandler();
-
- /// Warn about lock expressions which fail to resolve to lockable objects.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param Loc -- the SourceLocation of the unresolved expression.
- virtual void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) {}
-
- /// Warn about unlock function calls that do not have a prior matching lock
- /// expression.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param LockName -- A StringRef name for the lock expression, to be printed
- /// in the error message.
- /// \param Loc -- The SourceLocation of the Unlock
- virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
- SourceLocation Loc) {}
-
- /// Warn about an unlock function call that attempts to unlock a lock with
- /// the incorrect lock kind. For instance, a shared lock being unlocked
- /// exclusively, or vice versa.
- /// \param LockName -- A StringRef name for the lock expression, to be printed
- /// in the error message.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param Expected -- the kind of lock expected.
- /// \param Received -- the kind of lock received.
- /// \param Loc -- The SourceLocation of the Unlock.
- virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
- LockKind Expected, LockKind Received,
- SourceLocation Loc) {}
-
- /// Warn about lock function calls for locks which are already held.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param LockName -- A StringRef name for the lock expression, to be printed
- /// in the error message.
- /// \param Loc -- The location of the second lock expression.
- virtual void handleDoubleLock(StringRef Kind, Name LockName,
- SourceLocation Loc) {}
-
- /// Warn about situations where a mutex is sometimes held and sometimes not.
- /// The three situations are:
- /// 1. a mutex is locked on an "if" branch but not the "else" branch,
- /// 2, or a mutex is only held at the start of some loop iterations,
- /// 3. or when a mutex is locked but not unlocked inside a function.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param LockName -- A StringRef name for the lock expression, to be printed
- /// in the error message.
- /// \param LocLocked -- The location of the lock expression where the mutex is
- /// locked
- /// \param LocEndOfScope -- The location of the end of the scope where the
- /// mutex is no longer held
- /// \param LEK -- which of the three above cases we should warn for
- virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
- SourceLocation LocLocked,
- SourceLocation LocEndOfScope,
- LockErrorKind LEK) {}
-
- /// Warn when a mutex is held exclusively and shared at the same point. For
- /// example, if a mutex is locked exclusively during an if branch and shared
- /// during the else branch.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param LockName -- A StringRef name for the lock expression, to be printed
- /// in the error message.
- /// \param Loc1 -- The location of the first lock expression.
- /// \param Loc2 -- The location of the second lock expression.
- virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
- SourceLocation Loc1,
- SourceLocation Loc2) {}
-
- /// Warn when a protected operation occurs while no locks are held.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param D -- The decl for the protected variable or function
- /// \param POK -- The kind of protected operation (e.g. variable access)
- /// \param AK -- The kind of access (i.e. read or write) that occurred
- /// \param Loc -- The location of the protected operation.
- virtual void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
- ProtectedOperationKind POK, AccessKind AK,
- SourceLocation Loc) {}
-
- /// Warn when a protected operation occurs while the specific mutex protecting
- /// the operation is not locked.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param D -- The decl for the protected variable or function
- /// \param POK -- The kind of protected operation (e.g. variable access)
- /// \param LockName -- A StringRef name for the lock expression, to be printed
- /// in the error message.
- /// \param LK -- The kind of access (i.e. read or write) that occurred
- /// \param Loc -- The location of the protected operation.
- virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
- ProtectedOperationKind POK, Name LockName,
- LockKind LK, SourceLocation Loc,
- Name *PossibleMatch = nullptr) {}
-
- /// Warn when acquiring a lock that the negative capability is not held.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param LockName -- The name for the lock expression, to be printed in the
- /// diagnostic.
- /// \param Neg -- The name of the negative capability to be printed in the
- /// diagnostic.
- /// \param Loc -- The location of the protected operation.
- virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
- SourceLocation Loc) {}
-
- /// Warn when a function is called while an excluded mutex is locked. For
- /// example, the mutex may be locked inside the function.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
- /// \param FunName -- The name of the function
- /// \param LockName -- A StringRef name for the lock expression, to be printed
- /// in the error message.
- /// \param Loc -- The location of the function call.
- 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) {}
-
- /// Warn that there is a cycle in acquired_before/after dependencies.
- virtual void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) {}
-
- /// Called by the analysis when starting analysis of a function.
- /// Used to issue suggestions for changes to annotations.
- virtual void enterFunction(const FunctionDecl *FD) {}
-
- /// Called by the analysis when finishing analysis of a function.
- virtual void leaveFunction(const FunctionDecl *FD) {}
-
- bool issueBetaWarnings() { return IssueBetaWarnings; }
- void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
-
-private:
- bool IssueBetaWarnings;
-};
-
-/// \brief 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.
-/// Each block in the CFG is traversed exactly once.
-void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
- ThreadSafetyHandler &Handler,
- BeforeSet **Bset);
-
-void threadSafetyCleanup(BeforeSet *Cache);
-
-/// \brief Helper function that returns a LockKind required for the given level
-/// of access.
-LockKind getLockKindFromAccessKind(AccessKind AK);
-
-}} // end namespace clang::threadSafety
-#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
deleted file mode 100644
index e357013..0000000
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ /dev/null
@@ -1,505 +0,0 @@
-//===- ThreadSafetyCommon.h ------------------------------------*- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Parts of thread safety analysis that are not specific to thread safety
-// itself have been factored into classes here, where they can be potentially
-// used by other analyses. Currently these include:
-//
-// * Generalize clang CFG visitors.
-// * Conversion of the clang CFG to SSA form.
-// * Translation of clang Exprs to TIL SExprs
-//
-// UNDER CONSTRUCTION. USE AT YOUR OWN RISK.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
-
-#include "clang/Analysis/Analyses/PostOrderCFGView.h"
-#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
-#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Basic/OperatorKinds.h"
-#include <memory>
-#include <ostream>
-#include <sstream>
-#include <vector>
-
-
-namespace clang {
-namespace threadSafety {
-
-
-// Various helper functions on til::SExpr
-namespace sx {
-
-inline bool equals(const til::SExpr *E1, const til::SExpr *E2) {
- return til::EqualsComparator::compareExprs(E1, E2);
-}
-
-inline bool matches(const til::SExpr *E1, const til::SExpr *E2) {
- // We treat a top-level wildcard as the "univsersal" lock.
- // It matches everything for the purpose of checking locks, but not
- // for unlocking them.
- if (isa<til::Wildcard>(E1))
- return isa<til::Wildcard>(E2);
- if (isa<til::Wildcard>(E2))
- return isa<til::Wildcard>(E1);
-
- return til::MatchComparator::compareExprs(E1, E2);
-}
-
-inline bool partiallyMatches(const til::SExpr *E1, const til::SExpr *E2) {
- const auto *PE1 = dyn_cast_or_null<til::Project>(E1);
- if (!PE1)
- return false;
- const auto *PE2 = dyn_cast_or_null<til::Project>(E2);
- if (!PE2)
- return false;
- return PE1->clangDecl() == PE2->clangDecl();
-}
-
-inline std::string toString(const til::SExpr *E) {
- std::stringstream ss;
- til::StdPrinter::print(E, ss);
- return ss.str();
-}
-
-} // end namespace sx
-
-
-
-// This class defines the interface of a clang CFG Visitor.
-// CFGWalker will invoke the following methods.
-// Note that methods are not virtual; the visitor is templatized.
-class CFGVisitor {
- // Enter the CFG for Decl D, and perform any initial setup operations.
- void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First) {}
-
- // Enter a CFGBlock.
- void enterCFGBlock(const CFGBlock *B) {}
-
- // Returns true if this visitor implements handlePredecessor
- bool visitPredecessors() { return true; }
-
- // Process a predecessor edge.
- void handlePredecessor(const CFGBlock *Pred) {}
-
- // Process a successor back edge to a previously visited block.
- void handlePredecessorBackEdge(const CFGBlock *Pred) {}
-
- // Called just before processing statements.
- void enterCFGBlockBody(const CFGBlock *B) {}
-
- // Process an ordinary statement.
- void handleStatement(const Stmt *S) {}
-
- // Process a destructor call
- void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD) {}
-
- // Called after all statements have been handled.
- void exitCFGBlockBody(const CFGBlock *B) {}
-
- // Return true
- bool visitSuccessors() { return true; }
-
- // Process a successor edge.
- void handleSuccessor(const CFGBlock *Succ) {}
-
- // Process a successor back edge to a previously visited block.
- void handleSuccessorBackEdge(const CFGBlock *Succ) {}
-
- // Leave a CFGBlock.
- void exitCFGBlock(const CFGBlock *B) {}
-
- // Leave the CFG, and perform any final cleanup operations.
- 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) {}
-
- // Initialize the CFGWalker. This setup only needs to be done once, even
- // if there are multiple passes over the CFG.
- bool init(AnalysisDeclContext &AC) {
- ACtx = &AC;
- CFGraph = AC.getCFG();
- if (!CFGraph)
- return false;
-
- // Ignore anonymous functions.
- if (!dyn_cast_or_null<NamedDecl>(AC.getDecl()))
- return false;
-
- SortedGraph = AC.getAnalysis<PostOrderCFGView>();
- if (!SortedGraph)
- return false;
-
- return true;
- }
-
- // Traverse the CFG, calling methods on V as appropriate.
- template <class Visitor>
- void walk(Visitor &V) {
- PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
-
- V.enterCFG(CFGraph, getDecl(), &CFGraph->getEntry());
-
- for (const auto *CurrBlock : *SortedGraph) {
- VisitedBlocks.insert(CurrBlock);
-
- V.enterCFGBlock(CurrBlock);
-
- // Process predecessors, handling back edges last
- if (V.visitPredecessors()) {
- SmallVector<CFGBlock*, 4> BackEdges;
- // Process successors
- for (CFGBlock::const_pred_iterator SI = CurrBlock->pred_begin(),
- SE = CurrBlock->pred_end();
- SI != SE; ++SI) {
- if (*SI == nullptr)
- continue;
-
- if (!VisitedBlocks.alreadySet(*SI)) {
- BackEdges.push_back(*SI);
- continue;
- }
- V.handlePredecessor(*SI);
- }
-
- for (auto *Blk : BackEdges)
- V.handlePredecessorBackEdge(Blk);
- }
-
- V.enterCFGBlockBody(CurrBlock);
-
- // Process statements
- for (const auto &BI : *CurrBlock) {
- switch (BI.getKind()) {
- case CFGElement::Statement: {
- V.handleStatement(BI.castAs<CFGStmt>().getStmt());
- break;
- }
- case CFGElement::AutomaticObjectDtor: {
- CFGAutomaticObjDtor AD = BI.castAs<CFGAutomaticObjDtor>();
- CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
- AD.getDestructorDecl(ACtx->getASTContext()));
- VarDecl *VD = const_cast<VarDecl*>(AD.getVarDecl());
- V.handleDestructorCall(VD, DD);
- break;
- }
- default:
- break;
- }
- }
-
- V.exitCFGBlockBody(CurrBlock);
-
- // Process successors, handling back edges first.
- if (V.visitSuccessors()) {
- SmallVector<CFGBlock*, 8> ForwardEdges;
-
- // Process successors
- for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
- SE = CurrBlock->succ_end();
- SI != SE; ++SI) {
- if (*SI == nullptr)
- continue;
-
- if (!VisitedBlocks.alreadySet(*SI)) {
- ForwardEdges.push_back(*SI);
- continue;
- }
- V.handleSuccessorBackEdge(*SI);
- }
-
- for (auto *Blk : ForwardEdges)
- V.handleSuccessor(Blk);
- }
-
- V.exitCFGBlock(CurrBlock);
- }
- V.exitCFG(&CFGraph->getExit());
- }
-
- const CFG *getGraph() const { return CFGraph; }
- CFG *getGraph() { return CFGraph; }
-
- const NamedDecl *getDecl() const {
- return dyn_cast<NamedDecl>(ACtx->getDecl());
- }
-
- const PostOrderCFGView *getSortedGraph() const { return SortedGraph; }
-
-private:
- CFG *CFGraph;
- AnalysisDeclContext *ACtx;
- PostOrderCFGView *SortedGraph;
-};
-
-
-
-
-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
-
-public:
- CapabilityExpr(const til::SExpr *E, bool Neg) : CapExpr(E), Negated(Neg) {}
-
- const til::SExpr* sexpr() const { return CapExpr; }
- bool negative() const { return Negated; }
-
- CapabilityExpr operator!() const {
- return CapabilityExpr(CapExpr, !Negated);
- }
-
- bool equals(const CapabilityExpr &other) const {
- return (Negated == other.Negated) && sx::equals(CapExpr, other.CapExpr);
- }
-
- bool matches(const CapabilityExpr &other) const {
- return (Negated == other.Negated) && sx::matches(CapExpr, other.CapExpr);
- }
-
- bool matchesUniv(const CapabilityExpr &CapE) const {
- return isUniversal() || matches(CapE);
- }
-
- bool partiallyMatches(const CapabilityExpr &other) const {
- return (Negated == other.Negated) &&
- sx::partiallyMatches(CapExpr, other.CapExpr);
- }
-
- const ValueDecl* valueDecl() const {
- if (Negated || CapExpr == nullptr)
- return nullptr;
- if (auto *P = dyn_cast<til::Project>(CapExpr))
- return P->clangDecl();
- if (auto *P = dyn_cast<til::LiteralPtr>(CapExpr))
- return P->clangDecl();
- return nullptr;
- }
-
- std::string toString() const {
- if (Negated)
- return "!" + sx::toString(CapExpr);
- return sx::toString(CapExpr);
- }
-
- bool shouldIgnore() const { return CapExpr == nullptr; }
-
- bool isInvalid() const { return sexpr() && isa<til::Undefined>(sexpr()); }
-
- 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
- /// 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.
- /// Actual arguments must be substituted for formal parameters to derive
- /// the appropriate mutex expression in the lexical context where the function
- /// is called. PrevCtx holds the context in which the arguments themselves
- /// 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 .?
-
- CallingContext(CallingContext *P, const NamedDecl *D = nullptr)
- : Prev(P), AttrDecl(D), SelfArg(nullptr),
- NumArgs(0), FunArgs(nullptr), SelfArrow(false)
- {}
- };
-
- SExprBuilder(til::MemRegionRef A)
- : Arena(A), SelfVar(nullptr), Scfg(nullptr), CurrentBB(nullptr),
- CurrentBlockInfo(nullptr) {
- // FIXME: we don't always have a self-variable.
- SelfVar = new (Arena) til::Variable(nullptr);
- SelfVar->setKind(til::Variable::VK_SFun);
- }
-
- // Translate a clang expression in an attribute to a til::SExpr.
- // Constructs the context from D, DeclExp, and SelfDecl.
- CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D,
- const Expr *DeclExp, VarDecl *SelfD=nullptr);
-
- CapabilityExpr translateAttrExpr(const Expr *AttrExp, CallingContext *Ctx);
-
- // Translate a clang statement or expression to a TIL expression.
- // Also performs substitution of variables; Ctx provides the context.
- // Dispatches on the type of S.
- til::SExpr *translate(const Stmt *S, CallingContext *Ctx);
- til::SCFG *buildCFG(CFGWalker &Walker);
-
- til::SExpr *lookupStmt(const Stmt *S);
-
- til::BasicBlock *lookupBlock(const CFGBlock *B) {
- return BlockMap[B->getBlockID()];
- }
-
- const til::SCFG *getCFG() const { return Scfg; }
- til::SCFG *getCFG() { return Scfg; }
-
-private:
- til::SExpr *translateDeclRefExpr(const DeclRefExpr *DRE,
- CallingContext *Ctx) ;
- til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
- til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx);
- til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx,
- const Expr *SelfE = nullptr);
- til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
- CallingContext *Ctx);
- til::SExpr *translateCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE,
- CallingContext *Ctx);
- til::SExpr *translateUnaryOperator(const UnaryOperator *UO,
- CallingContext *Ctx);
- til::SExpr *translateBinOp(til::TIL_BinaryOpcode Op,
- const BinaryOperator *BO,
- CallingContext *Ctx, bool Reverse = false);
- til::SExpr *translateBinAssign(til::TIL_BinaryOpcode Op,
- const BinaryOperator *BO,
- CallingContext *Ctx, bool Assign = false);
- til::SExpr *translateBinaryOperator(const BinaryOperator *BO,
- CallingContext *Ctx);
- til::SExpr *translateCastExpr(const CastExpr *CE, CallingContext *Ctx);
- til::SExpr *translateArraySubscriptExpr(const ArraySubscriptExpr *E,
- CallingContext *Ctx);
- til::SExpr *translateAbstractConditionalOperator(
- const AbstractConditionalOperator *C, CallingContext *Ctx);
-
- 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;
-
- // Map from clang local variables to indices in a LVarDefinitionMap.
- typedef llvm::DenseMap<const ValueDecl *, unsigned> LVarIndexMap;
-
- // Map from local variable indices to SSA variables (or constants).
- typedef std::pair<const ValueDecl *, til::SExpr *> NameVarPair;
- typedef CopyOnWriteVector<NameVarPair> LVarDefinitionMap;
-
- struct BlockInfo {
- LVarDefinitionMap ExitMap;
- bool HasBackEdges;
- unsigned UnprocessedSuccessors; // Successors yet to be processed
- unsigned ProcessedPredecessors; // Predecessors already processed
-
- BlockInfo()
- : HasBackEdges(false), UnprocessedSuccessors(0),
- ProcessedPredecessors(0) {}
- BlockInfo(BlockInfo &&RHS)
- : ExitMap(std::move(RHS.ExitMap)),
- HasBackEdges(RHS.HasBackEdges),
- UnprocessedSuccessors(RHS.UnprocessedSuccessors),
- ProcessedPredecessors(RHS.ProcessedPredecessors) {}
-
- BlockInfo &operator=(BlockInfo &&RHS) {
- if (this != &RHS) {
- ExitMap = std::move(RHS.ExitMap);
- HasBackEdges = RHS.HasBackEdges;
- UnprocessedSuccessors = RHS.UnprocessedSuccessors;
- ProcessedPredecessors = RHS.ProcessedPredecessors;
- }
- return *this;
- }
-
- private:
- BlockInfo(const BlockInfo &) = delete;
- void operator=(const BlockInfo &) = delete;
- };
-
- // 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; }
- void handlePredecessor(const CFGBlock *Pred);
- void handlePredecessorBackEdge(const CFGBlock *Pred);
- void enterCFGBlockBody(const CFGBlock *B);
- void handleStatement(const Stmt *S);
- void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD);
- void exitCFGBlockBody(const CFGBlock *B);
- bool visitSuccessors() { return true; }
- void handleSuccessor(const CFGBlock *Succ);
- void handleSuccessorBackEdge(const CFGBlock *Succ);
- void exitCFGBlock(const CFGBlock *B);
- void exitCFG(const CFGBlock *Last);
-
- 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,
- const ValueDecl *VD = nullptr);
- til::SExpr *lookupVarDecl(const ValueDecl *VD);
- til::SExpr *addVarDecl(const ValueDecl *VD, til::SExpr *E);
- til::SExpr *updateVarDecl(const ValueDecl *VD, til::SExpr *E);
-
- void makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E);
- void mergeEntryMap(LVarDefinitionMap Map);
- void mergeEntryMapBackEdge();
- void mergePhiNodesBackEdge(const CFGBlock *Blk);
-
-private:
- // Set to true when parsing capability expressions, which get translated
- // inaccurately in order to hack around smart pointers etc.
- 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.
-
- LVarDefinitionMap CurrentLVarMap;
- std::vector<til::Phi*> CurrentArguments;
- std::vector<til::SExpr*> CurrentInstructions;
- std::vector<til::Phi*> IncompleteArgs;
- til::BasicBlock *CurrentBB;
- BlockInfo *CurrentBlockInfo;
-};
-
-
-// Dump an SCFG to llvm::errs().
-void printSCFG(CFGWalker &Walker);
-
-
-} // end namespace threadSafety
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_THREAD_SAFETY_COMMON_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
deleted file mode 100644
index bc78021..0000000
--- a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
+++ /dev/null
@@ -1,108 +0,0 @@
-//===- ThreadSafetyLogical.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 representation for logical expressions with SExpr leaves
-// that are used as part of fact-checking capability expressions.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYLOGICAL_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYLOGICAL_H
-
-#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
-
-namespace clang {
-namespace threadSafety {
-namespace lexpr {
-
-class LExpr {
-public:
- enum Opcode {
- Terminal,
- And,
- Or,
- Not
- };
- Opcode kind() const { return Kind; }
-
- /// \brief 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;
-
-protected:
- LExpr(Opcode Kind) : Kind(Kind) {}
-
-private:
- Opcode Kind;
-};
-
-class Terminal : public LExpr {
- til::SExpr *Expr;
-
-public:
- Terminal(til::SExpr *Expr) : LExpr(LExpr::Terminal), Expr(Expr) {}
-
- const til::SExpr *expr() const { return Expr; }
- til::SExpr *expr() { return Expr; }
-
- static bool classof(const LExpr *E) { return E->kind() == LExpr::Terminal; }
-};
-
-class BinOp : public LExpr {
- LExpr *LHS, *RHS;
-
-protected:
- BinOp(LExpr *LHS, LExpr *RHS, Opcode Code) : LExpr(Code), LHS(LHS), RHS(RHS) {}
-
-public:
- const LExpr *left() const { return LHS; }
- LExpr *left() { return LHS; }
-
- const LExpr *right() const { return RHS; }
- LExpr *right() { return RHS; }
-};
-
-class And : public BinOp {
-public:
- And(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::And) {}
-
- static bool classof(const LExpr *E) { return E->kind() == LExpr::And; }
-};
-
-class Or : public BinOp {
-public:
- Or(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::Or) {}
-
- static bool classof(const LExpr *E) { return E->kind() == LExpr::Or; }
-};
-
-class Not : public LExpr {
- LExpr *Exp;
-
-public:
- Not(LExpr *Exp) : LExpr(LExpr::Not), Exp(Exp) {}
-
- const LExpr *exp() const { return Exp; }
- LExpr *exp() { return Exp; }
-
- static bool classof(const LExpr *E) { return E->kind() == LExpr::Not; }
-};
-
-/// \brief 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);
-
-bool LExpr::implies(const LExpr *RHS) const {
- return lexpr::implies(this, RHS);
-}
-
-}
-}
-}
-
-#endif
-
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
deleted file mode 100644
index 0d2458b..0000000
--- a/include/clang/Analysis/Analyses/ThreadSafetyOps.def
+++ /dev/null
@@ -1,57 +0,0 @@
-//===- ThreadSafetyTIL.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 the list of core opcodes for the Thread Safety
-// Typed Intermediate language. Please see ThreadSafetyTIL.h for more
-// information.
-//
-//===----------------------------------------------------------------------===//
-
-
-TIL_OPCODE_DEF(Future)
-TIL_OPCODE_DEF(Undefined)
-TIL_OPCODE_DEF(Wildcard)
-
-TIL_OPCODE_DEF(Literal)
-TIL_OPCODE_DEF(LiteralPtr)
-TIL_OPCODE_DEF(Variable)
-TIL_OPCODE_DEF(Function)
-TIL_OPCODE_DEF(SFunction)
-TIL_OPCODE_DEF(Code)
-TIL_OPCODE_DEF(Field)
-
-TIL_OPCODE_DEF(Apply)
-TIL_OPCODE_DEF(SApply)
-TIL_OPCODE_DEF(Project)
-
-TIL_OPCODE_DEF(Call)
-TIL_OPCODE_DEF(Alloc)
-TIL_OPCODE_DEF(Load)
-TIL_OPCODE_DEF(Store)
-TIL_OPCODE_DEF(ArrayIndex)
-TIL_OPCODE_DEF(ArrayAdd)
-
-TIL_OPCODE_DEF(UnaryOp)
-TIL_OPCODE_DEF(BinaryOp)
-TIL_OPCODE_DEF(Cast)
-
-TIL_OPCODE_DEF(SCFG)
-TIL_OPCODE_DEF(BasicBlock)
-TIL_OPCODE_DEF(Phi)
-
-// Terminator instructions
-TIL_OPCODE_DEF(Goto)
-TIL_OPCODE_DEF(Branch)
-TIL_OPCODE_DEF(Return)
-
-// pseudo-terms
-TIL_OPCODE_DEF(Identifier)
-TIL_OPCODE_DEF(IfThenElse)
-TIL_OPCODE_DEF(Let)
-
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
deleted file mode 100644
index be8a710..0000000
--- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ /dev/null
@@ -1,1918 +0,0 @@
-//===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT in the llvm repository for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a simple Typed Intermediate Language, or TIL, that is used
-// by the thread safety analysis (See ThreadSafety.cpp). The TIL is intended
-// to be largely independent of clang, in the hope that the analysis can be
-// reused for other non-C++ languages. All dependencies on clang/llvm should
-// go in ThreadSafetyUtil.h.
-//
-// Thread safety analysis works by comparing mutex expressions, e.g.
-//
-// class A { Mutex mu; int dat GUARDED_BY(this->mu); }
-// class B { A a; }
-//
-// void foo(B* b) {
-// (*b).a.mu.lock(); // locks (*b).a.mu
-// b->a.dat = 0; // substitute &b->a for 'this';
-// // requires lock on (&b->a)->mu
-// (b->a.mu).unlock(); // unlocks (b->a.mu)
-// }
-//
-// As illustrated by the above example, clang Exprs are not well-suited to
-// represent mutex expressions directly, since there is no easy way to compare
-// Exprs for equivalence. The thread safety analysis thus lowers clang Exprs
-// into a simple intermediate language (IL). The IL supports:
-//
-// (1) comparisons for semantic equality of expressions
-// (2) SSA renaming of variables
-// (3) wildcards and pattern matching over expressions
-// (4) hash-based expression lookup
-//
-// The TIL is currently very experimental, is intended only for use within
-// the thread safety analysis, and is subject to change without notice.
-// After the API stabilizes and matures, it may be appropriate to make this
-// more generally available to other analyses.
-//
-// UNDER CONSTRUCTION. USE AT YOUR OWN RISK.
-//
-//===----------------------------------------------------------------------===//
-
-#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 <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <stdint.h>
-#include <utility>
-
-
-namespace clang {
-namespace threadSafety {
-namespace til {
-
-
-/// Enum for the different distinct classes of SExpr
-enum TIL_Opcode {
-#define TIL_OPCODE_DEF(X) COP_##X,
-#include "ThreadSafetyOps.def"
-#undef TIL_OPCODE_DEF
-};
-
-/// Opcode for unary arithmetic operations.
-enum TIL_UnaryOpcode : unsigned char {
- UOP_Minus, // -
- UOP_BitNot, // ~
- UOP_LogicNot // !
-};
-
-/// Opcode for binary arithmetic operations.
-enum TIL_BinaryOpcode : unsigned char {
- BOP_Add, // +
- BOP_Sub, // -
- BOP_Mul, // *
- BOP_Div, // /
- BOP_Rem, // %
- BOP_Shl, // <<
- BOP_Shr, // >>
- BOP_BitAnd, // &
- BOP_BitXor, // ^
- BOP_BitOr, // |
- BOP_Eq, // ==
- BOP_Neq, // !=
- BOP_Lt, // <
- BOP_Leq, // <=
- BOP_LogicAnd, // && (no short-circuit)
- BOP_LogicOr // || (no short-circuit)
-};
-
-/// 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)
-};
-
-const TIL_Opcode COP_Min = COP_Future;
-const TIL_Opcode COP_Max = COP_Branch;
-const TIL_UnaryOpcode UOP_Min = UOP_Minus;
-const TIL_UnaryOpcode UOP_Max = UOP_LogicNot;
-const TIL_BinaryOpcode BOP_Min = BOP_Add;
-const TIL_BinaryOpcode BOP_Max = BOP_LogicOr;
-const TIL_CastOpcode CAST_Min = CAST_none;
-const TIL_CastOpcode CAST_Max = CAST_toInt;
-
-/// Return the name of a unary opcode.
-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
-/// types, such as functions, records, etc.
-/// Structured types that are passed by value (e.g. complex numbers)
-/// require special handling; they use BT_ValueRef, and size ST_0.
-struct ValueType {
- enum BaseType : unsigned char {
- BT_Void = 0,
- BT_Bool,
- BT_Int,
- BT_Float,
- BT_String, // String literals
- BT_Pointer,
- BT_ValueRef
- };
-
- enum SizeType : unsigned char {
- ST_0 = 0,
- ST_1,
- ST_8,
- ST_16,
- ST_32,
- ST_64,
- ST_128
- };
-
- 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;
- unsigned char VectSize; // 0 for scalar, otherwise num elements in vector
-};
-
-
-inline ValueType::SizeType ValueType::getSizeType(unsigned nbytes) {
- switch (nbytes) {
- case 1: return ST_8;
- case 2: return ST_16;
- case 4: return ST_32;
- case 8: return ST_64;
- case 16: return ST_128;
- default: return ST_0;
- }
-}
-
-
-template<>
-inline ValueType ValueType::getValueType<void>() {
- return ValueType(BT_Void, ST_0, false, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<bool>() {
- return ValueType(BT_Bool, ST_1, false, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<int8_t>() {
- return ValueType(BT_Int, ST_8, true, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<uint8_t>() {
- return ValueType(BT_Int, ST_8, false, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<int16_t>() {
- return ValueType(BT_Int, ST_16, true, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<uint16_t>() {
- return ValueType(BT_Int, ST_16, false, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<int32_t>() {
- return ValueType(BT_Int, ST_32, true, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<uint32_t>() {
- return ValueType(BT_Int, ST_32, false, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<int64_t>() {
- return ValueType(BT_Int, ST_64, true, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<uint64_t>() {
- return ValueType(BT_Int, ST_64, false, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<float>() {
- return ValueType(BT_Float, ST_32, true, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<double>() {
- return ValueType(BT_Float, ST_64, true, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<long double>() {
- return ValueType(BT_Float, ST_128, true, 0);
-}
-
-template<>
-inline ValueType ValueType::getValueType<StringRef>() {
- return ValueType(BT_String, getSizeType(sizeof(StringRef)), false, 0);
-}
-
-template<>
-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:
- TIL_Opcode opcode() const { return static_cast<TIL_Opcode>(Opcode); }
-
- // Subclasses of SExpr must define the following:
- //
- // This(const This& E, ...) {
- // copy constructor: construct copy of E, with some additional arguments.
- // }
- //
- // template <class V>
- // typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- // traverse all subexpressions, following the traversal/rewriter interface.
- // }
- //
- // template <class C> typename C::CType compare(CType* E, C& Cmp) {
- // compare all subexpressions, following the comparator interface
- // }
- void *operator new(size_t S, MemRegionRef &R) {
- return ::operator new(S, R);
- }
-
- /// SExpr objects cannot be deleted.
- // This declaration is public to workaround a gcc bug that breaks building
- // with REQUIRES_EH=1.
- void operator delete(void *) = delete;
-
- /// Returns the instruction ID for this expression.
- /// All basic block instructions have a unique ID (i.e. virtual register).
- unsigned id() const { return SExprID; }
-
- /// Returns the block, if this is an instruction in a basic block,
- /// otherwise returns null.
- 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) {}
-
- 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;
-};
-
-
-// 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;
- }
-}
-
-// Nodes which declare variables
-class Function;
-class SFunction;
-class Let;
-
-
-/// A named variable, e.g. "x".
-///
-/// There are two distinct places in which a Variable can appear in the AST.
-/// A variable declaration introduces a new variable, and can occur in 3 places:
-/// Let-expressions: (Let (x = t) u)
-/// Functions: (Function (x : t) u)
-/// Self-applicable functions (SFunction (x) t)
-///
-/// If a variable occurs in any other location, it is a reference to an existing
-/// variable declaration -- e.g. 'x' in (x * y + z). To save space, we don't
-/// allocate a separate AST node for variable references; a reference is just a
-/// 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
- };
-
- Variable(StringRef s, SExpr *D = nullptr)
- : SExpr(COP_Variable), Name(s), Definition(D), Cvdecl(nullptr) {
- Flags = VK_Let;
- }
- Variable(SExpr *D, const clang::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();
- }
-
- /// Return the kind of variable (let, function param, or self)
- VariableKind kind() const { return static_cast<VariableKind>(Flags); }
-
- /// Return the name of the variable, if any.
- StringRef name() const { return Name; }
-
- /// Return the clang declaration for this variable, if any.
- const clang::ValueDecl *clangDecl() const { return Cvdecl; }
-
- /// Return the definition of the variable.
- /// For let-vars, this is the setting expression.
- /// For function and self parameters, it is the type of the variable.
- SExpr *definition() { return Definition; }
- const SExpr *definition() const { return Definition; }
-
- 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; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- // This routine is only called for variable references.
- return Vs.reduceVariableRef(this);
- }
-
- template <class C>
- typename C::CType compare(const Variable* E, C& Cmp) const {
- return Cmp.compareVariableRefs(this, E);
- }
-
-private:
- friend class Function;
- friend class SFunction;
- friend class BasicBlock;
- friend class Let;
-
- StringRef Name; // The name of the variable.
- SExpr* Definition; // The TIL type or definition
- const clang::ValueDecl *Cvdecl; // The clang declaration for this variable.
-};
-
-
-/// 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:
- virtual ~Future() = delete;
-
-public:
- // 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;
- }
-
- // Return the result of this future; forcing it if necessary.
- SExpr *result() {
- switch (Status) {
- case FS_pending:
- return force();
- case FS_evaluating:
- return nullptr; // infinite loop; illegal recursion.
- case FS_done:
- return Result;
- }
- }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- assert(Result && "Cannot traverse Future that has not been forced.");
- return Vs.traverse(Result, Ctx);
- }
-
- template <class C>
- typename C::CType compare(const Future* E, C& Cmp) const {
- if (!Result || !E->Result)
- return Cmp.comparePointers(this, E);
- return Cmp.compare(Result, E->Result);
- }
-
-private:
- SExpr* force();
-
- FutureStatus Status;
- SExpr *Result;
-};
-
-
-/// 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 Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- return Vs.reduceUndefined(*this);
- }
-
- template <class C>
- typename C::CType compare(const Undefined* E, C& Cmp) const {
- return Cmp.trueResult();
- }
-
-private:
- const clang::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) {}
-
- template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- return Vs.reduceWildcard(*this);
- }
-
- template <class C>
- typename C::CType compare(const Wildcard* E, C& Cmp) const {
- return Cmp.trueResult();
- }
-};
-
-
-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 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) {}
-
- // The clang expression for this literal.
- const clang::Expr *clangExpr() const { return Cexpr; }
-
- ValueType valueType() const { return ValType; }
-
- template<class T> const LiteralT<T>& as() const {
- return *static_cast<const LiteralT<T>*>(this);
- }
- template<class T> LiteralT<T>& as() {
- return *static_cast<LiteralT<T>*>(this);
- }
-
- template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx);
-
- template <class C>
- typename C::CType compare(const Literal* E, C& Cmp) const {
- // TODO: defer actual comparison to LiteralT
- return Cmp.trueResult();
- }
-
-private:
- const ValueType ValType;
- const clang::Expr *Cexpr;
-};
-
-
-// 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) { }
-
- 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)
- return Vs.reduceLiteral(*this);
-
- switch (ValType.Base) {
- case ValueType::BT_Void:
- break;
- case ValueType::BT_Bool:
- return Vs.reduceLiteralT(as<bool>());
- case ValueType::BT_Int: {
- switch (ValType.Size) {
- case ValueType::ST_8:
- if (ValType.Signed)
- return Vs.reduceLiteralT(as<int8_t>());
- else
- return Vs.reduceLiteralT(as<uint8_t>());
- case ValueType::ST_16:
- if (ValType.Signed)
- return Vs.reduceLiteralT(as<int16_t>());
- else
- return Vs.reduceLiteralT(as<uint16_t>());
- case ValueType::ST_32:
- if (ValType.Signed)
- return Vs.reduceLiteralT(as<int32_t>());
- else
- return Vs.reduceLiteralT(as<uint32_t>());
- case ValueType::ST_64:
- if (ValType.Signed)
- return Vs.reduceLiteralT(as<int64_t>());
- else
- return Vs.reduceLiteralT(as<uint64_t>());
- default:
- break;
- }
- }
- case ValueType::BT_Float: {
- switch (ValType.Size) {
- case ValueType::ST_32:
- return Vs.reduceLiteralT(as<float>());
- case ValueType::ST_64:
- return Vs.reduceLiteralT(as<double>());
- default:
- break;
- }
- }
- case ValueType::BT_String:
- return Vs.reduceLiteralT(as<StringRef>());
- case ValueType::BT_Pointer:
- return Vs.reduceLiteralT(as<void*>());
- case ValueType::BT_ValueRef:
- break;
- }
- 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 clang::ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
- LiteralPtr(const LiteralPtr &R) : SExpr(R), Cvdecl(R.Cvdecl) {}
-
- // The clang declaration for the value that this pointer points to.
- const clang::ValueDecl *clangDecl() const { return Cvdecl; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- return Vs.reduceLiteralPtr(*this);
- }
-
- template <class C>
- typename C::CType compare(const LiteralPtr* E, C& Cmp) const {
- return Cmp.comparePointers(Cvdecl, E->Cvdecl);
- }
-
-private:
- const clang::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);
- }
-
- Variable *variableDecl() { return VarDecl; }
- const Variable *variableDecl() const { return VarDecl; }
-
- SExpr *body() { return Body; }
- const SExpr *body() const { return Body; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- // This is a variable declaration, so traverse the definition.
- auto E0 = Vs.traverse(VarDecl->Definition, Vs.typeCtx(Ctx));
- // Tell the rewriter to enter the scope of the function.
- Variable *Nvd = Vs.enterScope(*VarDecl, E0);
- auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
- Vs.exitScope(*VarDecl);
- return Vs.reduceFunction(*this, Nvd, E1);
- }
-
- template <class C>
- typename C::CType compare(const Function* E, C& Cmp) const {
- typename C::CType Ct =
- Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
- if (Cmp.notTrue(Ct))
- return Ct;
- Cmp.enterScope(variableDecl(), E->variableDecl());
- Ct = Cmp.compare(body(), E->body());
- Cmp.leaveScope();
- return Ct;
- }
-
-private:
- Variable *VarDecl;
- 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);
- Vd->setKind(Variable::VK_SFun);
- Vd->Definition = this;
- }
-
- Variable *variableDecl() { return VarDecl; }
- const Variable *variableDecl() const { return VarDecl; }
-
- SExpr *body() { return Body; }
- const SExpr *body() const { return Body; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- // A self-variable points to the SFunction itself.
- // A rewrite must introduce the variable with a null definition, and update
- // it after 'this' has been rewritten.
- Variable *Nvd = Vs.enterScope(*VarDecl, nullptr);
- auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
- Vs.exitScope(*VarDecl);
- // A rewrite operation will call SFun constructor to set Vvd->Definition.
- return Vs.reduceSFunction(*this, Nvd, E1);
- }
-
- template <class C>
- typename C::CType compare(const SFunction* E, C& Cmp) const {
- Cmp.enterScope(variableDecl(), E->variableDecl());
- typename C::CType Ct = Cmp.compare(body(), E->body());
- Cmp.leaveScope();
- return Ct;
- }
-
-private:
- Variable *VarDecl;
- 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) {}
-
- SExpr *returnType() { return ReturnType; }
- const SExpr *returnType() const { return ReturnType; }
-
- SExpr *body() { return Body; }
- const SExpr *body() const { return Body; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nt = Vs.traverse(ReturnType, Vs.typeCtx(Ctx));
- auto Nb = Vs.traverse(Body, Vs.lazyCtx(Ctx));
- return Vs.reduceCode(*this, Nt, Nb);
- }
-
- template <class C>
- typename C::CType compare(const Code* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(returnType(), E->returnType());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(body(), E->body());
- }
-
-private:
- SExpr* ReturnType;
- 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) {}
-
- SExpr *range() { return Range; }
- const SExpr *range() const { return Range; }
-
- SExpr *body() { return Body; }
- const SExpr *body() const { return Body; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nr = Vs.traverse(Range, Vs.typeCtx(Ctx));
- auto Nb = Vs.traverse(Body, Vs.lazyCtx(Ctx));
- return Vs.reduceField(*this, Nr, Nb);
- }
-
- template <class C>
- typename C::CType compare(const Field* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(range(), E->range());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(body(), E->body());
- }
-
-private:
- SExpr* Range;
- 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.
-/// Once all parameters have been applied, Call can be used to invoke the
-/// 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 *fun() { return Fun; }
- const SExpr *fun() const { return Fun; }
-
- SExpr *arg() { return Arg; }
- const SExpr *arg() const { return Arg; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nf = Vs.traverse(Fun, Vs.subExprCtx(Ctx));
- auto Na = Vs.traverse(Arg, Vs.subExprCtx(Ctx));
- return Vs.reduceApply(*this, Nf, Na);
- }
-
- template <class C>
- typename C::CType compare(const Apply* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(fun(), E->fun());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(arg(), E->arg());
- }
-
-private:
- SExpr* Fun;
- 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) {}
-
- SExpr *sfun() { return Sfun; }
- const SExpr *sfun() const { return Sfun; }
-
- SExpr *arg() { return Arg ? Arg : Sfun; }
- const SExpr *arg() const { return Arg ? Arg : Sfun; }
-
- bool isDelegation() const { return Arg != nullptr; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nf = Vs.traverse(Sfun, Vs.subExprCtx(Ctx));
- typename V::R_SExpr Na = Arg ? Vs.traverse(Arg, Vs.subExprCtx(Ctx))
- : nullptr;
- return Vs.reduceSApply(*this, Nf, Na);
- }
-
- template <class C>
- typename C::CType compare(const SApply* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(sfun(), E->sfun());
- if (Cmp.notTrue(Ct) || (!arg() && !E->arg()))
- return Ct;
- return Cmp.compare(arg(), E->arg());
- }
-
-private:
- SExpr* Sfun;
- 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, StringRef SName)
- : SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
- { }
- Project(SExpr *R, const clang::ValueDecl *Cvd)
- : SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
- { }
- Project(const Project &P, SExpr *R)
- : SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
- { }
-
- SExpr *record() { return Rec; }
- const SExpr *record() const { return Rec; }
-
- const clang::ValueDecl *clangDecl() const { return Cvdecl; }
-
- bool isArrow() const { return (Flags & 0x01) != 0; }
- void setArrow(bool b) {
- if (b) Flags |= 0x01;
- else Flags &= 0xFFFE;
- }
-
- StringRef slotName() const {
- if (Cvdecl)
- return Cvdecl->getName();
- else
- return SlotName;
- }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nr = Vs.traverse(Rec, Vs.subExprCtx(Ctx));
- return Vs.reduceProject(*this, Nr);
- }
-
- template <class C>
- typename C::CType compare(const Project* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(record(), E->record());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.comparePointers(Cvdecl, E->Cvdecl);
- }
-
-private:
- SExpr* Rec;
- StringRef SlotName;
- const clang::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)
- : SExpr(COP_Call), Target(T), Cexpr(Ce) {}
- Call(const Call &C, SExpr *T) : SExpr(C), Target(T), Cexpr(C.Cexpr) {}
-
- SExpr *target() { return Target; }
- const SExpr *target() const { return Target; }
-
- const clang::CallExpr *clangCallExpr() const { return Cexpr; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nt = Vs.traverse(Target, Vs.subExprCtx(Ctx));
- return Vs.reduceCall(*this, Nt);
- }
-
- template <class C>
- typename C::CType compare(const Call* E, C& Cmp) const {
- return Cmp.compare(target(), E->target());
- }
-
-private:
- SExpr* Target;
- const clang::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
- };
-
- 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(); }
-
- AllocKind kind() const { return static_cast<AllocKind>(Flags); }
-
- SExpr *dataType() { return Dtype; }
- const SExpr *dataType() const { return Dtype; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nd = Vs.traverse(Dtype, Vs.declCtx(Ctx));
- return Vs.reduceAlloc(*this, Nd);
- }
-
- template <class C>
- typename C::CType compare(const Alloc* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(dataType(), E->dataType());
- }
-
-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) {}
-
- SExpr *pointer() { return Ptr; }
- const SExpr *pointer() const { return Ptr; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Np = Vs.traverse(Ptr, Vs.subExprCtx(Ctx));
- return Vs.reduceLoad(*this, Np);
- }
-
- template <class C>
- typename C::CType compare(const Load* E, C& Cmp) const {
- return Cmp.compare(pointer(), E->pointer());
- }
-
-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) {}
-
- SExpr *destination() { return Dest; } // Address to store to
- const SExpr *destination() const { return Dest; }
-
- SExpr *source() { return Source; } // Value to store
- const SExpr *source() const { return Source; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Np = Vs.traverse(Dest, Vs.subExprCtx(Ctx));
- auto Nv = Vs.traverse(Source, Vs.subExprCtx(Ctx));
- return Vs.reduceStore(*this, Np, Nv);
- }
-
- template <class C>
- typename C::CType compare(const Store* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(destination(), E->destination());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(source(), E->source());
- }
-
-private:
- SExpr* Dest;
- 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 *array() { return Array; }
- const SExpr *array() const { return Array; }
-
- SExpr *index() { return Index; }
- const SExpr *index() const { return Index; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
- auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
- return Vs.reduceArrayIndex(*this, Na, Ni);
- }
-
- template <class C>
- typename C::CType compare(const ArrayIndex* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(array(), E->array());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(index(), E->index());
- }
-
-private:
- SExpr* Array;
- 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 *array() { return Array; }
- const SExpr *array() const { return Array; }
-
- SExpr *index() { return Index; }
- const SExpr *index() const { return Index; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
- auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
- return Vs.reduceArrayAdd(*this, Na, Ni);
- }
-
- template <class C>
- typename C::CType compare(const ArrayAdd* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(array(), E->array());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(index(), E->index());
- }
-
-private:
- SExpr* Array;
- 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; }
-
- TIL_UnaryOpcode unaryOpcode() const {
- return static_cast<TIL_UnaryOpcode>(Flags);
- }
-
- SExpr *expr() { return Expr0; }
- const SExpr *expr() const { return Expr0; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
- return Vs.reduceUnaryOp(*this, Ne);
- }
-
- template <class C>
- typename C::CType compare(const UnaryOp* E, C& Cmp) const {
- typename C::CType Ct =
- Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(expr(), E->expr());
- }
-
-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;
- }
-
- TIL_BinaryOpcode binaryOpcode() const {
- return static_cast<TIL_BinaryOpcode>(Flags);
- }
-
- SExpr *expr0() { return Expr0; }
- const SExpr *expr0() const { return Expr0; }
-
- SExpr *expr1() { return Expr1; }
- const SExpr *expr1() const { return Expr1; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Ne0 = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
- auto Ne1 = Vs.traverse(Expr1, Vs.subExprCtx(Ctx));
- return Vs.reduceBinaryOp(*this, Ne0, Ne1);
- }
-
- template <class C>
- typename C::CType compare(const BinaryOp* E, C& Cmp) const {
- typename C::CType Ct =
- Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode());
- if (Cmp.notTrue(Ct))
- return Ct;
- Ct = Cmp.compare(expr0(), E->expr0());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(expr1(), E->expr1());
- }
-
-private:
- SExpr* Expr0;
- 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; }
-
- TIL_CastOpcode castOpcode() const {
- return static_cast<TIL_CastOpcode>(Flags);
- }
-
- SExpr *expr() { return Expr0; }
- const SExpr *expr() const { return Expr0; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
- return Vs.reduceCast(*this, Ne);
- }
-
- template <class C>
- typename C::CType compare(const Cast* E, C& Cmp) const {
- typename C::CType Ct =
- Cmp.compareIntegers(castOpcode(), E->castOpcode());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(expr(), E->expr());
- }
-
-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;
-
- // In minimal SSA form, all Phi nodes are MultiVal.
- // During conversion to SSA, incomplete Phi nodes may be introduced, which
- // are later determined to be SingleVal, and are thus redundant.
- enum Status {
- PH_MultiVal = 0, // Phi node has multiple distinct values. (Normal)
- PH_SingleVal, // Phi node has one distinct value, and can be eliminated
- PH_Incomplete // Phi node is incomplete
- };
-
- static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
-
- 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) {}
-
- const ValArray &values() const { return Values; }
- ValArray &values() { return Values; }
-
- Status status() const { return static_cast<Status>(Flags); }
- 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; }
-
- /// Set the clang variable associated with this Phi node.
- void setClangDecl(const clang::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) {
- Nvs.push_back( Vs.traverse(Val, Vs.subExprCtx(Ctx)) );
- }
- return Vs.reducePhi(*this, Nvs);
- }
-
- template <class C>
- typename C::CType compare(const Phi *E, C &Cmp) const {
- // TODO: implement CFG comparisons
- return Cmp.comparePointers(this, E);
- }
-
-private:
- ValArray Values;
- const clang::ValueDecl* Cvdecl;
-};
-
-
-/// Base class for basic block terminators: Branch, Goto, and Return.
-class Terminator : public SExpr {
-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() 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
-/// phi nodes of that block. The index can be used to retrieve the "arguments"
-/// 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) {}
-
- const BasicBlock *targetBlock() const { return TargetBlock; }
- BasicBlock *targetBlock() { return TargetBlock; }
-
- /// Returns the index into the
- unsigned index() const { return Index; }
-
- /// Return the list of basic blocks that this terminator can branch to.
- ArrayRef<BasicBlock*> successors() {
- return TargetBlock;
- }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- BasicBlock *Ntb = Vs.reduceBasicBlockRef(TargetBlock);
- return Vs.reduceGoto(*this, Ntb);
- }
-
- template <class C>
- typename C::CType compare(const Goto *E, C &Cmp) const {
- // TODO: implement CFG comparisons
- return Cmp.comparePointers(this, E);
- }
-
-private:
- BasicBlock *TargetBlock;
- 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;
- }
-
- const SExpr *condition() const { return Condition; }
- SExpr *condition() { return Condition; }
-
- const BasicBlock *thenBlock() const { return Branches[0]; }
- BasicBlock *thenBlock() { return Branches[0]; }
-
- const BasicBlock *elseBlock() const { return Branches[1]; }
- BasicBlock *elseBlock() { return Branches[1]; }
-
- /// Return the list of basic blocks that this terminator can branch to.
- ArrayRef<BasicBlock*> successors() {
- return llvm::makeArrayRef(Branches);
- }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
- BasicBlock *Ntb = Vs.reduceBasicBlockRef(Branches[0]);
- BasicBlock *Nte = Vs.reduceBasicBlockRef(Branches[1]);
- return Vs.reduceBranch(*this, Nc, Ntb, Nte);
- }
-
- template <class C>
- typename C::CType compare(const Branch *E, C &Cmp) const {
- // TODO: implement CFG comparisons
- return Cmp.comparePointers(this, E);
- }
-
-private:
- 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) {}
-
- /// Return an empty list.
- ArrayRef<BasicBlock*> successors() {
- return None;
- }
-
- SExpr *returnValue() { return Retval; }
- const SExpr *returnValue() const { return Retval; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Ne = Vs.traverse(Retval, Vs.subExprCtx(Ctx));
- return Vs.reduceReturn(*this, Ne);
- }
-
- template <class C>
- typename C::CType compare(const Return *E, C &Cmp) const {
- return Cmp.compare(Retval, E->Retval);
- }
-
-private:
- SExpr* Retval;
-};
-
-
-inline ArrayRef<BasicBlock*> Terminator::successors() {
- switch (opcode()) {
- case COP_Goto: return cast<Goto>(this)->successors();
- case COP_Branch: return cast<Branch>(this)->successors();
- case COP_Return: return cast<Return>(this)->successors();
- default:
- return None;
- }
-}
-
-
-/// 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
-/// instructions. It ends with a Terminator, which is a Branch or Goto to
-/// another basic block in the same SCFG.
-class BasicBlock : public SExpr {
-public:
- typedef SimpleArray<SExpr*> InstrArray;
- typedef SimpleArray<BasicBlock*> BlockArray;
-
- // 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) {}
-
- bool isParentOf(const TopologyNode& OtherNode) {
- return OtherNode.NodeID > NodeID &&
- OtherNode.NodeID < NodeID + SizeOfSubTree;
- }
-
- bool isParentOfOrEqual(const TopologyNode& OtherNode) {
- 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) {}
- BasicBlock(BasicBlock &B, MemRegionRef A, InstrArray &&As, InstrArray &&Is,
- Terminator *T)
- : SExpr(COP_BasicBlock), Arena(A), CFGPtr(nullptr), BlockID(0),Visited(0),
- Args(std::move(As)), Instrs(std::move(Is)), TermInstr(T) {}
-
- /// Returns the block ID. Every block has a unique ID in the CFG.
- int blockID() const { return BlockID; }
-
- /// Returns the number of predecessors.
- size_t numPredecessors() const { return Predecessors.size(); }
- size_t numSuccessors() const { return successors().size(); }
-
- const SCFG* cfg() const { return CFGPtr; }
- SCFG* cfg() { return CFGPtr; }
-
- const BasicBlock *parent() const { return DominatorNode.Parent; }
- BasicBlock *parent() { return DominatorNode.Parent; }
-
- const InstrArray &arguments() const { return Args; }
- InstrArray &arguments() { return Args; }
-
- InstrArray &instructions() { return Instrs; }
- const InstrArray &instructions() const { return Instrs; }
-
- /// Returns a list of predecessors.
- /// The order of predecessors in the list is important; each phi node has
- /// exactly one argument for each precessor, in the same order.
- BlockArray &predecessors() { return Predecessors; }
- const BlockArray &predecessors() const { return Predecessors; }
-
- ArrayRef<BasicBlock*> successors() { return TermInstr->successors(); }
- ArrayRef<BasicBlock*> successors() const { return TermInstr->successors(); }
-
- const Terminator *terminator() const { return TermInstr; }
- Terminator *terminator() { return TermInstr; }
-
- void setTerminator(Terminator *E) { TermInstr = E; }
-
- bool Dominates(const BasicBlock &Other) {
- return DominatorNode.isParentOfOrEqual(Other.DominatorNode);
- }
-
- bool PostDominates(const BasicBlock &Other) {
- return PostDominatorNode.isParentOfOrEqual(Other.PostDominatorNode);
- }
-
- /// Add a new argument.
- void addArgument(Phi *V) {
- 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);
-
- // Reserve space for Nargs arguments.
- void reserveArguments(unsigned Nargs) { Args.reserve(Nargs, Arena); }
-
- // Reserve space for Nins instructions.
- void reserveInstructions(unsigned Nins) { Instrs.reserve(Nins, Arena); }
-
- // Reserve space for NumPreds predecessors, including space in phi nodes.
- void reservePredecessors(unsigned NumPreds);
-
- /// Return the index of BB, or Predecessors.size if BB is not a predecessor.
- unsigned findPredecessorIndex(const BasicBlock *BB) const {
- auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB);
- return std::distance(Predecessors.cbegin(), I);
- }
-
- template <class V>
- typename V::R_BasicBlock traverse(V &Vs, typename V::R_Ctx Ctx) {
- typename V::template Container<SExpr*> Nas(Vs, Args.size());
- typename V::template Container<SExpr*> Nis(Vs, Instrs.size());
-
- // Entering the basic block should do any scope initialization.
- Vs.enterBasicBlock(*this);
-
- for (auto *E : Args) {
- auto Ne = Vs.traverse(E, Vs.subExprCtx(Ctx));
- Nas.push_back(Ne);
- }
- for (auto *E : Instrs) {
- auto Ne = Vs.traverse(E, Vs.subExprCtx(Ctx));
- Nis.push_back(Ne);
- }
- auto Nt = Vs.traverse(TermInstr, Ctx);
-
- // Exiting the basic block should handle any scope cleanup.
- Vs.exitBasicBlock(*this);
-
- return Vs.reduceBasicBlock(*this, Nas, Nis, Nt);
- }
-
- template <class C>
- typename C::CType compare(const BasicBlock *E, C &Cmp) const {
- // TODO: implement CFG comparisons
- return Cmp.comparePointers(this, E);
- }
-
-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);
- 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
-};
-
-
-/// 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; }
-
- SCFG(MemRegionRef A, unsigned Nblocks)
- : SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks),
- Entry(nullptr), Exit(nullptr), NumInstructions(0), Normal(false) {
- Entry = new (A) BasicBlock(A);
- Exit = new (A) BasicBlock(A);
- auto *V = new (A) Phi();
- Exit->addArgument(V);
- Exit->setTerminator(new (A) Return(V));
- 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) {
- // TODO: set entry and exit!
- }
-
- /// Return true if this CFG is valid.
- bool valid() const { return Entry && Exit && Blocks.size() > 0; }
-
- /// Return true if this CFG has been normalized.
- /// After normalization, blocks are in topological order, and block and
- /// instruction IDs have been assigned.
- bool normal() const { return Normal; }
-
- iterator begin() { return Blocks.begin(); }
- iterator end() { return Blocks.end(); }
-
- const_iterator begin() const { return cbegin(); }
- const_iterator end() const { return cend(); }
-
- const_iterator cbegin() const { return Blocks.cbegin(); }
- const_iterator cend() const { return Blocks.cend(); }
-
- const BasicBlock *entry() const { return Entry; }
- BasicBlock *entry() { return Entry; }
- const BasicBlock *exit() const { return Exit; }
- BasicBlock *exit() { return Exit; }
-
- /// Return the number of blocks in the CFG.
- /// Block::blockID() will return a number less than numBlocks();
- size_t numBlocks() const { return Blocks.size(); }
-
- /// Return the total number of instructions in the CFG.
- /// This is useful for building instruction side-tables;
- /// A call to SExpr::id() will return a number less than numInstructions().
- unsigned numInstructions() { return NumInstructions; }
-
- inline void add(BasicBlock *BB) {
- assert(BB->CFGPtr == nullptr);
- BB->CFGPtr = this;
- Blocks.reserveCheck(1, Arena);
- Blocks.push_back(BB);
- }
-
- void setEntry(BasicBlock *BB) { Entry = BB; }
- void setExit(BasicBlock *BB) { Exit = BB; }
-
- void computeNormalForm();
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- Vs.enterCFG(*this);
- typename V::template Container<BasicBlock *> Bbs(Vs, Blocks.size());
-
- for (auto *B : Blocks) {
- Bbs.push_back( B->traverse(Vs, Vs.subExprCtx(Ctx)) );
- }
- Vs.exitCFG(*this);
- return Vs.reduceSCFG(*this, Bbs);
- }
-
- template <class C>
- typename C::CType compare(const SCFG *E, C &Cmp) const {
- // TODO: implement CFG comparisons
- return Cmp.comparePointers(this, E);
- }
-
-private:
- void renumberInstrs(); // assign unique ids to all instructions
-
-private:
- MemRegionRef Arena;
- BlockArray Blocks;
- BasicBlock *Entry;
- BasicBlock *Exit;
- unsigned NumInstructions;
- bool Normal;
-};
-
-
-
-/// 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& I) : SExpr(I), Name(I.Name) { }
-
- StringRef name() const { return Name; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- return Vs.reduceIdentifier(*this);
- }
-
- template <class C>
- typename C::CType compare(const Identifier* E, C& Cmp) const {
- return Cmp.compareStrings(name(), E->name());
- }
-
-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)
- { }
- IfThenElse(const IfThenElse &I, SExpr *C, SExpr *T, SExpr *E)
- : SExpr(I), Condition(C), ThenExpr(T), ElseExpr(E)
- { }
-
- SExpr *condition() { return Condition; } // Address to store to
- const SExpr *condition() const { return Condition; }
-
- SExpr *thenExpr() { return ThenExpr; } // Value to store
- const SExpr *thenExpr() const { return ThenExpr; }
-
- SExpr *elseExpr() { return ElseExpr; } // Value to store
- const SExpr *elseExpr() const { return ElseExpr; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
- auto Nt = Vs.traverse(ThenExpr, Vs.subExprCtx(Ctx));
- auto Ne = Vs.traverse(ElseExpr, Vs.subExprCtx(Ctx));
- return Vs.reduceIfThenElse(*this, Nc, Nt, Ne);
- }
-
- template <class C>
- typename C::CType compare(const IfThenElse* E, C& Cmp) const {
- typename C::CType Ct = Cmp.compare(condition(), E->condition());
- if (Cmp.notTrue(Ct))
- return Ct;
- Ct = Cmp.compare(thenExpr(), E->thenExpr());
- if (Cmp.notTrue(Ct))
- return Ct;
- return Cmp.compare(elseExpr(), E->elseExpr());
- }
-
-private:
- SExpr* Condition;
- SExpr* ThenExpr;
- 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);
- }
-
- Variable *variableDecl() { return VarDecl; }
- const Variable *variableDecl() const { return VarDecl; }
-
- SExpr *body() { return Body; }
- const SExpr *body() const { return Body; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- // This is a variable declaration, so traverse the definition.
- auto E0 = Vs.traverse(VarDecl->Definition, Vs.subExprCtx(Ctx));
- // Tell the rewriter to enter the scope of the let variable.
- Variable *Nvd = Vs.enterScope(*VarDecl, E0);
- auto E1 = Vs.traverse(Body, Ctx);
- Vs.exitScope(*VarDecl);
- return Vs.reduceLet(*this, Nvd, E1);
- }
-
- template <class C>
- typename C::CType compare(const Let* E, C& Cmp) const {
- typename C::CType Ct =
- Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
- if (Cmp.notTrue(Ct))
- return Ct;
- Cmp.enterScope(variableDecl(), E->variableDecl());
- Ct = Cmp.compare(body(), E->body());
- Cmp.leaveScope();
- return Ct;
- }
-
-private:
- Variable *VarDecl;
- SExpr* Body;
-};
-
-
-
-const SExpr *getCanonicalVal(const SExpr *E);
-SExpr* simplifyToCanonicalVal(SExpr *E);
-void simplifyIncompleteArg(til::Phi *Ph);
-
-
-} // end namespace til
-} // end namespace threadSafety
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
deleted file mode 100644
index 705fe91..0000000
--- a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
+++ /dev/null
@@ -1,902 +0,0 @@
-//===- ThreadSafetyTraverse.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 framework for doing generic traversals and rewriting
-// operations over the Thread Safety TIL.
-//
-// UNDER CONSTRUCTION. USE AT YOUR OWN RISK.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
-
-#include "ThreadSafetyTIL.h"
-#include <ostream>
-
-namespace clang {
-namespace threadSafety {
-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
-// (in-place) rewriting, hashing, typing, etc.
-//
-// Traversals implement the functional notion of a "fold" operation on SExprs.
-// Each SExpr class provides a traverse method, which does the following:
-// * e->traverse(v):
-// // compute a result r_i for each subexpression e_i
-// for (i = 1..n) r_i = v.traverse(e_i);
-// // combine results into a result for e, where X is the class of e
-// return v.reduceX(*e, r_1, .. r_n).
-//
-// A visitor can control the traversal by overriding the following methods:
-// * v.traverse(e):
-// return v.traverseByCase(e), which returns v.traverseX(e)
-// * v.traverseX(e): (X is the class of e)
-// return e->traverse(v).
-// * v.reduceX(*e, r_1, .. r_n):
-// compute a result for a node of type X
-//
-// The reduceX methods control the kind of traversal (visitor, copy, etc.).
-// They are defined in derived classes.
-//
-// Class R defines the basic interface types (R_SExpr).
-template <class Self, class R>
-class Traversal {
-public:
- Self *self() { return static_cast<Self *>(this); }
-
- // Traverse an expression -- returning a result of type R_SExpr.
- // Override this method to do something for every expression, regardless
- // of which kind it is.
- // E is a reference, so this can be use for in-place updates.
- // The type T must be a subclass of SExpr.
- template <class T>
- typename R::R_SExpr traverse(T* &E, typename R::R_Ctx Ctx) {
- return traverseSExpr(E, Ctx);
- }
-
- // Override this method to do something for every expression.
- // Does not allow in-place updates.
- typename R::R_SExpr traverseSExpr(SExpr *E, typename R::R_Ctx Ctx) {
- return traverseByCase(E, Ctx);
- }
-
- // Helper method to call traverseX(e) on the appropriate type.
- typename R::R_SExpr traverseByCase(SExpr *E, typename R::R_Ctx Ctx) {
- switch (E->opcode()) {
-#define TIL_OPCODE_DEF(X) \
- case COP_##X: \
- return self()->traverse##X(cast<X>(E), Ctx);
-#include "ThreadSafetyOps.def"
-#undef TIL_OPCODE_DEF
- }
- return self()->reduceNull();
- }
-
-// Traverse e, by static dispatch on the type "X" of e.
-// Override these methods to do something for a particular kind of term.
-#define TIL_OPCODE_DEF(X) \
- typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) { \
- return e->traverse(*self(), Ctx); \
- }
-#include "ThreadSafetyOps.def"
-#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
- };
-
- // 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;
-
- // Create context for an ordinary subexpression.
- R_Ctx subExprCtx(R_Ctx Ctx) { return TRV_Normal; }
-
- // Create context for a subexpression that occurs in a declaration position
- // (e.g. function body).
- R_Ctx declCtx(R_Ctx Ctx) { return TRV_Decl; }
-
- // Create context for a subexpression that occurs in a position that
- // should be reduced lazily. (e.g. code body).
- R_Ctx lazyCtx(R_Ctx Ctx) { return TRV_Lazy; }
-
- // Create context for a subexpression that occurs in a type position.
- 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;
-
- // Container is a minimal interface used to store results when traversing
- // SExprs of variable arity, such as Phi, Goto, and SCFG.
- template <class T> class Container {
- public:
- // Allocate a new container with a capacity for n elements.
- Container(CopyReducerBase &S, unsigned N) : Elems(S.Arena, N) {}
-
- // Push a new element onto the container.
- void push_back(T E) { Elems.push_back(E); }
-
- SimpleArray<T> Elems;
- };
-
- CopyReducerBase(MemRegionRef A) : Arena(A) {}
-
-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;
-
- // 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;
- };
-};
-
-
-// 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() {}
-
-public:
- R_SExpr reduceNull() { return true; }
- R_SExpr reduceUndefined(Undefined &Orig) { return true; }
- R_SExpr reduceWildcard(Wildcard &Orig) { return true; }
-
- R_SExpr reduceLiteral(Literal &Orig) { return true; }
- template<class T>
- R_SExpr reduceLiteralT(LiteralT<T> &Orig) { return true; }
- R_SExpr reduceLiteralPtr(Literal &Orig) { return true; }
-
- 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;
- }
-
- 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;
- }
-
- Variable *enterScope(Variable &Orig, R_SExpr E0) { return &Orig; }
- void exitScope(const Variable &Orig) {}
- void enterCFG(SCFG &Cfg) {}
- void exitCFG(SCFG &Cfg) {}
- void enterBasicBlock(BasicBlock &BB) {}
- void exitBasicBlock(BasicBlock &BB) {}
-
- Variable *reduceVariableRef (Variable *Ovd) { return Ovd; }
- BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
-
-public:
- bool traverse(SExpr *E, TraversalKind K = TRV_Normal) {
- Success = Success && this->traverseByCase(E);
- return Success;
- }
-
- static bool visit(SExpr *E) {
- Self Visitor;
- return Visitor.traverse(E, TRV_Normal);
- }
-
-private:
- bool Success;
-};
-
-
-// Basic class for comparison operations over expressions.
-template <typename Self>
-class Comparator {
-protected:
- Self *self() { return reinterpret_cast<Self *>(this); }
-
-public:
- bool compareByCase(const SExpr *E1, const SExpr* E2) {
- switch (E1->opcode()) {
-#define TIL_OPCODE_DEF(X) \
- case COP_##X: \
- return cast<X>(E1)->compare(cast<X>(E2), *self());
-#include "ThreadSafetyOps.def"
-#undef TIL_OPCODE_DEF
- }
- return false;
- }
-};
-
-
-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;
-
- 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 compare(const SExpr *E1, const SExpr* E2) {
- if (E1->opcode() != E2->opcode())
- return false;
- return compareByCase(E1, E2);
- }
-
- // TODO -- handle alpha-renaming of variables
- void enterScope(const Variable* V1, const Variable* V2) { }
- void leaveScope() { }
-
- bool compareVariableRefs(const Variable* V1, const Variable* V2) {
- return V1 == V2;
- }
-
- static bool compareExprs(const SExpr *E1, const SExpr* E2) {
- EqualsComparator Eq;
- return Eq.compare(E1, E2);
- }
-};
-
-
-
-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;
-
- 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 compare(const SExpr *E1, const SExpr* E2) {
- // Wildcards match anything.
- if (E1->opcode() == COP_Wildcard || E2->opcode() == COP_Wildcard)
- return true;
- // otherwise normal equality.
- if (E1->opcode() != E2->opcode())
- return false;
- return compareByCase(E1, E2);
- }
-
- // TODO -- handle alpha-renaming of variables
- void enterScope(const Variable* V1, const Variable* V2) { }
- void leaveScope() { }
-
- bool compareVariableRefs(const Variable* V1, const Variable* V2) {
- return V1 == V2;
- }
-
- static bool compareExprs(const SExpr *E1, const SExpr* E2) {
- MatchComparator Matcher;
- return Matcher.compare(E1, E2);
- }
-};
-
-
-
-// inline std::ostream& operator<<(std::ostream& SS, StringRef R) {
-// return SS.write(R.data(), R.size());
-// }
-
-// Pretty printer for TIL expressions
-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.
-
-public:
- PrettyPrinter(bool V = false, bool C = true, bool CS = true)
- : Verbose(V), Cleanup(C), CStyle(CS)
- {}
-
- static void print(const SExpr *E, StreamType &SS) {
- Self printer;
- printer.printSExpr(E, SS, Prec_MAX);
- }
-
-protected:
- Self *self() { return reinterpret_cast<Self *>(this); }
-
- void newline(StreamType &SS) {
- SS << "\n";
- }
-
- // TODO: further distinguish between binary operations.
- static const unsigned Prec_Atom = 0;
- static const unsigned Prec_Postfix = 1;
- static const unsigned Prec_Unary = 2;
- static const unsigned Prec_Binary = 3;
- static const unsigned Prec_Other = 4;
- static const unsigned Prec_Decl = 5;
- static const unsigned Prec_MAX = 6;
-
- // Return the precedence of a given node, for use in pretty printing.
- unsigned precedence(const SExpr *E) {
- switch (E->opcode()) {
- case COP_Future: return Prec_Atom;
- case COP_Undefined: return Prec_Atom;
- case COP_Wildcard: return Prec_Atom;
-
- case COP_Literal: return Prec_Atom;
- case COP_LiteralPtr: return Prec_Atom;
- case COP_Variable: return Prec_Atom;
- case COP_Function: return Prec_Decl;
- case COP_SFunction: return Prec_Decl;
- case COP_Code: return Prec_Decl;
- case COP_Field: return Prec_Decl;
-
- case COP_Apply: return Prec_Postfix;
- case COP_SApply: return Prec_Postfix;
- case COP_Project: return Prec_Postfix;
-
- case COP_Call: return Prec_Postfix;
- case COP_Alloc: return Prec_Other;
- case COP_Load: return Prec_Postfix;
- case COP_Store: return Prec_Other;
- case COP_ArrayIndex: return Prec_Postfix;
- case COP_ArrayAdd: return Prec_Postfix;
-
- case COP_UnaryOp: return Prec_Unary;
- case COP_BinaryOp: return Prec_Binary;
- case COP_Cast: return Prec_Atom;
-
- case COP_SCFG: return Prec_Decl;
- case COP_BasicBlock: return Prec_MAX;
- case COP_Phi: return Prec_Atom;
- case COP_Goto: return Prec_Atom;
- case COP_Branch: return Prec_Atom;
- case COP_Return: return Prec_Other;
-
- case COP_Identifier: return Prec_Atom;
- case COP_IfThenElse: return Prec_Other;
- case COP_Let: return Prec_Decl;
- }
- return Prec_MAX;
- }
-
- void printBlockLabel(StreamType & SS, const BasicBlock *BB, int index) {
- if (!BB) {
- SS << "BB_null";
- return;
- }
- SS << "BB_";
- SS << BB->blockID();
- if (index >= 0) {
- SS << ":";
- SS << index;
- }
- }
-
-
- void printSExpr(const SExpr *E, StreamType &SS, unsigned P, bool Sub=true) {
- if (!E) {
- self()->printNull(SS);
- return;
- }
- if (Sub && E->block() && E->opcode() != COP_Variable) {
- SS << "_x" << E->id();
- return;
- }
- if (self()->precedence(E) > P) {
- // Wrap expr in () if necessary.
- SS << "(";
- self()->printSExpr(E, SS, Prec_MAX);
- SS << ")";
- return;
- }
-
- switch (E->opcode()) {
-#define TIL_OPCODE_DEF(X) \
- case COP_##X: \
- self()->print##X(cast<X>(E), SS); \
- return;
-#include "ThreadSafetyOps.def"
-#undef TIL_OPCODE_DEF
- }
- }
-
- void printNull(StreamType &SS) {
- SS << "#null";
- }
-
- void printFuture(const Future *E, StreamType &SS) {
- self()->printSExpr(E->maybeGetResult(), SS, Prec_Atom);
- }
-
- void printUndefined(const Undefined *E, StreamType &SS) {
- SS << "#undefined";
- }
-
- void printWildcard(const Wildcard *E, StreamType &SS) {
- SS << "*";
- }
-
- template<class T>
- void printLiteralT(const LiteralT<T> *E, StreamType &SS) {
- SS << E->value();
- }
-
- void printLiteralT(const LiteralT<uint8_t> *E, StreamType &SS) {
- SS << "'" << E->value() << "'";
- }
-
- void printLiteral(const Literal *E, StreamType &SS) {
- if (E->clangExpr()) {
- SS << getSourceLiteralString(E->clangExpr());
- return;
- }
- else {
- ValueType VT = E->valueType();
- switch (VT.Base) {
- case ValueType::BT_Void: {
- SS << "void";
- return;
- }
- case ValueType::BT_Bool: {
- if (E->as<bool>().value())
- SS << "true";
- else
- SS << "false";
- return;
- }
- case ValueType::BT_Int: {
- switch (VT.Size) {
- case ValueType::ST_8:
- if (VT.Signed)
- printLiteralT(&E->as<int8_t>(), SS);
- else
- printLiteralT(&E->as<uint8_t>(), SS);
- return;
- case ValueType::ST_16:
- if (VT.Signed)
- printLiteralT(&E->as<int16_t>(), SS);
- else
- printLiteralT(&E->as<uint16_t>(), SS);
- return;
- case ValueType::ST_32:
- if (VT.Signed)
- printLiteralT(&E->as<int32_t>(), SS);
- else
- printLiteralT(&E->as<uint32_t>(), SS);
- return;
- case ValueType::ST_64:
- if (VT.Signed)
- printLiteralT(&E->as<int64_t>(), SS);
- else
- printLiteralT(&E->as<uint64_t>(), SS);
- return;
- default:
- break;
- }
- break;
- }
- case ValueType::BT_Float: {
- switch (VT.Size) {
- case ValueType::ST_32:
- printLiteralT(&E->as<float>(), SS);
- return;
- case ValueType::ST_64:
- printLiteralT(&E->as<double>(), SS);
- return;
- default:
- break;
- }
- break;
- }
- case ValueType::BT_String: {
- SS << "\"";
- printLiteralT(&E->as<StringRef>(), SS);
- SS << "\"";
- return;
- }
- case ValueType::BT_Pointer: {
- SS << "#ptr";
- return;
- }
- case ValueType::BT_ValueRef: {
- SS << "#vref";
- return;
- }
- }
- }
- SS << "#lit";
- }
-
- void printLiteralPtr(const LiteralPtr *E, StreamType &SS) {
- SS << E->clangDecl()->getNameAsString();
- }
-
- void printVariable(const Variable *V, StreamType &SS, bool IsVarDecl=false) {
- if (CStyle && V->kind() == Variable::VK_SFun)
- SS << "this";
- else
- SS << V->name() << V->id();
- }
-
- void printFunction(const Function *E, StreamType &SS, unsigned sugared = 0) {
- switch (sugared) {
- default:
- SS << "\\("; // Lambda
- break;
- case 1:
- SS << "("; // Slot declarations
- break;
- case 2:
- SS << ", "; // Curried functions
- break;
- }
- self()->printVariable(E->variableDecl(), SS, true);
- SS << ": ";
- self()->printSExpr(E->variableDecl()->definition(), SS, Prec_MAX);
-
- const SExpr *B = E->body();
- if (B && B->opcode() == COP_Function)
- self()->printFunction(cast<Function>(B), SS, 2);
- else {
- SS << ")";
- self()->printSExpr(B, SS, Prec_Decl);
- }
- }
-
- void printSFunction(const SFunction *E, StreamType &SS) {
- SS << "@";
- self()->printVariable(E->variableDecl(), SS, true);
- SS << " ";
- self()->printSExpr(E->body(), SS, Prec_Decl);
- }
-
- void printCode(const Code *E, StreamType &SS) {
- SS << ": ";
- self()->printSExpr(E->returnType(), SS, Prec_Decl-1);
- SS << " -> ";
- self()->printSExpr(E->body(), SS, Prec_Decl);
- }
-
- void printField(const Field *E, StreamType &SS) {
- SS << ": ";
- self()->printSExpr(E->range(), SS, Prec_Decl-1);
- SS << " = ";
- self()->printSExpr(E->body(), SS, Prec_Decl);
- }
-
- void printApply(const Apply *E, StreamType &SS, bool sugared = false) {
- const SExpr *F = E->fun();
- if (F->opcode() == COP_Apply) {
- printApply(cast<Apply>(F), SS, true);
- SS << ", ";
- } else {
- self()->printSExpr(F, SS, Prec_Postfix);
- SS << "(";
- }
- self()->printSExpr(E->arg(), SS, Prec_MAX);
- if (!sugared)
- SS << ")$";
- }
-
- void printSApply(const SApply *E, StreamType &SS) {
- self()->printSExpr(E->sfun(), SS, Prec_Postfix);
- if (E->isDelegation()) {
- SS << "@(";
- self()->printSExpr(E->arg(), SS, Prec_MAX);
- SS << ")";
- }
- }
-
- 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 (!SAP->isDelegation() && V->kind() == Variable::VK_SFun) {
- SS << E->slotName();
- return;
- }
- }
- }
- if (isa<Wildcard>(E->record())) {
- // handle existentials
- SS << "&";
- SS << E->clangDecl()->getQualifiedNameAsString();
- return;
- }
- }
- self()->printSExpr(E->record(), SS, Prec_Postfix);
- if (CStyle && E->isArrow()) {
- SS << "->";
- }
- else {
- SS << ".";
- }
- SS << E->slotName();
- }
-
- void printCall(const Call *E, StreamType &SS) {
- const SExpr *T = E->target();
- if (T->opcode() == COP_Apply) {
- self()->printApply(cast<Apply>(T), SS, true);
- SS << ")";
- }
- else {
- self()->printSExpr(T, SS, Prec_Postfix);
- SS << "()";
- }
- }
-
- void printAlloc(const Alloc *E, StreamType &SS) {
- SS << "new ";
- self()->printSExpr(E->dataType(), SS, Prec_Other-1);
- }
-
- void printLoad(const Load *E, StreamType &SS) {
- self()->printSExpr(E->pointer(), SS, Prec_Postfix);
- if (!CStyle)
- SS << "^";
- }
-
- void printStore(const Store *E, StreamType &SS) {
- self()->printSExpr(E->destination(), SS, Prec_Other-1);
- SS << " := ";
- self()->printSExpr(E->source(), SS, Prec_Other-1);
- }
-
- void printArrayIndex(const ArrayIndex *E, StreamType &SS) {
- self()->printSExpr(E->array(), SS, Prec_Postfix);
- SS << "[";
- self()->printSExpr(E->index(), SS, Prec_MAX);
- SS << "]";
- }
-
- void printArrayAdd(const ArrayAdd *E, StreamType &SS) {
- self()->printSExpr(E->array(), SS, Prec_Postfix);
- SS << " + ";
- self()->printSExpr(E->index(), SS, Prec_Atom);
- }
-
- void printUnaryOp(const UnaryOp *E, StreamType &SS) {
- SS << getUnaryOpcodeString(E->unaryOpcode());
- self()->printSExpr(E->expr(), SS, Prec_Unary);
- }
-
- void printBinaryOp(const BinaryOp *E, StreamType &SS) {
- self()->printSExpr(E->expr0(), SS, Prec_Binary-1);
- SS << " " << getBinaryOpcodeString(E->binaryOpcode()) << " ";
- self()->printSExpr(E->expr1(), SS, Prec_Binary-1);
- }
-
- void printCast(const Cast *E, StreamType &SS) {
- if (!CStyle) {
- SS << "cast[";
- SS << E->castOpcode();
- SS << "](";
- self()->printSExpr(E->expr(), SS, Prec_Unary);
- SS << ")";
- return;
- }
- self()->printSExpr(E->expr(), SS, Prec_Unary);
- }
-
- void printSCFG(const SCFG *E, StreamType &SS) {
- SS << "CFG {\n";
- for (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);
- SS << "let " << V->name() << V->id() << " = ";
- E = V->definition();
- Sub = true;
- }
- else if (E->opcode() != COP_Store) {
- SS << "let _x" << E->id() << " = ";
- }
- self()->printSExpr(E, SS, Prec_MAX, Sub);
- SS << ";";
- newline(SS);
- }
-
- void printBasicBlock(const BasicBlock *E, StreamType &SS) {
- SS << "BB_" << E->blockID() << ":";
- if (E->parent())
- SS << " BB_" << E->parent()->blockID();
- newline(SS);
-
- for (auto *A : E->arguments())
- printBBInstr(A, SS);
-
- for (auto *I : E->instructions())
- printBBInstr(I, SS);
-
- const SExpr *T = E->terminator();
- if (T) {
- self()->printSExpr(T, SS, Prec_MAX, false);
- SS << ";";
- newline(SS);
- }
- newline(SS);
- }
-
- void printPhi(const Phi *E, StreamType &SS) {
- SS << "phi(";
- if (E->status() == Phi::PH_SingleVal)
- self()->printSExpr(E->values()[0], SS, Prec_MAX);
- else {
- unsigned i = 0;
- for (auto V : E->values()) {
- if (i++ > 0)
- SS << ", ";
- self()->printSExpr(V, SS, Prec_MAX);
- }
- }
- SS << ")";
- }
-
- void printGoto(const Goto *E, StreamType &SS) {
- SS << "goto ";
- printBlockLabel(SS, E->targetBlock(), E->index());
- }
-
- void printBranch(const Branch *E, StreamType &SS) {
- SS << "branch (";
- self()->printSExpr(E->condition(), SS, Prec_MAX);
- SS << ") ";
- printBlockLabel(SS, E->thenBlock(), -1);
- SS << " ";
- printBlockLabel(SS, E->elseBlock(), -1);
- }
-
- void printReturn(const Return *E, StreamType &SS) {
- SS << "return ";
- self()->printSExpr(E->returnValue(), SS, Prec_Other);
- }
-
- void printIdentifier(const Identifier *E, StreamType &SS) {
- SS << E->name();
- }
-
- void printIfThenElse(const IfThenElse *E, StreamType &SS) {
- if (CStyle) {
- printSExpr(E->condition(), SS, Prec_Unary);
- SS << " ? ";
- printSExpr(E->thenExpr(), SS, Prec_Unary);
- SS << " : ";
- printSExpr(E->elseExpr(), SS, Prec_Unary);
- return;
- }
- SS << "if (";
- printSExpr(E->condition(), SS, Prec_MAX);
- SS << ") then ";
- printSExpr(E->thenExpr(), SS, Prec_Other);
- SS << " else ";
- printSExpr(E->elseExpr(), SS, Prec_Other);
- }
-
- void printLet(const Let *E, StreamType &SS) {
- SS << "let ";
- printVariable(E->variableDecl(), SS, true);
- SS << " = ";
- printSExpr(E->variableDecl()->definition(), SS, Prec_Decl-1);
- SS << "; ";
- printSExpr(E->body(), SS, Prec_Decl-1);
- }
-};
-
-
-class StdPrinter : public PrettyPrinter<StdPrinter, std::ostream> { };
-
-
-
-} // end namespace til
-} // end namespace threadSafety
-} // end namespace clang
-
-#endif // LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
deleted file mode 100644
index 4d3402f..0000000
--- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
+++ /dev/null
@@ -1,358 +0,0 @@
-//===- ThreadSafetyUtil.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 some basic utility classes for use by ThreadSafetyTIL.h
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYUTIL_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYUTIL_H
-
-#include "clang/AST/ExprCXX.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
-#include <cassert>
-#include <cstddef>
-#include <ostream>
-#include <utility>
-#include <vector>
-
-namespace clang {
-namespace threadSafety {
-namespace til {
-
-// Simple wrapper class to abstract away from the details of memory management.
-// SExprs are allocated in pools, and deallocated all at once.
-class MemRegionRef {
-private:
- union AlignmentType {
- double d;
- void *p;
- long double dd;
- long long ii;
- };
-
-public:
- MemRegionRef() : Allocator(nullptr) {}
- MemRegionRef(llvm::BumpPtrAllocator *A) : Allocator(A) {}
-
- void *allocate(size_t Sz) {
- return Allocator->Allocate(Sz, llvm::AlignOf<AlignmentType>::Alignment);
- }
-
- template <typename T> T *allocateT() { return Allocator->Allocate<T>(); }
-
- template <typename T> T *allocateT(size_t NumElems) {
- return Allocator->Allocate<T>(NumElems);
- }
-
-private:
- llvm::BumpPtrAllocator *Allocator;
-};
-
-
-} // end namespace til
-} // end namespace threadSafety
-} // end namespace clang
-
-
-inline void *operator new(size_t Sz,
- clang::threadSafety::til::MemRegionRef &R) {
- return R.allocate(Sz);
-}
-
-
-namespace clang {
-namespace threadSafety {
-
-std::string getSourceLiteralString(const clang::Expr *CE);
-
-using llvm::StringRef;
-using clang::SourceLocation;
-
-namespace til {
-
-
-// A simple fixed size array class that does not manage its own memory,
-// suitable for use with bump pointer allocation.
-template <class T> class SimpleArray {
-public:
- SimpleArray() : Data(nullptr), Size(0), Capacity(0) {}
- 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) {}
- SimpleArray(SimpleArray<T> &&A)
- : Data(A.Data), Size(A.Size), Capacity(A.Capacity) {
- A.Data = nullptr;
- A.Size = 0;
- A.Capacity = 0;
- }
-
- SimpleArray &operator=(SimpleArray &&RHS) {
- if (this != &RHS) {
- Data = RHS.Data;
- Size = RHS.Size;
- Capacity = RHS.Capacity;
-
- RHS.Data = nullptr;
- RHS.Size = RHS.Capacity = 0;
- }
- return *this;
- }
-
- // Reserve space for at least Ncp items, reallocating if necessary.
- void reserve(size_t Ncp, MemRegionRef A) {
- if (Ncp <= Capacity)
- return;
- T *Odata = Data;
- Data = A.allocateT<T>(Ncp);
- Capacity = Ncp;
- memcpy(Data, Odata, sizeof(T) * Size);
- return;
- }
-
- // Reserve space for at least N more items.
- void reserveCheck(size_t N, MemRegionRef A) {
- if (Capacity == 0)
- reserve(u_max(InitialCapacity, N), A);
- else if (Size + N < Capacity)
- 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;
-
- size_t size() const { return Size; }
- size_t capacity() const { return Capacity; }
-
- T &operator[](unsigned i) {
- 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; }
-
- const_iterator begin() const { return Data; }
- const_iterator end() const { return Data + Size; }
-
- const_iterator cbegin() const { return Data; }
- const_iterator cend() const { return Data + Size; }
-
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
-
- const_reverse_iterator rbegin() const {
- return const_reverse_iterator(end());
- }
- const_reverse_iterator rend() const {
- return const_reverse_iterator(begin());
- }
-
- void push_back(const T &Elem) {
- assert(Size < Capacity);
- Data[Size++] = Elem;
- }
-
- // drop last n elements from array
- void drop(unsigned n = 0) {
- assert(Size > n);
- Size -= n;
- }
-
- void setValues(unsigned Sz, const T& C) {
- assert(Sz <= Capacity);
- Size = Sz;
- for (unsigned i = 0; i < Sz; ++i) {
- Data[i] = C;
- }
- }
-
- template <class Iter> unsigned append(Iter I, Iter E) {
- size_t Osz = Size;
- size_t J = Osz;
- for (; J < Capacity && I != E; ++J, ++I)
- Data[J] = *I;
- Size = J;
- return J - Osz;
- }
-
- 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());
- }
-
-private:
- // std::max is annoying here, because it requires a reference,
- // thus forcing InitialCapacity to be initialized outside the .h file.
- size_t u_max(size_t i, size_t j) { return (i < j) ? j : i; }
-
- static const size_t InitialCapacity = 4;
-
- SimpleArray(const SimpleArray<T> &A) = delete;
-
- T *Data;
- size_t Size;
- size_t Capacity;
-};
-
-
-} // end namespace til
-
-
-// A copy on write vector.
-// The vector can be in one of three states:
-// * invalid -- no operations are permitted.
-// * read-only -- read operations are permitted.
-// * writable -- read and write operations are permitted.
-// The init(), destroy(), and makeWritable() methods will change state.
-template<typename T>
-class CopyOnWriteVector {
- class VectorData {
- public:
- VectorData() : NumRefs(1) { }
- VectorData(const VectorData &VD) : NumRefs(1), Vect(VD.Vect) { }
-
- unsigned NumRefs;
- 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;
-
-public:
- CopyOnWriteVector() : Data(nullptr) {}
- CopyOnWriteVector(CopyOnWriteVector &&V) : Data(V.Data) { V.Data = nullptr; }
- ~CopyOnWriteVector() { destroy(); }
-
- // Returns true if this holds a valid vector.
- bool valid() const { return Data; }
-
- // Returns true if this vector is writable.
- bool writable() const { return Data && Data->NumRefs == 1; }
-
- // If this vector is not valid, initialize it to a valid vector.
- void init() {
- if (!Data) {
- Data = new VectorData();
- }
- }
-
- // Destroy this vector; thus making it invalid.
- void destroy() {
- if (!Data)
- return;
- if (Data->NumRefs <= 1)
- delete Data;
- else
- --Data->NumRefs;
- Data = nullptr;
- }
-
- // Make this vector writable, creating a copy if needed.
- void makeWritable() {
- if (!Data) {
- Data = new VectorData();
- return;
- }
- if (Data->NumRefs == 1)
- return; // already writeable.
- --Data->NumRefs;
- Data = new VectorData(*Data);
- }
-
- // 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;
-
- const std::vector<T> &elements() const { return Data->Vect; }
-
- const_iterator begin() const { return elements().cbegin(); }
- const_iterator end() const { return elements().cend(); }
-
- const T& operator[](unsigned i) const { return elements()[i]; }
-
- unsigned size() const { return Data ? elements().size() : 0; }
-
- // Return true if V and this vector refer to the same data.
- bool sameAs(const CopyOnWriteVector &V) const { return Data == V.Data; }
-
- // Clear vector. The vector must be writable.
- void clear() {
- assert(writable() && "Vector is not writable!");
- Data->Vect.clear();
- }
-
- // Push a new element onto the end. The vector must be writable.
- void push_back(const T &Elem) {
- assert(writable() && "Vector is not writable!");
- Data->Vect.push_back(Elem);
- }
-
- // Gets a mutable reference to the element at index(i).
- // The vector must be writable.
- T& elem(unsigned i) {
- assert(writable() && "Vector is not writable!");
- return Data->Vect[i];
- }
-
- // Drops elements from the back until the vector has size i.
- void downsize(unsigned i) {
- assert(writable() && "Vector is not writable!");
- Data->Vect.erase(Data->Vect.begin() + i, Data->Vect.end());
- }
-
-private:
- CopyOnWriteVector(VectorData *D) : Data(D) {
- if (!Data)
- return;
- ++Data->NumRefs;
- }
-
- VectorData *Data;
-};
-
-
-inline std::ostream& operator<<(std::ostream& ss, const StringRef str) {
- return ss.write(str.data(), str.size());
-}
-
-
-} // end namespace threadSafety
-} // end 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
deleted file mode 100644
index 53ff20c..0000000
--- a/include/clang/Analysis/Analyses/UninitializedValues.h
+++ /dev/null
@@ -1,126 +0,0 @@
-//= UninitializedValues.h - Finding uses of uninitialized values -*- 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 APIs for invoking and reported uninitialized values
-// warnings.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
-
-#include "clang/AST/Stmt.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-class AnalysisDeclContext;
-class CFG;
-class DeclContext;
-class Expr;
-class VarDecl;
-
-/// A use of a variable, which might be uninitialized.
-class UninitUse {
-public:
- struct Branch {
- const Stmt *Terminator;
- unsigned Output;
- };
-
-private:
- /// The expression which uses this variable.
- const Expr *User;
-
- /// Is this use uninitialized whenever the function is called?
- bool UninitAfterCall;
-
- /// Is this use uninitialized whenever the variable declaration is reached?
- bool UninitAfterDecl;
-
- /// Does this use always see an uninitialized value?
- bool AlwaysUninit;
-
- /// This use is always uninitialized if it occurs after any of these branches
- /// is taken.
- SmallVector<Branch, 2> UninitBranches;
-
-public:
- UninitUse(const Expr *User, bool AlwaysUninit)
- : User(User), UninitAfterCall(false), UninitAfterDecl(false),
- AlwaysUninit(AlwaysUninit) {}
-
- void addUninitBranch(Branch B) {
- UninitBranches.push_back(B);
- }
-
- void setUninitAfterCall() { UninitAfterCall = true; }
- void setUninitAfterDecl() { UninitAfterDecl = true; }
-
- /// Get the expression containing the uninitialized use.
- const Expr *getUser() const { return User; }
-
- /// The kind of uninitialized use.
- 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
- };
-
- /// Get the kind of uninitialized use.
- Kind getKind() const {
- return AlwaysUninit ? Always :
- UninitAfterCall ? AfterCall :
- UninitAfterDecl ? AfterDecl :
- !branch_empty() ? Sometimes : Maybe;
- }
-
- typedef SmallVectorImpl<Branch>::const_iterator branch_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(); }
- bool branch_empty() const { return UninitBranches.empty(); }
-};
-
-class UninitVariablesHandler {
-public:
- UninitVariablesHandler() {}
- virtual ~UninitVariablesHandler();
-
- /// Called when the uninitialized variable is used at the given expression.
- virtual void handleUseOfUninitVariable(const VarDecl *vd,
- const UninitUse &use) {}
-
- /// Called when the uninitialized variable analysis detects the
- /// idiom 'int x = x'. All other uses of 'x' within the initializer
- /// are handled by handleUseOfUninitVariable.
- virtual void handleSelfInit(const VarDecl *vd) {}
-};
-
-struct UninitVariablesAnalysisStats {
- unsigned NumVariablesAnalyzed;
- unsigned NumBlockVisits;
-};
-
-void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
- AnalysisDeclContext &ac,
- UninitVariablesHandler &handler,
- UninitVariablesAnalysisStats &stats);
-
-}
-#endif
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
deleted file mode 100644
index 931190e..0000000
--- a/include/clang/Analysis/AnalysisContext.h
+++ /dev/null
@@ -1,480 +0,0 @@
-//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- 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 AnalysisDeclContext, a class that manages the analysis
-// context data for path sensitive analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
-#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/CodeInjector.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
-#include <memory>
-
-namespace clang {
-
-class Stmt;
-class CFGReverseBlockReachabilityAnalysis;
-class CFGStmtMap;
-class LiveVariables;
-class ManagedAnalysis;
-class ParentMap;
-class PseudoConstantAnalysis;
-class LocationContextManager;
-class StackFrameContext;
-class BlockInvocationContext;
-class AnalysisDeclContextManager;
-class LocationContext;
-
-namespace idx { class TranslationUnit; }
-
-/// The base class of a hierarchy of objects representing analyses tied
-/// to AnalysisDeclContext.
-class ManagedAnalysis {
-protected:
- ManagedAnalysis() {}
-public:
- virtual ~ManagedAnalysis();
-
- // Subclasses need to implement:
- //
- // static const void *getTag();
- //
- // Which returns a fixed pointer address to distinguish classes of
- // analysis objects. They also need to implement:
- //
- // static [Derived*] create(AnalysisDeclContext &Ctx);
- //
- // which creates the analysis object given an AnalysisDeclContext.
-};
-
-
-/// AnalysisDeclContext contains the context data for the function or method
-/// under analysis.
-class AnalysisDeclContext {
- /// Backpoint to the AnalysisManager object that created this
- /// AnalysisDeclContext. This may be null.
- AnalysisDeclContextManager *Manager;
-
- const Decl * const D;
-
- std::unique_ptr<CFG> cfg, completeCFG;
- std::unique_ptr<CFGStmtMap> cfgStmtMap;
-
- CFG::BuildOptions cfgBuildOptions;
- CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
-
- bool builtCFG, builtCompleteCFG;
- std::unique_ptr<ParentMap> PM;
- std::unique_ptr<PseudoConstantAnalysis> PCA;
- std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
-
- llvm::BumpPtrAllocator A;
-
- llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
-
- void *ManagedAnalyses;
-
-public:
- AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
- const Decl *D);
-
- AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
- const Decl *D,
- const CFG::BuildOptions &BuildOptions);
-
- ~AnalysisDeclContext();
-
- ASTContext &getASTContext() const { return D->getASTContext(); }
- const Decl *getDecl() const { return D; }
-
- /// Return the AnalysisDeclContextManager (if any) that created
- /// this AnalysisDeclContext.
- AnalysisDeclContextManager *getManager() const {
- return Manager;
- }
-
- /// Return the build options used to construct the CFG.
- CFG::BuildOptions &getCFGBuildOptions() {
- return cfgBuildOptions;
- }
-
- const CFG::BuildOptions &getCFGBuildOptions() const {
- return cfgBuildOptions;
- }
-
- /// getAddEHEdges - Return true iff we are adding exceptional edges from
- /// callExprs. If this is false, then try/catch statements and blocks
- /// reachable from them can appear to be dead in the CFG, analysis passes must
- /// cope with that.
- bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
- bool getUseUnoptimizedCFG() const {
- return !cfgBuildOptions.PruneTriviallyFalseEdges;
- }
- bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
- bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
-
- void registerForcedBlockExpression(const Stmt *stmt);
- const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
-
- /// \brief Get the body of the Declaration.
- Stmt *getBody() const;
-
- /// \brief 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.
- ///
- /// 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
- /// model file.
- ///
- /// Note, the lookup is not free. We are going to call getBody behind
- /// the scenes.
- /// \sa getBody
- bool isBodyAutosynthesizedFromModelFile() const;
-
- CFG *getCFG();
-
- CFGStmtMap *getCFGStmtMap();
-
- CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
-
- /// Return a version of the CFG without any edges pruned.
- CFG *getUnoptimizedCFG();
-
- void dumpCFG(bool ShowColors);
-
- /// \brief 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; }
-
- ParentMap &getParentMap();
- PseudoConstantAnalysis *getPseudoConstantAnalysis();
-
- typedef const VarDecl * const * referenced_decls_iterator;
-
- llvm::iterator_range<referenced_decls_iterator>
- getReferencedBlockVars(const BlockDecl *BD);
-
- /// Return the ImplicitParamDecl* associated with 'self' if this
- /// AnalysisDeclContext wraps an ObjCMethodDecl. Returns NULL otherwise.
- const ImplicitParamDecl *getSelfDecl() const;
-
- const StackFrameContext *getStackFrame(LocationContext const *Parent,
- const Stmt *S,
- const CFGBlock *Blk,
- unsigned Idx);
-
- const BlockInvocationContext *
- getBlockInvocationContext(const LocationContext *parent,
- const BlockDecl *BD,
- const void *ContextData);
-
- /// Return the specified analysis object, lazily running the analysis if
- /// necessary. Return NULL if the analysis could not run.
- template <typename T>
- T *getAnalysis() {
- const void *tag = T::getTag();
- ManagedAnalysis *&data = getAnalysisImpl(tag);
- if (!data) {
- data = T::create(*this);
- }
- return static_cast<T*>(data);
- }
-private:
- ManagedAnalysis *&getAnalysisImpl(const void* tag);
-
- LocationContextManager &getLocationContextManager();
-};
-
-class LocationContext : public llvm::FoldingSetNode {
-public:
- enum ContextKind { StackFrame, Scope, Block };
-
-private:
- ContextKind Kind;
-
- // AnalysisDeclContext can't be const since some methods may modify its
- // member.
- AnalysisDeclContext *Ctx;
-
- const LocationContext *Parent;
-
-protected:
- LocationContext(ContextKind k, AnalysisDeclContext *ctx,
- const LocationContext *parent)
- : Kind(k), Ctx(ctx), Parent(parent) {}
-
-public:
- virtual ~LocationContext();
-
- ContextKind getKind() const { return Kind; }
-
- AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
-
- const LocationContext *getParent() const { return Parent; }
-
- bool isParentOf(const LocationContext *LC) const;
-
- const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); }
-
- CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); }
-
- template <typename T>
- T *getAnalysis() const {
- return getAnalysisDeclContext()->getAnalysis<T>();
- }
-
- ParentMap &getParentMap() const {
- return getAnalysisDeclContext()->getParentMap();
- }
-
- const ImplicitParamDecl *getSelfDecl() const {
- return Ctx->getSelfDecl();
- }
-
- const StackFrameContext *getCurrentStackFrame() 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() const;
-
-public:
- static void ProfileCommon(llvm::FoldingSetNodeID &ID,
- ContextKind ck,
- AnalysisDeclContext *ctx,
- const LocationContext *parent,
- const void *data);
-};
-
-class StackFrameContext : public LocationContext {
- // The callsite where this stack frame is established.
- const Stmt *CallSite;
-
- // The parent block of the callsite.
- const CFGBlock *Block;
-
- // 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) {}
-
-public:
- ~StackFrameContext() override {}
-
- const Stmt *getCallSite() const { return CallSite; }
-
- const CFGBlock *getCallSiteBlock() const { return Block; }
-
- /// Return true if the current LocationContext has no caller context.
- bool inTopFrame() const override { return getParent() == nullptr; }
-
- unsigned getIndex() const { return Index; }
-
- void Profile(llvm::FoldingSetNodeID &ID) override;
-
- static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
- const LocationContext *parent, const Stmt *s,
- const CFGBlock *blk, unsigned idx) {
- ProfileCommon(ID, StackFrame, ctx, parent, s);
- ID.AddPointer(blk);
- ID.AddInteger(idx);
- }
-
- static bool classof(const LocationContext *Ctx) {
- return Ctx->getKind() == StackFrame;
- }
-};
-
-class ScopeContext : public LocationContext {
- const Stmt *Enter;
-
- friend class LocationContextManager;
- ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
- const Stmt *s)
- : LocationContext(Scope, ctx, parent), Enter(s) {}
-
-public:
- ~ScopeContext() override {}
-
- void Profile(llvm::FoldingSetNodeID &ID) override;
-
- static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
- const LocationContext *parent, const Stmt *s) {
- ProfileCommon(ID, Scope, ctx, parent, s);
- }
-
- static bool classof(const LocationContext *Ctx) {
- return Ctx->getKind() == Scope;
- }
-};
-
-class BlockInvocationContext : public LocationContext {
- 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) {}
-
-public:
- ~BlockInvocationContext() override {}
-
- const BlockDecl *getBlockDecl() const { return BD; }
-
- const void *getContextData() const { return ContextData; }
-
- void Profile(llvm::FoldingSetNodeID &ID) override;
-
- static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
- const LocationContext *parent, const BlockDecl *bd,
- const void *contextData) {
- ProfileCommon(ID, Block, ctx, parent, bd);
- ID.AddPointer(contextData);
- }
-
- static bool classof(const LocationContext *Ctx) {
- return Ctx->getKind() == Block;
- }
-};
-
-class LocationContextManager {
- llvm::FoldingSet<LocationContext> Contexts;
-public:
- ~LocationContextManager();
-
- const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx,
- const LocationContext *parent,
- const Stmt *s,
- const CFGBlock *blk, unsigned idx);
-
- const ScopeContext *getScope(AnalysisDeclContext *ctx,
- const LocationContext *parent,
- const Stmt *s);
-
- const BlockInvocationContext *
- getBlockInvocationContext(AnalysisDeclContext *ctx,
- const LocationContext *parent,
- const BlockDecl *BD,
- const void *ContextData);
-
- /// Discard all previously created LocationContext objects.
- void clear();
-private:
- template <typename LOC, typename DATA>
- const LOC *getLocationContext(AnalysisDeclContext *ctx,
- const LocationContext *parent,
- const DATA *d);
-};
-
-class AnalysisDeclContextManager {
- typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap;
-
- ContextMap Contexts;
- LocationContextManager LocContexts;
- CFG::BuildOptions cfgBuildOptions;
-
- /// Pointer to an interface that can provide function bodies for
- /// declarations from external source.
- std::unique_ptr<CodeInjector> Injector;
-
- /// Flag to indicate whether or not bodies should be synthesized
- /// for well-known functions.
- bool SynthesizeBodies;
-
-public:
- AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
- bool addImplicitDtors = false,
- bool addInitializers = false,
- bool addTemporaryDtors = false,
- bool synthesizeBodies = false,
- bool addStaticInitBranches = false,
- bool addCXXNewAllocator = true,
- CodeInjector* injector = nullptr);
-
- ~AnalysisDeclContextManager();
-
- AnalysisDeclContext *getContext(const Decl *D);
-
- bool getUseUnoptimizedCFG() const {
- return !cfgBuildOptions.PruneTriviallyFalseEdges;
- }
-
- CFG::BuildOptions &getCFGBuildOptions() {
- return cfgBuildOptions;
- }
-
- /// Return true if faux bodies should be synthesized for well-known
- /// functions.
- bool synthesizeBodies() const { return SynthesizeBodies; }
-
- const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
- LocationContext const *Parent,
- const Stmt *S,
- const CFGBlock *Blk,
- unsigned Idx) {
- return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
- }
-
- // Get the top level stack frame.
- const StackFrameContext *getStackFrame(const Decl *D) {
- return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr,
- 0);
- }
-
- // Get a stack frame with parent.
- StackFrameContext const *getStackFrame(const Decl *D,
- LocationContext const *Parent,
- const Stmt *S,
- const CFGBlock *Blk,
- unsigned Idx) {
- return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
- }
-
- /// Discard all previously created AnalysisDeclContexts.
- void clear();
-
-private:
- friend class AnalysisDeclContext;
-
- LocationContextManager &getLocationContextManager() {
- return LocContexts;
- }
-};
-
-} // end clang namespace
-#endif
diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h
deleted file mode 100644
index 8d28971..0000000
--- a/include/clang/Analysis/AnalysisDiagnostic.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- 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_ANALYSIS_ANALYSISDIAGNOSTIC_H
-#define LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define ANALYSISSTART
-#include "clang/Basic/DiagnosticAnalysisKinds.inc"
-#undef DIAG
- NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
deleted file mode 100644
index 293990c..0000000
--- a/include/clang/Analysis/CFG.h
+++ /dev/null
@@ -1,1113 +0,0 @@
-//===--- CFG.h - Classes for representing and building CFGs------*- 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 CFG and CFGBuilder classes for representing and
-// building Control-Flow Graphs (CFGs) from ASTs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CFG_H
-#define LLVM_CLANG_ANALYSIS_CFG_H
-
-#include "clang/AST/Stmt.h"
-#include "clang/Analysis/Support/BumpVector.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
-#include <bitset>
-#include <cassert>
-#include <iterator>
-#include <memory>
-
-namespace clang {
- class CXXDestructorDecl;
- class Decl;
- class Stmt;
- class Expr;
- class FieldDecl;
- class VarDecl;
- class CXXCtorInitializer;
- class CXXBaseSpecifier;
- class CXXBindTemporaryExpr;
- class CFG;
- class PrinterHelper;
- class LangOptions;
- class ASTContext;
- class CXXRecordDecl;
- class CXXDeleteExpr;
- class CXXNewExpr;
- class BinaryOperator;
-
-/// CFGElement - Represents a top-level expression in a basic block.
-class CFGElement {
-public:
- enum Kind {
- // main kind
- Statement,
- Initializer,
- NewAllocator,
- // dtor kind
- AutomaticObjectDtor,
- DeleteDtor,
- BaseDtor,
- MemberDtor,
- TemporaryDtor,
- DTOR_BEGIN = AutomaticObjectDtor,
- DTOR_END = TemporaryDtor
- };
-
-protected:
- // The int bits are used to mark the kind.
- llvm::PointerIntPair<void *, 2> Data1;
- llvm::PointerIntPair<void *, 2> Data2;
-
- CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
- : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
- Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
- assert(getKind() == kind);
- }
-
- CFGElement() {}
-public:
-
- /// \brief Convert to the specified CFGElement type, asserting that this
- /// CFGElement is of the desired type.
- template<typename T>
- T castAs() const {
- assert(T::isKind(*this));
- T t;
- CFGElement& e = t;
- e = *this;
- return t;
- }
-
- /// \brief Convert to the specified CFGElement type, returning None if this
- /// CFGElement is not of the desired type.
- template<typename T>
- Optional<T> getAs() const {
- if (!T::isKind(*this))
- return None;
- T t;
- CFGElement& e = t;
- e = *this;
- return t;
- }
-
- Kind getKind() const {
- unsigned x = Data2.getInt();
- x <<= 2;
- x |= Data1.getInt();
- return (Kind) x;
- }
-};
-
-class CFGStmt : public CFGElement {
-public:
- CFGStmt(Stmt *S) : CFGElement(Statement, S) {}
-
- const Stmt *getStmt() const {
- return static_cast<const Stmt *>(Data1.getPointer());
- }
-
-private:
- friend class CFGElement;
- CFGStmt() {}
- static bool isKind(const CFGElement &E) {
- return E.getKind() == Statement;
- }
-};
-
-/// CFGInitializer - Represents C++ base or member initializer from
-/// constructor's initialization list.
-class CFGInitializer : public CFGElement {
-public:
- CFGInitializer(CXXCtorInitializer *initializer)
- : CFGElement(Initializer, initializer) {}
-
- CXXCtorInitializer* getInitializer() const {
- return static_cast<CXXCtorInitializer*>(Data1.getPointer());
- }
-
-private:
- friend class CFGElement;
- CFGInitializer() {}
- static bool isKind(const CFGElement &E) {
- return E.getKind() == Initializer;
- }
-};
-
-/// CFGNewAllocator - Represents C++ allocator call.
-class CFGNewAllocator : public CFGElement {
-public:
- explicit CFGNewAllocator(const CXXNewExpr *S)
- : CFGElement(NewAllocator, S) {}
-
- // Get the new expression.
- const CXXNewExpr *getAllocatorExpr() const {
- return static_cast<CXXNewExpr *>(Data1.getPointer());
- }
-
-private:
- friend class CFGElement;
- CFGNewAllocator() {}
- static bool isKind(const CFGElement &elem) {
- return elem.getKind() == NewAllocator;
- }
-};
-
-/// CFGImplicitDtor - Represents C++ object destructor implicitly generated
-/// by compiler on various occasions.
-class CFGImplicitDtor : public CFGElement {
-protected:
- CFGImplicitDtor() {}
- CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
- : CFGElement(kind, data1, data2) {
- assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
- }
-
-public:
- const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
- bool isNoReturn(ASTContext &astContext) const;
-
-private:
- friend class CFGElement;
- static bool isKind(const CFGElement &E) {
- Kind kind = E.getKind();
- return kind >= DTOR_BEGIN && kind <= DTOR_END;
- }
-};
-
-/// CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated
-/// for automatic object or temporary bound to const reference at the point
-/// of leaving its local scope.
-class CFGAutomaticObjDtor: public CFGImplicitDtor {
-public:
- CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
- : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {}
-
- const VarDecl *getVarDecl() const {
- return static_cast<VarDecl*>(Data1.getPointer());
- }
-
- // Get statement end of which triggered the destructor call.
- const Stmt *getTriggerStmt() const {
- return static_cast<Stmt*>(Data2.getPointer());
- }
-
-private:
- friend class CFGElement;
- CFGAutomaticObjDtor() {}
- static bool isKind(const CFGElement &elem) {
- return elem.getKind() == AutomaticObjectDtor;
- }
-};
-
-/// CFGDeleteDtor - Represents C++ object destructor generated
-/// from a call to delete.
-class CFGDeleteDtor : public CFGImplicitDtor {
-public:
- CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE)
- : CFGImplicitDtor(DeleteDtor, RD, DE) {}
-
- const CXXRecordDecl *getCXXRecordDecl() const {
- return static_cast<CXXRecordDecl*>(Data1.getPointer());
- }
-
- // Get Delete expression which triggered the destructor call.
- const CXXDeleteExpr *getDeleteExpr() const {
- return static_cast<CXXDeleteExpr *>(Data2.getPointer());
- }
-
-private:
- friend class CFGElement;
- CFGDeleteDtor() {}
- static bool isKind(const CFGElement &elem) {
- return elem.getKind() == DeleteDtor;
- }
-};
-
-/// CFGBaseDtor - Represents C++ object destructor implicitly generated for
-/// base object in destructor.
-class CFGBaseDtor : public CFGImplicitDtor {
-public:
- CFGBaseDtor(const CXXBaseSpecifier *base)
- : CFGImplicitDtor(BaseDtor, base) {}
-
- const CXXBaseSpecifier *getBaseSpecifier() const {
- return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
- }
-
-private:
- friend class CFGElement;
- CFGBaseDtor() {}
- static bool isKind(const CFGElement &E) {
- return E.getKind() == BaseDtor;
- }
-};
-
-/// CFGMemberDtor - Represents C++ object destructor implicitly generated for
-/// member object in destructor.
-class CFGMemberDtor : public CFGImplicitDtor {
-public:
- CFGMemberDtor(const FieldDecl *field)
- : CFGImplicitDtor(MemberDtor, field, nullptr) {}
-
- const FieldDecl *getFieldDecl() const {
- return static_cast<const FieldDecl*>(Data1.getPointer());
- }
-
-private:
- friend class CFGElement;
- CFGMemberDtor() {}
- static bool isKind(const CFGElement &E) {
- return E.getKind() == MemberDtor;
- }
-};
-
-/// CFGTemporaryDtor - Represents C++ object destructor implicitly generated
-/// at the end of full expression for temporary object.
-class CFGTemporaryDtor : public CFGImplicitDtor {
-public:
- CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
- : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {}
-
- const CXXBindTemporaryExpr *getBindTemporaryExpr() const {
- return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
- }
-
-private:
- friend class CFGElement;
- CFGTemporaryDtor() {}
- static bool isKind(const CFGElement &E) {
- return E.getKind() == TemporaryDtor;
- }
-};
-
-/// CFGTerminator - Represents CFGBlock terminator statement.
-///
-/// TemporaryDtorsBranch bit is set to true if the terminator marks a branch
-/// in control flow of destructors of temporaries. In this case terminator
-/// statement is the same statement that branches control flow in evaluation
-/// of matching full expression.
-class CFGTerminator {
- llvm::PointerIntPair<Stmt *, 1> Data;
-public:
- CFGTerminator() {}
- CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
- : Data(S, TemporaryDtorsBranch) {}
-
- Stmt *getStmt() { return Data.getPointer(); }
- const Stmt *getStmt() const { return Data.getPointer(); }
-
- bool isTemporaryDtorsBranch() const { return Data.getInt(); }
-
- operator Stmt *() { return getStmt(); }
- operator const Stmt *() const { return getStmt(); }
-
- Stmt *operator->() { return getStmt(); }
- const Stmt *operator->() const { return getStmt(); }
-
- Stmt &operator*() { return *getStmt(); }
- const Stmt &operator*() const { return *getStmt(); }
-
- explicit operator bool() const { return getStmt(); }
-};
-
-/// CFGBlock - Represents a single basic block in a source-level CFG.
-/// It consists of:
-///
-/// (1) A set of statements/expressions (which may contain subexpressions).
-/// (2) A "terminator" statement (not in the set of statements).
-/// (3) A list of successors and predecessors.
-///
-/// Terminator: The terminator represents the type of control-flow that occurs
-/// at the end of the basic block. The terminator is a Stmt* referring to an
-/// AST node that has control-flow: if-statements, breaks, loops, etc.
-/// If the control-flow is conditional, the condition expression will appear
-/// within the set of statements in the block (usually the last statement).
-///
-/// Predecessors: the order in the set of predecessors is arbitrary.
-///
-/// Successors: the order in the set of successors is NOT arbitrary. We
-/// currently have the following orderings based on the terminator:
-///
-/// Terminator Successor Ordering
-/// -----------------------------------------------------
-/// if Then Block; Else Block
-/// ? operator LHS expression; RHS expression
-/// &&, || expression that uses result of && or ||, RHS
-///
-/// But note that any of that may be NULL in case of optimized-out edges.
-///
-class CFGBlock {
- class ElementList {
- typedef BumpVector<CFGElement> ImplTy;
- ImplTy Impl;
- public:
- ElementList(BumpVectorContext &C) : Impl(C, 4) {}
-
- typedef std::reverse_iterator<ImplTy::iterator> iterator;
- typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
- typedef ImplTy::iterator reverse_iterator;
- typedef ImplTy::const_iterator const_reverse_iterator;
- typedef ImplTy::const_reference const_reference;
-
- void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
- reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E,
- BumpVectorContext &C) {
- return Impl.insert(I, Cnt, E, C);
- }
-
- const_reference front() const { return Impl.back(); }
- const_reference back() const { return Impl.front(); }
-
- iterator begin() { return Impl.rbegin(); }
- iterator end() { return Impl.rend(); }
- const_iterator begin() const { return Impl.rbegin(); }
- const_iterator end() const { return Impl.rend(); }
- reverse_iterator rbegin() { return Impl.begin(); }
- reverse_iterator rend() { return Impl.end(); }
- const_reverse_iterator rbegin() const { return Impl.begin(); }
- const_reverse_iterator rend() const { return Impl.end(); }
-
- CFGElement operator[](size_t i) const {
- assert(i < Impl.size());
- return Impl[Impl.size() - 1 - i];
- }
-
- size_t size() const { return Impl.size(); }
- bool empty() const { return Impl.empty(); }
- };
-
- /// Stmts - The set of statements in the basic block.
- ElementList Elements;
-
- /// Label - An (optional) label that prefixes the executable
- /// statements in the block. When this variable is non-NULL, it is
- /// either an instance of LabelStmt, SwitchCase or CXXCatchStmt.
- Stmt *Label;
-
- /// Terminator - The terminator for a basic block that
- /// indicates the type of control-flow that occurs between a block
- /// and its successors.
- CFGTerminator Terminator;
-
- /// LoopTarget - Some blocks are used to represent the "loop edge" to
- /// the start of a loop from within the loop body. This Stmt* will be
- /// refer to the loop statement for such blocks (and be null otherwise).
- const Stmt *LoopTarget;
-
- /// BlockID - A numerical ID assigned to a CFGBlock during construction
- /// of the CFG.
- unsigned BlockID;
-
-public:
- /// This class represents a potential adjacent block in the CFG. It encodes
- /// whether or not the block is actually reachable, or can be proved to be
- /// trivially unreachable. For some cases it allows one to encode scenarios
- /// where a block was substituted because the original (now alternate) block
- /// is unreachable.
- class AdjacentBlock {
- enum Kind {
- AB_Normal,
- AB_Unreachable,
- AB_Alternate
- };
-
- CFGBlock *ReachableBlock;
- llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
-
- public:
- /// Construct an AdjacentBlock with a possibly unreachable block.
- AdjacentBlock(CFGBlock *B, bool IsReachable);
-
- /// Construct an AdjacentBlock with a reachable block and an alternate
- /// unreachable block.
- AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock);
-
- /// Get the reachable block, if one exists.
- CFGBlock *getReachableBlock() const {
- return ReachableBlock;
- }
-
- /// Get the potentially unreachable block.
- CFGBlock *getPossiblyUnreachableBlock() const {
- return UnreachableBlock.getPointer();
- }
-
- /// Provide an implicit conversion to CFGBlock* so that
- /// AdjacentBlock can be substituted for CFGBlock*.
- operator CFGBlock*() const {
- return getReachableBlock();
- }
-
- CFGBlock& operator *() const {
- return *getReachableBlock();
- }
-
- CFGBlock* operator ->() const {
- return getReachableBlock();
- }
-
- bool isReachable() const {
- Kind K = (Kind) UnreachableBlock.getInt();
- return K == AB_Normal || K == AB_Alternate;
- }
- };
-
-private:
- /// Predecessors/Successors - Keep track of the predecessor / successor
- /// CFG blocks.
- typedef BumpVector<AdjacentBlock> AdjacentBlocks;
- AdjacentBlocks Preds;
- AdjacentBlocks Succs;
-
- /// NoReturn - This bit is set when the basic block contains a function call
- /// or implicit destructor that is attributed as 'noreturn'. In that case,
- /// control cannot technically ever proceed past this block. All such blocks
- /// will have a single immediate successor: the exit block. This allows them
- /// to be easily reached from the exit block and using this bit quickly
- /// recognized without scanning the contents of the block.
- ///
- /// Optimization Note: This bit could be profitably folded with Terminator's
- /// storage if the memory usage of CFGBlock becomes an issue.
- unsigned HasNoReturnElement : 1;
-
- /// Parent - The parent CFG that owns this CFGBlock.
- CFG *Parent;
-
-public:
- explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
- : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr),
- BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
- Parent(parent) {}
-
- // Statement iterators
- typedef ElementList::iterator iterator;
- typedef ElementList::const_iterator const_iterator;
- typedef ElementList::reverse_iterator reverse_iterator;
- typedef ElementList::const_reverse_iterator const_reverse_iterator;
-
- CFGElement front() const { return Elements.front(); }
- CFGElement back() const { return Elements.back(); }
-
- iterator begin() { return Elements.begin(); }
- iterator end() { return Elements.end(); }
- const_iterator begin() const { return Elements.begin(); }
- const_iterator end() const { return Elements.end(); }
-
- reverse_iterator rbegin() { return Elements.rbegin(); }
- reverse_iterator rend() { return Elements.rend(); }
- const_reverse_iterator rbegin() const { return Elements.rbegin(); }
- const_reverse_iterator rend() const { return Elements.rend(); }
-
- unsigned size() const { return Elements.size(); }
- bool empty() const { return Elements.empty(); }
-
- CFGElement operator[](size_t i) const { return Elements[i]; }
-
- // CFG iterators
- typedef AdjacentBlocks::iterator pred_iterator;
- typedef AdjacentBlocks::const_iterator const_pred_iterator;
- typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator;
- typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator;
-
- typedef AdjacentBlocks::iterator succ_iterator;
- typedef AdjacentBlocks::const_iterator const_succ_iterator;
- typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator;
- typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator;
-
- pred_iterator pred_begin() { return Preds.begin(); }
- pred_iterator pred_end() { return Preds.end(); }
- const_pred_iterator pred_begin() const { return Preds.begin(); }
- const_pred_iterator pred_end() const { return Preds.end(); }
-
- pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); }
- pred_reverse_iterator pred_rend() { return Preds.rend(); }
- const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
- const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
-
- succ_iterator succ_begin() { return Succs.begin(); }
- succ_iterator succ_end() { return Succs.end(); }
- const_succ_iterator succ_begin() const { return Succs.begin(); }
- const_succ_iterator succ_end() const { return Succs.end(); }
-
- succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); }
- succ_reverse_iterator succ_rend() { return Succs.rend(); }
- const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
- const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
-
- unsigned succ_size() const { return Succs.size(); }
- bool succ_empty() const { return Succs.empty(); }
-
- unsigned pred_size() const { return Preds.size(); }
- bool pred_empty() const { return Preds.empty(); }
-
-
- class FilterOptions {
- public:
- FilterOptions() {
- IgnoreNullPredecessors = 1;
- IgnoreDefaultsWithCoveredEnums = 0;
- }
-
- unsigned IgnoreNullPredecessors : 1;
- unsigned IgnoreDefaultsWithCoveredEnums : 1;
- };
-
- static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
- const CFGBlock *Dst);
-
- template <typename IMPL, bool IsPred>
- class FilteredCFGBlockIterator {
- private:
- IMPL I, E;
- const FilterOptions F;
- const CFGBlock *From;
- public:
- explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
- const CFGBlock *from,
- const FilterOptions &f)
- : I(i), E(e), F(f), From(from) {
- while (hasMore() && Filter(*I))
- ++I;
- }
-
- bool hasMore() const { return I != E; }
-
- FilteredCFGBlockIterator &operator++() {
- do { ++I; } while (hasMore() && Filter(*I));
- return *this;
- }
-
- const CFGBlock *operator*() const { return *I; }
- private:
- bool Filter(const CFGBlock *To) {
- return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
- }
- };
-
- typedef FilteredCFGBlockIterator<const_pred_iterator, true>
- filtered_pred_iterator;
-
- typedef FilteredCFGBlockIterator<const_succ_iterator, false>
- filtered_succ_iterator;
-
- filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const {
- return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
- }
-
- filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const {
- return filtered_succ_iterator(succ_begin(), succ_end(), this, f);
- }
-
- // Manipulation of block contents
-
- void setTerminator(CFGTerminator Term) { Terminator = Term; }
- void setLabel(Stmt *Statement) { Label = Statement; }
- void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
- void setHasNoReturnElement() { HasNoReturnElement = true; }
-
- CFGTerminator getTerminator() { return Terminator; }
- const CFGTerminator getTerminator() const { return Terminator; }
-
- Stmt *getTerminatorCondition(bool StripParens = true);
-
- const Stmt *getTerminatorCondition(bool StripParens = true) const {
- return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens);
- }
-
- const Stmt *getLoopTarget() const { return LoopTarget; }
-
- Stmt *getLabel() { return Label; }
- const Stmt *getLabel() const { return Label; }
-
- bool hasNoReturnElement() const { return HasNoReturnElement; }
-
- unsigned getBlockID() const { return BlockID; }
-
- CFG *getParent() const { return Parent; }
-
- void dump() const;
-
- void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const;
- void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
- bool ShowColors) const;
- void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
- void printAsOperand(raw_ostream &OS, bool /*PrintType*/) {
- OS << "BB#" << getBlockID();
- }
-
- /// Adds a (potentially unreachable) successor block to the current block.
- void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C);
-
- void appendStmt(Stmt *statement, BumpVectorContext &C) {
- Elements.push_back(CFGStmt(statement), C);
- }
-
- void appendInitializer(CXXCtorInitializer *initializer,
- BumpVectorContext &C) {
- Elements.push_back(CFGInitializer(initializer), C);
- }
-
- void appendNewAllocator(CXXNewExpr *NE,
- BumpVectorContext &C) {
- Elements.push_back(CFGNewAllocator(NE), C);
- }
-
- void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) {
- Elements.push_back(CFGBaseDtor(BS), C);
- }
-
- void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C) {
- Elements.push_back(CFGMemberDtor(FD), C);
- }
-
- void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C) {
- Elements.push_back(CFGTemporaryDtor(E), C);
- }
-
- void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) {
- Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
- }
-
- void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
- Elements.push_back(CFGDeleteDtor(RD, DE), C);
- }
-
- // Destructors must be inserted 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 beginAutomaticObjDtorsInsert(iterator I, size_t Cnt,
- BumpVectorContext &C) {
- return iterator(Elements.insert(I.base(), Cnt,
- CFGAutomaticObjDtor(nullptr, nullptr), C));
- }
- iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) {
- *I = CFGAutomaticObjDtor(VD, S);
- return ++I;
- }
-};
-
-/// \brief CFGCallback defines methods that should be called when a logical
-/// operator error is found when building the CFG.
-class CFGCallback {
-public:
- CFGCallback() {}
- virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
- virtual void compareBitwiseEquality(const BinaryOperator *B,
- bool isAlwaysTrue) {}
- virtual ~CFGCallback() {}
-};
-
-/// CFG - Represents a source-level, intra-procedural CFG that represents the
-/// control-flow of a Stmt. The Stmt can represent an entire function body,
-/// or a single expression. A CFG will always contain one empty block that
-/// represents the Exit point of the CFG. A CFG will also contain a designated
-/// Entry block. The CFG solely represents control-flow; it consists of
-/// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
-/// was constructed from.
-class CFG {
-public:
- //===--------------------------------------------------------------------===//
- // CFG Construction & Manipulation.
- //===--------------------------------------------------------------------===//
-
- class BuildOptions {
- std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
- public:
- typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
- ForcedBlkExprs **forcedBlkExprs;
- CFGCallback *Observer;
- bool PruneTriviallyFalseEdges;
- bool AddEHEdges;
- bool AddInitializers;
- bool AddImplicitDtors;
- bool AddTemporaryDtors;
- bool AddStaticInitBranches;
- bool AddCXXNewAllocator;
- bool AddCXXDefaultInitExprInCtors;
-
- bool alwaysAdd(const Stmt *stmt) const {
- return alwaysAddMask[stmt->getStmtClass()];
- }
-
- BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) {
- alwaysAddMask[stmtClass] = val;
- return *this;
- }
-
- BuildOptions &setAllAlwaysAdd() {
- alwaysAddMask.set();
- return *this;
- }
-
- BuildOptions()
- : forcedBlkExprs(nullptr), Observer(nullptr),
- PruneTriviallyFalseEdges(true), AddEHEdges(false),
- AddInitializers(false), AddImplicitDtors(false),
- AddTemporaryDtors(false), AddStaticInitBranches(false),
- AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
- };
-
- /// \brief Provides a custom implementation of the iterator class to have the
- /// same interface as Function::iterator - iterator returns CFGBlock
- /// (not a pointer to CFGBlock).
- class graph_iterator {
- public:
- typedef CFGBlock value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef BumpVector<CFGBlock*>::iterator ImplTy;
-
- graph_iterator(const ImplTy &i) : I(i) {}
-
- bool operator==(const graph_iterator &X) const { return I == X.I; }
- bool operator!=(const graph_iterator &X) const { return I != X.I; }
-
- reference operator*() const { return **I; }
- pointer operator->() const { return *I; }
- operator CFGBlock* () { return *I; }
-
- graph_iterator &operator++() { ++I; return *this; }
- graph_iterator &operator--() { --I; return *this; }
-
- private:
- ImplTy I;
- };
-
- class const_graph_iterator {
- public:
- typedef const CFGBlock value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef BumpVector<CFGBlock*>::const_iterator ImplTy;
-
- const_graph_iterator(const ImplTy &i) : I(i) {}
-
- bool operator==(const const_graph_iterator &X) const { return I == X.I; }
- bool operator!=(const const_graph_iterator &X) const { return I != X.I; }
-
- reference operator*() const { return **I; }
- pointer operator->() const { return *I; }
- operator CFGBlock* () const { return *I; }
-
- const_graph_iterator &operator++() { ++I; return *this; }
- const_graph_iterator &operator--() { --I; return *this; }
-
- private:
- ImplTy I;
- };
-
- /// buildCFG - Builds a CFG from an AST.
- static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
- const BuildOptions &BO);
-
- /// createBlock - Create a new block in the CFG. The CFG owns the block;
- /// the caller should not directly free it.
- CFGBlock *createBlock();
-
- /// setEntry - Set the entry block of the CFG. This is typically used
- /// only during CFG construction. Most CFG clients expect that the
- /// entry block has no predecessors and contains no statements.
- void setEntry(CFGBlock *B) { Entry = B; }
-
- /// setIndirectGotoBlock - Set the block used for indirect goto jumps.
- /// This is typically used only during CFG construction.
- void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; }
-
- //===--------------------------------------------------------------------===//
- // Block Iterators
- //===--------------------------------------------------------------------===//
-
- typedef BumpVector<CFGBlock*> CFGBlockListTy;
- typedef CFGBlockListTy::iterator iterator;
- typedef CFGBlockListTy::const_iterator const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- CFGBlock & front() { return *Blocks.front(); }
- CFGBlock & back() { return *Blocks.back(); }
-
- iterator begin() { return Blocks.begin(); }
- iterator end() { return Blocks.end(); }
- const_iterator begin() const { return Blocks.begin(); }
- const_iterator end() const { return Blocks.end(); }
-
- graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); }
- graph_iterator nodes_end() { return graph_iterator(Blocks.end()); }
- const_graph_iterator nodes_begin() const {
- return const_graph_iterator(Blocks.begin());
- }
- const_graph_iterator nodes_end() const {
- return const_graph_iterator(Blocks.end());
- }
-
- reverse_iterator rbegin() { return Blocks.rbegin(); }
- reverse_iterator rend() { return Blocks.rend(); }
- const_reverse_iterator rbegin() const { return Blocks.rbegin(); }
- const_reverse_iterator rend() const { return Blocks.rend(); }
-
- CFGBlock & getEntry() { return *Entry; }
- const CFGBlock & getEntry() const { return *Entry; }
- CFGBlock & getExit() { return *Exit; }
- const CFGBlock & getExit() const { return *Exit; }
-
- CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; }
- const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
-
- typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator;
- try_block_iterator try_blocks_begin() const {
- return TryDispatchBlocks.begin();
- }
- try_block_iterator try_blocks_end() const {
- return TryDispatchBlocks.end();
- }
-
- void addTryDispatchBlock(const CFGBlock *block) {
- TryDispatchBlocks.push_back(block);
- }
-
- /// Records a synthetic DeclStmt and the DeclStmt it was constructed from.
- ///
- /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains
- /// multiple decls.
- void addSyntheticDeclStmt(const DeclStmt *Synthetic,
- const DeclStmt *Source) {
- assert(Synthetic->isSingleDecl() && "Can handle single declarations only");
- assert(Synthetic != Source && "Don't include original DeclStmts in map");
- assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map");
- SyntheticDeclStmts[Synthetic] = Source;
- }
-
- typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator
- synthetic_stmt_iterator;
-
- /// Iterates over synthetic DeclStmts in the CFG.
- ///
- /// Each element is a (synthetic statement, source statement) pair.
- ///
- /// \sa addSyntheticDeclStmt
- synthetic_stmt_iterator synthetic_stmt_begin() const {
- return SyntheticDeclStmts.begin();
- }
-
- /// \sa synthetic_stmt_begin
- synthetic_stmt_iterator synthetic_stmt_end() const {
- return SyntheticDeclStmts.end();
- }
-
- //===--------------------------------------------------------------------===//
- // Member templates useful for various batch operations over CFGs.
- //===--------------------------------------------------------------------===//
-
- template <typename CALLBACK>
- void VisitBlockStmts(CALLBACK& O) const {
- for (const_iterator I=begin(), E=end(); I != E; ++I)
- for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end();
- BI != BE; ++BI) {
- if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
- O(const_cast<Stmt*>(stmt->getStmt()));
- }
- }
-
- //===--------------------------------------------------------------------===//
- // CFG Introspection.
- //===--------------------------------------------------------------------===//
-
- /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which
- /// start at 0).
- unsigned getNumBlockIDs() const { return NumBlockIDs; }
-
- /// size - Return the total number of CFGBlocks within the CFG
- /// This is simply a renaming of the getNumBlockIDs(). This is necessary
- /// because the dominator implementation needs such an interface.
- unsigned size() const { return NumBlockIDs; }
-
- //===--------------------------------------------------------------------===//
- // CFG Debugging: Pretty-Printing and Visualization.
- //===--------------------------------------------------------------------===//
-
- void viewCFG(const LangOptions &LO) const;
- void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const;
- void dump(const LangOptions &LO, bool ShowColors) const;
-
- //===--------------------------------------------------------------------===//
- // Internal: constructors and data.
- //===--------------------------------------------------------------------===//
-
- CFG()
- : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
- Blocks(BlkBVC, 10) {}
-
- llvm::BumpPtrAllocator& getAllocator() {
- return BlkBVC.getAllocator();
- }
-
- BumpVectorContext &getBumpVectorContext() {
- return BlkBVC;
- }
-
-private:
- CFGBlock *Entry;
- CFGBlock *Exit;
- CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch
- // for indirect gotos
- unsigned NumBlockIDs;
-
- BumpVectorContext BlkBVC;
-
- CFGBlockListTy Blocks;
-
- /// C++ 'try' statements are modeled with an indirect dispatch block.
- /// This is the collection of such blocks present in the CFG.
- std::vector<const CFGBlock *> TryDispatchBlocks;
-
- /// Collects DeclStmts synthesized for this CFG and maps each one back to its
- /// source DeclStmt.
- llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
-};
-} // end namespace clang
-
-//===----------------------------------------------------------------------===//
-// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-
-/// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
-/// CFGTerminator to a specific Stmt class.
-template <> struct simplify_type< ::clang::CFGTerminator> {
- typedef ::clang::Stmt *SimpleType;
- static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) {
- return Val.getStmt();
- }
-};
-
-// Traits for: CFGBlock
-
-template <> struct GraphTraits< ::clang::CFGBlock *> {
- typedef ::clang::CFGBlock NodeType;
- typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
-
- static NodeType* getEntryNode(::clang::CFGBlock *BB)
- { return BB; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->succ_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->succ_end(); }
-};
-
-template <> struct GraphTraits< const ::clang::CFGBlock *> {
- typedef const ::clang::CFGBlock NodeType;
- typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
-
- static NodeType* getEntryNode(const clang::CFGBlock *BB)
- { return BB; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->succ_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->succ_end(); }
-};
-
-template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
- typedef ::clang::CFGBlock NodeType;
- typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G)
- { return G.Graph; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->pred_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->pred_end(); }
-};
-
-template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
- typedef const ::clang::CFGBlock NodeType;
- typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G)
- { return G.Graph; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->pred_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->pred_end(); }
-};
-
-// Traits for: CFG
-
-template <> struct GraphTraits< ::clang::CFG* >
- : public GraphTraits< ::clang::CFGBlock *> {
-
- typedef ::clang::CFG::graph_iterator nodes_iterator;
-
- static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
- static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
- static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); }
- static unsigned size(::clang::CFG* F) { return F->size(); }
-};
-
-template <> struct GraphTraits<const ::clang::CFG* >
- : public GraphTraits<const ::clang::CFGBlock *> {
-
- typedef ::clang::CFG::const_graph_iterator nodes_iterator;
-
- static NodeType *getEntryNode( const ::clang::CFG* F) {
- return &F->getEntry();
- }
- static nodes_iterator nodes_begin( const ::clang::CFG* F) {
- return F->nodes_begin();
- }
- static nodes_iterator nodes_end( const ::clang::CFG* F) {
- return F->nodes_end();
- }
- static unsigned size(const ::clang::CFG* F) {
- return F->size();
- }
-};
-
-template <> struct GraphTraits<Inverse< ::clang::CFG*> >
- : public GraphTraits<Inverse< ::clang::CFGBlock*> > {
-
- typedef ::clang::CFG::graph_iterator nodes_iterator;
-
- static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); }
- static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
- static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
-};
-
-template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
- : public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
-
- typedef ::clang::CFG::const_graph_iterator nodes_iterator;
-
- static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
- static nodes_iterator nodes_begin(const ::clang::CFG* F) {
- return F->nodes_begin();
- }
- static nodes_iterator nodes_end(const ::clang::CFG* F) {
- return F->nodes_end();
- }
-};
-} // end llvm namespace
-
-#endif // LLVM_CLANG_ANALYSIS_CFG_H
diff --git a/include/clang/Analysis/CFGStmtMap.h b/include/clang/Analysis/CFGStmtMap.h
deleted file mode 100644
index 4dfa91d..0000000
--- a/include/clang/Analysis/CFGStmtMap.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- 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 CFGStmtMap class, which defines a mapping from
-// Stmt* to CFGBlock*
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CFGSTMTMAP_H
-#define LLVM_CLANG_ANALYSIS_CFGSTMTMAP_H
-
-#include "clang/Analysis/CFG.h"
-
-namespace clang {
-
-class CFG;
-class CFGBlock;
-class ParentMap;
-class Stmt;
-
-class CFGStmtMap {
- ParentMap *PM;
- void *M;
-
- CFGStmtMap(ParentMap *pm, void *m) : PM(pm), M(m) {}
-
-public:
- ~CFGStmtMap();
-
- /// Returns a new CFGMap for the given CFG. It is the caller's
- /// responsibility to 'delete' this object when done using it.
- static CFGStmtMap *Build(CFG* C, ParentMap *PM);
-
- /// Returns the CFGBlock the specified Stmt* appears in. For Stmt* that
- /// are terminators, the CFGBlock is the block they appear as a terminator,
- /// and not the block they appear as a block-level expression (e.g, '&&').
- /// CaseStmts and LabelStmts map to the CFGBlock they label.
- CFGBlock *getBlock(Stmt * S);
-
- const CFGBlock *getBlock(const Stmt * S) const {
- return const_cast<CFGStmtMap*>(this)->getBlock(const_cast<Stmt*>(S));
- }
-};
-
-} // end clang namespace
-#endif
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
deleted file mode 100644
index eda22a5..0000000
--- a/include/clang/Analysis/CallGraph.h
+++ /dev/null
@@ -1,253 +0,0 @@
-//== CallGraph.h - AST-based Call graph ------------------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the AST-based CallGraph.
-//
-// A call graph for functions whose definitions/bodies are available in the
-// current translation unit. The graph has a "virtual" root node that contains
-// edges to all externally available functions.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH_H
-#define LLVM_CLANG_ANALYSIS_CALLGRAPH_H
-
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SetVector.h"
-
-namespace clang {
-class CallGraphNode;
-
-/// \brief 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
-/// declarations.
-class CallGraph : public RecursiveASTVisitor<CallGraph> {
- friend class CallGraphNode;
-
- typedef llvm::DenseMap<const Decl *, CallGraphNode *> FunctionMapTy;
-
- /// FunctionMap owns all CallGraphNodes.
- FunctionMapTy FunctionMap;
-
- /// This is a virtual root node that has edges to all the functions.
- CallGraphNode *Root;
-
-public:
- CallGraph();
- ~CallGraph();
-
- /// \brief Populate the call graph with the functions in the given
- /// declaration.
- ///
- /// Recursively walks the declaration to find all the dependent Decls as well.
- void addToCallGraph(Decl *D) {
- TraverseDecl(D);
- }
-
- /// \brief Determine if a declaration should be included in the graph.
- static bool includeInGraph(const Decl *D);
-
- /// \brief Lookup the node for the given declaration.
- CallGraphNode *getNode(const Decl *) const;
-
- /// \brief Lookup the node for the given declaration. If none found, insert
- /// one into the graph.
- CallGraphNode *getOrInsertNode(Decl *);
-
- /// Iterators through all the elements in the graph. Note, this gives
- /// non-deterministic order.
- typedef FunctionMapTy::iterator iterator;
- typedef FunctionMapTy::const_iterator const_iterator;
- iterator begin() { return FunctionMap.begin(); }
- iterator end() { return FunctionMap.end(); }
- const_iterator begin() const { return FunctionMap.begin(); }
- const_iterator end() const { return FunctionMap.end(); }
-
- /// \brief 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
- /// externally are represented as callees of the node.
- CallGraphNode *getRoot() const { return Root; }
-
- /// Iterators through all the nodes of the graph that have no parent. These
- /// are the unreachable nodes, which are either unused or are due to us
- /// failing to add a call edge due to the analysis imprecision.
- typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator;
- typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator;
-
- void print(raw_ostream &os) const;
- void dump() const;
- void viewGraph() const;
-
- void addNodesForBlocks(DeclContext *D);
-
- /// Part of recursive declaration visitation. We recursively visit all the
- /// declarations to collect the root functions.
- bool VisitFunctionDecl(FunctionDecl *FD) {
- // We skip function template definitions, as their semantics is
- // only determined when they are instantiated.
- if (includeInGraph(FD)) {
- // Add all blocks declared inside this function to the graph.
- addNodesForBlocks(FD);
- // If this function has external linkage, anything could call it.
- // Note, we are not precise here. For example, the function could have
- // its address taken.
- addNodeForDecl(FD, FD->isGlobal());
- }
- return true;
- }
-
- /// Part of recursive declaration visitation.
- bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
- if (includeInGraph(MD)) {
- addNodesForBlocks(MD);
- addNodeForDecl(MD, true);
- }
- return true;
- }
-
- // We are only collecting the declarations, so do not step into the bodies.
- bool TraverseStmt(Stmt *S) { return true; }
-
- bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-private:
- /// \brief Add the given declaration to the call graph.
- void addNodeForDecl(Decl *D, bool IsGlobal);
-
- /// \brief Allocate a new node in the graph.
- CallGraphNode *allocateNewNode(Decl *);
-};
-
-class CallGraphNode {
-public:
- typedef CallGraphNode* CallRecord;
-
-private:
- /// \brief The function/method declaration.
- Decl *FD;
-
- /// \brief The list of functions called from this node.
- SmallVector<CallRecord, 5> CalledFunctions;
-
-public:
- CallGraphNode(Decl *D) : FD(D) {}
-
- typedef SmallVectorImpl<CallRecord>::iterator iterator;
- typedef SmallVectorImpl<CallRecord>::const_iterator const_iterator;
-
- /// Iterators through all the callees/children of the node.
- inline iterator begin() { return CalledFunctions.begin(); }
- inline iterator end() { return CalledFunctions.end(); }
- inline const_iterator begin() const { return CalledFunctions.begin(); }
- inline const_iterator end() const { return CalledFunctions.end(); }
-
- inline bool empty() const {return CalledFunctions.empty(); }
- inline unsigned size() const {return CalledFunctions.size(); }
-
- void addCallee(CallGraphNode *N, CallGraph *CG) {
- CalledFunctions.push_back(N);
- }
-
- Decl *getDecl() const { return FD; }
-
- void print(raw_ostream &os) const;
- void dump() const;
-};
-
-} // end clang namespace
-
-// Graph traits for iteration, viewing.
-namespace llvm {
-template <> struct GraphTraits<clang::CallGraphNode*> {
- typedef clang::CallGraphNode NodeType;
- typedef clang::CallGraphNode::CallRecord CallRecordTy;
- typedef std::pointer_to_unary_function<CallRecordTy,
- clang::CallGraphNode*> CGNDerefFun;
- static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; }
- typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
- static inline ChildIteratorType child_begin(NodeType *N) {
- return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
- }
- static inline ChildIteratorType child_end (NodeType *N) {
- return map_iterator(N->end(), CGNDerefFun(CGNDeref));
- }
- static clang::CallGraphNode *CGNDeref(CallRecordTy P) {
- return P;
- }
-};
-
-template <> struct GraphTraits<const clang::CallGraphNode*> {
- typedef const clang::CallGraphNode NodeType;
- typedef NodeType::const_iterator ChildIteratorType;
- static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; }
- static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
- static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
-};
-
-template <> struct GraphTraits<clang::CallGraph*>
- : public GraphTraits<clang::CallGraphNode*> {
-
- static NodeType *getEntryNode(clang::CallGraph *CGN) {
- return CGN->getRoot(); // Start at the external node!
- }
- typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
- typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
- // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef mapped_iterator<clang::CallGraph::iterator, DerefFun> nodes_iterator;
-
- static nodes_iterator nodes_begin(clang::CallGraph *CG) {
- return map_iterator(CG->begin(), DerefFun(CGdereference));
- }
- static nodes_iterator nodes_end (clang::CallGraph *CG) {
- return map_iterator(CG->end(), DerefFun(CGdereference));
- }
- static clang::CallGraphNode &CGdereference(PairTy P) {
- return *(P.second);
- }
-
- static unsigned size(clang::CallGraph *CG) {
- return CG->size();
- }
-};
-
-template <> struct GraphTraits<const clang::CallGraph*> :
- public GraphTraits<const clang::CallGraphNode*> {
- static NodeType *getEntryNode(const clang::CallGraph *CGN) {
- return CGN->getRoot();
- }
- typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
- typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
- // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef mapped_iterator<clang::CallGraph::const_iterator,
- DerefFun> nodes_iterator;
-
- static nodes_iterator nodes_begin(const clang::CallGraph *CG) {
- return map_iterator(CG->begin(), DerefFun(CGdereference));
- }
- static nodes_iterator nodes_end(const clang::CallGraph *CG) {
- return map_iterator(CG->end(), DerefFun(CGdereference));
- }
- static clang::CallGraphNode &CGdereference(PairTy P) {
- return *(P.second);
- }
-
- static unsigned size(const clang::CallGraph *CG) {
- return CG->size();
- }
-};
-
-} // end llvm namespace
-
-#endif
diff --git a/include/clang/Analysis/CodeInjector.h b/include/clang/Analysis/CodeInjector.h
deleted file mode 100644
index 413a55b..0000000
--- a/include/clang/Analysis/CodeInjector.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- CodeInjector.h ------------------------------------------*- 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::CodeInjector interface which is responsible for
-/// injecting AST of function definitions that may not be available in the
-/// original source.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CODEINJECTOR_H
-#define LLVM_CLANG_ANALYSIS_CODEINJECTOR_H
-
-namespace clang {
-
-class Stmt;
-class FunctionDecl;
-class ObjCMethodDecl;
-
-/// \brief 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
-/// function call that has no definition available in the current translation
-/// unit. If the returned statement is not a null pointer, it is assumed to be
-/// the body of a function which will be used for the analysis. The source of
-/// the body can be arbitrary, but it is advised to use memoization to avoid
-/// unnecessary reparsing of the external source that provides the body of the
-/// functions.
-class CodeInjector {
-public:
- CodeInjector();
- virtual ~CodeInjector();
-
- virtual Stmt *getBody(const FunctionDecl *D) = 0;
- virtual Stmt *getBody(const ObjCMethodDecl *D) = 0;
-};
-}
-
-#endif
diff --git a/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/include/clang/Analysis/DomainSpecific/CocoaConventions.h
deleted file mode 100644
index 8b3fcff..0000000
--- a/include/clang/Analysis/DomainSpecific/CocoaConventions.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements cocoa naming convention analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_DOMAINSPECIFIC_COCOACONVENTIONS_H
-#define LLVM_CLANG_ANALYSIS_DOMAINSPECIFIC_COCOACONVENTIONS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-class FunctionDecl;
-class QualType;
-
-namespace ento {
-namespace cocoa {
-
- bool isRefType(QualType RetTy, StringRef Prefix,
- StringRef Name = StringRef());
-
- bool isCocoaObjectRef(QualType T);
-
-}
-
-namespace coreFoundation {
- bool isCFObjectRef(QualType T);
-
- bool followsCreateRule(const FunctionDecl *FD);
-}
-
-}} // end: "clang:ento"
-
-#endif
diff --git a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
deleted file mode 100644
index f9e800a..0000000
--- a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//= ObjCNoReturn.h - Handling of Cocoa APIs known not to return --*- C++ -*---//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements special handling of recognizing ObjC API hooks that
-// do not return but aren't marked as such in API headers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_DOMAINSPECIFIC_OBJCNORETURN_H
-#define LLVM_CLANG_ANALYSIS_DOMAINSPECIFIC_OBJCNORETURN_H
-
-#include "clang/Basic/IdentifierTable.h"
-
-namespace clang {
-
-class ASTContext;
-class ObjCMessageExpr;
-
-class ObjCNoReturn {
- /// Cached "raise" selector.
- Selector RaiseSel;
-
- /// Cached identifier for "NSException".
- IdentifierInfo *NSExceptionII;
-
- enum { NUM_RAISE_SELECTORS = 2 };
-
- /// Cached set of selectors in NSException that are 'noreturn'.
- Selector NSExceptionInstanceRaiseSelectors[NUM_RAISE_SELECTORS];
-
-public:
- ObjCNoReturn(ASTContext &C);
-
- /// Return true if the given message expression is known to never
- /// return.
- bool isImplicitNoReturn(const ObjCMessageExpr *ME);
-};
-}
-
-#endif
diff --git a/include/clang/Analysis/FlowSensitive/DataflowValues.h b/include/clang/Analysis/FlowSensitive/DataflowValues.h
deleted file mode 100644
index f86b2b0..0000000
--- a/include/clang/Analysis/FlowSensitive/DataflowValues.h
+++ /dev/null
@@ -1,172 +0,0 @@
-//===--- DataflowValues.h - Data structure for dataflow values --*- 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 skeleton data structure for encapsulating the dataflow
-// values for a CFG. Typically this is subclassed to provide methods for
-// computing these values from a CFG.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
-#define LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
-
-#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/ProgramPoint.h"
-#include "llvm/ADT/DenseMap.h"
-
-//===----------------------------------------------------------------------===//
-/// Dataflow Directional Tag Classes. These are used for tag dispatching
-/// within the dataflow solver/transfer functions to determine what direction
-/// a dataflow analysis flows.
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-namespace dataflow {
- struct forward_analysis_tag {};
- struct backward_analysis_tag {};
-} // end namespace dataflow
-
-//===----------------------------------------------------------------------===//
-/// DataflowValues. Container class to store dataflow values for a CFG.
-//===----------------------------------------------------------------------===//
-
-template <typename ValueTypes,
- typename _AnalysisDirTag = dataflow::forward_analysis_tag >
-class DataflowValues {
-
- //===--------------------------------------------------------------------===//
- // Type declarations.
- //===--------------------------------------------------------------------===//
-
-public:
- typedef typename ValueTypes::ValTy ValTy;
- typedef typename ValueTypes::AnalysisDataTy AnalysisDataTy;
- typedef _AnalysisDirTag AnalysisDirTag;
- typedef llvm::DenseMap<ProgramPoint, ValTy> EdgeDataMapTy;
- typedef llvm::DenseMap<const CFGBlock*, ValTy> BlockDataMapTy;
- typedef llvm::DenseMap<const Stmt*, ValTy> StmtDataMapTy;
-
- //===--------------------------------------------------------------------===//
- // Predicates.
- //===--------------------------------------------------------------------===//
-
-public:
- /// isForwardAnalysis - Returns true if the dataflow values are computed
- /// from a forward analysis.
- bool isForwardAnalysis() { return isForwardAnalysis(AnalysisDirTag()); }
-
- /// isBackwardAnalysis - Returns true if the dataflow values are computed
- /// from a backward analysis.
- bool isBackwardAnalysis() { return !isForwardAnalysis(); }
-
-private:
- bool isForwardAnalysis(dataflow::forward_analysis_tag) { return true; }
- bool isForwardAnalysis(dataflow::backward_analysis_tag) { return false; }
-
- //===--------------------------------------------------------------------===//
- // Initialization and accessors methods.
- //===--------------------------------------------------------------------===//
-
-public:
- DataflowValues() : StmtDataMap(NULL) {}
- ~DataflowValues() { delete StmtDataMap; }
-
- /// InitializeValues - Invoked by the solver to initialize state needed for
- /// dataflow analysis. This method is usually specialized by subclasses.
- void InitializeValues(const CFG& cfg) {}
-
-
- /// getEdgeData - Retrieves the dataflow values associated with a
- /// CFG edge.
- ValTy& getEdgeData(const BlockEdge &E) {
- typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E);
- assert (I != EdgeDataMap.end() && "No data associated with Edge.");
- return I->second;
- }
-
- const ValTy& getEdgeData(const BlockEdge &E) const {
- return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E);
- }
-
- /// getBlockData - Retrieves the dataflow values associated with a
- /// specified CFGBlock. If the dataflow analysis is a forward analysis,
- /// this data is associated with the END of the block. If the analysis
- /// is a backwards analysis, it is associated with the ENTRY of the block.
- ValTy& getBlockData(const CFGBlock *B) {
- typename BlockDataMapTy::iterator I = BlockDataMap.find(B);
- assert (I != BlockDataMap.end() && "No data associated with block.");
- return I->second;
- }
-
- const ValTy& getBlockData(const CFGBlock *B) const {
- return const_cast<DataflowValues*>(this)->getBlockData(B);
- }
-
- /// getStmtData - Retrieves the dataflow values associated with a
- /// specified Stmt. If the dataflow analysis is a forward analysis,
- /// this data corresponds to the point immediately before a Stmt.
- /// If the analysis is a backwards analysis, it is associated with
- /// the point after a Stmt. This data is only computed for block-level
- /// expressions, and only when requested when the analysis is executed.
- ValTy& getStmtData(const Stmt *S) {
- assert (StmtDataMap && "Dataflow values were not computed for statements.");
- typename StmtDataMapTy::iterator I = StmtDataMap->find(S);
- assert (I != StmtDataMap->end() && "No data associated with statement.");
- return I->second;
- }
-
- const ValTy& getStmtData(const Stmt *S) const {
- return const_cast<DataflowValues*>(this)->getStmtData(S);
- }
-
- /// getEdgeDataMap - Retrieves the internal map between CFG edges and
- /// dataflow values. Usually used by a dataflow solver to compute
- /// values for blocks.
- EdgeDataMapTy& getEdgeDataMap() { return EdgeDataMap; }
- const EdgeDataMapTy& getEdgeDataMap() const { return EdgeDataMap; }
-
- /// getBlockDataMap - Retrieves the internal map between CFGBlocks and
- /// dataflow values. If the dataflow analysis operates in the forward
- /// direction, the values correspond to the dataflow values at the start
- /// of the block. Otherwise, for a backward analysis, the values correpsond
- /// to the dataflow values at the end of the block.
- BlockDataMapTy& getBlockDataMap() { return BlockDataMap; }
- const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; }
-
- /// getStmtDataMap - Retrieves the internal map between Stmts and
- /// dataflow values.
- StmtDataMapTy& getStmtDataMap() {
- if (!StmtDataMap) StmtDataMap = new StmtDataMapTy();
- return *StmtDataMap;
- }
-
- const StmtDataMapTy& getStmtDataMap() const {
- return const_cast<DataflowValues*>(this)->getStmtDataMap();
- }
-
- /// getAnalysisData - Retrieves the meta data associated with a
- /// dataflow analysis for analyzing a particular CFG.
- /// This is typically consumed by transfer function code (via the solver).
- /// This can also be used by subclasses to interpret the dataflow values.
- AnalysisDataTy& getAnalysisData() { return AnalysisData; }
- const AnalysisDataTy& getAnalysisData() const { return AnalysisData; }
-
- //===--------------------------------------------------------------------===//
- // Internal data.
- //===--------------------------------------------------------------------===//
-
-protected:
- EdgeDataMapTy EdgeDataMap;
- BlockDataMapTy BlockDataMap;
- StmtDataMapTy* StmtDataMap;
- AnalysisDataTy AnalysisData;
-};
-
-} // end namespace clang
-#endif
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
deleted file mode 100644
index 6d816fd..0000000
--- a/include/clang/Analysis/ProgramPoint.h
+++ /dev/null
@@ -1,704 +0,0 @@
-//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- 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 interface ProgramPoint, which identifies a
-// distinct location in a function.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
-#define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
-
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Analysis/CFG.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-#include <string>
-#include <utility>
-
-namespace clang {
-
-class AnalysisDeclContext;
-class FunctionDecl;
-class LocationContext;
-
-/// ProgramPoints can be "tagged" as representing points specific to a given
-/// analysis entity. Tags are abstract annotations, with an associated
-/// description and potentially other information.
-class ProgramPointTag {
-public:
- ProgramPointTag(void *tagKind = nullptr) : TagKind(tagKind) {}
- virtual ~ProgramPointTag();
- virtual StringRef getTagDescription() const = 0;
-
-protected:
- /// Used to implement 'isKind' in subclasses.
- const void *getTagKind() { return TagKind; }
-
-private:
- const void *TagKind;
-};
-
-class SimpleProgramPointTag : public ProgramPointTag {
- std::string Desc;
-public:
- SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg);
- StringRef getTagDescription() const override;
-};
-
-class ProgramPoint {
-public:
- enum Kind { BlockEdgeKind,
- BlockEntranceKind,
- BlockExitKind,
- PreStmtKind,
- PreStmtPurgeDeadSymbolsKind,
- PostStmtPurgeDeadSymbolsKind,
- PostStmtKind,
- PreLoadKind,
- PostLoadKind,
- PreStoreKind,
- PostStoreKind,
- PostConditionKind,
- PostLValueKind,
- MinPostStmtKind = PostStmtKind,
- MaxPostStmtKind = PostLValueKind,
- PostInitializerKind,
- CallEnterKind,
- CallExitBeginKind,
- CallExitEndKind,
- PreImplicitCallKind,
- PostImplicitCallKind,
- MinImplicitCallKind = PreImplicitCallKind,
- MaxImplicitCallKind = PostImplicitCallKind,
- EpsilonKind};
-
-private:
- const void *Data1;
- llvm::PointerIntPair<const void *, 2, unsigned> Data2;
-
- // The LocationContext could be NULL to allow ProgramPoint to be used in
- // context insensitive analysis.
- llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
-
- llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
-
-protected:
- ProgramPoint() {}
- ProgramPoint(const void *P,
- Kind k,
- const LocationContext *l,
- const ProgramPointTag *tag = nullptr)
- : Data1(P),
- Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
- L(l, (((unsigned) k) >> 2) & 0x3),
- Tag(tag, (((unsigned) k) >> 4) & 0x3) {
- assert(getKind() == k);
- assert(getLocationContext() == l);
- assert(getData1() == P);
- }
-
- ProgramPoint(const void *P1,
- const void *P2,
- Kind k,
- const LocationContext *l,
- const ProgramPointTag *tag = nullptr)
- : Data1(P1),
- Data2(P2, (((unsigned) k) >> 0) & 0x3),
- L(l, (((unsigned) k) >> 2) & 0x3),
- Tag(tag, (((unsigned) k) >> 4) & 0x3) {}
-
-protected:
- const void *getData1() const { return Data1; }
- const void *getData2() const { return Data2.getPointer(); }
- void setData2(const void *d) { Data2.setPointer(d); }
-
-public:
- /// Create a new ProgramPoint object that is the same as the original
- /// except for using the specified tag value.
- ProgramPoint withTag(const ProgramPointTag *tag) const {
- return ProgramPoint(getData1(), getData2(), getKind(),
- getLocationContext(), tag);
- }
-
- /// \brief Convert to the specified ProgramPoint type, asserting that this
- /// ProgramPoint is of the desired type.
- template<typename T>
- T castAs() const {
- assert(T::isKind(*this));
- T t;
- ProgramPoint& PP = t;
- PP = *this;
- return t;
- }
-
- /// \brief Convert to the specified ProgramPoint type, returning None if this
- /// ProgramPoint is not of the desired type.
- template<typename T>
- Optional<T> getAs() const {
- if (!T::isKind(*this))
- return None;
- T t;
- ProgramPoint& PP = t;
- PP = *this;
- return t;
- }
-
- Kind getKind() const {
- unsigned x = Tag.getInt();
- x <<= 2;
- x |= L.getInt();
- x <<= 2;
- x |= Data2.getInt();
- return (Kind) x;
- }
-
- /// \brief Is this a program point corresponding to purge/removal of dead
- /// symbols and bindings.
- bool isPurgeKind() {
- Kind K = getKind();
- return (K == PostStmtPurgeDeadSymbolsKind ||
- K == PreStmtPurgeDeadSymbolsKind);
- }
-
- const ProgramPointTag *getTag() const { return Tag.getPointer(); }
-
- const LocationContext *getLocationContext() const {
- return L.getPointer();
- }
-
- // For use with DenseMap. This hash is probably slow.
- unsigned getHashValue() const {
- llvm::FoldingSetNodeID ID;
- Profile(ID);
- return ID.ComputeHash();
- }
-
- bool operator==(const ProgramPoint & RHS) const {
- return Data1 == RHS.Data1 &&
- Data2 == RHS.Data2 &&
- L == RHS.L &&
- Tag == RHS.Tag;
- }
-
- bool operator!=(const ProgramPoint &RHS) const {
- return Data1 != RHS.Data1 ||
- Data2 != RHS.Data2 ||
- L != RHS.L ||
- Tag != RHS.Tag;
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger((unsigned) getKind());
- ID.AddPointer(getData1());
- ID.AddPointer(getData2());
- ID.AddPointer(getLocationContext());
- ID.AddPointer(getTag());
- }
-
- static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
- const LocationContext *LC,
- const ProgramPointTag *tag);
-};
-
-class BlockEntrance : public ProgramPoint {
-public:
- BlockEntrance(const CFGBlock *B, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : ProgramPoint(B, BlockEntranceKind, L, tag) {
- assert(B && "BlockEntrance requires non-null block");
- }
-
- const CFGBlock *getBlock() const {
- return reinterpret_cast<const CFGBlock*>(getData1());
- }
-
- Optional<CFGElement> getFirstElement() const {
- const CFGBlock *B = getBlock();
- return B->empty() ? Optional<CFGElement>() : B->front();
- }
-
-private:
- friend class ProgramPoint;
- BlockEntrance() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == BlockEntranceKind;
- }
-};
-
-class BlockExit : public ProgramPoint {
-public:
- BlockExit(const CFGBlock *B, const LocationContext *L)
- : ProgramPoint(B, BlockExitKind, L) {}
-
- const CFGBlock *getBlock() const {
- return reinterpret_cast<const CFGBlock*>(getData1());
- }
-
- const Stmt *getTerminator() const {
- return getBlock()->getTerminator();
- }
-
-private:
- friend class ProgramPoint;
- BlockExit() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == BlockExitKind;
- }
-};
-
-class StmtPoint : public ProgramPoint {
-public:
- StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
- const ProgramPointTag *tag)
- : ProgramPoint(S, p2, k, L, tag) {
- assert(S);
- }
-
- const Stmt *getStmt() const { return (const Stmt*) getData1(); }
-
- template <typename T>
- const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
-
-protected:
- StmtPoint() {}
-private:
- friend class ProgramPoint;
- static bool isKind(const ProgramPoint &Location) {
- unsigned k = Location.getKind();
- return k >= PreStmtKind && k <= MaxPostStmtKind;
- }
-};
-
-
-class PreStmt : public StmtPoint {
-public:
- PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag,
- const Stmt *SubStmt = nullptr)
- : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
-
- const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
-
-private:
- friend class ProgramPoint;
- PreStmt() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PreStmtKind;
- }
-};
-
-class PostStmt : public StmtPoint {
-protected:
- PostStmt() {}
- PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, data, k, L, tag) {}
-
-public:
- explicit PostStmt(const Stmt *S, Kind k, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, nullptr, k, L, tag) {}
-
- explicit PostStmt(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, nullptr, PostStmtKind, L, tag) {}
-
-private:
- friend class ProgramPoint;
- static bool isKind(const ProgramPoint &Location) {
- unsigned k = Location.getKind();
- return k >= MinPostStmtKind && k <= MaxPostStmtKind;
- }
-};
-
-// PostCondition represents the post program point of a branch condition.
-class PostCondition : public PostStmt {
-public:
- PostCondition(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : PostStmt(S, PostConditionKind, L, tag) {}
-
-private:
- friend class ProgramPoint;
- PostCondition() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostConditionKind;
- }
-};
-
-class LocationCheck : public StmtPoint {
-protected:
- LocationCheck() {}
- LocationCheck(const Stmt *S, const LocationContext *L,
- ProgramPoint::Kind K, const ProgramPointTag *tag)
- : StmtPoint(S, nullptr, K, L, tag) {}
-
-private:
- friend class ProgramPoint;
- static bool isKind(const ProgramPoint &location) {
- unsigned k = location.getKind();
- return k == PreLoadKind || k == PreStoreKind;
- }
-};
-
-class PreLoad : public LocationCheck {
-public:
- PreLoad(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : LocationCheck(S, L, PreLoadKind, tag) {}
-
-private:
- friend class ProgramPoint;
- PreLoad() {}
- static bool isKind(const ProgramPoint &location) {
- return location.getKind() == PreLoadKind;
- }
-};
-
-class PreStore : public LocationCheck {
-public:
- PreStore(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : LocationCheck(S, L, PreStoreKind, tag) {}
-
-private:
- friend class ProgramPoint;
- PreStore() {}
- static bool isKind(const ProgramPoint &location) {
- return location.getKind() == PreStoreKind;
- }
-};
-
-class PostLoad : public PostStmt {
-public:
- PostLoad(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : PostStmt(S, PostLoadKind, L, tag) {}
-
-private:
- friend class ProgramPoint;
- PostLoad() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostLoadKind;
- }
-};
-
-/// \brief Represents a program point after a store evaluation.
-class PostStore : public PostStmt {
-public:
- /// Construct the post store point.
- /// \param Loc can be used to store the information about the location
- /// used in the form it was uttered in the code.
- PostStore(const Stmt *S, const LocationContext *L, const void *Loc,
- const ProgramPointTag *tag = nullptr)
- : PostStmt(S, PostStoreKind, L, tag) {
- assert(getData2() == nullptr);
- setData2(Loc);
- }
-
- /// \brief Returns the information about the location used in the store,
- /// how it was uttered in the code.
- const void *getLocationValue() const {
- return getData2();
- }
-
-private:
- friend class ProgramPoint;
- PostStore() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostStoreKind;
- }
-};
-
-class PostLValue : public PostStmt {
-public:
- PostLValue(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : PostStmt(S, PostLValueKind, L, tag) {}
-
-private:
- friend class ProgramPoint;
- PostLValue() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostLValueKind;
- }
-};
-
-/// Represents a point after we ran remove dead bindings BEFORE
-/// processing the given statement.
-class PreStmtPurgeDeadSymbols : public StmtPoint {
-public:
- PreStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { }
-
-private:
- friend class ProgramPoint;
- PreStmtPurgeDeadSymbols() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
- }
-};
-
-/// Represents a point after we ran remove dead bindings AFTER
-/// processing the given statement.
-class PostStmtPurgeDeadSymbols : public StmtPoint {
-public:
- PostStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = nullptr)
- : StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { }
-
-private:
- friend class ProgramPoint;
- PostStmtPurgeDeadSymbols() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
- }
-};
-
-class BlockEdge : public ProgramPoint {
-public:
- BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L)
- : ProgramPoint(B1, B2, BlockEdgeKind, L) {
- assert(B1 && "BlockEdge: source block must be non-null");
- assert(B2 && "BlockEdge: destination block must be non-null");
- }
-
- const CFGBlock *getSrc() const {
- return static_cast<const CFGBlock*>(getData1());
- }
-
- const CFGBlock *getDst() const {
- return static_cast<const CFGBlock*>(getData2());
- }
-
-private:
- friend class ProgramPoint;
- BlockEdge() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == BlockEdgeKind;
- }
-};
-
-class PostInitializer : public ProgramPoint {
-public:
- /// \brief Construct a PostInitializer point that represents a location after
- /// CXXCtorInitializer expression evaluation.
- ///
- /// \param I The initializer.
- /// \param Loc The location of the field being initialized.
- PostInitializer(const CXXCtorInitializer *I,
- const void *Loc,
- const LocationContext *L)
- : ProgramPoint(I, Loc, PostInitializerKind, L) {}
-
- const CXXCtorInitializer *getInitializer() const {
- return static_cast<const CXXCtorInitializer *>(getData1());
- }
-
- /// \brief Returns the location of the field.
- const void *getLocationValue() const {
- return getData2();
- }
-
-private:
- friend class ProgramPoint;
- PostInitializer() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostInitializerKind;
- }
-};
-
-/// Represents an implicit call event.
-///
-/// The nearest statement is provided for diagnostic purposes.
-class ImplicitCallPoint : public ProgramPoint {
-public:
- ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K,
- const LocationContext *L, const ProgramPointTag *Tag)
- : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {}
-
- const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); }
- SourceLocation getLocation() const {
- return SourceLocation::getFromPtrEncoding(getData1());
- }
-
-protected:
- ImplicitCallPoint() {}
-private:
- friend class ProgramPoint;
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() >= MinImplicitCallKind &&
- Location.getKind() <= MaxImplicitCallKind;
- }
-};
-
-/// Represents a program point just before an implicit call event.
-///
-/// Explicit calls will appear as PreStmt program points.
-class PreImplicitCall : public ImplicitCallPoint {
-public:
- PreImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
- const ProgramPointTag *Tag = nullptr)
- : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
-
-private:
- friend class ProgramPoint;
- PreImplicitCall() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PreImplicitCallKind;
- }
-};
-
-/// Represents a program point just after an implicit call event.
-///
-/// Explicit calls will appear as PostStmt program points.
-class PostImplicitCall : public ImplicitCallPoint {
-public:
- PostImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
- const ProgramPointTag *Tag = nullptr)
- : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
-
-private:
- friend class ProgramPoint;
- PostImplicitCall() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == PostImplicitCallKind;
- }
-};
-
-/// Represents a point when we begin processing an inlined call.
-/// CallEnter uses the caller's location context.
-class CallEnter : public ProgramPoint {
-public:
- CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx,
- const LocationContext *callerCtx)
- : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {}
-
- const Stmt *getCallExpr() const {
- return static_cast<const Stmt *>(getData1());
- }
-
- const StackFrameContext *getCalleeContext() const {
- return static_cast<const StackFrameContext *>(getData2());
- }
-
-private:
- friend class ProgramPoint;
- CallEnter() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == CallEnterKind;
- }
-};
-
-/// Represents a point when we start the call exit sequence (for inlined call).
-///
-/// The call exit is simulated with a sequence of nodes, which occur between
-/// CallExitBegin and CallExitEnd. The following operations occur between the
-/// two program points:
-/// - CallExitBegin
-/// - Bind the return value
-/// - Run Remove dead bindings (to clean up the dead symbols from the callee).
-/// - CallExitEnd
-class CallExitBegin : public ProgramPoint {
-public:
- // CallExitBegin uses the callee's location context.
- CallExitBegin(const StackFrameContext *L)
- : ProgramPoint(nullptr, CallExitBeginKind, L, nullptr) {}
-
-private:
- friend class ProgramPoint;
- CallExitBegin() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == CallExitBeginKind;
- }
-};
-
-/// Represents a point when we finish the call exit sequence (for inlined call).
-/// \sa CallExitBegin
-class CallExitEnd : public ProgramPoint {
-public:
- // CallExitEnd uses the caller's location context.
- CallExitEnd(const StackFrameContext *CalleeCtx,
- const LocationContext *CallerCtx)
- : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
-
- const StackFrameContext *getCalleeContext() const {
- return static_cast<const StackFrameContext *>(getData1());
- }
-
-private:
- friend class ProgramPoint;
- CallExitEnd() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == CallExitEndKind;
- }
-};
-
-/// This is a meta program point, which should be skipped by all the diagnostic
-/// reasoning etc.
-class EpsilonPoint : public ProgramPoint {
-public:
- EpsilonPoint(const LocationContext *L, const void *Data1,
- const void *Data2 = nullptr,
- const ProgramPointTag *tag = nullptr)
- : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {}
-
- const void *getData() const { return getData1(); }
-
-private:
- friend class ProgramPoint;
- EpsilonPoint() {}
- static bool isKind(const ProgramPoint &Location) {
- return Location.getKind() == EpsilonKind;
- }
-};
-
-} // end namespace clang
-
-
-namespace llvm { // Traits specialization for DenseMap
-
-template <> struct DenseMapInfo<clang::ProgramPoint> {
-
-static inline clang::ProgramPoint getEmptyKey() {
- uintptr_t x =
- reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
- return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
-}
-
-static inline clang::ProgramPoint getTombstoneKey() {
- uintptr_t x =
- reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
- return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
-}
-
-static unsigned getHashValue(const clang::ProgramPoint &Loc) {
- return Loc.getHashValue();
-}
-
-static bool isEqual(const clang::ProgramPoint &L,
- const clang::ProgramPoint &R) {
- return L == R;
-}
-
-};
-
-template <>
-struct isPodLike<clang::ProgramPoint> { static const bool value = true; };
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
deleted file mode 100644
index 591d17b..0000000
--- a/include/clang/Analysis/Support/BumpVector.h
+++ /dev/null
@@ -1,250 +0,0 @@
-//===-- BumpVector.h - Vector-like ADT that uses bump allocation --*- 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 BumpVector, a vector-like ADT whose contents are
-// allocated from a BumpPtrAllocator.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: Most of this is copy-and-paste from SmallVector.h. We can
-// refactor this core logic into something common that is shared between
-// the two. The main thing that is different is the allocation strategy.
-
-#ifndef LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H
-#define LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H
-
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/type_traits.h"
-#include <algorithm>
-#include <cstring>
-#include <iterator>
-#include <memory>
-
-namespace clang {
-
-class BumpVectorContext {
- llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc;
-public:
- /// Construct a new BumpVectorContext that creates a new BumpPtrAllocator
- /// and destroys it when the BumpVectorContext object is destroyed.
- BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {}
-
- BumpVectorContext(BumpVectorContext &&Other) : Alloc(Other.Alloc) {
- Other.Alloc.setInt(false);
- Other.Alloc.setPointer(nullptr);
- }
-
- /// Construct a new BumpVectorContext that reuses an existing
- /// BumpPtrAllocator. This BumpPtrAllocator is not destroyed when the
- /// BumpVectorContext object is destroyed.
- BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, 0) {}
-
- ~BumpVectorContext() {
- if (Alloc.getInt())
- delete Alloc.getPointer();
- }
-
- llvm::BumpPtrAllocator &getAllocator() { return *Alloc.getPointer(); }
-};
-
-template<typename T>
-class BumpVector {
- T *Begin, *End, *Capacity;
-public:
- // Default ctor - Initialize to empty.
- explicit BumpVector(BumpVectorContext &C, unsigned N)
- : Begin(nullptr), End(nullptr), Capacity(nullptr) {
- reserve(C, N);
- }
-
- ~BumpVector() {
- if (std::is_class<T>::value) {
- // Destroy the constructed elements in the vector.
- destroy_range(Begin, End);
- }
- }
-
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T value_type;
- typedef T* iterator;
- typedef const T* const_iterator;
-
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
-
- // forward iterator creation methods.
- iterator begin() { return Begin; }
- const_iterator begin() const { return Begin; }
- iterator end() { return End; }
- const_iterator end() const { return End; }
-
- // reverse iterator creation methods.
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
-
- bool empty() const { return Begin == End; }
- size_type size() const { return End-Begin; }
-
- reference operator[](unsigned idx) {
- assert(Begin + idx < End);
- return Begin[idx];
- }
- const_reference operator[](unsigned idx) const {
- assert(Begin + idx < End);
- return Begin[idx];
- }
-
- reference front() {
- return begin()[0];
- }
- const_reference front() const {
- return begin()[0];
- }
-
- reference back() {
- return end()[-1];
- }
- const_reference back() const {
- return end()[-1];
- }
-
- void pop_back() {
- --End;
- End->~T();
- }
-
- T pop_back_val() {
- T Result = back();
- pop_back();
- return Result;
- }
-
- void clear() {
- if (std::is_class<T>::value) {
- destroy_range(Begin, End);
- }
- End = Begin;
- }
-
- /// data - Return a pointer to the vector's buffer, even if empty().
- pointer data() {
- return pointer(Begin);
- }
-
- /// data - Return a pointer to the vector's buffer, even if empty().
- const_pointer data() const {
- return const_pointer(Begin);
- }
-
- void push_back(const_reference Elt, BumpVectorContext &C) {
- if (End < Capacity) {
- Retry:
- new (End) T(Elt);
- ++End;
- return;
- }
- grow(C);
- goto Retry;
- }
-
- /// insert - Insert some number of copies of element into a position. Return
- /// iterator to position after last inserted copy.
- iterator insert(iterator I, size_t Cnt, const_reference E,
- BumpVectorContext &C) {
- assert (I >= Begin && I <= End && "Iterator out of bounds.");
- if (End + Cnt <= Capacity) {
- Retry:
- move_range_right(I, End, Cnt);
- construct_range(I, I + Cnt, E);
- End += Cnt;
- return I + Cnt;
- }
- ptrdiff_t D = I - Begin;
- grow(C, size() + Cnt);
- I = Begin + D;
- goto Retry;
- }
-
- void reserve(BumpVectorContext &C, unsigned N) {
- if (unsigned(Capacity-Begin) < N)
- grow(C, N);
- }
-
- /// capacity - Return the total number of elements in the currently allocated
- /// buffer.
- size_t capacity() const { return Capacity - Begin; }
-
-private:
- /// grow - double the size of the allocated memory, guaranteeing space for at
- /// least one more element or MinSize if specified.
- void grow(BumpVectorContext &C, size_type MinSize = 1);
-
- void construct_range(T *S, T *E, const T &Elt) {
- for (; S != E; ++S)
- new (S) T(Elt);
- }
-
- void destroy_range(T *S, T *E) {
- while (S != E) {
- --E;
- E->~T();
- }
- }
-
- void move_range_right(T *S, T *E, size_t D) {
- for (T *I = E + D - 1, *IL = S + D - 1; I != IL; --I) {
- --E;
- new (I) T(*E);
- E->~T();
- }
- }
-};
-
-// Define this out-of-line to dissuade the C++ compiler from inlining it.
-template <typename T>
-void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) {
- size_t CurCapacity = Capacity-Begin;
- size_t CurSize = size();
- size_t NewCapacity = 2*CurCapacity;
- if (NewCapacity < MinSize)
- NewCapacity = MinSize;
-
- // Allocate the memory from the BumpPtrAllocator.
- T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity);
-
- // Copy the elements over.
- if (Begin != End) {
- if (std::is_class<T>::value) {
- std::uninitialized_copy(Begin, End, NewElts);
- // Destroy the original elements.
- destroy_range(Begin, End);
- } else {
- // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
- memcpy(NewElts, Begin, CurSize * sizeof(T));
- }
- }
-
- // For now, leak 'Begin'. We can add it back to a freelist in
- // BumpVectorContext.
- Begin = NewElts;
- End = NewElts+CurSize;
- Capacity = Begin+NewCapacity;
-}
-
-} // end: clang namespace
-#endif
diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h
deleted file mode 100644
index 75e9faf..0000000
--- a/include/clang/Basic/ABI.h
+++ /dev/null
@@ -1,211 +0,0 @@
-//===----- ABI.h - ABI related declarations ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Enums/classes describing ABI related information about constructors,
-/// destructors and thunks.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_ABI_H
-#define LLVM_CLANG_BASIC_ABI_H
-
-#include "llvm/Support/DataTypes.h"
-#include <cstring>
-
-namespace clang {
-
-/// \brief C++ constructor types.
-enum CXXCtorType {
- Ctor_Complete, ///< Complete object ctor
- Ctor_Base, ///< Base object ctor
- Ctor_Comdat, ///< The COMDAT used for ctors
- Ctor_CopyingClosure, ///< Copying closure variant of a ctor
- Ctor_DefaultClosure, ///< Default closure variant of a ctor
-};
-
-/// \brief C++ destructor types.
-enum CXXDtorType {
- Dtor_Deleting, ///< Deleting dtor
- Dtor_Complete, ///< Complete object dtor
- Dtor_Base, ///< Base object dtor
- Dtor_Comdat ///< The COMDAT used for dtors
-};
-
-/// \brief A return adjustment.
-struct ReturnAdjustment {
- /// \brief 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
- /// adjustment, if needed.
- union VirtualAdjustment {
- // Itanium ABI
- struct {
- /// \brief 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
- /// of the derived class.
- uint32_t VBPtrOffset;
-
- /// \brief Index of the virtual base in the vbtable.
- uint32_t VBIndex;
- } Microsoft;
-
- VirtualAdjustment() {
- memset(this, 0, sizeof(*this));
- }
-
- bool Equals(const VirtualAdjustment &Other) const {
- return memcmp(this, &Other, sizeof(Other)) == 0;
- }
-
- bool isEmpty() const {
- VirtualAdjustment Zero;
- return Equals(Zero);
- }
-
- bool Less(const VirtualAdjustment &RHS) const {
- return memcmp(this, &RHS, sizeof(RHS)) < 0;
- }
- } Virtual;
-
- ReturnAdjustment() : NonVirtual(0) {}
-
- bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
-
- friend bool operator==(const ReturnAdjustment &LHS,
- const ReturnAdjustment &RHS) {
- return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
- }
-
- friend bool operator!=(const ReturnAdjustment &LHS, const ReturnAdjustment &RHS) {
- return !(LHS == RHS);
- }
-
- friend bool operator<(const ReturnAdjustment &LHS,
- const ReturnAdjustment &RHS) {
- if (LHS.NonVirtual < RHS.NonVirtual)
- return true;
-
- return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
- }
-};
-
-/// \brief A \c this pointer adjustment.
-struct ThisAdjustment {
- /// \brief 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
- /// adjustment, if needed.
- union VirtualAdjustment {
- // Itanium ABI
- struct {
- /// \brief 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.
- int32_t VtordispOffset;
-
- /// \brief 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.
- int32_t VBOffsetOffset;
- } Microsoft;
-
- VirtualAdjustment() {
- memset(this, 0, sizeof(*this));
- }
-
- bool Equals(const VirtualAdjustment &Other) const {
- return memcmp(this, &Other, sizeof(Other)) == 0;
- }
-
- bool isEmpty() const {
- VirtualAdjustment Zero;
- return Equals(Zero);
- }
-
- bool Less(const VirtualAdjustment &RHS) const {
- return memcmp(this, &RHS, sizeof(RHS)) < 0;
- }
- } Virtual;
-
- ThisAdjustment() : NonVirtual(0) { }
-
- bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
-
- friend bool operator==(const ThisAdjustment &LHS,
- const ThisAdjustment &RHS) {
- return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
- }
-
- friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
- return !(LHS == RHS);
- }
-
- friend bool operator<(const ThisAdjustment &LHS,
- const ThisAdjustment &RHS) {
- if (LHS.NonVirtual < RHS.NonVirtual)
- return true;
-
- return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
- }
-};
-
-class CXXMethodDecl;
-
-/// \brief The \c this pointer adjustment as well as an optional return
-/// adjustment for a thunk.
-struct ThunkInfo {
- /// \brief The \c this pointer adjustment.
- ThisAdjustment This;
-
- /// \brief The return adjustment.
- ReturnAdjustment Return;
-
- /// \brief 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
- /// an ABI-specific comparator.
- const CXXMethodDecl *Method;
-
- ThunkInfo() : Method(nullptr) { }
-
- ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
- const CXXMethodDecl *Method = nullptr)
- : This(This), Return(Return), Method(Method) {}
-
- friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
- return LHS.This == RHS.This && LHS.Return == RHS.Return &&
- LHS.Method == RHS.Method;
- }
-
- bool isEmpty() const {
- return This.isEmpty() && Return.isEmpty() && Method == nullptr;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h
deleted file mode 100644
index 8dd7566..0000000
--- a/include/clang/Basic/AddressSpaces.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===--- AddressSpaces.h - Language-specific address spaces -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Provides definitions for the various language-specific address
-/// spaces.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
-#define LLVM_CLANG_BASIC_ADDRESSSPACES_H
-
-namespace clang {
-
-namespace LangAS {
-
-/// \brief Defines the set of possible language-specific address spaces.
-///
-/// This uses a high starting offset so as not to conflict with any address
-/// space used by a target.
-enum ID {
- Offset = 0xFFFF00,
-
- opencl_global = Offset,
- opencl_local,
- opencl_constant,
- opencl_generic,
-
- cuda_device,
- cuda_constant,
- cuda_shared,
-
- Last,
- Count = Last-Offset
-};
-
-/// The type of a lookup table which maps from language-specific address spaces
-/// to target-specific ones.
-typedef unsigned Map[Count];
-
-}
-
-}
-
-#endif
diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h
deleted file mode 100644
index 18a2b8a..0000000
--- a/include/clang/Basic/AllDiagnostics.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===--- AllDiagnostics.h - Aggregate Diagnostic headers --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Includes all the separate Diagnostic headers & some related helpers.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_ALLDIAGNOSTICS_H
-#define LLVM_CLANG_BASIC_ALLDIAGNOSTICS_H
-
-#include "clang/AST/ASTDiagnostic.h"
-#include "clang/AST/CommentDiagnostic.h"
-#include "clang/Analysis/AnalysisDiagnostic.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Sema/SemaDiagnostic.h"
-#include "clang/Serialization/SerializationDiagnostic.h"
-
-namespace clang {
-template <size_t SizeOfStr, typename FieldType>
-class StringSizerHelper {
- char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1];
-public:
- enum { Size = SizeOfStr };
-};
-} // end namespace clang
-
-#define STR_SIZE(str, fieldTy) clang::StringSizerHelper<sizeof(str)-1, \
- fieldTy>::Size
-
-#endif
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
deleted file mode 100644
index d5ba722..0000000
--- a/include/clang/Basic/Attr.td
+++ /dev/null
@@ -1,2172 +0,0 @@
-//==--- Attr.td - attribute definitions -----------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// The documentation is organized by category. Attributes can have category-
-// specific documentation that is collated within the larger document.
-class DocumentationCategory<string name> {
- string Name = name;
- code Content = [{}];
-}
-def DocCatFunction : DocumentationCategory<"Function Attributes">;
-def DocCatVariable : DocumentationCategory<"Variable Attributes">;
-def DocCatType : DocumentationCategory<"Type Attributes">;
-def DocCatStmt : DocumentationCategory<"Statement Attributes">;
-// Attributes listed under the Undocumented category do not generate any public
-// documentation. Ideally, this category should be used for internal-only
-// attributes which contain no spellings.
-def DocCatUndocumented : DocumentationCategory<"Undocumented">;
-
-class DocDeprecated<string replacement = ""> {
- // If the Replacement field is empty, no replacement will be listed with the
- // documentation. Otherwise, the documentation will specify the attribute has
- // been superseded by this replacement.
- string Replacement = replacement;
-}
-
-// Specifies the documentation to be associated with the given category.
-class Documentation {
- DocumentationCategory Category;
- code Content;
-
- // If the heading is empty, one may be picked automatically. If the attribute
- // only has one spelling, no heading is required as the attribute's sole
- // spelling is sufficient. If all spellings are semantically common, the
- // heading will be the semantic spelling. If the spellings are not
- // semantically common and no heading is provided, an error will be emitted.
- string Heading = "";
-
- // When set, specifies that the attribute is deprecated and can optionally
- // specify a replacement attribute.
- DocDeprecated Deprecated;
-}
-
-// Specifies that the attribute is explicitly undocumented. This can be a
-// helpful placeholder for the attribute while working on the implementation,
-// but should not be used once feature work has been completed.
-def Undocumented : Documentation {
- let Category = DocCatUndocumented;
-}
-
-include "clang/Basic/AttrDocs.td"
-
-// An attribute's subject is whatever it appertains to. In this file, it is
-// more accurately a list of things that an attribute can appertain to. All
-// Decls and Stmts are possibly AttrSubjects (even though the syntax may not
-// allow attributes on a given Decl or Stmt).
-class AttrSubject;
-
-include "clang/Basic/DeclNodes.td"
-include "clang/Basic/StmtNodes.td"
-
-// A subset-subject is an AttrSubject constrained to operate only on some subset
-// of that subject.
-//
-// The code fragment is a boolean expression that will confirm that the subject
-// meets the requirements; the subject will have the name S, and will have the
-// type specified by the base. It should be a simple boolean expression.
-class SubsetSubject<AttrSubject base, code check> : AttrSubject {
- AttrSubject Base = base;
- code CheckCode = check;
-}
-
-// This is the type of a variable which C++11 allows alignas(...) to appertain
-// to.
-def NormalVar : SubsetSubject<Var,
- [{S->getStorageClass() != VarDecl::Register &&
- S->getKind() != Decl::ImplicitParam &&
- S->getKind() != Decl::ParmVar &&
- S->getKind() != Decl::NonTypeTemplateParm}]>;
-def NonBitField : SubsetSubject<Field,
- [{!S->isBitField()}]>;
-
-def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
- [{S->isInstanceMethod()}]>;
-
-def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
- [{S->getMethodFamily() == OMF_init &&
- (isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
- (isa<ObjCCategoryDecl>(S->getDeclContext()) &&
- cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}]>;
-
-def Struct : SubsetSubject<Record,
- [{!S->isUnion()}]>;
-
-def TLSVar : SubsetSubject<Var,
- [{S->getTLSKind() != 0}]>;
-
-def SharedVar : SubsetSubject<Var,
- [{S->hasGlobalStorage() && !S->getTLSKind()}]>;
-
-def GlobalVar : SubsetSubject<Var,
- [{S->hasGlobalStorage()}]>;
-
-// 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,
-// because the attribute can have no Subjects clause to accomplish this. But in
-// the case of a SubsetSubject, there's no way to express it without this hack.
-def DeclBase : AttrSubject;
-def FunctionLike : SubsetSubject<DeclBase,
- [{S->getFunctionType(false) != nullptr}]>;
-
-def OpenCLKernelFunction : SubsetSubject<Function, [{
- S->hasAttr<OpenCLKernelAttr>()
-}]>;
-
-// HasFunctionProto is a more strict version of FunctionLike, so it should
-// never be specified in a Subjects list along with FunctionLike (due to the
-// inclusive nature of subject testing).
-def HasFunctionProto : SubsetSubject<DeclBase,
- [{(S->getFunctionType(true) != nullptr &&
- isa<FunctionProtoType>(S->getFunctionType())) ||
- isa<ObjCMethodDecl>(S) ||
- isa<BlockDecl>(S)}]>;
-
-// A single argument to an attribute
-class Argument<string name, bit optional, bit fake = 0> {
- string Name = name;
- bit Optional = optional;
-
- /// A fake argument is used to store and serialize additional information
- /// in an attribute without actually changing its parsing or pretty-printing.
- bit Fake = fake;
-}
-
-class BoolArgument<string name, bit opt = 0> : Argument<name, opt>;
-class IdentifierArgument<string name, bit opt = 0> : Argument<name, opt>;
-class IntArgument<string name, bit opt = 0> : Argument<name, opt>;
-class StringArgument<string name, bit opt = 0> : Argument<name, opt>;
-class ExprArgument<string name, bit opt = 0> : Argument<name, opt>;
-class FunctionArgument<string name, bit opt = 0> : Argument<name, opt>;
-class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
-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>;
-
-// A version of the form major.minor[.subminor].
-class VersionArgument<string name, bit opt = 0> : Argument<name, opt>;
-
-// This one's a doozy, so it gets its own special type
-// It can be an unsigned integer, or a type. Either can
-// be dependent.
-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> {
- bit Default = default;
-}
-
-// An integer argument with a default value
-class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
- int Default = default;
-}
-
-// This argument is more complex, it includes the enumerator type name,
-// a list of strings to accept, and a list of enumerators to map them to.
-class EnumArgument<string name, string type, list<string> values,
- list<string> enums, bit opt = 0, bit fake = 0>
- : Argument<name, opt, fake> {
- string Type = type;
- list<string> Values = values;
- list<string> Enums = enums;
-}
-
-// FIXME: There should be a VariadicArgument type that takes any other type
-// of argument and generates the appropriate type.
-class VariadicEnumArgument<string name, string type, list<string> values,
- list<string> enums> : Argument<name, 1> {
- string Type = type;
- list<string> Values = values;
- list<string> Enums = enums;
-}
-
-// This handles one spelling of an attribute.
-class Spelling<string name, string variety> {
- string Name = name;
- string Variety = variety;
- bit KnownToGCC;
-}
-
-class GNU<string name> : Spelling<name, "GNU">;
-class Declspec<string name> : Spelling<name, "Declspec">;
-class CXX11<string namespace, string name, int version = 1>
- : Spelling<name, "CXX11"> {
- string Namespace = namespace;
- int Version = version;
-}
-class Keyword<string name> : Spelling<name, "Keyword">;
-class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
- string Namespace = namespace;
-}
-
-// The GCC spelling implies GNU<name, "GNU"> and CXX11<"gnu", name> and also
-// sets KnownToGCC to 1. This spelling should be used for any GCC-compatible
-// attributes.
-class GCC<string name> : Spelling<name, "GCC"> {
- let KnownToGCC = 1;
-}
-
-class Accessor<string name, list<Spelling> spellings> {
- string Name = name;
- list<Spelling> Spellings = spellings;
-}
-
-class SubjectDiag<bit warn> {
- bit Warn = warn;
-}
-def WarnDiag : SubjectDiag<1>;
-def ErrorDiag : SubjectDiag<0>;
-
-class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag,
- string customDiag = ""> {
- list<AttrSubject> Subjects = subjects;
- SubjectDiag Diag = diag;
- string CustomDiag = customDiag;
-}
-
-class LangOpt<string name, bit negated = 0> {
- string Name = name;
- bit Negated = negated;
-}
-def MicrosoftExt : LangOpt<"MicrosoftExt">;
-def Borland : LangOpt<"Borland">;
-def CUDA : LangOpt<"CUDA">;
-def COnly : LangOpt<"CPlusPlus", 1>;
-
-// Defines targets for target-specific attributes. The list of strings should
-// specify architectures for which the target applies, based off the ArchType
-// enumeration in Triple.h.
-class TargetArch<list<string> arches> {
- list<string> Arches = arches;
- list<string> OSes;
- list<string> CXXABIs;
-}
-def TargetARM : TargetArch<["arm", "thumb"]>;
-def TargetMips : TargetArch<["mips", "mipsel"]>;
-def TargetMSP430 : TargetArch<["msp430"]>;
-def TargetX86 : TargetArch<["x86"]>;
-def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
- let OSes = ["Win32"];
-}
-def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
- let CXXABIs = ["Microsoft"];
-}
-
-class Attr {
- // The various ways in which an attribute can be spelled in source
- list<Spelling> Spellings;
- // The things to which an attribute can appertain
- SubjectList Subjects;
- // The arguments allowed on an attribute
- list<Argument> Args = [];
- // Accessors which should be generated for the attribute.
- list<Accessor> Accessors = [];
- // Set to true for attributes with arguments which require delayed parsing.
- bit LateParsed = 0;
- // Set to false to prevent an attribute from being propagated from a template
- // to the instantiation.
- bit Clone = 1;
- // Set to true for attributes which must be instantiated within templates
- bit TemplateDependent = 0;
- // Set to true for attributes that have a corresponding AST node.
- bit ASTNode = 1;
- // Set to true for attributes which have handler in Sema.
- bit SemaHandler = 1;
- // Set to true for attributes that are completely ignored.
- bit Ignored = 0;
- // Set to true if the attribute's parsing does not match its semantic
- // content. Eg) It parses 3 args, but semantically takes 4 args. Opts out of
- // common attribute error checking.
- bit HasCustomParsing = 0;
- // 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;
- // Lists language options, one of which is required to be true for the
- // attribute to be applicable. If empty, no language options are required.
- list<LangOpt> LangOpts = [];
- // Any additional text that should be included verbatim in the class.
- // Note: Any additional data members will leak and should be constructed
- // externally on the ASTContext.
- code AdditionalMembers = [{}];
- // Any documentation that should be associated with the attribute. Since an
- // attribute may be documented under multiple categories, more than one
- // Documentation entry may be listed.
- list<Documentation> Documentation;
-}
-
-/// A type attribute is not processed on a declaration or a statement.
-class TypeAttr : Attr {
- // By default, type attributes do not get an AST node.
- let ASTNode = 0;
-}
-
-/// An inheritable attribute is inherited by later redeclarations.
-class InheritableAttr : Attr;
-
-/// A target-specific attribute. This class is meant to be used as a mixin
-/// with InheritableAttr or Attr depending on the attribute's needs.
-class TargetSpecificAttr<TargetArch target> {
- TargetArch Target = target;
- // Attributes are generally required to have unique spellings for their names
- // so that the parser can determine what kind of attribute it has parsed.
- // However, target-specific attributes are special in that the attribute only
- // "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
- // should contain a shared value between the attributes.
- //
- // Target-specific attributes which use this feature should ensure that the
- // spellings match exactly betweeen the attributes, and if the arguments or
- // subjects differ, should specify HasCustomParsing = 1 and implement their
- // own parsing and semantic handling requirements as-needed.
- string ParseKind;
-}
-
-/// An inheritable parameter attribute is inherited by later
-/// redeclarations, even when it's written on a parameter.
-class InheritableParamAttr : InheritableAttr;
-
-/// An ignored attribute, which we parse but discard with no checking.
-class IgnoredAttr : Attr {
- let Ignored = 1;
- let ASTNode = 0;
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
-//
-// Attributes begin here
-//
-
-def AddressSpace : TypeAttr {
- let Spellings = [GNU<"address_space">];
- let Args = [IntArgument<"AddressSpace">];
- let Documentation = [Undocumented];
-}
-
-def Alias : Attr {
- let Spellings = [GCC<"alias">];
- let Args = [StringArgument<"Aliasee">];
- let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
- "ExpectedFunctionGlobalVarMethodOrProperty">;
- let Documentation = [Undocumented];
-}
-
-def Aligned : InheritableAttr {
- let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
- Keyword<"_Alignas">];
-// let Subjects = SubjectList<[NonBitField, NormalVar, Tag]>;
- let Args = [AlignedArgument<"Alignment", 1>];
- let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
- Accessor<"isC11", [Keyword<"_Alignas">]>,
- Accessor<"isAlignas", [Keyword<"alignas">,
- Keyword<"_Alignas">]>,
- Accessor<"isDeclspec",[Declspec<"align">]>];
- let Documentation = [Undocumented];
-}
-
-def AlignValue : Attr {
- let Spellings = [
- // Unfortunately, this is semantically an assertion, not a directive
- // (something else must ensure the alignment), so aligned_value is a
- // probably a better name. We might want to add an aligned_value spelling in
- // the future (and a corresponding C++ attribute), but this can be done
- // later once we decide if we also want them to have slightly-different
- // semantics than Intel's align_value.
- GNU<"align_value">
- // Intel's compiler on Windows also supports:
- // , Declspec<"align_value">
- ];
- let Args = [ExprArgument<"Alignment">];
- let Subjects = SubjectList<[Var, TypedefName], WarnDiag,
- "ExpectedVariableOrTypedef">;
- let Documentation = [AlignValueDocs];
-}
-
-def AlignMac68k : InheritableAttr {
- // This attribute has no spellings as it is only ever created implicitly.
- let Spellings = [];
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
-def AlwaysInline : InheritableAttr {
- let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def TLSModel : InheritableAttr {
- let Spellings = [GCC<"tls_model">];
- let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
- let Args = [StringArgument<"Model">];
- let Documentation = [TLSModelDocs];
-}
-
-def AnalyzerNoReturn : InheritableAttr {
- let Spellings = [GNU<"analyzer_noreturn">];
- let Documentation = [Undocumented];
-}
-
-def Annotate : InheritableParamAttr {
- let Spellings = [GNU<"annotate">];
- let Args = [StringArgument<"Annotation">];
- let Documentation = [Undocumented];
-}
-
-def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
- // NOTE: If you add any additional spellings, MSP430Interrupt's and
- // MipsInterrupt's spellings must match.
- let Spellings = [GNU<"interrupt">];
- let Args = [EnumArgument<"Interrupt", "InterruptType",
- ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
- ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
- 1>];
- let ParseKind = "Interrupt";
- let HasCustomParsing = 1;
- let Documentation = [ARMInterruptDocs];
-}
-
-def AsmLabel : InheritableAttr {
- let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
- let Args = [StringArgument<"Label">];
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
-def Availability : InheritableAttr {
- let Spellings = [GNU<"availability">];
- let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
- VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
- BoolArgument<"unavailable">, StringArgument<"message">];
- let AdditionalMembers =
-[{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
- return llvm::StringSwitch<llvm::StringRef>(Platform)
- .Case("android", "Android")
- .Case("ios", "iOS")
- .Case("macosx", "OS X")
- .Case("tvos", "tvOS")
- .Case("watchos", "watchOS")
- .Case("ios_app_extension", "iOS (App Extension)")
- .Case("macosx_app_extension", "OS X (App Extension)")
- .Case("tvos_app_extension", "tvOS (App Extension)")
- .Case("watchos_app_extension", "watchOS (App Extension)")
- .Default(llvm::StringRef());
-} }];
- let HasCustomParsing = 1;
- let DuplicatesAllowedWhileMerging = 1;
-// let Subjects = SubjectList<[Named]>;
- let Documentation = [AvailabilityDocs];
-}
-
-def Blocks : InheritableAttr {
- let Spellings = [GNU<"blocks">];
- let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
- let Documentation = [Undocumented];
-}
-
-def Bounded : IgnoredAttr {
- let Spellings = [GNU<"bounded">];
-}
-
-def CarriesDependency : InheritableParamAttr {
- let Spellings = [GNU<"carries_dependency">,
- CXX11<"","carries_dependency", 200809>];
- let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>;
- let Documentation = [CarriesDependencyDocs];
-}
-
-def CDecl : InheritableAttr {
- let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [Undocumented];
-}
-
-// cf_audited_transfer indicates that the given function has been
-// audited and has been marked with the appropriate cf_consumed and
-// cf_returns_retained attributes. It is generally applied by
-// '#pragma clang arc_cf_code_audited' rather than explicitly.
-def CFAuditedTransfer : InheritableAttr {
- let Spellings = [GNU<"cf_audited_transfer">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-// cf_unknown_transfer is an explicit opt-out of cf_audited_transfer.
-// It indicates that the function has unknown or unautomatable
-// transfer semantics.
-def CFUnknownTransfer : InheritableAttr {
- let Spellings = [GNU<"cf_unknown_transfer">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def CFReturnsRetained : InheritableAttr {
- let Spellings = [GNU<"cf_returns_retained">];
-// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
-}
-
-def CFReturnsNotRetained : InheritableAttr {
- let Spellings = [GNU<"cf_returns_not_retained">];
-// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
-}
-
-def CFConsumed : InheritableParamAttr {
- let Spellings = [GNU<"cf_consumed">];
- let Subjects = SubjectList<[ParmVar]>;
- let Documentation = [Undocumented];
-}
-
-def Cleanup : InheritableAttr {
- let Spellings = [GCC<"cleanup">];
- let Args = [FunctionArgument<"FunctionDecl">];
- let Subjects = SubjectList<[Var]>;
- let Documentation = [Undocumented];
-}
-
-def Cold : InheritableAttr {
- let Spellings = [GCC<"cold">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def Common : InheritableAttr {
- let Spellings = [GCC<"common">];
- let Subjects = SubjectList<[Var]>;
- let Documentation = [Undocumented];
-}
-
-def Const : InheritableAttr {
- let Spellings = [GCC<"const">, GCC<"__const">];
- let Documentation = [Undocumented];
-}
-
-def Constructor : InheritableAttr {
- let Spellings = [GCC<"constructor">];
- let Args = [DefaultIntArgument<"Priority", 65535>];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def CUDAConstant : InheritableAttr {
- let Spellings = [GNU<"constant">];
- let Subjects = SubjectList<[Var]>;
- let LangOpts = [CUDA];
- let Documentation = [Undocumented];
-}
-
-def CUDACudartBuiltin : IgnoredAttr {
- let Spellings = [GNU<"cudart_builtin">];
- let LangOpts = [CUDA];
-}
-
-def CUDADevice : InheritableAttr {
- let Spellings = [GNU<"device">];
- let Subjects = SubjectList<[Function, Var]>;
- let LangOpts = [CUDA];
- let Documentation = [Undocumented];
-}
-
-def CUDADeviceBuiltin : IgnoredAttr {
- let Spellings = [GNU<"device_builtin">];
- let LangOpts = [CUDA];
-}
-
-def CUDADeviceBuiltinSurfaceType : IgnoredAttr {
- let Spellings = [GNU<"device_builtin_surface_type">];
- let LangOpts = [CUDA];
-}
-
-def CUDADeviceBuiltinTextureType : IgnoredAttr {
- let Spellings = [GNU<"device_builtin_texture_type">];
- let LangOpts = [CUDA];
-}
-
-def CUDAGlobal : InheritableAttr {
- let Spellings = [GNU<"global">];
- let Subjects = SubjectList<[Function]>;
- let LangOpts = [CUDA];
- let Documentation = [Undocumented];
-}
-
-def CUDAHost : InheritableAttr {
- let Spellings = [GNU<"host">];
- let Subjects = SubjectList<[Function]>;
- let LangOpts = [CUDA];
- let Documentation = [Undocumented];
-}
-
-def CUDAInvalidTarget : InheritableAttr {
- let Spellings = [];
- let Subjects = SubjectList<[Function]>;
- let LangOpts = [CUDA];
- let Documentation = [Undocumented];
-}
-
-def CUDALaunchBounds : InheritableAttr {
- let Spellings = [GNU<"launch_bounds">];
- let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>];
- let LangOpts = [CUDA];
- let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag,
- "ExpectedFunctionOrMethod">;
- // An AST node is created for this attribute, but is not used by other parts
- // of the compiler. However, this node needs to exist in the AST because
- // non-LLVM backends may be relying on the attribute's presence.
- let Documentation = [Undocumented];
-}
-
-def CUDAShared : InheritableAttr {
- let Spellings = [GNU<"shared">];
- let Subjects = SubjectList<[Var]>;
- let LangOpts = [CUDA];
- let Documentation = [Undocumented];
-}
-
-def C11NoReturn : InheritableAttr {
- let Spellings = [Keyword<"_Noreturn">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let SemaHandler = 0;
- let Documentation = [C11NoReturnDocs];
-}
-
-def CXX11NoReturn : InheritableAttr {
- let Spellings = [CXX11<"","noreturn", 200809>];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [CXX11NoReturnDocs];
-}
-
-def OpenCLKernel : InheritableAttr {
- let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-// This attribute is both a type attribute, and a declaration attribute (for
-// parameter variables).
-def OpenCLImageAccess : Attr {
- let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
- Keyword<"__write_only">, Keyword<"write_only">,
- Keyword<"__read_write">, Keyword<"read_write">];
- let Subjects = SubjectList<[ParmVar], ErrorDiag>;
- let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
- Keyword<"read_only">]>,
- Accessor<"isReadWrite", [Keyword<"__read_write">,
- Keyword<"read_write">]>,
- Accessor<"isWriteOnly", [Keyword<"__write_only">,
- Keyword<"write_only">]>];
- let Documentation = [Undocumented];
-}
-
-def OpenCLPrivateAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__private">, Keyword<"private">];
- let Documentation = [OpenCLAddressSpacePrivateDocs];
-}
-
-def OpenCLGlobalAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__global">, Keyword<"global">];
- let Documentation = [OpenCLAddressSpaceGlobalDocs];
-}
-
-def OpenCLLocalAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__local">, Keyword<"local">];
- let Documentation = [OpenCLAddressSpaceLocalDocs];
-}
-
-def OpenCLConstantAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__constant">, Keyword<"constant">];
- let Documentation = [OpenCLAddressSpaceConstantDocs];
-}
-
-def OpenCLGenericAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__generic">, Keyword<"generic">];
- let Documentation = [OpenCLAddressSpaceGenericDocs];
-}
-
-def Deprecated : InheritableAttr {
- let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
- CXX11<"","deprecated", 201309>];
- let Args = [StringArgument<"Message", 1>];
- let Documentation = [Undocumented];
-}
-
-def Destructor : InheritableAttr {
- let Spellings = [GCC<"destructor">];
- let Args = [DefaultIntArgument<"Priority", 65535>];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def EnableIf : InheritableAttr {
- let Spellings = [GNU<"enable_if">];
- let Subjects = SubjectList<[Function]>;
- let Args = [ExprArgument<"Cond">, StringArgument<"Message">];
- let TemplateDependent = 1;
- let Documentation = [EnableIfDocs];
-}
-
-def ExtVectorType : Attr {
- let Spellings = [GNU<"ext_vector_type">];
- let Subjects = SubjectList<[TypedefName], ErrorDiag>;
- let Args = [ExprArgument<"NumElements">];
- let ASTNode = 0;
- let Documentation = [Undocumented];
-}
-
-def FallThrough : Attr {
- let Spellings = [CXX11<"clang", "fallthrough">];
-// let Subjects = [NullStmt];
- let Documentation = [FallthroughDocs];
-}
-
-def FastCall : InheritableAttr {
- let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">,
- Keyword<"_fastcall">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [FastCallDocs];
-}
-
-def Final : InheritableAttr {
- let Spellings = [Keyword<"final">, Keyword<"sealed">];
- let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>];
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
-def MinSize : InheritableAttr {
- let Spellings = [GNU<"minsize">];
- let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def FlagEnum : InheritableAttr {
- let Spellings = [GNU<"flag_enum">];
- let Subjects = SubjectList<[Enum]>;
- let Documentation = [FlagEnumDocs];
- let LangOpts = [COnly];
-}
-
-def Flatten : InheritableAttr {
- let Spellings = [GCC<"flatten">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [FlattenDocs];
-}
-
-def Format : InheritableAttr {
- let Spellings = [GCC<"format">];
- let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
- IntArgument<"FirstArg">];
- let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto], WarnDiag,
- "ExpectedFunctionWithProtoType">;
- let Documentation = [FormatDocs];
-}
-
-def FormatArg : InheritableAttr {
- let Spellings = [GCC<"format_arg">];
- let Args = [IntArgument<"FormatIdx">];
- let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag,
- "ExpectedFunctionWithProtoType">;
- let Documentation = [Undocumented];
-}
-
-def GNUInline : InheritableAttr {
- let Spellings = [GCC<"gnu_inline">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def Hot : InheritableAttr {
- let Spellings = [GCC<"hot">];
- let Subjects = SubjectList<[Function]>;
- // An AST node is created for this attribute, but not actually used beyond
- // semantic checking for mutual exclusion with the Cold attribute.
- let Documentation = [Undocumented];
-}
-
-def IBAction : InheritableAttr {
- let Spellings = [GNU<"ibaction">];
- let Subjects = SubjectList<[ObjCInstanceMethod], WarnDiag,
- "ExpectedObjCInstanceMethod">;
- // An AST node is created for this attribute, but is not used by other parts
- // of the compiler. However, this node needs to exist in the AST because
- // external tools rely on it.
- let Documentation = [Undocumented];
-}
-
-def IBOutlet : InheritableAttr {
- let Spellings = [GNU<"iboutlet">];
-// let Subjects = [ObjCIvar, ObjCProperty];
- let Documentation = [Undocumented];
-}
-
-def IBOutletCollection : InheritableAttr {
- let Spellings = [GNU<"iboutletcollection">];
- let Args = [TypeArgument<"Interface", 1>];
-// let Subjects = [ObjCIvar, ObjCProperty];
- let Documentation = [Undocumented];
-}
-
-def Restrict : InheritableAttr {
- let Spellings = [Declspec<"restrict">, GCC<"malloc">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def MaxFieldAlignment : InheritableAttr {
- // This attribute has no spellings as it is only ever created implicitly.
- let Spellings = [];
- let Args = [UnsignedArgument<"Alignment">];
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
-def MayAlias : InheritableAttr {
- // FIXME: this is a type attribute in GCC, but a declaration attribute here.
- let Spellings = [GCC<"may_alias">];
- let Documentation = [Undocumented];
-}
-
-def MSABI : InheritableAttr {
- let Spellings = [GCC<"ms_abi">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [MSABIDocs];
-}
-
-def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> {
- // NOTE: If you add any additional spellings, ARMInterrupt's and
- // MipsInterrupt's spellings must match.
- let Spellings = [GNU<"interrupt">];
- let Args = [UnsignedArgument<"Number">];
- let ParseKind = "Interrupt";
- let HasCustomParsing = 1;
- let Documentation = [Undocumented];
-}
-
-def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
- let Spellings = [GCC<"mips16">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> {
- // NOTE: If you add any additional spellings, ARMInterrupt's and
- // MSP430Interrupt's spellings must match.
- let Spellings = [GNU<"interrupt">];
- let Subjects = SubjectList<[Function]>;
- let Args = [EnumArgument<"Interrupt", "InterruptType",
- ["vector=sw0", "vector=sw1", "vector=hw0",
- "vector=hw1", "vector=hw2", "vector=hw3",
- "vector=hw4", "vector=hw5", "eic", ""],
- ["sw0", "sw1", "hw0", "hw1", "hw2", "hw3",
- "hw4", "hw5", "eic", "eic"]
- >];
- let ParseKind = "Interrupt";
- let Documentation = [MipsInterruptDocs];
-}
-
-def Mode : Attr {
- let Spellings = [GCC<"mode">];
- let Args = [IdentifierArgument<"Mode">];
- let Documentation = [Undocumented];
-}
-
-def Naked : InheritableAttr {
- let Spellings = [GCC<"naked">, Declspec<"naked">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def NeonPolyVectorType : TypeAttr {
- let Spellings = [GNU<"neon_polyvector_type">];
- let Args = [IntArgument<"NumElements">];
- let Documentation = [Undocumented];
-}
-
-def NeonVectorType : TypeAttr {
- let Spellings = [GNU<"neon_vector_type">];
- let Args = [IntArgument<"NumElements">];
- let Documentation = [Undocumented];
-}
-
-def ReturnsTwice : InheritableAttr {
- let Spellings = [GCC<"returns_twice">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def DisableTailCalls : InheritableAttr {
- let Spellings = [GNU<"disable_tail_calls">,
- CXX11<"clang", "disable_tail_calls">];
- let Subjects = SubjectList<[Function, ObjCMethod]>;
- let Documentation = [DisableTailCallsDocs];
-}
-
-def NoAlias : InheritableAttr {
- let Spellings = [Declspec<"noalias">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [NoAliasDocs];
-}
-
-def NoCommon : InheritableAttr {
- let Spellings = [GCC<"nocommon">];
- let Subjects = SubjectList<[Var]>;
- let Documentation = [Undocumented];
-}
-
-def NoDebug : InheritableAttr {
- let Spellings = [GCC<"nodebug">];
- let Documentation = [Undocumented];
-}
-
-def NoDuplicate : InheritableAttr {
- let Spellings = [GNU<"noduplicate">, CXX11<"clang", "noduplicate">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [NoDuplicateDocs];
-}
-
-def NoInline : InheritableAttr {
- let Spellings = [GCC<"noinline">, Declspec<"noinline">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
- let Spellings = [GCC<"nomips16">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-// This is not a TargetSpecificAttr so that is silently accepted and
-// ignored on other targets as encouraged by the OpenCL spec.
-//
-// See OpenCL 1.2 6.11.5: "It is our intention that a particular
-// implementation of OpenCL be free to ignore all attributes and the
-// resulting executable binary will produce the same result."
-//
-// However, only AMD GPU targets will emit the corresponding IR
-// attribute.
-//
-// FIXME: This provides a sub-optimal error message if you attempt to
-// use this in CUDA, since CUDA does not use the same terminology.
-def AMDGPUNumVGPR : InheritableAttr {
- let Spellings = [GNU<"amdgpu_num_vgpr">];
- let Args = [UnsignedArgument<"NumVGPR">];
- let Documentation = [AMDGPUNumVGPRDocs];
-
-// FIXME: This should be for OpenCLKernelFunction, but is not to
-// workaround needing to see kernel attribute before others to know if
-// this should be rejected on non-kernels.
- let Subjects = SubjectList<[Function], ErrorDiag,
- "ExpectedKernelFunction">;
-}
-
-def AMDGPUNumSGPR : InheritableAttr {
- let Spellings = [GNU<"amdgpu_num_sgpr">];
- let Args = [UnsignedArgument<"NumSGPR">];
- let Documentation = [AMDGPUNumSGPRDocs];
- let Subjects = SubjectList<[Function], ErrorDiag,
- "ExpectedKernelFunction">;
-}
-
-def NoSplitStack : InheritableAttr {
- let Spellings = [GCC<"no_split_stack">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [NoSplitStackDocs];
-}
-
-def NonNull : InheritableAttr {
- let Spellings = [GCC<"nonnull">];
- let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
- "ExpectedFunctionMethodOrParameter">;
- let Args = [VariadicUnsignedArgument<"Args">];
- let AdditionalMembers =
-[{bool isNonNull(unsigned idx) const {
- if (!args_size())
- return true;
- for (const auto &V : args())
- if (V == idx)
- return true;
- return false;
- } }];
- // FIXME: We should merge duplicates into a single nonnull attribute.
- let DuplicatesAllowedWhileMerging = 1;
- let Documentation = [NonNullDocs];
-}
-
-def ReturnsNonNull : InheritableAttr {
- let Spellings = [GCC<"returns_nonnull">];
- let Subjects = SubjectList<[ObjCMethod, Function], WarnDiag,
- "ExpectedFunctionOrMethod">;
- let Documentation = [ReturnsNonNullDocs];
-}
-
-// pass_object_size(N) indicates that the parameter should have
-// __builtin_object_size with Type=N evaluated on the parameter at the callsite.
-def PassObjectSize : InheritableParamAttr {
- let Spellings = [GNU<"pass_object_size">];
- let Args = [IntArgument<"Type">];
- let Subjects = SubjectList<[ParmVar]>;
- let Documentation = [PassObjectSizeDocs];
-}
-
-// Nullability type attributes.
-def TypeNonNull : TypeAttr {
- let Spellings = [Keyword<"_Nonnull">];
- let Documentation = [TypeNonNullDocs];
-}
-
-def TypeNullable : TypeAttr {
- let Spellings = [Keyword<"_Nullable">];
- let Documentation = [TypeNullableDocs];
-}
-
-def TypeNullUnspecified : TypeAttr {
- let Spellings = [Keyword<"_Null_unspecified">];
- let Documentation = [TypeNullUnspecifiedDocs];
-}
-
-def ObjCKindOf : TypeAttr {
- let Spellings = [Keyword<"__kindof">];
- let Documentation = [Undocumented];
-}
-
-def AssumeAligned : InheritableAttr {
- let Spellings = [GCC<"assume_aligned">];
- let Subjects = SubjectList<[ObjCMethod, Function]>;
- let Args = [ExprArgument<"Alignment">, ExprArgument<"Offset", 1>];
- let Documentation = [AssumeAlignedDocs];
-}
-
-def NoReturn : InheritableAttr {
- let Spellings = [GCC<"noreturn">, Declspec<"noreturn">];
- // FIXME: Does GCC allow this on the function instead?
- let Documentation = [Undocumented];
-}
-
-def NoInstrumentFunction : InheritableAttr {
- let Spellings = [GCC<"no_instrument_function">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def NotTailCalled : InheritableAttr {
- let Spellings = [GNU<"not_tail_called">, CXX11<"clang", "not_tail_called">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [NotTailCalledDocs];
-}
-
-def NoThrow : InheritableAttr {
- let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
- let Documentation = [Undocumented];
-}
-
-def NvWeak : IgnoredAttr {
- let Spellings = [GNU<"nv_weak">];
- let LangOpts = [CUDA];
-}
-
-def ObjCBridge : InheritableAttr {
- let Spellings = [GNU<"objc_bridge">];
- let Subjects = SubjectList<[Record, TypedefName], ErrorDiag,
- "ExpectedStructOrUnionOrTypedef">;
- let Args = [IdentifierArgument<"BridgedType">];
- let Documentation = [Undocumented];
-}
-
-def ObjCBridgeMutable : InheritableAttr {
- let Spellings = [GNU<"objc_bridge_mutable">];
- let Subjects = SubjectList<[Record], ErrorDiag>;
- let Args = [IdentifierArgument<"BridgedType">];
- let Documentation = [Undocumented];
-}
-
-def ObjCBridgeRelated : InheritableAttr {
- let Spellings = [GNU<"objc_bridge_related">];
- let Subjects = SubjectList<[Record], ErrorDiag>;
- let Args = [IdentifierArgument<"RelatedClass">,
- IdentifierArgument<"ClassMethod", 1>,
- IdentifierArgument<"InstanceMethod", 1>];
- let HasCustomParsing = 1;
- let Documentation = [Undocumented];
-}
-
-def NSReturnsRetained : InheritableAttr {
- let Spellings = [GNU<"ns_returns_retained">];
-// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
-}
-
-def NSReturnsNotRetained : InheritableAttr {
- let Spellings = [GNU<"ns_returns_not_retained">];
-// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
-}
-
-def NSReturnsAutoreleased : InheritableAttr {
- let Spellings = [GNU<"ns_returns_autoreleased">];
-// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
-}
-
-def NSConsumesSelf : InheritableAttr {
- let Spellings = [GNU<"ns_consumes_self">];
- let Subjects = SubjectList<[ObjCMethod]>;
- let Documentation = [Undocumented];
-}
-
-def NSConsumed : InheritableParamAttr {
- let Spellings = [GNU<"ns_consumed">];
- let Subjects = SubjectList<[ParmVar]>;
- let Documentation = [Undocumented];
-}
-
-def ObjCException : InheritableAttr {
- let Spellings = [GNU<"objc_exception">];
- let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def ObjCMethodFamily : InheritableAttr {
- let Spellings = [GNU<"objc_method_family">];
- let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
- let Args = [EnumArgument<"Family", "FamilyKind",
- ["none", "alloc", "copy", "init", "mutableCopy", "new"],
- ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init",
- "OMF_mutableCopy", "OMF_new"]>];
- let Documentation = [ObjCMethodFamilyDocs];
-}
-
-def ObjCNSObject : InheritableAttr {
- let Spellings = [GNU<"NSObject">];
- let Documentation = [Undocumented];
-}
-
-def ObjCIndependentClass : InheritableAttr {
- let Spellings = [GNU<"objc_independent_class">];
- let Documentation = [Undocumented];
-}
-
-def ObjCPreciseLifetime : InheritableAttr {
- let Spellings = [GNU<"objc_precise_lifetime">];
- let Subjects = SubjectList<[Var], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def ObjCReturnsInnerPointer : InheritableAttr {
- let Spellings = [GNU<"objc_returns_inner_pointer">];
- let Subjects = SubjectList<[ObjCMethod, ObjCProperty], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def ObjCRequiresSuper : InheritableAttr {
- let Spellings = [GNU<"objc_requires_super">];
- let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
- let Documentation = [ObjCRequiresSuperDocs];
-}
-
-def ObjCRootClass : InheritableAttr {
- let Spellings = [GNU<"objc_root_class">];
- let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def ObjCExplicitProtocolImpl : InheritableAttr {
- let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">];
- let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def ObjCDesignatedInitializer : Attr {
- let Spellings = [GNU<"objc_designated_initializer">];
- let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag,
- "ExpectedObjCInterfaceDeclInitMethod">;
- let Documentation = [Undocumented];
-}
-
-def ObjCRuntimeName : Attr {
- let Spellings = [GNU<"objc_runtime_name">];
- let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>;
- let Args = [StringArgument<"MetadataName">];
- let Documentation = [ObjCRuntimeNameDocs];
-}
-
-def ObjCBoxable : Attr {
- let Spellings = [GNU<"objc_boxable">];
- let Subjects = SubjectList<[Record], ErrorDiag, "ExpectedStructOrUnion">;
- let Documentation = [ObjCBoxableDocs];
-}
-
-def OptimizeNone : InheritableAttr {
- let Spellings = [GNU<"optnone">, CXX11<"clang", "optnone">];
- let Subjects = SubjectList<[Function, ObjCMethod]>;
- let Documentation = [OptnoneDocs];
-}
-
-def Overloadable : Attr {
- let Spellings = [GNU<"overloadable">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [OverloadableDocs];
-}
-
-def Override : InheritableAttr {
- let Spellings = [Keyword<"override">];
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
-def Ownership : InheritableAttr {
- let Spellings = [GNU<"ownership_holds">, GNU<"ownership_returns">,
- GNU<"ownership_takes">];
- let Accessors = [Accessor<"isHolds", [GNU<"ownership_holds">]>,
- Accessor<"isReturns", [GNU<"ownership_returns">]>,
- Accessor<"isTakes", [GNU<"ownership_takes">]>];
- let AdditionalMembers = [{
- enum OwnershipKind { Holds, Returns, Takes };
- OwnershipKind getOwnKind() const {
- return isHolds() ? Holds :
- isTakes() ? Takes :
- Returns;
- }
- }];
- let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">];
- let Subjects = SubjectList<[HasFunctionProto], WarnDiag,
- "ExpectedFunctionWithProtoType">;
- let Documentation = [Undocumented];
-}
-
-def Packed : InheritableAttr {
- let Spellings = [GCC<"packed">];
-// let Subjects = [Tag, Field];
- let Documentation = [Undocumented];
-}
-
-def IntelOclBicc : InheritableAttr {
- let Spellings = [GNU<"intel_ocl_bicc">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [Undocumented];
-}
-
-def Pcs : InheritableAttr {
- let Spellings = [GCC<"pcs">];
- let Args = [EnumArgument<"PCS", "PCSType",
- ["aapcs", "aapcs-vfp"],
- ["AAPCS", "AAPCS_VFP"]>];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [PcsDocs];
-}
-
-def Pure : InheritableAttr {
- let Spellings = [GCC<"pure">];
- let Documentation = [Undocumented];
-}
-
-def Regparm : TypeAttr {
- let Spellings = [GCC<"regparm">];
- let Args = [UnsignedArgument<"NumParams">];
- let Documentation = [RegparmDocs];
-}
-
-def ReqdWorkGroupSize : InheritableAttr {
- let Spellings = [GNU<"reqd_work_group_size">];
- let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
- UnsignedArgument<"ZDim">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def WorkGroupSizeHint : InheritableAttr {
- let Spellings = [GNU<"work_group_size_hint">];
- let Args = [UnsignedArgument<"XDim">,
- UnsignedArgument<"YDim">,
- UnsignedArgument<"ZDim">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def InitPriority : InheritableAttr {
- let Spellings = [GNU<"init_priority">];
- let Args = [UnsignedArgument<"Priority">];
- let Subjects = SubjectList<[Var], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def Section : InheritableAttr {
- let Spellings = [GCC<"section">, Declspec<"allocate">];
- let Args = [StringArgument<"Name">];
- let Subjects = SubjectList<[Function, GlobalVar,
- ObjCMethod, ObjCProperty], ErrorDiag,
- "ExpectedFunctionGlobalVarMethodOrProperty">;
- let Documentation = [SectionDocs];
-}
-
-def Sentinel : InheritableAttr {
- let Spellings = [GCC<"sentinel">];
- let Args = [DefaultIntArgument<"Sentinel", 0>,
- DefaultIntArgument<"NullPos", 0>];
-// let Subjects = SubjectList<[Function, ObjCMethod, Block, Var]>;
- let Documentation = [Undocumented];
-}
-
-def StdCall : InheritableAttr {
- let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [StdCallDocs];
-}
-
-def SysVABI : InheritableAttr {
- let Spellings = [GCC<"sysv_abi">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [Undocumented];
-}
-
-def ThisCall : InheritableAttr {
- let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">,
- Keyword<"_thiscall">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [ThisCallDocs];
-}
-
-def VectorCall : InheritableAttr {
- let Spellings = [GNU<"vectorcall">, Keyword<"__vectorcall">,
- Keyword<"_vectorcall">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [VectorCallDocs];
-}
-
-def Pascal : InheritableAttr {
- let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
-// let Subjects = [Function, ObjCMethod];
- let Documentation = [Undocumented];
-}
-
-def Target : InheritableAttr {
- let Spellings = [GCC<"target">];
- let Args = [StringArgument<"featuresStr">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [TargetDocs];
- let AdditionalMembers = [{
- typedef std::pair<std::vector<std::string>, StringRef> ParsedTargetAttr;
- ParsedTargetAttr parse() const {
- ParsedTargetAttr Ret;
- SmallVector<StringRef, 1> AttrFeatures;
- getFeaturesStr().split(AttrFeatures, ",");
-
- // Grab the various features and prepend a "+" to turn on the feature to
- // the backend and add them to our existing set of features.
- for (auto &Feature : AttrFeatures) {
- // Go ahead and trim whitespace rather than either erroring or
- // accepting it weirdly.
- Feature = Feature.trim();
-
- // We don't support cpu tuning this way currently.
- // TODO: Support the fpmath option. It will require checking
- // overall feature validity for the function with the rest of the
- // attributes on the function.
- if (Feature.startswith("fpmath=") || Feature.startswith("tune="))
- continue;
-
- // While we're here iterating check for a different target cpu.
- if (Feature.startswith("arch="))
- Ret.second = Feature.split("=").second.trim();
- else if (Feature.startswith("no-"))
- Ret.first.push_back("-" + Feature.split("-").second.str());
- else
- Ret.first.push_back("+" + Feature.str());
- }
- return Ret;
- }
- }];
-}
-
-def TransparentUnion : InheritableAttr {
- let Spellings = [GCC<"transparent_union">];
-// let Subjects = SubjectList<[Record, TypedefName]>;
- let Documentation = [Undocumented];
-}
-
-def Unavailable : InheritableAttr {
- let Spellings = [GNU<"unavailable">];
- let Args = [StringArgument<"Message", 1>,
- EnumArgument<"ImplicitReason", "ImplicitReason",
- ["", "", "", ""],
- ["IR_None",
- "IR_ARCForbiddenType",
- "IR_ForbiddenWeak",
- "IR_ARCForbiddenConversion",
- "IR_ARCInitReturnsUnrelated",
- "IR_ARCFieldWithOwnership"], 1, /*fake*/ 1>];
- let Documentation = [Undocumented];
-}
-
-def ArcWeakrefUnavailable : InheritableAttr {
- let Spellings = [GNU<"objc_arc_weak_reference_unavailable">];
- let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def ObjCGC : TypeAttr {
- let Spellings = [GNU<"objc_gc">];
- let Args = [IdentifierArgument<"Kind">];
- let Documentation = [Undocumented];
-}
-
-def ObjCOwnership : InheritableAttr {
- let Spellings = [GNU<"objc_ownership">];
- let Args = [IdentifierArgument<"Kind">];
- let ASTNode = 0;
- let Documentation = [Undocumented];
-}
-
-def ObjCRequiresPropertyDefs : InheritableAttr {
- let Spellings = [GNU<"objc_requires_property_definitions">];
- let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def Unused : InheritableAttr {
- let Spellings = [GCC<"unused">];
- let Subjects = SubjectList<[Var, ObjCIvar, Type, Label, Field, ObjCMethod,
- FunctionLike], WarnDiag,
- "ExpectedVariableFunctionOrLabel">;
- let Documentation = [Undocumented];
-}
-
-def Used : InheritableAttr {
- let Spellings = [GCC<"used">];
- let Documentation = [Undocumented];
-}
-
-def Uuid : InheritableAttr {
- let Spellings = [Declspec<"uuid">];
- let Args = [StringArgument<"Guid">];
-// let Subjects = SubjectList<[CXXRecord]>;
- let LangOpts = [MicrosoftExt, Borland];
- let Documentation = [Undocumented];
-}
-
-def VectorSize : TypeAttr {
- let Spellings = [GCC<"vector_size">];
- let Args = [ExprArgument<"NumBytes">];
- let Documentation = [Undocumented];
-}
-
-def VecTypeHint : InheritableAttr {
- let Spellings = [GNU<"vec_type_hint">];
- let Args = [TypeArgument<"TypeHint">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def Visibility : InheritableAttr {
- let Clone = 0;
- let Spellings = [GCC<"visibility">];
- let Args = [EnumArgument<"Visibility", "VisibilityType",
- ["default", "hidden", "internal", "protected"],
- ["Default", "Hidden", "Hidden", "Protected"]>];
- let Documentation = [Undocumented];
-}
-
-def TypeVisibility : InheritableAttr {
- let Clone = 0;
- let Spellings = [GNU<"type_visibility">, CXX11<"clang", "type_visibility">];
- let Args = [EnumArgument<"Visibility", "VisibilityType",
- ["default", "hidden", "internal", "protected"],
- ["Default", "Hidden", "Hidden", "Protected"]>];
-// let Subjects = [Tag, ObjCInterface, Namespace];
- let Documentation = [Undocumented];
-}
-
-def VecReturn : InheritableAttr {
- let Spellings = [GNU<"vecreturn">];
- let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def WarnUnused : InheritableAttr {
- let Spellings = [GNU<"warn_unused">];
- let Subjects = SubjectList<[Record]>;
- let Documentation = [Undocumented];
-}
-
-def WarnUnusedResult : InheritableAttr {
- let Spellings = [GCC<"warn_unused_result">,
- CXX11<"clang", "warn_unused_result">];
- let Subjects = SubjectList<[ObjCMethod, CXXRecord, FunctionLike], WarnDiag,
- "ExpectedFunctionMethodOrClass">;
- let Documentation = [Undocumented];
-}
-
-def Weak : InheritableAttr {
- let Spellings = [GCC<"weak">];
- let Subjects = SubjectList<[Var, Function, CXXRecord]>;
- let Documentation = [Undocumented];
-}
-
-def WeakImport : InheritableAttr {
- let Spellings = [GNU<"weak_import">];
- let Documentation = [Undocumented];
-}
-
-def WeakRef : InheritableAttr {
- let Spellings = [GCC<"weakref">];
- // A WeakRef that has an argument is treated as being an AliasAttr
- let Args = [StringArgument<"Aliasee", 1>];
- let Subjects = SubjectList<[Var, Function], ErrorDiag>;
- let Documentation = [Undocumented];
-}
-
-def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> {
- let Spellings = [GNU<"force_align_arg_pointer">];
- // Technically, this appertains to a FunctionDecl, but the target-specific
- // code silently allows anything function-like (such as typedefs or function
- // pointers), but does not apply the attribute to them.
- let Documentation = [Undocumented];
-}
-
-def NoSanitize : InheritableAttr {
- let Spellings = [GNU<"no_sanitize">, CXX11<"clang", "no_sanitize">];
- let Args = [VariadicStringArgument<"Sanitizers">];
- let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
- let Documentation = [NoSanitizeDocs];
- let AdditionalMembers = [{
- SanitizerMask getMask() const {
- SanitizerMask Mask = 0;
- for (auto SanitizerName : sanitizers()) {
- SanitizerMask ParsedMask =
- parseSanitizerValue(SanitizerName, /*AllowGroups=*/true);
- Mask |= expandSanitizerGroups(ParsedMask);
- }
- return Mask;
- }
- }];
-}
-
-// Attributes to disable a specific sanitizer. No new sanitizers should be added
-// to this list; the no_sanitize attribute should be extended instead.
-def NoSanitizeSpecific : InheritableAttr {
- let Spellings = [GCC<"no_address_safety_analysis">,
- GCC<"no_sanitize_address">,
- GCC<"no_sanitize_thread">,
- GNU<"no_sanitize_memory">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
- NoSanitizeMemoryDocs];
- let ASTNode = 0;
-}
-
-// C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
-
-def GuardedVar : InheritableAttr {
- let Spellings = [GNU<"guarded_var">];
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
- let Documentation = [Undocumented];
-}
-
-def PtGuardedVar : InheritableAttr {
- let Spellings = [GNU<"pt_guarded_var">];
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
- let Documentation = [Undocumented];
-}
-
-def Lockable : InheritableAttr {
- let Spellings = [GNU<"lockable">];
- let Subjects = SubjectList<[Record]>;
- let Documentation = [Undocumented];
- let ASTNode = 0; // Replaced by Capability
-}
-
-def ScopedLockable : InheritableAttr {
- let Spellings = [GNU<"scoped_lockable">];
- let Subjects = SubjectList<[Record]>;
- let Documentation = [Undocumented];
-}
-
-def Capability : InheritableAttr {
- let Spellings = [GNU<"capability">, CXX11<"clang", "capability">,
- GNU<"shared_capability">,
- CXX11<"clang", "shared_capability">];
- let Subjects = SubjectList<[Record, TypedefName], ErrorDiag,
- "ExpectedStructOrUnionOrTypedef">;
- let Args = [StringArgument<"Name">];
- let Accessors = [Accessor<"isShared",
- [GNU<"shared_capability">,
- CXX11<"clang","shared_capability">]>];
- let Documentation = [Undocumented];
- let AdditionalMembers = [{
- bool isMutex() const { return getName().equals_lower("mutex"); }
- bool isRole() const { return getName().equals_lower("role"); }
- }];
-}
-
-def AssertCapability : InheritableAttr {
- let Spellings = [GNU<"assert_capability">,
- CXX11<"clang", "assert_capability">,
- GNU<"assert_shared_capability">,
- CXX11<"clang", "assert_shared_capability">];
- let Subjects = SubjectList<[Function]>;
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Args = [ExprArgument<"Expr">];
- let Accessors = [Accessor<"isShared",
- [GNU<"assert_shared_capability">,
- CXX11<"clang", "assert_shared_capability">]>];
- let Documentation = [AssertCapabilityDocs];
-}
-
-def AcquireCapability : InheritableAttr {
- let Spellings = [GNU<"acquire_capability">,
- CXX11<"clang", "acquire_capability">,
- GNU<"acquire_shared_capability">,
- CXX11<"clang", "acquire_shared_capability">,
- 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 Args = [VariadicExprArgument<"Args">];
- let Accessors = [Accessor<"isShared",
- [GNU<"acquire_shared_capability">,
- CXX11<"clang", "acquire_shared_capability">,
- GNU<"shared_lock_function">]>];
- let Documentation = [AcquireCapabilityDocs];
-}
-
-def TryAcquireCapability : InheritableAttr {
- let Spellings = [GNU<"try_acquire_capability">,
- CXX11<"clang", "try_acquire_capability">,
- GNU<"try_acquire_shared_capability">,
- CXX11<"clang", "try_acquire_shared_capability">];
- let Subjects = SubjectList<[Function],
- ErrorDiag>;
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
- let Accessors = [Accessor<"isShared",
- [GNU<"try_acquire_shared_capability">,
- CXX11<"clang", "try_acquire_shared_capability">]>];
- let Documentation = [TryAcquireCapabilityDocs];
-}
-
-def ReleaseCapability : InheritableAttr {
- let Spellings = [GNU<"release_capability">,
- CXX11<"clang", "release_capability">,
- GNU<"release_shared_capability">,
- CXX11<"clang", "release_shared_capability">,
- GNU<"release_generic_capability">,
- CXX11<"clang", "release_generic_capability">,
- GNU<"unlock_function">];
- let Subjects = SubjectList<[Function]>;
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Args = [VariadicExprArgument<"Args">];
- let Accessors = [Accessor<"isShared",
- [GNU<"release_shared_capability">,
- CXX11<"clang", "release_shared_capability">]>,
- Accessor<"isGeneric",
- [GNU<"release_generic_capability">,
- CXX11<"clang", "release_generic_capability">,
- GNU<"unlock_function">]>];
- let Documentation = [ReleaseCapabilityDocs];
-}
-
-def RequiresCapability : InheritableAttr {
- let Spellings = [GNU<"requires_capability">,
- CXX11<"clang", "requires_capability">,
- GNU<"exclusive_locks_required">,
- GNU<"requires_shared_capability">,
- CXX11<"clang", "requires_shared_capability">,
- GNU<"shared_locks_required">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function]>;
- let Accessors = [Accessor<"isShared", [GNU<"requires_shared_capability">,
- GNU<"shared_locks_required">,
- CXX11<"clang","requires_shared_capability">]>];
- let Documentation = [Undocumented];
-}
-
-def NoThreadSafetyAnalysis : InheritableAttr {
- let Spellings = [GNU<"no_thread_safety_analysis">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def GuardedBy : InheritableAttr {
- let Spellings = [GNU<"guarded_by">];
- let Args = [ExprArgument<"Arg">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
- let Documentation = [Undocumented];
-}
-
-def PtGuardedBy : InheritableAttr {
- let Spellings = [GNU<"pt_guarded_by">];
- let Args = [ExprArgument<"Arg">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
- let Documentation = [Undocumented];
-}
-
-def AcquiredAfter : InheritableAttr {
- let Spellings = [GNU<"acquired_after">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
- let Documentation = [Undocumented];
-}
-
-def AcquiredBefore : InheritableAttr {
- let Spellings = [GNU<"acquired_before">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
- let Documentation = [Undocumented];
-}
-
-def AssertExclusiveLock : InheritableAttr {
- let Spellings = [GNU<"assert_exclusive_lock">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def AssertSharedLock : InheritableAttr {
- let Spellings = [GNU<"assert_shared_lock">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-// The first argument is an integer or boolean value specifying the return value
-// of a successful lock acquisition.
-def ExclusiveTrylockFunction : InheritableAttr {
- let Spellings = [GNU<"exclusive_trylock_function">];
- let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-// The first argument is an integer or boolean value specifying the return value
-// of a successful lock acquisition.
-def SharedTrylockFunction : InheritableAttr {
- let Spellings = [GNU<"shared_trylock_function">];
- let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def LockReturned : InheritableAttr {
- let Spellings = [GNU<"lock_returned">];
- let Args = [ExprArgument<"Arg">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-def LocksExcluded : InheritableAttr {
- let Spellings = [GNU<"locks_excluded">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
-}
-
-// C/C++ consumed attributes.
-
-def Consumable : InheritableAttr {
- let Spellings = [GNU<"consumable">];
- let Subjects = SubjectList<[CXXRecord]>;
- let Args = [EnumArgument<"DefaultState", "ConsumedState",
- ["unknown", "consumed", "unconsumed"],
- ["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [ConsumableDocs];
-}
-
-def ConsumableAutoCast : InheritableAttr {
- let Spellings = [GNU<"consumable_auto_cast_state">];
- let Subjects = SubjectList<[CXXRecord]>;
- let Documentation = [Undocumented];
-}
-
-def ConsumableSetOnRead : InheritableAttr {
- let Spellings = [GNU<"consumable_set_state_on_read">];
- let Subjects = SubjectList<[CXXRecord]>;
- let Documentation = [Undocumented];
-}
-
-def CallableWhen : InheritableAttr {
- let Spellings = [GNU<"callable_when">];
- let Subjects = SubjectList<[CXXMethod]>;
- let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState",
- ["unknown", "consumed", "unconsumed"],
- ["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [CallableWhenDocs];
-}
-
-def ParamTypestate : InheritableAttr {
- let Spellings = [GNU<"param_typestate">];
- let Subjects = SubjectList<[ParmVar]>;
- let Args = [EnumArgument<"ParamState", "ConsumedState",
- ["unknown", "consumed", "unconsumed"],
- ["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [ParamTypestateDocs];
-}
-
-def ReturnTypestate : InheritableAttr {
- let Spellings = [GNU<"return_typestate">];
- let Subjects = SubjectList<[Function, ParmVar]>;
- let Args = [EnumArgument<"State", "ConsumedState",
- ["unknown", "consumed", "unconsumed"],
- ["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [ReturnTypestateDocs];
-}
-
-def SetTypestate : InheritableAttr {
- let Spellings = [GNU<"set_typestate">];
- let Subjects = SubjectList<[CXXMethod]>;
- let Args = [EnumArgument<"NewState", "ConsumedState",
- ["unknown", "consumed", "unconsumed"],
- ["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [SetTypestateDocs];
-}
-
-def TestTypestate : InheritableAttr {
- let Spellings = [GNU<"test_typestate">];
- let Subjects = SubjectList<[CXXMethod]>;
- let Args = [EnumArgument<"TestState", "ConsumedState",
- ["consumed", "unconsumed"],
- ["Consumed", "Unconsumed"]>];
- let Documentation = [TestTypestateDocs];
-}
-
-// 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 Args = [IdentifierArgument<"ArgumentKind">,
- UnsignedArgument<"ArgumentIdx">,
- UnsignedArgument<"TypeTagIdx">,
- BoolArgument<"IsPointer">];
- let HasCustomParsing = 1;
- let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs];
-}
-
-def TypeTagForDatatype : InheritableAttr {
- let Spellings = [GNU<"type_tag_for_datatype">];
- let Args = [IdentifierArgument<"ArgumentKind">,
- TypeArgument<"MatchingCType">,
- BoolArgument<"LayoutCompatible">,
- BoolArgument<"MustBeNull">];
-// let Subjects = SubjectList<[Var], ErrorDiag>;
- let HasCustomParsing = 1;
- let Documentation = [TypeTagForDatatypeDocs];
-}
-
-// Microsoft-related attributes
-
-def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
- let Spellings = [Declspec<"novtable">];
- let Subjects = SubjectList<[CXXRecord]>;
- let Documentation = [MSNoVTableDocs];
-}
-
-def : IgnoredAttr {
- let Spellings = [Declspec<"property">];
-}
-
-def MSStruct : InheritableAttr {
- let Spellings = [GCC<"ms_struct">];
- let Subjects = SubjectList<[Record]>;
- let Documentation = [Undocumented];
-}
-
-def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
- let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
- let Subjects = SubjectList<[Function, Var, CXXRecord]>;
- let Documentation = [Undocumented];
-}
-
-def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
- let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
- let Subjects = SubjectList<[Function, Var, CXXRecord]>;
- let Documentation = [Undocumented];
-}
-
-def SelectAny : InheritableAttr {
- let Spellings = [Declspec<"selectany">];
- let LangOpts = [MicrosoftExt];
- let Documentation = [Undocumented];
-}
-
-def Thread : Attr {
- let Spellings = [Declspec<"thread">];
- let LangOpts = [MicrosoftExt];
- let Documentation = [ThreadDocs];
- let Subjects = SubjectList<[Var]>;
-}
-
-def Win64 : IgnoredAttr {
- let Spellings = [Keyword<"__w64">];
- let LangOpts = [MicrosoftExt];
-}
-
-def Ptr32 : TypeAttr {
- let Spellings = [Keyword<"__ptr32">];
- let Documentation = [Undocumented];
-}
-
-def Ptr64 : TypeAttr {
- let Spellings = [Keyword<"__ptr64">];
- let Documentation = [Undocumented];
-}
-
-def SPtr : TypeAttr {
- let Spellings = [Keyword<"__sptr">];
- let Documentation = [Undocumented];
-}
-
-def UPtr : TypeAttr {
- let Spellings = [Keyword<"__uptr">];
- let Documentation = [Undocumented];
-}
-
-def MSInheritance : InheritableAttr {
- let LangOpts = [MicrosoftExt];
- let Args = [DefaultBoolArgument<"BestCase", 1>];
- let Spellings = [Keyword<"__single_inheritance">,
- Keyword<"__multiple_inheritance">,
- Keyword<"__virtual_inheritance">,
- Keyword<"__unspecified_inheritance">];
- let AdditionalMembers = [{
- static bool hasVBPtrOffsetField(Spelling Inheritance) {
- return Inheritance == Keyword_unspecified_inheritance;
- }
-
- // Only member pointers to functions need a this adjustment, since it can be
- // combined with the field offset for data pointers.
- static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) {
- return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance;
- }
-
- static bool hasVBTableOffsetField(Spelling Inheritance) {
- return Inheritance >= Keyword_virtual_inheritance;
- }
-
- static bool hasOnlyOneField(bool IsMemberFunction,
- Spelling Inheritance) {
- if (IsMemberFunction)
- return Inheritance <= Keyword_single_inheritance;
- return Inheritance <= Keyword_multiple_inheritance;
- }
- }];
- let Documentation = [MSInheritanceDocs];
-}
-
-def MSVtorDisp : InheritableAttr {
- // This attribute has no spellings as it is only ever created implicitly.
- let Spellings = [];
- let Args = [UnsignedArgument<"vdm">];
- let SemaHandler = 0;
-
- let AdditionalMembers = [{
- enum Mode {
- Never,
- ForVBaseOverride,
- ForVFTable
- };
-
- Mode getVtorDispMode() const { return Mode(vdm); }
- }];
- let Documentation = [Undocumented];
-}
-
-def InitSeg : Attr {
- let Spellings = [Pragma<"", "init_seg">];
- let Args = [StringArgument<"Section">];
- let SemaHandler = 0;
- let Documentation = [InitSegDocs];
- let AdditionalMembers = [{
- void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
- OS << '(' << getSection() << ')';
- }
- }];
-}
-
-def Unaligned : IgnoredAttr {
- let Spellings = [Keyword<"__unaligned">];
-}
-
-def LoopHint : Attr {
- /// #pragma clang loop <option> directive
- /// 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.
- /// unroll: fully unroll loop if State == Enable.
- /// unroll_count: unrolls loop 'Value' times.
-
- /// #pragma unroll <argument> directive
- /// <no arg>: fully unrolls loop.
- /// boolean: fully unrolls loop if State == Enable.
- /// expression: unrolls loop 'Value' times.
-
- let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">,
- Pragma<"", "nounroll">];
-
- /// State of the loop optimization specified by the spelling.
- let Args = [EnumArgument<"Option", "OptionType",
- ["vectorize", "vectorize_width", "interleave", "interleave_count",
- "unroll", "unroll_count"],
- ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
- "Unroll", "UnrollCount"]>,
- EnumArgument<"State", "LoopHintState",
- ["enable", "disable", "numeric", "assume_safety", "full"],
- ["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>,
- ExprArgument<"Value">];
-
- let AdditionalMembers = [{
- static const char *getOptionName(int Option) {
- switch(Option) {
- case Vectorize: return "vectorize";
- case VectorizeWidth: return "vectorize_width";
- case Interleave: return "interleave";
- case InterleaveCount: return "interleave_count";
- case Unroll: return "unroll";
- case UnrollCount: return "unroll_count";
- }
- llvm_unreachable("Unhandled LoopHint option.");
- }
-
- void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
- unsigned SpellingIndex = getSpellingListIndex();
- // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
- // "nounroll" is already emitted as the pragma name.
- if (SpellingIndex == Pragma_nounroll)
- return;
- else if (SpellingIndex == Pragma_unroll) {
- OS << getValueString(Policy);
- return;
- }
-
- assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
- OS << getOptionName(option) << getValueString(Policy);
- }
-
- // Return a string containing the loop hint argument including the
- // enclosing parentheses.
- std::string getValueString(const PrintingPolicy &Policy) const {
- std::string ValueName;
- llvm::raw_string_ostream OS(ValueName);
- OS << "(";
- if (state == Numeric)
- value->printPretty(OS, nullptr, Policy);
- else if (state == Enable)
- OS << "enable";
- else if (state == Full)
- OS << "full";
- else if (state == AssumeSafety)
- OS << "assume_safety";
- else
- OS << "disable";
- OS << ")";
- return OS.str();
- }
-
- // Return a string suitable for identifying this attribute in diagnostics.
- std::string getDiagnosticName(const PrintingPolicy &Policy) const {
- unsigned SpellingIndex = getSpellingListIndex();
- if (SpellingIndex == Pragma_nounroll)
- return "#pragma nounroll";
- else if (SpellingIndex == Pragma_unroll)
- return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : "");
-
- assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
- return getOptionName(option) + getValueString(Policy);
- }
- }];
-
- let Documentation = [LoopHintDocs, UnrollHintDocs];
-}
-
-def CapturedRecord : InheritableAttr {
- // This attribute has no spellings as it is only ever created implicitly.
- let Spellings = [];
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
-def OMPThreadPrivateDecl : InheritableAttr {
- // This attribute has no spellings as it is only ever created implicitly.
- let Spellings = [];
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
-def InternalLinkage : InheritableAttr {
- let Spellings = [GNU<"internal_linkage">, CXX11<"clang", "internal_linkage">];
- let Subjects = SubjectList<[Var, Function, CXXRecord]>;
- let Documentation = [InternalLinkageDocs];
-}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
deleted file mode 100644
index 2567d55..0000000
--- a/include/clang/Basic/AttrDocs.td
+++ /dev/null
@@ -1,1861 +0,0 @@
-//==--- AttrDocs.td - Attribute documentation ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-
-def GlobalDocumentation {
- code Intro =[{..
- -------------------------------------------------------------------
- NOTE: This file is automatically generated by running clang-tblgen
- -gen-attr-docs. Do not edit this file by hand!!
- -------------------------------------------------------------------
-
-===================
-Attributes in Clang
-===================
-.. contents::
- :local:
-
-Introduction
-============
-
-This page lists the attributes currently supported by Clang.
-}];
-}
-
-def SectionDocs : Documentation {
- let Category = DocCatVariable;
- let Content = [{
-The ``section`` attribute allows you to specify a specific section a
-global variable or function should be in after translation.
- }];
- let Heading = "section (gnu::section, __declspec(allocate))";
-}
-
-def InitSegDocs : Documentation {
- let Category = DocCatVariable;
- let Content = [{
-The attribute applied by ``pragma init_seg()`` controls the section into
-which global initialization function pointers are emitted. It is only
-available with ``-fms-extensions``. Typically, this function pointer is
-emitted into ``.CRT$XCU`` on Windows. The user can change the order of
-initialization by using a different section name with the same
-``.CRT$XC`` prefix and a suffix that sorts lexicographically before or
-after the standard ``.CRT$XCU`` sections. See the init_seg_
-documentation on MSDN for more information.
-
-.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx
- }];
-}
-
-def TLSModelDocs : Documentation {
- let Category = DocCatVariable;
- let Content = [{
-The ``tls_model`` attribute allows you to specify which thread-local storage
-model to use. It accepts the following strings:
-
-* global-dynamic
-* local-dynamic
-* initial-exec
-* local-exec
-
-TLS models are mutually exclusive.
- }];
-}
-
-def ThreadDocs : Documentation {
- let Category = DocCatVariable;
- let Content = [{
-The ``__declspec(thread)`` attribute declares a variable with thread local
-storage. It is available under the ``-fms-extensions`` flag for MSVC
-compatibility. See the documentation for `__declspec(thread)`_ on MSDN.
-
-.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
-
-In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the
-GNU ``__thread`` keyword. The variable must not have a destructor and must have
-a constant initializer, if any. The attribute only applies to variables
-declared with static storage duration, such as globals, class static data
-members, and static locals.
- }];
-}
-
-def CarriesDependencyDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``carries_dependency`` attribute specifies dependency propagation into and
-out of functions.
-
-When specified on a function or Objective-C method, the ``carries_dependency``
-attribute means that the return value carries a dependency out of the function,
-so that the implementation need not constrain ordering upon return from that
-function. Implementations of the function and its caller may choose to preserve
-dependencies instead of emitting memory ordering instructions such as fences.
-
-Note, this attribute does not change the meaning of the program, but may result
-in generation of more efficient code.
- }];
-}
-
-def C11NoReturnDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-A function declared as ``_Noreturn`` shall not return to its caller. The
-compiler will generate a diagnostic for a function declared as ``_Noreturn``
-that appears to be capable of returning to its caller.
- }];
-}
-
-def CXX11NoReturnDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-A function declared as ``[[noreturn]]`` shall not return to its caller. The
-compiler will generate a diagnostic for a function declared as ``[[noreturn]]``
-that appears to be capable of returning to its caller.
- }];
-}
-
-def AssertCapabilityDocs : Documentation {
- let Category = DocCatFunction;
- let Heading = "assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability)";
- let Content = [{
-Marks a function that dynamically tests whether a capability is held, and halts
-the program if it is not held.
- }];
-}
-
-def AcquireCapabilityDocs : Documentation {
- let Category = DocCatFunction;
- let Heading = "acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability)";
- let Content = [{
-Marks a function as acquiring a capability.
- }];
-}
-
-def TryAcquireCapabilityDocs : Documentation {
- let Category = DocCatFunction;
- let Heading = "try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability)";
- let Content = [{
-Marks a function that attempts to acquire a capability. This function may fail to
-actually acquire the capability; they accept a Boolean value determining
-whether acquiring the capability means success (true), or failing to acquire
-the capability means success (false).
- }];
-}
-
-def ReleaseCapabilityDocs : Documentation {
- let Category = DocCatFunction;
- let Heading = "release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability)";
- let Content = [{
-Marks a function as releasing a capability.
- }];
-}
-
-def AssumeAlignedDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Use ``__attribute__((assume_aligned(<alignment>[,<offset>]))`` on a function
-declaration to specify that the return value of the function (which must be a
-pointer type) has the specified offset, in bytes, from an address with the
-specified alignment. The offset is taken to be zero if omitted.
-
-.. code-block:: c++
-
- // The returned pointer value has 32-byte alignment.
- void *a() __attribute__((assume_aligned (32)));
-
- // The returned pointer value is 4 bytes greater than an address having
- // 32-byte alignment.
- void *b() __attribute__((assume_aligned (32, 4)));
-
-Note that this attribute provides information to the compiler regarding a
-condition that the code already ensures is true. It does not cause the compiler
-to enforce the provided alignment assumption.
- }];
-}
-
-def EnableIfDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-.. Note:: Some features of this attribute are experimental. The meaning of
- multiple enable_if attributes on a single declaration is subject to change in
- a future version of clang. Also, the ABI is not standardized and the name
- mangling may change in future versions. To avoid that, use asm labels.
-
-The ``enable_if`` attribute can be placed on function declarations to control
-which overload is selected based on the values of the function's arguments.
-When combined with the ``overloadable`` attribute, this feature is also
-available in C.
-
-.. code-block:: 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);
- isdigit(-10); // results in a compile-time error.
- }
-
-The enable_if attribute takes two arguments, the first is an expression written
-in terms of the function parameters, the second is a string explaining why this
-overload candidate could not be selected to be displayed in diagnostics. The
-expression is part of the function signature for the purposes of determining
-whether it is a redeclaration (following the rules used when determining
-whether a C++ template specialization is ODR-equivalent), but is not part of
-the type.
-
-The enable_if expression is evaluated as if it were the body of a
-bool-returning constexpr function declared with the arguments of the function
-it is being applied to, then called with the parameters at the call site. If the
-result is false or could not be determined through constant expression
-evaluation, then this overload will not be chosen and the provided string may
-be used in a diagnostic if the compile fails as a result.
-
-Because the enable_if expression is an unevaluated context, there are no global
-state changes, nor the ability to pass information from the enable_if
-expression to the function body. For example, suppose we want calls to
-strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of
-strbuf) only if the size of strbuf can be determined:
-
-.. code-block:: c++
-
- __attribute__((always_inline))
- static inline size_t strnlen(const char *s, size_t maxlen)
- __attribute__((overloadable))
- __attribute__((enable_if(__builtin_object_size(s, 0) != -1))),
- "chosen when the buffer size is known but 'maxlen' is not")))
- {
- return strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
- }
-
-Multiple enable_if attributes may be applied to a single declaration. In this
-case, the enable_if expressions are evaluated from left to right in the
-following manner. First, the candidates whose enable_if expressions evaluate to
-false or cannot be evaluated are discarded. If the remaining candidates do not
-share ODR-equivalent enable_if expressions, the overload resolution is
-ambiguous. Otherwise, enable_if overload resolution continues with the next
-enable_if attribute on the candidates that have not been discarded and have
-remaining enable_if attributes. In this way, we pick the most specific
-overload out of a number of viable overloads using enable_if.
-
-.. code-block:: c++
-
- 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
-
-In this example, a call to f() is always resolved to #2, as the first enable_if
-expression is ODR-equivalent for both declarations, but #1 does not have another
-enable_if expression to continue evaluating, so the next round of evaluation has
-only a single candidate. In a call to g(1, 1), the call is ambiguous even though
-#2 has more enable_if attributes, because the first enable_if expressions are
-not ODR-equivalent.
-
-Query for this feature with ``__has_attribute(enable_if)``.
- }];
-}
-
-def PassObjectSizeDocs : Documentation {
- let Category = DocCatVariable; // Technically it's a parameter doc, but eh.
- let Content = [{
-.. Note:: The mangling of functions with parameters that are annotated with
- ``pass_object_size`` is subject to change. You can get around this by
- using ``__asm__("foo")`` to explicitly name your functions, thus preserving
- your ABI; also, non-overloadable C functions with ``pass_object_size`` are
- not mangled.
-
-The ``pass_object_size(Type)`` attribute can be placed on function parameters to
-instruct clang to call ``__builtin_object_size(param, Type)`` at each callsite
-of said function, and implicitly pass the result of this call in as an invisible
-argument of type ``size_t`` directly after the parameter annotated with
-``pass_object_size``. Clang will also replace any calls to
-``__builtin_object_size(param, Type)`` in the function by said implicit
-parameter.
-
-Example usage:
-
-.. code-block:: c
-
- int bzero1(char *const p __attribute__((pass_object_size(0))))
- __attribute__((noinline)) {
- int i = 0;
- for (/**/; i < (int)__builtin_object_size(p, 0); ++i) {
- p[i] = 0;
- }
- return i;
- }
-
- int main() {
- char chars[100];
- int n = bzero1(&chars[0]);
- assert(n == sizeof(chars));
- return 0;
- }
-
-If successfully evaluating ``__builtin_object_size(param, Type)`` at the
-callsite is not possible, then the "failed" value is passed in. So, using the
-definition of ``bzero1`` from above, the following code would exit cleanly:
-
-.. code-block:: c
-
- int main2(int argc, char *argv[]) {
- int n = bzero1(argv);
- assert(n == -1);
- return 0;
- }
-
-``pass_object_size`` plays a part in overload resolution. If two overload
-candidates are otherwise equally good, then the overload with one or more
-parameters with ``pass_object_size`` is preferred. This implies that the choice
-between two identical overloads both with ``pass_object_size`` on one or more
-parameters will always be ambiguous; for this reason, having two such overloads
-is illegal. For example:
-
-.. code-block:: c++
-
- #define PS(N) __attribute__((pass_object_size(N)))
- // OK
- void Foo(char *a, char *b); // Overload A
- // OK -- overload A has no parameters with pass_object_size.
- void Foo(char *a PS(0), char *b PS(0)); // Overload B
- // Error -- Same signature (sans pass_object_size) as overload B, and both
- // overloads have one or more parameters with the pass_object_size attribute.
- void Foo(void *a PS(0), void *b);
-
- // OK
- void Bar(void *a PS(0)); // Overload C
- // OK
- void Bar(char *c PS(1)); // Overload D
-
- void main() {
- char known[10], *unknown;
- Foo(unknown, unknown); // Calls overload B
- Foo(known, unknown); // Calls overload B
- Foo(unknown, known); // Calls overload B
- Foo(known, known); // Calls overload B
-
- Bar(known); // Calls overload D
- Bar(unknown); // Calls overload D
- }
-
-Currently, ``pass_object_size`` is a bit restricted in terms of its usage:
-
-* Only one use of ``pass_object_size`` is allowed per parameter.
-
-* It is an error to take the address of a function with ``pass_object_size`` on
- any of its parameters. If you wish to do this, you can create an overload
- without ``pass_object_size`` on any parameters.
-
-* It is an error to apply the ``pass_object_size`` attribute to parameters that
- are not pointers. Additionally, any parameter that ``pass_object_size`` is
- applied to must be marked ``const`` at its function's definition.
- }];
-}
-
-def OverloadableDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Clang provides support for C++ function overloading in C. Function overloading
-in C is introduced using the ``overloadable`` attribute. For example, one
-might provide several overloaded versions of a ``tgsin`` function that invokes
-the appropriate standard function computing the sine of a value with ``float``,
-``double``, or ``long double`` precision:
-
-.. code-block:: c
-
- #include <math.h>
- float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
- double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
- long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }
-
-Given these declarations, one can call ``tgsin`` with a ``float`` value to
-receive a ``float`` result, with a ``double`` to receive a ``double`` result,
-etc. Function overloading in C follows the rules of C++ function overloading
-to pick the best overload given the call arguments, with a few C-specific
-semantics:
-
-* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a
- floating-point promotion (per C99) rather than as a floating-point conversion
- (as in C++).
-
-* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is
- considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are
- compatible types.
-
-* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
- and ``U`` are compatible types. This conversion is given "conversion" rank.
-
-The declaration of ``overloadable`` functions is restricted to function
-declarations and definitions. Most importantly, if any function with a given
-name is given the ``overloadable`` attribute, then all function declarations
-and definitions with that name (and in that scope) must have the
-``overloadable`` attribute. This rule even applies to redeclarations of
-functions whose original declaration had the ``overloadable`` attribute, e.g.,
-
-.. code-block:: c
-
- int f(int) __attribute__((overloadable));
- float f(float); // error: declaration of "f" must have the "overloadable" attribute
-
- int g(int) __attribute__((overloadable));
- int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute
-
-Functions marked ``overloadable`` must have prototypes. Therefore, the
-following code is ill-formed:
-
-.. code-block:: c
-
- int h() __attribute__((overloadable)); // error: h does not have a prototype
-
-However, ``overloadable`` functions are allowed to use a ellipsis even if there
-are no named parameters (as is permitted in C++). This feature is particularly
-useful when combined with the ``unavailable`` attribute:
-
-.. code-block:: c++
-
- void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error
-
-Functions declared with the ``overloadable`` attribute have their names mangled
-according to the same rules as C++ function names. For example, the three
-``tgsin`` functions in our motivating example get the mangled names
-``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two
-caveats to this use of name mangling:
-
-* Future versions of Clang may change the name mangling of functions overloaded
- in C, so you should not depend on an specific mangling. To be completely
- safe, we strongly urge the use of ``static inline`` with ``overloadable``
- functions.
-
-* The ``overloadable`` attribute has almost no meaning when used in C++,
- because names will already be mangled and functions are already overloadable.
- However, when an ``overloadable`` function occurs within an ``extern "C"``
- linkage specification, it's name *will* be mangled in the same way as it
- would in C.
-
-Query for this feature with ``__has_extension(attribute_overloadable)``.
- }];
-}
-
-def ObjCMethodFamilyDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Many methods in Objective-C have conventional meanings determined by their
-selectors. It is sometimes useful to be able to mark a method as having a
-particular conventional meaning despite not having the right selector, or as
-not having the conventional meaning that its selector would suggest. For these
-use cases, we provide an attribute to specifically describe the "method family"
-that a method belongs to.
-
-**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of
-``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This
-attribute can only be placed at the end of a method declaration:
-
-.. code-block:: objc
-
- - (NSString *)initMyStringValue __attribute__((objc_method_family(none)));
-
-Users who do not wish to change the conventional meaning of a method, and who
-merely want to document its non-standard retain and release semantics, should
-use the retaining behavior attributes (``ns_returns_retained``,
-``ns_returns_not_retained``, etc).
-
-Query for this feature with ``__has_attribute(objc_method_family)``.
- }];
-}
-
-def NoDuplicateDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``noduplicate`` attribute can be placed on function declarations to control
-whether function calls to this function can be duplicated or not as a result of
-optimizations. This is required for the implementation of functions with
-certain special requirements, like the OpenCL "barrier" function, that might
-need to be run concurrently by all the threads that are executing in lockstep
-on the hardware. For example this attribute applied on the function
-"nodupfunc" in the code below avoids that:
-
-.. code-block:: c
-
- void nodupfunc() __attribute__((noduplicate));
- // Setting it as a C++11 attribute is also valid
- // void nodupfunc() [[clang::noduplicate]];
- void foo();
- void bar();
-
- nodupfunc();
- if (a > n) {
- foo();
- } else {
- bar();
- }
-
-gets possibly modified by some optimizations into code similar to this:
-
-.. code-block:: c
-
- if (a > n) {
- nodupfunc();
- foo();
- } else {
- nodupfunc();
- bar();
- }
-
-where the call to "nodupfunc" is duplicated and sunk into the two branches
-of the condition.
- }];
-}
-
-def NoSplitStackDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``no_split_stack`` attribute disables the emission of the split stack
-preamble for a particular function. It has no effect if ``-fsplit-stack``
-is not specified.
- }];
-}
-
-def ObjCRequiresSuperDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Some Objective-C classes allow a subclass to override a particular method in a
-parent class but expect that the overriding method also calls the overridden
-method in the parent class. For these cases, we provide an attribute to
-designate that a method requires a "call to ``super``" in the overriding
-method in the subclass.
-
-**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only
-be placed at the end of a method declaration:
-
-.. code-block:: objc
-
- - (void)foo __attribute__((objc_requires_super));
-
-This attribute can only be applied the method declarations within a class, and
-not a protocol. Currently this attribute does not enforce any placement of
-where the call occurs in the overriding method (such as in the case of
-``-dealloc`` where the call must appear at the end). It checks only that it
-exists.
-
-Note that on both OS X and iOS that the Foundation framework provides a
-convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this
-attribute:
-
-.. code-block:: objc
-
- - (void)foo NS_REQUIRES_SUPER;
-
-This macro is conditionally defined depending on the compiler's support for
-this attribute. If the compiler does not support the attribute the macro
-expands to nothing.
-
-Operationally, when a method has this annotation the compiler will warn if the
-implementation of an override in a subclass does not call super. For example:
-
-.. code-block:: objc
-
- warning: method possibly missing a [super AnnotMeth] call
- - (void) AnnotMeth{};
- ^
- }];
-}
-
-def ObjCRuntimeNameDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-By default, the Objective-C interface or protocol identifier is used
-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
-
- }];
-}
-
-def ObjCBoxableDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Structs and unions marked with the ``objc_boxable`` attribute can be used
-with the Objective-C boxed expression syntax, ``@(...)``.
-
-**Usage**: ``__attribute__((objc_boxable))``. This attribute
-can only be placed on a declaration of a trivially-copyable struct or union:
-
-.. code-block:: objc
-
- struct __attribute__((objc_boxable)) some_struct {
- int i;
- };
- union __attribute__((objc_boxable)) some_union {
- int i;
- float f;
- };
- typedef struct __attribute__((objc_boxable)) _some_struct some_struct;
-
- // ...
-
- some_struct ss;
- NSValue *boxed = @(ss);
-
- }];
-}
-
-def AvailabilityDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``availability`` attribute can be placed on declarations to describe the
-lifecycle of that declaration relative to operating system versions. Consider
-the function declaration for a hypothetical function ``f``:
-
-.. code-block:: c++
-
- void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
-
-The availability attribute states that ``f`` was introduced in Mac OS X 10.4,
-deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information
-is used by Clang to determine when it is safe to use ``f``: for example, if
-Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()``
-succeeds. If Clang is instructed to compile code for Mac OS X 10.6, the call
-succeeds but Clang emits a warning specifying that the function is deprecated.
-Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call
-fails because ``f()`` is no longer available.
-
-The availability attribute is a comma-separated list starting with the
-platform name and then including clauses specifying important milestones in the
-declaration's lifetime (in any order) along with additional information. Those
-clauses can be:
-
-introduced=\ *version*
- The first version in which this declaration was introduced.
-
-deprecated=\ *version*
- The first version in which this declaration was deprecated, meaning that
- users should migrate away from this API.
-
-obsoleted=\ *version*
- The first version in which this declaration was obsoleted, meaning that it
- was removed completely and can no longer be used.
-
-unavailable
- This declaration is never available on this platform.
-
-message=\ *string-literal*
- Additional message text that Clang will provide when emitting a warning or
- error about use of a deprecated or obsoleted declaration. Useful to direct
- users to replacement APIs.
-
-Multiple availability attributes can be placed on a declaration, which may
-correspond to different platforms. Only the availability attribute with the
-platform corresponding to the target platform will be used; any others will be
-ignored. If no availability attribute specifies availability for the current
-target platform, the availability attributes are ignored. Supported platforms
-are:
-
-``ios``
- Apple's iOS operating system. The minimum deployment target is specified by
- the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*``
- command-line arguments.
-
-``macosx``
- Apple's Mac OS X operating system. The minimum deployment target is
- specified by the ``-mmacosx-version-min=*version*`` command-line argument.
-
-``tvos``
- Apple's tvOS operating system. The minimum deployment target is specified by
- the ``-mtvos-version-min=*version*`` command-line argument.
-
-``watchos``
- Apple's watchOS operating system. The minimum deployment target is specified by
- the ``-mwatchos-version-min=*version*`` command-line argument.
-
-A declaration can be used even when deploying back to a platform version prior
-to when the declaration was introduced. When this happens, the declaration is
-`weakly linked
-<https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_,
-as if the ``weak_import`` attribute were added to the declaration. A
-weakly-linked declaration may or may not be present a run-time, and a program
-can determine whether the declaration is present by checking whether the
-address of that declaration is non-NULL.
-
-If there are multiple declarations of the same entity, the availability
-attributes must either match on a per-platform basis or later
-declarations must not have availability attributes for that
-platform. For example:
-
-.. code-block:: c
-
- void g(void) __attribute__((availability(macosx,introduced=10.4)));
- void g(void) __attribute__((availability(macosx,introduced=10.4))); // okay, matches
- void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform
- void g(void); // okay, inherits both macosx and ios availability from above.
- void g(void) __attribute__((availability(macosx,introduced=10.5))); // error: mismatch
-
-When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,:
-
-.. code-block:: objc
-
- @interface A
- - (id)method __attribute__((availability(macosx,introduced=10.4)));
- - (id)method2 __attribute__((availability(macosx,introduced=10.4)));
- @end
-
- @interface B : A
- - (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later
- - (id)method __attribute__((availability(macosx,introduced=10.5))); // error: this method was available via the base class in 10.4
- @end
- }];
-}
-
-def FallthroughDocs : Documentation {
- let Category = DocCatStmt;
- let Content = [{
-The ``clang::fallthrough`` attribute is used along with the
-``-Wimplicit-fallthrough`` argument to annotate intentional fall-through
-between switch labels. It can only be applied to a null statement placed at a
-point of execution between any statement and the next switch label. It is
-common to mark these places with a specific comment, but this attribute is
-meant to replace comments with a more strict annotation, which can be checked
-by the compiler. This attribute doesn't change semantics of the code and can
-be used wherever an intended fall-through occurs. It is designed to mimic
-control-flow statements like ``break;``, so it can be placed in most places
-where ``break;`` can, but only if there are no statements on the execution path
-between it and the next switch label.
-
-Here is an example:
-
-.. code-block:: c++
-
- // compile with -Wimplicit-fallthrough
- switch (n) {
- case 22:
- case 33: // no warning: no statements between case labels
- f();
- case 44: // warning: unannotated fall-through
- g();
- [[clang::fallthrough]];
- case 55: // no warning
- if (x) {
- h();
- break;
- }
- else {
- i();
- [[clang::fallthrough]];
- }
- case 66: // no warning
- p();
- [[clang::fallthrough]]; // warning: fallthrough annotation does not
- // directly precede case label
- q();
- case 77: // warning: unannotated fall-through
- r();
- }
- }];
-}
-
-def ARMInterruptDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on
-ARM 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.
-
-The parameter passed to the interrupt attribute is optional, but if
-provided it must be a string literal with one of the following values: "IRQ",
-"FIQ", "SWI", "ABORT", "UNDEF".
-
-The semantics are as follows:
-
-- If the function is AAPCS, Clang instructs the backend to realign the stack to
- 8 bytes on entry. This is a general requirement of the AAPCS at public
- interfaces, but may not hold when an exception is taken. Doing this allows
- other AAPCS functions to be called.
-- If the CPU is M-class this is all that needs to be done since the architecture
- itself is designed in such a way that functions obeying the normal AAPCS ABI
- constraints are valid exception handlers.
-- If the CPU is not M-class, the prologue and epilogue are modified to save all
- non-banked registers that are used, so that upon return the user-mode state
- will not be corrupted. Note that to avoid unnecessary overhead, only
- general-purpose (integer) registers are saved in this way. If VFP operations
- are needed, that state must be saved manually.
-
- Specifically, interrupt kinds other than "FIQ" will save all core registers
- except "lr" and "sp". "FIQ" interrupts will save r0-r7.
-- If the CPU is not M-class, the return instruction is changed to one of the
- canonical sequences permitted by the architecture for exception return. Where
- possible the function itself will make the necessary "lr" adjustments so that
- the "preferred return address" is selected.
-
- Unfortunately the compiler is unable to make this guarantee for an "UNDEF"
- handler, where the offset from "lr" to the preferred return address depends on
- the execution state of the code which generated the exception. In this case
- a sequence equivalent to "movs pc, lr" will be used.
- }];
-}
-
-def MipsInterruptDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on
-MIPS 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.
-
-By default, the compiler will produce a function prologue and epilogue suitable for
-an interrupt service routine that handles an External Interrupt Controller (eic)
-generated interrupt. This behaviour can be explicitly requested with the "eic"
-argument.
-
-Otherwise, for use with vectored interrupt mode, the argument passed should be
-of the form "vector=LEVEL" where LEVEL is one of the following values:
-"sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5". The compiler will
-then set the interrupt mask to the corresponding level which will mask all
-interrupts up to and including the argument.
-
-The semantics are as follows:
-
-- The prologue is modified so that the Exception Program Counter (EPC) and
- Status coprocessor registers are saved to the stack. The interrupt mask is
- set so that the function can only be interrupted by a higher priority
- interrupt. The epilogue will restore the previous values of EPC and Status.
-
-- The prologue and epilogue are modified to save and restore all non-kernel
- registers as necessary.
-
-- The FPU is disabled in the prologue, as the floating pointer registers are not
- spilled to the stack.
-
-- The function return sequence is changed to use an exception return instruction.
-
-- The parameter sets the interrupt mask for the function corresponding to the
- interrupt level specified. If no mask is specified the interrupt mask
- defaults to "eic".
- }];
-}
-
-def TargetDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Clang supports the GNU style ``__attribute__((target("OPTIONS")))`` attribute.
-This attribute may be attached to a function definition and instructs
-the backend to use different code generation options than were passed on the
-command line.
-
-The current set of options correspond to the existing "subtarget features" for
-the target with or without a "-mno-" in front corresponding to the absence
-of the feature, as well as ``arch="CPU"`` which will change the default "CPU"
-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.
-}];
-}
-
-def DocCatAMDGPURegisterAttributes :
- DocumentationCategory<"AMD GPU Register Attributes"> {
- let Content = [{
-Clang supports attributes for controlling register usage on AMD GPU
-targets. These attributes may be attached to a kernel function
-definition and is an optimization hint to the backend for the maximum
-number of registers to use. This is useful in cases where register
-limited occupancy is known to be an important factor for the
-performance for the kernel.
-
-The semantics are as follows:
-
-- The backend will attempt to limit the number of used registers to
- the specified value, but the exact number used is not
- guaranteed. The number used may be rounded up to satisfy the
- allocation requirements or ABI constraints of the subtarget. For
- example, on Southern Islands VGPRs may only be allocated in
- increments of 4, so requesting a limit of 39 VGPRs will really
- attempt to use up to 40. Requesting more registers than the
- subtarget supports will truncate to the maximum allowed. The backend
- may also use fewer registers than requested whenever possible.
-
-- 0 implies the default no limit on register usage.
-
-- Ignored on older VLIW subtargets which did not have separate scalar
- and vector registers, R600 through Northern Islands.
-
-}];
-}
-
-
-def AMDGPUNumVGPRDocs : Documentation {
- let Category = DocCatAMDGPURegisterAttributes;
- let Content = [{
-Clang supports the
-``__attribute__((amdgpu_num_vgpr(<num_registers>)))`` attribute on AMD
-Southern Islands GPUs and later for controlling the number of vector
-registers. A typical value would be between 4 and 256 in increments
-of 4.
-}];
-}
-
-def AMDGPUNumSGPRDocs : Documentation {
- let Category = DocCatAMDGPURegisterAttributes;
- let Content = [{
-
-Clang supports the
-``__attribute__((amdgpu_num_sgpr(<num_registers>)))`` attribute on AMD
-Southern Islands GPUs and later for controlling the number of scalar
-registers. A typical value would be between 8 and 104 in increments of
-8.
-
-Due to common instruction constraints, an additional 2-4 SGPRs are
-typically required for internal use depending on features used. This
-value is a hint for the total number of SGPRs to use, and not the
-number of user SGPRs, so no special consideration needs to be given
-for these.
-}];
-}
-
-def DocCatCallingConvs : DocumentationCategory<"Calling Conventions"> {
- let Content = [{
-Clang supports several different calling conventions, depending on the target
-platform and architecture. The calling convention used for a function determines
-how parameters are passed, how results are returned to the caller, and other
-low-level details of calling a function.
- }];
-}
-
-def PcsDocs : Documentation {
- let Category = DocCatCallingConvs;
- let Content = [{
-On ARM targets, this attribute can be used to select calling conventions
-similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
-"aapcs-vfp".
- }];
-}
-
-def RegparmDocs : Documentation {
- let Category = DocCatCallingConvs;
- let Content = [{
-On 32-bit x86 targets, the regparm attribute causes the compiler to pass
-the first three integer parameters in EAX, EDX, and ECX instead of on the
-stack. This attribute has no effect on variadic functions, and all parameters
-are passed via the stack as normal.
- }];
-}
-
-def SysVABIDocs : Documentation {
- let Category = DocCatCallingConvs;
- let Content = [{
-On Windows x86_64 targets, this attribute changes the calling convention of a
-function to match the default convention used on Sys V targets such as Linux,
-Mac, and BSD. This attribute has no effect on other targets.
- }];
-}
-
-def MSABIDocs : Documentation {
- let Category = DocCatCallingConvs;
- let Content = [{
-On non-Windows x86_64 targets, this attribute changes the calling convention of
-a function to match the default convention used on Windows x86_64. This
-attribute has no effect on Windows targets or non-x86_64 targets.
- }];
-}
-
-def StdCallDocs : Documentation {
- let Category = DocCatCallingConvs;
- let Content = [{
-On 32-bit x86 targets, this attribute changes the calling convention of a
-function to clear parameters off of the stack on return. This convention does
-not support variadic calls or unprototyped functions in C, and has no effect on
-x86_64 targets. This calling convention is used widely by the Windows API and
-COM applications. See the documentation for `__stdcall`_ on MSDN.
-
-.. _`__stdcall`: http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
- }];
-}
-
-def FastCallDocs : Documentation {
- let Category = DocCatCallingConvs;
- let Content = [{
-On 32-bit x86 targets, this attribute changes the calling convention of a
-function to use ECX and EDX as register parameters and clear parameters off of
-the stack on return. This convention does not support variadic calls or
-unprototyped functions in C, and has no effect on x86_64 targets. This calling
-convention is supported primarily for compatibility with existing code. Users
-seeking register parameters should use the ``regparm`` attribute, which does
-not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN.
-
-.. _`__fastcall`: http://msdn.microsoft.com/en-us/library/6xa169sk.aspx
- }];
-}
-
-def ThisCallDocs : Documentation {
- let Category = DocCatCallingConvs;
- let Content = [{
-On 32-bit x86 targets, this attribute changes the calling convention of a
-function to use ECX for the first parameter (typically the implicit ``this``
-parameter of C++ methods) and clear parameters off of the stack on return. This
-convention does not support variadic calls or unprototyped functions in C, and
-has no effect on x86_64 targets. See the documentation for `__thiscall`_ on
-MSDN.
-
-.. _`__thiscall`: http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx
- }];
-}
-
-def VectorCallDocs : Documentation {
- let Category = DocCatCallingConvs;
- let Content = [{
-On 32-bit x86 *and* x86_64 targets, this attribute changes the calling
-convention of a function to pass vector parameters in SSE registers.
-
-On 32-bit x86 targets, this calling convention is similar to ``__fastcall``.
-The first two integer parameters are passed in ECX and EDX. Subsequent integer
-parameters are passed in memory, and callee clears the stack. On x86_64
-targets, the callee does *not* clear the stack, and integer parameters are
-passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling
-convention.
-
-On both 32-bit x86 and x86_64 targets, vector and floating point arguments are
-passed in XMM0-XMM5. Homogenous vector aggregates of up to four elements are
-passed in sequential SSE registers if enough are available. If AVX is enabled,
-256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that
-cannot be passed in registers for any reason is passed by reference, which
-allows the caller to align the parameter memory.
-
-See the documentation for `__vectorcall`_ on MSDN for more details.
-
-.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx
- }];
-}
-
-def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> {
- let Content = [{
-Clang supports additional attributes for checking basic resource management
-properties, specifically for unique objects that have a single owning reference.
-The following attributes are currently supported, although **the implementation
-for these annotations is currently in development and are subject to change.**
- }];
-}
-
-def SetTypestateDocs : Documentation {
- let Category = DocCatConsumed;
- let Content = [{
-Annotate methods that transition an object into a new state with
-``__attribute__((set_typestate(new_state)))``. The new state must be
-unconsumed, consumed, or unknown.
- }];
-}
-
-def CallableWhenDocs : Documentation {
- let Category = DocCatConsumed;
- let Content = [{
-Use ``__attribute__((callable_when(...)))`` to indicate what states a method
-may be called in. Valid states are unconsumed, consumed, or unknown. Each
-argument to this attribute must be a quoted string. E.g.:
-
-``__attribute__((callable_when("unconsumed", "unknown")))``
- }];
-}
-
-def TestTypestateDocs : Documentation {
- let Category = DocCatConsumed;
- let Content = [{
-Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method
-returns true if the object is in the specified state..
- }];
-}
-
-def ParamTypestateDocs : Documentation {
- let Category = DocCatConsumed;
- let Content = [{
-This attribute specifies expectations about function parameters. Calls to an
-function with annotated parameters will issue a warning if the corresponding
-argument isn't in the expected state. The attribute is also used to set the
-initial state of the parameter when analyzing the function's body.
- }];
-}
-
-def ReturnTypestateDocs : Documentation {
- let Category = DocCatConsumed;
- let Content = [{
-The ``return_typestate`` attribute can be applied to functions or parameters.
-When applied to a function the attribute specifies the state of the returned
-value. The function's body is checked to ensure that it always returns a value
-in the specified state. On the caller side, values returned by the annotated
-function are initialized to the given state.
-
-When applied to a function parameter it modifies the state of an argument after
-a call to the function returns. The function's body is checked to ensure that
-the parameter is in the expected state before returning.
- }];
-}
-
-def ConsumableDocs : Documentation {
- let Category = DocCatConsumed;
- let Content = [{
-Each ``class`` that uses any of the typestate annotations must first be marked
-using the ``consumable`` attribute. Failure to do so will result in a warning.
-
-This attribute accepts a single parameter that must be one of the following:
-``unknown``, ``consumed``, or ``unconsumed``.
- }];
-}
-
-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.
-
-See :ref:`Controlling Code Generation <controlling-code-generation>` for a
-full list of supported sanitizer flags.
- }];
-}
-
-def NoSanitizeAddressDocs : Documentation {
- let Category = DocCatFunction;
- // This function has multiple distinct spellings, and so it requires a custom
- // heading to be specified. The most common spelling is sufficient.
- let Heading = "no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address)";
- 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.
- }];
-}
-
-def NoSanitizeThreadDocs : Documentation {
- let Category = DocCatFunction;
- let Heading = "no_sanitize_thread";
- let Content = [{
-.. _langext-thread_sanitizer:
-
-Use ``__attribute__((no_sanitize_thread))`` on a function declaration to
-specify that checks for data races on plain (non-atomic) memory accesses should
-not be inserted by ThreadSanitizer. The function is still instrumented by the
-tool to avoid false positives and provide meaningful stack traces.
- }];
-}
-
-def NoSanitizeMemoryDocs : Documentation {
- let Category = DocCatFunction;
- let Heading = "no_sanitize_memory";
- let Content = [{
-.. _langext-memory_sanitizer:
-
-Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
-specify that checks for uninitialized memory should not be inserted
-(e.g. by MemorySanitizer). The function may still be instrumented by the tool
-to avoid false positives in other places.
- }];
-}
-
-def DocCatTypeSafety : DocumentationCategory<"Type Safety Checking"> {
- let Content = [{
-Clang supports additional attributes to enable checking type safety properties
-that can't be enforced by the C type system. Use cases include:
-
-* MPI library implementations, where these attributes enable checking that
- the buffer type matches the passed ``MPI_Datatype``;
-* for HDF5 library there is a similar use case to MPI;
-* checking types of variadic functions' arguments for functions like
- ``fcntl()`` and ``ioctl()``.
-
-You can detect support for these attributes with ``__has_attribute()``. For
-example:
-
-.. code-block:: c++
-
- #if defined(__has_attribute)
- # if __has_attribute(argument_with_type_tag) && \
- __has_attribute(pointer_with_type_tag) && \
- __has_attribute(type_tag_for_datatype)
- # define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx)))
- /* ... other macros ... */
- # endif
- #endif
-
- #if !defined(ATTR_MPI_PWT)
- # define ATTR_MPI_PWT(buffer_idx, type_idx)
- #endif
-
- int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
- ATTR_MPI_PWT(1,3);
- }];
-}
-
-def ArgumentWithTypeTagDocs : Documentation {
- let Category = DocCatTypeSafety;
- let Heading = "argument_with_type_tag";
- let Content = [{
-Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,
-type_tag_idx)))`` on a function declaration to specify that the function
-accepts a type tag that determines the type of some other argument.
-``arg_kind`` is an identifier that should be used when annotating all
-applicable type tags.
-
-This attribute is primarily useful for checking arguments of variadic functions
-(``pointer_with_type_tag`` can be used in most non-variadic cases).
-
-For example:
-
-.. code-block:: c++
-
- int fcntl(int fd, int cmd, ...)
- __attribute__(( argument_with_type_tag(fcntl,3,2) ));
- }];
-}
-
-def PointerWithTypeTagDocs : Documentation {
- let Category = DocCatTypeSafety;
- let Heading = "pointer_with_type_tag";
- let Content = [{
-Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``
-on a function declaration to specify that the function accepts a type tag that
-determines the pointee type of some other pointer argument.
-
-For example:
-
-.. code-block:: c++
-
- int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
- __attribute__(( pointer_with_type_tag(mpi,1,3) ));
- }];
-}
-
-def TypeTagForDatatypeDocs : Documentation {
- let Category = DocCatTypeSafety;
- let Content = [{
-Clang supports annotating type tags of two forms.
-
-* **Type tag that is an expression containing a reference to some declared
- identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a
- declaration with that identifier:
-
- .. code-block:: c++
-
- extern struct mpi_datatype mpi_datatype_int
- __attribute__(( type_tag_for_datatype(mpi,int) ));
- #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
-
-* **Type tag that is an integral literal.** Introduce a ``static const``
- variable with a corresponding initializer value and attach
- ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration,
- for example:
-
- .. code-block:: c++
-
- #define MPI_INT ((MPI_Datatype) 42)
- static const MPI_Datatype mpi_datatype_int
- __attribute__(( type_tag_for_datatype(mpi,int) )) = 42
-
-The attribute also accepts an optional third argument that determines how the
-expression is compared to the type tag. There are two supported flags:
-
-* ``layout_compatible`` will cause types to be compared according to
- layout-compatibility rules (C++11 [class.mem] p 17, 18). This is
- implemented to support annotating types like ``MPI_DOUBLE_INT``.
-
- For example:
-
- .. code-block:: c++
-
- /* In mpi.h */
- struct internal_mpi_double_int { double d; int i; };
- extern struct mpi_datatype mpi_datatype_double_int
- __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) ));
-
- #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
-
- /* In user code */
- struct my_pair { double a; int b; };
- struct my_pair *buffer;
- MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning
-
- struct my_int_pair { int a; int b; }
- struct my_int_pair *buffer2;
- MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element
- // type 'struct my_int_pair'
- // doesn't match specified MPI_Datatype
-
-* ``must_be_null`` specifies that the expression should be a null pointer
- constant, for example:
-
- .. code-block:: c++
-
- /* In mpi.h */
- extern struct mpi_datatype mpi_datatype_null
- __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
-
- #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
-
- /* In user code */
- MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL
- // was specified but buffer
- // is not a null pointer
- }];
-}
-
-def FlattenDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``flatten`` attribute causes calls within the attributed function to
-be inlined unless it is impossible to do so, for example if the body of the
-callee is unavailable or if the callee has the ``noinline`` attribute.
- }];
-}
-
-def FormatDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-
-Clang supports the ``format`` attribute, which indicates that the function
-accepts a ``printf`` or ``scanf``-like format string and corresponding
-arguments or a ``va_list`` that contains these arguments.
-
-Please see `GCC documentation about format attribute
-<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details
-about attribute syntax.
-
-Clang implements two kinds of checks with this attribute.
-
-#. Clang checks that the function with the ``format`` attribute is called with
- a format string that uses format specifiers that are allowed, and that
- arguments match the format string. This is the ``-Wformat`` warning, it is
- on by default.
-
-#. Clang checks that the format string argument is a literal string. This is
- the ``-Wformat-nonliteral`` warning, it is off by default.
-
- Clang implements this mostly the same way as GCC, but there is a difference
- for functions that accept a ``va_list`` argument (for example, ``vprintf``).
- GCC does not emit ``-Wformat-nonliteral`` warning for calls to such
- functions. Clang does not warn if the format string comes from a function
- parameter, where the function is annotated with a compatible attribute,
- otherwise it warns. For example:
-
- .. code-block:: c
-
- __attribute__((__format__ (__scanf__, 1, 3)))
- void foo(const char* s, char *buf, ...) {
- va_list ap;
- va_start(ap, buf);
-
- vprintf(s, ap); // warning: format string is not a string literal
- }
-
- In this case we warn because ``s`` contains a format string for a
- ``scanf``-like function, but it is passed to a ``printf``-like function.
-
- If the attribute is removed, clang still warns, because the format string is
- not a string literal.
-
- Another example:
-
- .. code-block:: c
-
- __attribute__((__format__ (__printf__, 1, 3)))
- void foo(const char* s, char *buf, ...) {
- va_list ap;
- va_start(ap, buf);
-
- vprintf(s, ap); // warning
- }
-
- In this case Clang does not warn because the format string ``s`` and
- the corresponding arguments are annotated. If the arguments are
- incorrect, the caller of ``foo`` will receive a warning.
- }];
-}
-
-def AlignValueDocs : Documentation {
- let Category = DocCatType;
- let Content = [{
-The align_value attribute can be added to the typedef of a pointer type or the
-declaration of a variable of pointer or reference type. It specifies that the
-pointer will point to, or the reference will bind to, only objects with at
-least the provided alignment. This alignment value must be some positive power
-of 2.
-
- .. code-block:: c
-
- typedef double * aligned_double_ptr __attribute__((align_value(64)));
- void foo(double & x __attribute__((align_value(128)),
- aligned_double_ptr y) { ... }
-
-If the pointer value does not have the specified alignment at runtime, the
-behavior of the program is undefined.
- }];
-}
-
-def FlagEnumDocs : Documentation {
- let Category = DocCatType;
- let Content = [{
-This attribute can be added to an enumerator to signal to the compiler that it
-is intended to be used as a flag type. This will cause the compiler to assume
-that the range of the type includes all of the values that you can get by
-manipulating bits of the enumerator when issuing warnings.
- }];
-}
-
-def MSInheritanceDocs : Documentation {
- let Category = DocCatType;
- let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
- let Content = [{
-This collection of keywords is enabled under ``-fms-extensions`` and controls
-the pointer-to-member representation used on ``*-*-win32`` targets.
-
-The ``*-*-win32`` targets utilize a pointer-to-member representation which
-varies in size and alignment depending on the definition of the underlying
-class.
-
-However, this is problematic when a forward declaration is only available and
-no definition has been made yet. In such cases, Clang is forced to utilize the
-most general representation that is available to it.
-
-These keywords make it possible to use a pointer-to-member representation other
-than the most general one regardless of whether or not the definition will ever
-be present in the current translation unit.
-
-This family of keywords belong between the ``class-key`` and ``class-name``:
-
-.. code-block:: c++
-
- struct __single_inheritance S;
- int S::*i;
- struct S {};
-
-This keyword can be applied to class templates but only has an effect when used
-on full specializations:
-
-.. code-block:: c++
-
- template <typename T, typename U> struct __single_inheritance A; // warning: inheritance model ignored on primary template
- template <typename T> struct __multiple_inheritance A<T, T>; // warning: inheritance model ignored on partial specialization
- template <> struct __single_inheritance A<int, float>;
-
-Note that choosing an inheritance model less general than strictly necessary is
-an error:
-
-.. code-block:: c++
-
- struct __multiple_inheritance S; // error: inheritance model does not match definition
- int S::*i;
- struct S {};
-}];
-}
-
-def MSNoVTableDocs : Documentation {
- let Category = DocCatType;
- let Content = [{
-This attribute can be added to a class declaration or definition to signal to
-the compiler that constructors and destructors will not reference the virtual
-function table. It is only supported when using the Microsoft C++ ABI.
- }];
-}
-
-def OptnoneDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``optnone`` attribute suppresses essentially all optimizations
-on a function or method, regardless of the optimization level applied to
-the compilation unit as a whole. This is particularly useful when you
-need to debug a particular function, but it is infeasible to build the
-entire application without optimization. Avoiding optimization on the
-specified function can improve the quality of the debugging information
-for that function.
-
-This attribute is incompatible with the ``always_inline`` and ``minsize``
-attributes.
- }];
-}
-
-def LoopHintDocs : Documentation {
- let Category = DocCatStmt;
- let Heading = "#pragma clang loop";
- let Content = [{
-The ``#pragma clang loop`` directive allows loop optimization hints to be
-specified for the subsequent loop. The directive allows vectorization,
-interleaving, and unrolling to be enabled or disabled. Vector width as well
-as interleave and unrolling count can be manually specified. See
-`language extensions
-<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
-for details.
- }];
-}
-
-def UnrollHintDocs : Documentation {
- let Category = DocCatStmt;
- let Heading = "#pragma unroll, #pragma nounroll";
- let Content = [{
-Loop unrolling optimization hints can be specified with ``#pragma unroll`` and
-``#pragma nounroll``. The pragma is placed immediately before a for, while,
-do-while, or c++11 range-based for loop.
-
-Specifying ``#pragma unroll`` without a parameter directs the loop unroller to
-attempt to fully unroll the loop if the trip count is known at compile time and
-attempt to partially unroll the loop if the trip count is not known at compile
-time:
-
-.. code-block:: c++
-
- #pragma unroll
- for (...) {
- ...
- }
-
-Specifying the optional parameter, ``#pragma unroll _value_``, directs the
-unroller to unroll the loop ``_value_`` times. The parameter may optionally be
-enclosed in parentheses:
-
-.. code-block:: c++
-
- #pragma unroll 16
- for (...) {
- ...
- }
-
- #pragma unroll(16)
- for (...) {
- ...
- }
-
-Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled:
-
-.. code-block:: c++
-
- #pragma nounroll
- for (...) {
- ...
- }
-
-``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to
-``#pragma clang loop unroll(full)`` and
-``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll``
-is equivalent to ``#pragma clang loop unroll(disable)``. See
-`language extensions
-<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
-for further details including limitations of the unroll hints.
- }];
-}
-
-def DocOpenCLAddressSpaces : DocumentationCategory<"OpenCL Address Spaces"> {
- let Content = [{
-The address space qualifier may be used to specify the region of memory that is
-used to allocate the object. OpenCL supports the following address spaces:
-__generic(generic), __global(global), __local(local), __private(private),
-__constant(constant).
-
- .. code-block:: c
-
- __constant int c = ...;
-
- __generic int* foo(global int* g) {
- __local int* l;
- private int p;
- ...
- return l;
- }
-
-More details can be found in the OpenCL C language Spec v2.0, Section 6.5.
- }];
-}
-
-def OpenCLAddressSpaceGenericDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Content = [{
-The generic address space attribute is only available with OpenCL v2.0 and later.
-It can be used with pointer types. Variables in global and local scope and
-function parameters in non-kernel functions can have the generic address space
-type attribute. It is intended to be a placeholder for any other address space
-except for '__constant' in OpenCL code which can be used with multiple address
-spaces.
- }];
-}
-
-def OpenCLAddressSpaceConstantDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Content = [{
-The constant address space attribute signals that an object is located in
-a constant (non-modifiable) memory region. It is available to all work items.
-Any type can be annotated with the constant address space attribute. Objects
-with the constant address space qualifier can be declared in any scope and must
-have an initializer.
- }];
-}
-
-def OpenCLAddressSpaceGlobalDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Content = [{
-The global address space attribute specifies that an object is allocated in
-global memory, which is accessible by all work items. The content stored in this
-memory area persists between kernel executions. Pointer types to the global
-address space are allowed as function parameters or local variables. Starting
-with OpenCL v2.0, the global address space can be used with global (program
-scope) variables and static local variable as well.
- }];
-}
-
-def OpenCLAddressSpaceLocalDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Content = [{
-The local address space specifies that an object is allocated in the local (work
-group) memory area, which is accessible to all work items in the same work
-group. The content stored in this memory region is not accessible after
-the kernel execution ends. In a kernel function scope, any variable can be in
-the local address space. In other scopes, only pointer types to the local address
-space are allowed. Local address space variables cannot have an initializer.
- }];
-}
-
-def OpenCLAddressSpacePrivateDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Content = [{
-The private address space specifies that an object is allocated in the private
-(work item) memory. Other work items cannot access the same memory area and its
-content is destroyed after work item execution ends. Local variables can be
-declared in the private address space. Function arguments are always in the
-private address space. Kernel function arguments of a pointer or an array type
-cannot point to the private address space.
- }];
-}
-
-def NullabilityDocs : DocumentationCategory<"Nullability Attributes"> {
- let Content = [{
-Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``).
-
-The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example:
-
- .. code-block:: c
-
- // No meaningful result when 'ptr' is null (here, it happens to be undefined behavior).
- int fetch(int * _Nonnull ptr) { return *ptr; }
-
- // 'ptr' may be null.
- int fetch_or_zero(int * _Nullable ptr) {
- return ptr ? *ptr : 0;
- }
-
- // A nullable pointer to non-null pointers to const characters.
- const char *join_strings(const char * _Nonnull * _Nullable strings, unsigned n);
-
-In Objective-C, there is an alternate spelling for the nullability qualifiers that can be used in Objective-C methods and properties using context-sensitive, non-underscored keywords. For example:
-
- .. code-block:: objective-c
-
- @interface NSView : NSResponder
- - (nullable NSView *)ancestorSharedWithView:(nonnull NSView *)aView;
- @property (assign, nullable) NSView *superview;
- @property (readonly, nonnull) NSArray *subviews;
- @end
- }];
-}
-
-def TypeNonNullDocs : Documentation {
- let Category = NullabilityDocs;
- let Content = [{
-The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``_Nonnull`` pointer type. For example, given a declaration such as:
-
- .. code-block:: c
-
- int fetch(int * _Nonnull ptr);
-
-a caller of ``fetch`` should not provide a null value, and the compiler will produce a warning if it sees a literal null value passed to ``fetch``. Note that, unlike the declaration attribute ``nonnull``, the presence of ``_Nonnull`` does not imply that passing null is undefined behavior: ``fetch`` is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null.
- }];
-}
-
-def TypeNullableDocs : Documentation {
- let Category = NullabilityDocs;
- let Content = [{
-The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullable`` pointer type can be null. For example, given:
-
- .. code-block:: c
-
- int fetch_or_zero(int * _Nullable ptr);
-
-a caller of ``fetch_or_zero`` can provide null.
- }];
-}
-
-def TypeNullUnspecifiedDocs : Documentation {
- let Category = NullabilityDocs;
- let Content = [{
-The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API.
- }];
-}
-
-def NonNullDocs : Documentation {
- let Category = NullabilityDocs;
- let Content = [{
-The ``nonnull`` attribute indicates that some function parameters must not be null, and can be used in several different ways. It's original usage (`from GCC <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes>`_) is as a function (or Objective-C method) attribute that specifies which parameters of the function are nonnull in a comma-separated list. For example:
-
- .. code-block:: c
-
- extern void * my_memcpy (void *dest, const void *src, size_t len)
- __attribute__((nonnull (1, 2)));
-
-Here, the ``nonnull`` attribute indicates that parameters 1 and 2
-cannot have a null value. Omitting the parenthesized list of parameter indices means that all parameters of pointer type cannot be null:
-
- .. code-block:: c
-
- extern void * my_memcpy (void *dest, const void *src, size_t len)
- __attribute__((nonnull));
-
-Clang also allows the ``nonnull`` attribute to be placed directly on a function (or Objective-C method) parameter, eliminating the need to specify the parameter index ahead of type. For example:
-
- .. code-block:: c
-
- extern void * my_memcpy (void *dest __attribute__((nonnull)),
- const void *src __attribute__((nonnull)), size_t len);
-
-Note that the ``nonnull`` attribute indicates that passing null to a non-null parameter is undefined behavior, which the optimizer may take advantage of to, e.g., remove null checks. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable.
- }];
-}
-
-def ReturnsNonNullDocs : Documentation {
- let Category = NullabilityDocs;
- let Content = [{
-The ``returns_nonnull`` attribute indicates that a particular function (or Objective-C method) always returns a non-null pointer. For example, a particular system ``malloc`` might be defined to terminate a process when memory is not available rather than returning a null pointer:
-
- .. code-block:: c
-
- extern void * malloc (size_t size) __attribute__((returns_nonnull));
-
-The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable
-}];
-}
-
-def NoAliasDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``noalias`` attribute indicates that the only memory accesses inside
-function are loads and stores from objects pointed to by its pointer-typed
-arguments, with arbitrary offsets.
- }];
-}
-
-def NotTailCalledDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``not_tail_called`` attribute prevents tail-call optimization on statically bound calls. It has no effect on indirect calls. Virtual functions, objective-c methods, and functions marked as ``always_inline`` cannot be marked as ``not_tail_called``.
-
-For example, it prevents tail-call optimization in the following case:
-
- .. code-block: c
-
- int __attribute__((not_tail_called)) foo1(int);
-
- int foo2(int a) {
- return foo1(a); // No tail-call optimization on direct calls.
- }
-
-However, it doesn't prevent tail-call optimization in this case:
-
- .. code-block: c
-
- int __attribute__((not_tail_called)) foo1(int);
-
- int foo2(int a) {
- int (*fn)(int) = &foo1;
-
- // not_tail_called has no effect on an indirect call even if the call can be
- // resolved at compile time.
- return (*fn)(a);
- }
-
-Marking virtual functions as ``not_tail_called`` is an error:
-
- .. code-block: c++
-
- class Base {
- public:
- // not_tail_called on a virtual function is an error.
- [[clang::not_tail_called]] virtual int foo1();
-
- virtual int foo2();
-
- // Non-virtual functions can be marked ``not_tail_called``.
- [[clang::not_tail_called]] int foo3();
- };
-
- class Derived1 : public Base {
- public:
- int foo1() override;
-
- // not_tail_called on a virtual function is an error.
- [[clang::not_tail_called]] int foo2() override;
- };
- }];
-}
-
-def InternalLinkageDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``internal_linkage`` attribute changes the linkage type of the declaration to internal.
-This is similar to C-style ``static``, but can be used on classes and class methods. When applied to a class definition,
-this attribute affects all methods and static data members of that class.
-This can be used to contain the ABI of a C++ library by excluding unwanted class methods from the export tables.
- }];
-}
-
-def DisableTailCallsDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization inside the marked function.
-
-For example:
-
- .. code-block:: c
-
- int callee(int);
-
- int foo(int a) __attribute__((disable_tail_calls)) {
- return callee(a); // This call is not tail-call optimized.
- }
-
-Marking virtual functions as ``disable_tail_calls`` is legal.
-
- .. code-block: c++
-
- int callee(int);
-
- class Base {
- public:
- [[clang::disable_tail_calls]] virtual int foo1() {
- return callee(); // This call is not tail-call optimized.
- }
- };
-
- class Derived1 : public Base {
- public:
- int foo1() override {
- return callee(); // This call is tail-call optimized.
- }
- };
-
- }];
-}
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
deleted file mode 100644
index f0b0a64..0000000
--- a/include/clang/Basic/AttrKinds.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===----- Attr.h - Enum values for C Attribute Kinds ----------*- 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::attr::Kind enum.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_ATTRKINDS_H
-#define LLVM_CLANG_BASIC_ATTRKINDS_H
-
-namespace clang {
-
-namespace attr {
-
-// \brief A list of all the recognized kinds of attributes.
-enum Kind {
-#define ATTR(X) X,
-#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
-#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
-#include "clang/Basic/AttrList.inc"
- NUM_ATTRS
-};
-
-} // end namespace attr
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
deleted file mode 100644
index a2b8684..0000000
--- a/include/clang/Basic/Attributes.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===--- Attributes.h - Attributes header -----------------------*- 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_BASIC_ATTRIBUTES_H
-#define LLVM_CLANG_BASIC_ATTRIBUTES_H
-
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/TargetInfo.h"
-
-namespace clang {
-
-class IdentifierInfo;
-
-enum class AttrSyntax {
- /// Is the identifier known as a GNU-style attribute?
- GNU,
- /// Is the identifier known as a __declspec-style attribute?
- Declspec,
- // Is the identifier known as a C++-style attribute?
- CXX,
- // Is the identifier known as a pragma attribute?
- Pragma
-};
-
-/// \brief 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,
- const LangOptions &LangOpts);
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_BASIC_ATTRIBUTES_H
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
deleted file mode 100644
index 4f474eb..0000000
--- a/include/clang/Basic/Builtins.def
+++ /dev/null
@@ -1,1257 +0,0 @@
-//===--- Builtins.def - Builtin function info 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 the standard builtin function database. Users of this file
-// must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: This should really be a .td file, but that requires modifying tblgen.
-// Perhaps tblgen should have plugins.
-
-// The first value provided to the macro specifies the function name of the
-// builtin, and results in a clang::builtin::BIXX enum value for XX.
-
-// The second value provided to the macro specifies the type of the function
-// (result value, then each argument) as follows:
-// v -> void
-// b -> boolean
-// c -> char
-// s -> short
-// i -> int
-// h -> half
-// f -> float
-// d -> double
-// z -> size_t
-// F -> constant CFString
-// G -> id
-// H -> SEL
-// M -> struct objc_super
-// a -> __builtin_va_list
-// A -> "reference" to __builtin_va_list
-// V -> Vector, followed by the number of elements and the base type.
-// E -> ext_vector, followed by the number of elements and the base type.
-// X -> _Complex, followed by the base type.
-// Y -> ptrdiff_t
-// P -> FILE
-// J -> jmp_buf
-// SJ -> sigjmp_buf
-// K -> ucontext_t
-// p -> pid_t
-// . -> "...". 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
-// LLL -> __int128_t (e.g. LLLi)
-// W -> int64_t
-// S -> signed
-// U -> unsigned
-// I -> Required to constant fold to an integer constant expression.
-//
-// Types may be postfixed with the following modifiers:
-// * -> pointer (optionally followed by an address space number, if no address
-// space is specified than any address space will be accepted)
-// & -> reference (optionally followed by an address space number)
-// C -> const
-// D -> volatile
-
-// The third value provided to the macro specifies information about attributes
-// of the function. These must be kept in sync with the predicates in the
-// Builtin::Context class. Currently we have:
-// n -> nothrow
-// r -> noreturn
-// c -> const
-// t -> signature is meaningless, use custom typechecking
-// F -> this is a libc/libm function with a '__builtin_' prefix added.
-// f -> this is a libc/libm function without the '__builtin_' prefix. It can
-// be followed by ':headername:' to state which header this function
-// comes from.
-// i -> this is a runtime library implemented function without the
-// '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
-// p:N: -> this is a printf-like function whose Nth argument is the format
-// string.
-// P:N: -> similar to the p:N: attribute, but the function is like vprintf
-// in that it accepts its arguments as a va_list rather than
-// through an ellipsis
-// s:N: -> this is a scanf-like function whose Nth argument is the format
-// string.
-// 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
-// j -> returns_twice (like setjmp)
-// u -> arguments are not evaluated for their side-effects
-// FIXME: gcc has nonnull
-
-#if defined(BUILTIN) && !defined(LIBBUILTIN)
-# define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
-#endif
-
-#if defined(BUILTIN) && !defined(LANGBUILTIN)
-# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
-#endif
-
-// Standard libc/libm functions:
-BUILTIN(__builtin_atan2 , "ddd" , "Fnc")
-BUILTIN(__builtin_atan2f, "fff" , "Fnc")
-BUILTIN(__builtin_atan2l, "LdLdLd", "Fnc")
-BUILTIN(__builtin_abs , "ii" , "ncF")
-BUILTIN(__builtin_copysign, "ddd", "ncF")
-BUILTIN(__builtin_copysignf, "fff", "ncF")
-BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
-BUILTIN(__builtin_fabs , "dd" , "ncF")
-BUILTIN(__builtin_fabsf, "ff" , "ncF")
-BUILTIN(__builtin_fabsl, "LdLd", "ncF")
-BUILTIN(__builtin_fmod , "ddd" , "Fnc")
-BUILTIN(__builtin_fmodf, "fff" , "Fnc")
-BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_frexp , "ddi*" , "Fn")
-BUILTIN(__builtin_frexpf, "ffi*" , "Fn")
-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_inf , "d" , "nc")
-BUILTIN(__builtin_inff , "f" , "nc")
-BUILTIN(__builtin_infl , "Ld" , "nc")
-BUILTIN(__builtin_labs , "LiLi" , "Fnc")
-BUILTIN(__builtin_llabs, "LLiLLi", "Fnc")
-BUILTIN(__builtin_ldexp , "ddi" , "Fnc")
-BUILTIN(__builtin_ldexpf, "ffi" , "Fnc")
-BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc")
-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_powi , "ddi" , "Fnc")
-BUILTIN(__builtin_powif, "ffi" , "Fnc")
-BUILTIN(__builtin_powil, "LdLdi", "Fnc")
-BUILTIN(__builtin_pow , "ddd" , "Fnc")
-BUILTIN(__builtin_powf, "fff" , "Fnc")
-BUILTIN(__builtin_powl, "LdLdLd", "Fnc")
-
-// Standard unary libc/libm functions with double/float/long double variants:
-BUILTIN(__builtin_acos , "dd" , "Fnc")
-BUILTIN(__builtin_acosf, "ff" , "Fnc")
-BUILTIN(__builtin_acosl, "LdLd", "Fnc")
-BUILTIN(__builtin_acosh , "dd" , "Fnc")
-BUILTIN(__builtin_acoshf, "ff" , "Fnc")
-BUILTIN(__builtin_acoshl, "LdLd", "Fnc")
-BUILTIN(__builtin_asin , "dd" , "Fnc")
-BUILTIN(__builtin_asinf, "ff" , "Fnc")
-BUILTIN(__builtin_asinl, "LdLd", "Fnc")
-BUILTIN(__builtin_asinh , "dd" , "Fnc")
-BUILTIN(__builtin_asinhf, "ff" , "Fnc")
-BUILTIN(__builtin_asinhl, "LdLd", "Fnc")
-BUILTIN(__builtin_atan , "dd" , "Fnc")
-BUILTIN(__builtin_atanf, "ff" , "Fnc")
-BUILTIN(__builtin_atanl, "LdLd", "Fnc")
-BUILTIN(__builtin_atanh , "dd", "Fnc")
-BUILTIN(__builtin_atanhf, "ff", "Fnc")
-BUILTIN(__builtin_atanhl, "LdLd", "Fnc")
-BUILTIN(__builtin_cbrt , "dd", "Fnc")
-BUILTIN(__builtin_cbrtf, "ff", "Fnc")
-BUILTIN(__builtin_cbrtl, "LdLd", "Fnc")
-BUILTIN(__builtin_ceil , "dd" , "Fnc")
-BUILTIN(__builtin_ceilf, "ff" , "Fnc")
-BUILTIN(__builtin_ceill, "LdLd", "Fnc")
-BUILTIN(__builtin_cos , "dd" , "Fnc")
-BUILTIN(__builtin_cosf, "ff" , "Fnc")
-BUILTIN(__builtin_cosh , "dd" , "Fnc")
-BUILTIN(__builtin_coshf, "ff" , "Fnc")
-BUILTIN(__builtin_coshl, "LdLd", "Fnc")
-BUILTIN(__builtin_cosl, "LdLd", "Fnc")
-BUILTIN(__builtin_erf , "dd", "Fnc")
-BUILTIN(__builtin_erff, "ff", "Fnc")
-BUILTIN(__builtin_erfl, "LdLd", "Fnc")
-BUILTIN(__builtin_erfc , "dd", "Fnc")
-BUILTIN(__builtin_erfcf, "ff", "Fnc")
-BUILTIN(__builtin_erfcl, "LdLd", "Fnc")
-BUILTIN(__builtin_exp , "dd" , "Fnc")
-BUILTIN(__builtin_expf, "ff" , "Fnc")
-BUILTIN(__builtin_expl, "LdLd", "Fnc")
-BUILTIN(__builtin_exp2 , "dd" , "Fnc")
-BUILTIN(__builtin_exp2f, "ff" , "Fnc")
-BUILTIN(__builtin_exp2l, "LdLd", "Fnc")
-BUILTIN(__builtin_expm1 , "dd", "Fnc")
-BUILTIN(__builtin_expm1f, "ff", "Fnc")
-BUILTIN(__builtin_expm1l, "LdLd", "Fnc")
-BUILTIN(__builtin_fdim, "ddd", "Fnc")
-BUILTIN(__builtin_fdimf, "fff", "Fnc")
-BUILTIN(__builtin_fdiml, "LdLdLd", "Fnc")
-BUILTIN(__builtin_floor , "dd" , "Fnc")
-BUILTIN(__builtin_floorf, "ff" , "Fnc")
-BUILTIN(__builtin_floorl, "LdLd", "Fnc")
-BUILTIN(__builtin_fma, "dddd", "Fnc")
-BUILTIN(__builtin_fmaf, "ffff", "Fnc")
-BUILTIN(__builtin_fmal, "LdLdLdLd", "Fnc")
-BUILTIN(__builtin_fmax, "ddd", "Fnc")
-BUILTIN(__builtin_fmaxf, "fff", "Fnc")
-BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_fmin, "ddd", "Fnc")
-BUILTIN(__builtin_fminf, "fff", "Fnc")
-BUILTIN(__builtin_fminl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_hypot , "ddd" , "Fnc")
-BUILTIN(__builtin_hypotf, "fff" , "Fnc")
-BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_ilogb , "id", "Fnc")
-BUILTIN(__builtin_ilogbf, "if", "Fnc")
-BUILTIN(__builtin_ilogbl, "iLd", "Fnc")
-BUILTIN(__builtin_lgamma , "dd", "Fnc")
-BUILTIN(__builtin_lgammaf, "ff", "Fnc")
-BUILTIN(__builtin_lgammal, "LdLd", "Fnc")
-BUILTIN(__builtin_llrint, "LLid", "Fnc")
-BUILTIN(__builtin_llrintf, "LLif", "Fnc")
-BUILTIN(__builtin_llrintl, "LLiLd", "Fnc")
-BUILTIN(__builtin_llround , "LLid", "Fnc")
-BUILTIN(__builtin_llroundf, "LLif", "Fnc")
-BUILTIN(__builtin_llroundl, "LLiLd", "Fnc")
-BUILTIN(__builtin_log , "dd" , "Fnc")
-BUILTIN(__builtin_log10 , "dd" , "Fnc")
-BUILTIN(__builtin_log10f, "ff" , "Fnc")
-BUILTIN(__builtin_log10l, "LdLd", "Fnc")
-BUILTIN(__builtin_log1p , "dd" , "Fnc")
-BUILTIN(__builtin_log1pf, "ff" , "Fnc")
-BUILTIN(__builtin_log1pl, "LdLd", "Fnc")
-BUILTIN(__builtin_log2, "dd" , "Fnc")
-BUILTIN(__builtin_log2f, "ff" , "Fnc")
-BUILTIN(__builtin_log2l, "LdLd" , "Fnc")
-BUILTIN(__builtin_logb , "dd", "Fnc")
-BUILTIN(__builtin_logbf, "ff", "Fnc")
-BUILTIN(__builtin_logbl, "LdLd", "Fnc")
-BUILTIN(__builtin_logf, "ff" , "Fnc")
-BUILTIN(__builtin_logl, "LdLd", "Fnc")
-BUILTIN(__builtin_lrint , "Lid", "Fnc")
-BUILTIN(__builtin_lrintf, "Lif", "Fnc")
-BUILTIN(__builtin_lrintl, "LiLd", "Fnc")
-BUILTIN(__builtin_lround , "Lid", "Fnc")
-BUILTIN(__builtin_lroundf, "Lif", "Fnc")
-BUILTIN(__builtin_lroundl, "LiLd", "Fnc")
-BUILTIN(__builtin_nearbyint , "dd", "Fnc")
-BUILTIN(__builtin_nearbyintf, "ff", "Fnc")
-BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc")
-BUILTIN(__builtin_nextafter , "ddd", "Fnc")
-BUILTIN(__builtin_nextafterf, "fff", "Fnc")
-BUILTIN(__builtin_nextafterl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_nexttoward , "ddLd", "Fnc")
-BUILTIN(__builtin_nexttowardf, "ffLd", "Fnc")
-BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_remainder , "ddd", "Fnc")
-BUILTIN(__builtin_remainderf, "fff", "Fnc")
-BUILTIN(__builtin_remainderl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_remquo , "dddi*", "Fn")
-BUILTIN(__builtin_remquof, "fffi*", "Fn")
-BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn")
-BUILTIN(__builtin_rint , "dd", "Fnc")
-BUILTIN(__builtin_rintf, "ff", "Fnc")
-BUILTIN(__builtin_rintl, "LdLd", "Fnc")
-BUILTIN(__builtin_round, "dd" , "Fnc")
-BUILTIN(__builtin_roundf, "ff" , "Fnc")
-BUILTIN(__builtin_roundl, "LdLd" , "Fnc")
-BUILTIN(__builtin_scalbln , "ddLi", "Fnc")
-BUILTIN(__builtin_scalblnf, "ffLi", "Fnc")
-BUILTIN(__builtin_scalblnl, "LdLdLi", "Fnc")
-BUILTIN(__builtin_scalbn , "ddi", "Fnc")
-BUILTIN(__builtin_scalbnf, "ffi", "Fnc")
-BUILTIN(__builtin_scalbnl, "LdLdi", "Fnc")
-BUILTIN(__builtin_sin , "dd" , "Fnc")
-BUILTIN(__builtin_sinf, "ff" , "Fnc")
-BUILTIN(__builtin_sinh , "dd" , "Fnc")
-BUILTIN(__builtin_sinhf, "ff" , "Fnc")
-BUILTIN(__builtin_sinhl, "LdLd", "Fnc")
-BUILTIN(__builtin_sinl, "LdLd", "Fnc")
-BUILTIN(__builtin_sqrt , "dd" , "Fnc")
-BUILTIN(__builtin_sqrtf, "ff" , "Fnc")
-BUILTIN(__builtin_sqrtl, "LdLd", "Fnc")
-BUILTIN(__builtin_tan , "dd" , "Fnc")
-BUILTIN(__builtin_tanf, "ff" , "Fnc")
-BUILTIN(__builtin_tanh , "dd" , "Fnc")
-BUILTIN(__builtin_tanhf, "ff" , "Fnc")
-BUILTIN(__builtin_tanhl, "LdLd", "Fnc")
-BUILTIN(__builtin_tanl, "LdLd", "Fnc")
-BUILTIN(__builtin_tgamma , "dd", "Fnc")
-BUILTIN(__builtin_tgammaf, "ff", "Fnc")
-BUILTIN(__builtin_tgammal, "LdLd", "Fnc")
-BUILTIN(__builtin_trunc , "dd", "Fnc")
-BUILTIN(__builtin_truncf, "ff", "Fnc")
-BUILTIN(__builtin_truncl, "LdLd", "Fnc")
-
-// C99 complex builtins
-BUILTIN(__builtin_cabs, "dXd", "Fnc")
-BUILTIN(__builtin_cabsf, "fXf", "Fnc")
-BUILTIN(__builtin_cabsl, "LdXLd", "Fnc")
-BUILTIN(__builtin_cacos, "XdXd", "Fnc")
-BUILTIN(__builtin_cacosf, "XfXf", "Fnc")
-BUILTIN(__builtin_cacosh, "XdXd", "Fnc")
-BUILTIN(__builtin_cacoshf, "XfXf", "Fnc")
-BUILTIN(__builtin_cacoshl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_cacosl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_carg, "dXd", "Fnc")
-BUILTIN(__builtin_cargf, "fXf", "Fnc")
-BUILTIN(__builtin_cargl, "LdXLd", "Fnc")
-BUILTIN(__builtin_casin, "XdXd", "Fnc")
-BUILTIN(__builtin_casinf, "XfXf", "Fnc")
-BUILTIN(__builtin_casinh, "XdXd", "Fnc")
-BUILTIN(__builtin_casinhf, "XfXf", "Fnc")
-BUILTIN(__builtin_casinhl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_casinl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_catan, "XdXd", "Fnc")
-BUILTIN(__builtin_catanf, "XfXf", "Fnc")
-BUILTIN(__builtin_catanh, "XdXd", "Fnc")
-BUILTIN(__builtin_catanhf, "XfXf", "Fnc")
-BUILTIN(__builtin_catanhl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_catanl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_ccos, "XdXd", "Fnc")
-BUILTIN(__builtin_ccosf, "XfXf", "Fnc")
-BUILTIN(__builtin_ccosl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_ccosh, "XdXd", "Fnc")
-BUILTIN(__builtin_ccoshf, "XfXf", "Fnc")
-BUILTIN(__builtin_ccoshl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_cexp, "XdXd", "Fnc")
-BUILTIN(__builtin_cexpf, "XfXf", "Fnc")
-BUILTIN(__builtin_cexpl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_cimag, "dXd", "Fnc")
-BUILTIN(__builtin_cimagf, "fXf", "Fnc")
-BUILTIN(__builtin_cimagl, "LdXLd", "Fnc")
-BUILTIN(__builtin_conj, "XdXd", "Fnc")
-BUILTIN(__builtin_conjf, "XfXf", "Fnc")
-BUILTIN(__builtin_conjl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_clog, "XdXd", "Fnc")
-BUILTIN(__builtin_clogf, "XfXf", "Fnc")
-BUILTIN(__builtin_clogl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_cproj, "XdXd", "Fnc")
-BUILTIN(__builtin_cprojf, "XfXf", "Fnc")
-BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_cpow, "XdXdXd", "Fnc")
-BUILTIN(__builtin_cpowf, "XfXfXf", "Fnc")
-BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fnc")
-BUILTIN(__builtin_creal, "dXd", "Fnc")
-BUILTIN(__builtin_crealf, "fXf", "Fnc")
-BUILTIN(__builtin_creall, "LdXLd", "Fnc")
-BUILTIN(__builtin_csin, "XdXd", "Fnc")
-BUILTIN(__builtin_csinf, "XfXf", "Fnc")
-BUILTIN(__builtin_csinl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_csinh, "XdXd", "Fnc")
-BUILTIN(__builtin_csinhf, "XfXf", "Fnc")
-BUILTIN(__builtin_csinhl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_csqrt, "XdXd", "Fnc")
-BUILTIN(__builtin_csqrtf, "XfXf", "Fnc")
-BUILTIN(__builtin_csqrtl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_ctan, "XdXd", "Fnc")
-BUILTIN(__builtin_ctanf, "XfXf", "Fnc")
-BUILTIN(__builtin_ctanl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_ctanh, "XdXd", "Fnc")
-BUILTIN(__builtin_ctanhf, "XfXf", "Fnc")
-BUILTIN(__builtin_ctanhl, "XLdXLd", "Fnc")
-
-// FP Comparisons.
-BUILTIN(__builtin_isgreater , "i.", "Fnc")
-BUILTIN(__builtin_isgreaterequal, "i.", "Fnc")
-BUILTIN(__builtin_isless , "i.", "Fnc")
-BUILTIN(__builtin_islessequal , "i.", "Fnc")
-BUILTIN(__builtin_islessgreater , "i.", "Fnc")
-BUILTIN(__builtin_isunordered , "i.", "Fnc")
-
-// Unary FP classification
-BUILTIN(__builtin_fpclassify, "iiiii.", "Fnc")
-BUILTIN(__builtin_isfinite, "i.", "Fnc")
-BUILTIN(__builtin_isinf, "i.", "Fnc")
-BUILTIN(__builtin_isinf_sign, "i.", "Fnc")
-BUILTIN(__builtin_isnan, "i.", "Fnc")
-BUILTIN(__builtin_isnormal, "i.", "Fnc")
-
-// FP signbit builtins
-BUILTIN(__builtin_signbit, "i.", "Fnc")
-BUILTIN(__builtin_signbitf, "if", "Fnc")
-BUILTIN(__builtin_signbitl, "iLd", "Fnc")
-
-// Builtins for arithmetic.
-BUILTIN(__builtin_clzs , "iUs" , "nc")
-BUILTIN(__builtin_clz , "iUi" , "nc")
-BUILTIN(__builtin_clzl , "iULi" , "nc")
-BUILTIN(__builtin_clzll, "iULLi", "nc")
-// TODO: int clzimax(uintmax_t)
-BUILTIN(__builtin_ctzs , "iUs" , "nc")
-BUILTIN(__builtin_ctz , "iUi" , "nc")
-BUILTIN(__builtin_ctzl , "iULi" , "nc")
-BUILTIN(__builtin_ctzll, "iULLi", "nc")
-// TODO: int ctzimax(uintmax_t)
-BUILTIN(__builtin_ffs , "ii" , "Fnc")
-BUILTIN(__builtin_ffsl , "iLi" , "Fnc")
-BUILTIN(__builtin_ffsll, "iLLi", "Fnc")
-BUILTIN(__builtin_parity , "iUi" , "nc")
-BUILTIN(__builtin_parityl , "iULi" , "nc")
-BUILTIN(__builtin_parityll, "iULLi", "nc")
-BUILTIN(__builtin_popcount , "iUi" , "nc")
-BUILTIN(__builtin_popcountl , "iULi" , "nc")
-BUILTIN(__builtin_popcountll, "iULLi", "nc")
-
-// FIXME: These type signatures are not correct for targets with int != 32-bits
-// or with ULL != 64-bits.
-BUILTIN(__builtin_bswap16, "UsUs", "nc")
-BUILTIN(__builtin_bswap32, "UiUi", "nc")
-BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
-
-// Random GCC builtins
-BUILTIN(__builtin_constant_p, "i.", "nctu")
-BUILTIN(__builtin_classify_type, "i.", "nctu")
-BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
-BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
-BUILTIN(__builtin_va_start, "vA.", "nt")
-BUILTIN(__builtin_va_end, "vA", "n")
-BUILTIN(__builtin_va_copy, "vAA", "n")
-BUILTIN(__builtin_stdarg_start, "vA.", "n")
-BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc")
-BUILTIN(__builtin_bcmp, "iv*v*z", "Fn")
-BUILTIN(__builtin_bcopy, "vv*v*z", "n")
-BUILTIN(__builtin_bzero, "vv*z", "nF")
-BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:")
-BUILTIN(__builtin_memchr, "v*vC*iz", "nF")
-BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
-BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
-BUILTIN(__builtin_memmove, "v*v*vC*z", "nF")
-BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF")
-BUILTIN(__builtin_memset, "v*v*iz", "nF")
-BUILTIN(__builtin_printf, "icC*.", "Fp:0:")
-BUILTIN(__builtin_stpcpy, "c*c*cC*", "nF")
-BUILTIN(__builtin_stpncpy, "c*c*cC*z", "nF")
-BUILTIN(__builtin_strcasecmp, "icC*cC*", "nF")
-BUILTIN(__builtin_strcat, "c*c*cC*", "nF")
-BUILTIN(__builtin_strchr, "c*cC*i", "nF")
-BUILTIN(__builtin_strcmp, "icC*cC*", "nF")
-BUILTIN(__builtin_strcpy, "c*c*cC*", "nF")
-BUILTIN(__builtin_strcspn, "zcC*cC*", "nF")
-BUILTIN(__builtin_strdup, "c*cC*", "nF")
-BUILTIN(__builtin_strlen, "zcC*", "nF")
-BUILTIN(__builtin_strncasecmp, "icC*cC*z", "nF")
-BUILTIN(__builtin_strncat, "c*c*cC*z", "nF")
-BUILTIN(__builtin_strncmp, "icC*cC*z", "nF")
-BUILTIN(__builtin_strncpy, "c*c*cC*z", "nF")
-BUILTIN(__builtin_strndup, "c*cC*z", "nF")
-BUILTIN(__builtin_strpbrk, "c*cC*cC*", "nF")
-BUILTIN(__builtin_strrchr, "c*cC*i", "nF")
-BUILTIN(__builtin_strspn, "zcC*cC*", "nF")
-BUILTIN(__builtin_strstr, "c*cC*cC*", "nF")
-BUILTIN(__builtin_return_address, "v*IUi", "n")
-BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
-BUILTIN(__builtin_frame_address, "v*IUi", "n")
-BUILTIN(__builtin___clear_cache, "vc*c*", "n")
-BUILTIN(__builtin_flt_rounds, "i", "nc")
-BUILTIN(__builtin_setjmp, "iv**", "j")
-BUILTIN(__builtin_longjmp, "vv**i", "r")
-BUILTIN(__builtin_unwind_init, "v", "")
-BUILTIN(__builtin_eh_return_data_regno, "iIi", "nc")
-BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:")
-BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
-BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
-
-// GCC exception builtins
-BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t!
-BUILTIN(__builtin_frob_return_addr, "v*v*", "n")
-BUILTIN(__builtin_dwarf_cfa, "v*", "n")
-BUILTIN(__builtin_init_dwarf_reg_size_table, "vv*", "n")
-BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
-BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
-
-// GCC Object size checking builtins
-BUILTIN(__builtin_object_size, "zvC*i", "nu")
-BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
-BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF")
-BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
-BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF")
-BUILTIN(__builtin___memset_chk, "v*v*izz", "nF")
-BUILTIN(__builtin___stpcpy_chk, "c*c*cC*z", "nF")
-BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF")
-BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF")
-BUILTIN(__builtin___strlcat_chk, "zc*cC*zz", "nF")
-BUILTIN(__builtin___strlcpy_chk, "zc*cC*zz", "nF")
-BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
-BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
-BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF")
-BUILTIN(__builtin___snprintf_chk, "ic*zizcC*.", "Fp:4:")
-BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "Fp:3:")
-BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "FP:4:")
-BUILTIN(__builtin___vsprintf_chk, "ic*izcC*a", "FP:3:")
-BUILTIN(__builtin___fprintf_chk, "iP*icC*.", "Fp:2:")
-BUILTIN(__builtin___printf_chk, "iicC*.", "Fp:1:")
-BUILTIN(__builtin___vfprintf_chk, "iP*icC*a", "FP:2:")
-BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
-
-BUILTIN(__builtin_unpredictable, "LiLi" , "nc")
-BUILTIN(__builtin_expect, "LiLiLi" , "nc")
-BUILTIN(__builtin_prefetch, "vvC*.", "nc")
-BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
-BUILTIN(__builtin_trap, "v", "nr")
-BUILTIN(__builtin_debugtrap, "v", "n")
-BUILTIN(__builtin_unreachable, "v", "nr")
-BUILTIN(__builtin_shufflevector, "v." , "nc")
-BUILTIN(__builtin_convertvector, "v." , "nct")
-BUILTIN(__builtin_alloca, "v*z" , "Fn")
-BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
-
-// "Overloaded" Atomic operator builtins. These are overloaded to support data
-// types of i8, i16, i32, i64, and i128. The front-end sees calls to the
-// non-suffixed version of these (which has a bogus type) and transforms them to
-// the right overloaded version in Sema (plus casts).
-
-// FIXME: These assume that char -> i8, short -> i16, int -> i32,
-// long long -> i64.
-
-BUILTIN(__sync_fetch_and_add, "v.", "t")
-BUILTIN(__sync_fetch_and_add_1, "ccD*c.", "nt")
-BUILTIN(__sync_fetch_and_add_2, "ssD*s.", "nt")
-BUILTIN(__sync_fetch_and_add_4, "iiD*i.", "nt")
-BUILTIN(__sync_fetch_and_add_8, "LLiLLiD*LLi.", "nt")
-BUILTIN(__sync_fetch_and_add_16, "LLLiLLLiD*LLLi.", "nt")
-
-BUILTIN(__sync_fetch_and_sub, "v.", "t")
-BUILTIN(__sync_fetch_and_sub_1, "ccD*c.", "nt")
-BUILTIN(__sync_fetch_and_sub_2, "ssD*s.", "nt")
-BUILTIN(__sync_fetch_and_sub_4, "iiD*i.", "nt")
-BUILTIN(__sync_fetch_and_sub_8, "LLiLLiD*LLi.", "nt")
-BUILTIN(__sync_fetch_and_sub_16, "LLLiLLLiD*LLLi.", "nt")
-
-BUILTIN(__sync_fetch_and_or, "v.", "t")
-BUILTIN(__sync_fetch_and_or_1, "ccD*c.", "nt")
-BUILTIN(__sync_fetch_and_or_2, "ssD*s.", "nt")
-BUILTIN(__sync_fetch_and_or_4, "iiD*i.", "nt")
-BUILTIN(__sync_fetch_and_or_8, "LLiLLiD*LLi.", "nt")
-BUILTIN(__sync_fetch_and_or_16, "LLLiLLLiD*LLLi.", "nt")
-
-BUILTIN(__sync_fetch_and_and, "v.", "t")
-BUILTIN(__sync_fetch_and_and_1, "ccD*c.", "tn")
-BUILTIN(__sync_fetch_and_and_2, "ssD*s.", "tn")
-BUILTIN(__sync_fetch_and_and_4, "iiD*i.", "tn")
-BUILTIN(__sync_fetch_and_and_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_fetch_and_and_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_fetch_and_xor, "v.", "t")
-BUILTIN(__sync_fetch_and_xor_1, "ccD*c.", "tn")
-BUILTIN(__sync_fetch_and_xor_2, "ssD*s.", "tn")
-BUILTIN(__sync_fetch_and_xor_4, "iiD*i.", "tn")
-BUILTIN(__sync_fetch_and_xor_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_fetch_and_xor_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_fetch_and_nand, "v.", "t")
-BUILTIN(__sync_fetch_and_nand_1, "ccD*c.", "tn")
-BUILTIN(__sync_fetch_and_nand_2, "ssD*s.", "tn")
-BUILTIN(__sync_fetch_and_nand_4, "iiD*i.", "tn")
-BUILTIN(__sync_fetch_and_nand_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_fetch_and_nand_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_add_and_fetch, "v.", "t")
-BUILTIN(__sync_add_and_fetch_1, "ccD*c.", "tn")
-BUILTIN(__sync_add_and_fetch_2, "ssD*s.", "tn")
-BUILTIN(__sync_add_and_fetch_4, "iiD*i.", "tn")
-BUILTIN(__sync_add_and_fetch_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_add_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_sub_and_fetch, "v.", "t")
-BUILTIN(__sync_sub_and_fetch_1, "ccD*c.", "tn")
-BUILTIN(__sync_sub_and_fetch_2, "ssD*s.", "tn")
-BUILTIN(__sync_sub_and_fetch_4, "iiD*i.", "tn")
-BUILTIN(__sync_sub_and_fetch_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_sub_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_or_and_fetch, "v.", "t")
-BUILTIN(__sync_or_and_fetch_1, "ccD*c.", "tn")
-BUILTIN(__sync_or_and_fetch_2, "ssD*s.", "tn")
-BUILTIN(__sync_or_and_fetch_4, "iiD*i.", "tn")
-BUILTIN(__sync_or_and_fetch_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_or_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_and_and_fetch, "v.", "t")
-BUILTIN(__sync_and_and_fetch_1, "ccD*c.", "tn")
-BUILTIN(__sync_and_and_fetch_2, "ssD*s.", "tn")
-BUILTIN(__sync_and_and_fetch_4, "iiD*i.", "tn")
-BUILTIN(__sync_and_and_fetch_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_and_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_xor_and_fetch, "v.", "t")
-BUILTIN(__sync_xor_and_fetch_1, "ccD*c.", "tn")
-BUILTIN(__sync_xor_and_fetch_2, "ssD*s.", "tn")
-BUILTIN(__sync_xor_and_fetch_4, "iiD*i.", "tn")
-BUILTIN(__sync_xor_and_fetch_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_xor_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_nand_and_fetch, "v.", "t")
-BUILTIN(__sync_nand_and_fetch_1, "ccD*c.", "tn")
-BUILTIN(__sync_nand_and_fetch_2, "ssD*s.", "tn")
-BUILTIN(__sync_nand_and_fetch_4, "iiD*i.", "tn")
-BUILTIN(__sync_nand_and_fetch_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_nand_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_bool_compare_and_swap, "v.", "t")
-BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "tn")
-BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "tn")
-BUILTIN(__sync_bool_compare_and_swap_4, "biD*ii.", "tn")
-BUILTIN(__sync_bool_compare_and_swap_8, "bLLiD*LLiLLi.", "tn")
-BUILTIN(__sync_bool_compare_and_swap_16, "bLLLiD*LLLiLLLi.", "tn")
-
-BUILTIN(__sync_val_compare_and_swap, "v.", "t")
-BUILTIN(__sync_val_compare_and_swap_1, "ccD*cc.", "tn")
-BUILTIN(__sync_val_compare_and_swap_2, "ssD*ss.", "tn")
-BUILTIN(__sync_val_compare_and_swap_4, "iiD*ii.", "tn")
-BUILTIN(__sync_val_compare_and_swap_8, "LLiLLiD*LLiLLi.", "tn")
-BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLiD*LLLiLLLi.", "tn")
-
-BUILTIN(__sync_lock_test_and_set, "v.", "t")
-BUILTIN(__sync_lock_test_and_set_1, "ccD*c.", "tn")
-BUILTIN(__sync_lock_test_and_set_2, "ssD*s.", "tn")
-BUILTIN(__sync_lock_test_and_set_4, "iiD*i.", "tn")
-BUILTIN(__sync_lock_test_and_set_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_lock_test_and_set_16, "LLLiLLLiD*LLLi.", "tn")
-
-BUILTIN(__sync_lock_release, "v.", "t")
-BUILTIN(__sync_lock_release_1, "vcD*.", "tn")
-BUILTIN(__sync_lock_release_2, "vsD*.", "tn")
-BUILTIN(__sync_lock_release_4, "viD*.", "tn")
-BUILTIN(__sync_lock_release_8, "vLLiD*.", "tn")
-BUILTIN(__sync_lock_release_16, "vLLLiD*.", "tn")
-
-BUILTIN(__sync_swap, "v.", "t")
-BUILTIN(__sync_swap_1, "ccD*c.", "tn")
-BUILTIN(__sync_swap_2, "ssD*s.", "tn")
-BUILTIN(__sync_swap_4, "iiD*i.", "tn")
-BUILTIN(__sync_swap_8, "LLiLLiD*LLi.", "tn")
-BUILTIN(__sync_swap_16, "LLLiLLLiD*LLLi.", "tn")
-
-// Some of our atomics builtins are handled by AtomicExpr rather than
-// as normal builtin CallExprs. This macro is used for such builtins.
-#ifndef ATOMIC_BUILTIN
-#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) BUILTIN(ID, TYPE, ATTRS)
-#endif
-
-// C11 _Atomic operations for <stdatomic.h>.
-ATOMIC_BUILTIN(__c11_atomic_init, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_load, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_store, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_exchange, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_compare_exchange_strong, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_compare_exchange_weak, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_fetch_add, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_fetch_sub, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_fetch_and, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_fetch_or, "v.", "t")
-ATOMIC_BUILTIN(__c11_atomic_fetch_xor, "v.", "t")
-BUILTIN(__c11_atomic_thread_fence, "vi", "n")
-BUILTIN(__c11_atomic_signal_fence, "vi", "n")
-BUILTIN(__c11_atomic_is_lock_free, "iz", "n")
-
-// GNU atomic builtins.
-ATOMIC_BUILTIN(__atomic_load, "v.", "t")
-ATOMIC_BUILTIN(__atomic_load_n, "v.", "t")
-ATOMIC_BUILTIN(__atomic_store, "v.", "t")
-ATOMIC_BUILTIN(__atomic_store_n, "v.", "t")
-ATOMIC_BUILTIN(__atomic_exchange, "v.", "t")
-ATOMIC_BUILTIN(__atomic_exchange_n, "v.", "t")
-ATOMIC_BUILTIN(__atomic_compare_exchange, "v.", "t")
-ATOMIC_BUILTIN(__atomic_compare_exchange_n, "v.", "t")
-ATOMIC_BUILTIN(__atomic_fetch_add, "v.", "t")
-ATOMIC_BUILTIN(__atomic_fetch_sub, "v.", "t")
-ATOMIC_BUILTIN(__atomic_fetch_and, "v.", "t")
-ATOMIC_BUILTIN(__atomic_fetch_or, "v.", "t")
-ATOMIC_BUILTIN(__atomic_fetch_xor, "v.", "t")
-ATOMIC_BUILTIN(__atomic_fetch_nand, "v.", "t")
-ATOMIC_BUILTIN(__atomic_add_fetch, "v.", "t")
-ATOMIC_BUILTIN(__atomic_sub_fetch, "v.", "t")
-ATOMIC_BUILTIN(__atomic_and_fetch, "v.", "t")
-ATOMIC_BUILTIN(__atomic_or_fetch, "v.", "t")
-ATOMIC_BUILTIN(__atomic_xor_fetch, "v.", "t")
-ATOMIC_BUILTIN(__atomic_nand_fetch, "v.", "t")
-BUILTIN(__atomic_test_and_set, "bvD*i", "n")
-BUILTIN(__atomic_clear, "vvD*i", "n")
-BUILTIN(__atomic_thread_fence, "vi", "n")
-BUILTIN(__atomic_signal_fence, "vi", "n")
-BUILTIN(__atomic_always_lock_free, "izvCD*", "n")
-BUILTIN(__atomic_is_lock_free, "izvCD*", "n")
-
-#undef ATOMIC_BUILTIN
-
-// Non-overloaded atomic builtins.
-BUILTIN(__sync_synchronize, "v.", "n")
-// GCC does not support these, they are a Clang extension.
-BUILTIN(__sync_fetch_and_min, "iiD*i", "n")
-BUILTIN(__sync_fetch_and_max, "iiD*i", "n")
-BUILTIN(__sync_fetch_and_umin, "UiUiD*Ui", "n")
-BUILTIN(__sync_fetch_and_umax, "UiUiD*Ui", "n")
-
-// Random libc builtins.
-BUILTIN(__builtin_abort, "v", "Fnr")
-BUILTIN(__builtin_index, "c*cC*i", "Fn")
-BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
-
-// Microsoft builtins. These are only active with -fms-extensions.
-LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__exception_code, "ULi", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_exception_code, "ULi", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__exception_info, "v*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_exception_info, "v*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
-
-// Microsoft library builtins.
-LIBBUILTIN(_setjmpex, "iJ", "fj", "setjmpex.h", ALL_MS_LANGUAGES)
-
-// C99 library functions
-// C99 stdlib.h
-LIBBUILTIN(abort, "v", "fr", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(calloc, "v*zz", "f", "stdlib.h", ALL_LANGUAGES)
-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)
-// C99 string.h
-LIBBUILTIN(memcpy, "v*v*vC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(memcmp, "ivC*vC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(memmove, "v*v*vC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strcpy, "c*c*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strncpy, "c*c*cC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strcmp, "icC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strncmp, "icC*cC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strcat, "c*c*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strncat, "c*c*cC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strxfrm, "zc*cC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(memchr, "v*vC*iz", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strchr, "c*cC*i", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strcspn, "zcC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strpbrk, "c*cC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strrchr, "c*cC*i", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strspn, "zcC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strstr, "c*cC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strtok, "c*c*cC*", "f", "string.h", ALL_LANGUAGES)
-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
-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)
-LIBBUILTIN(sprintf, "ic*cC*.", "fp:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vprintf, "icC*a", "fP:0:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vfprintf, "i.", "fP:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(scanf, "icC*R.", "fs:0:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(fscanf, "iP*RcC*R.", "fs:1:", "stdio.h", ALL_LANGUAGES)
-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)
-// C99
-// In some systems setjmp is a macro that expands to _setjmp. We undefine
-// it here to avoid having two identical LIBBUILTIN entries.
-#undef setjmp
-LIBBUILTIN(setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(longjmp, "vJi", "fr", "setjmp.h", ALL_LANGUAGES)
-
-// Non-C library functions, active in GNU mode only.
-// Functions with (returns_twice) attribute (marked as "j") are still active in
-// all languages, because losing this attribute would result in miscompilation
-// when these functions are used in non-GNU mode. PR16138.
-LIBBUILTIN(alloca, "v*z", "f", "stdlib.h", ALL_GNU_LANGUAGES)
-// POSIX string.h
-LIBBUILTIN(stpcpy, "c*c*cC*", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(stpncpy, "c*c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(strdup, "c*cC*", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(strndup, "c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
-// POSIX strings.h
-LIBBUILTIN(index, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_GNU_LANGUAGES)
-// In some systems str[n]casejmp is a macro that expands to _str[n]icmp.
-// We undefine then here to avoid wrong name.
-#undef strcasecmp
-#undef strncasecmp
-LIBBUILTIN(strcasecmp, "icC*cC*", "f", "strings.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_GNU_LANGUAGES)
-// POSIX unistd.h
-LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_LANGUAGES)
-// POSIX setjmp.h
-
-LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(__sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(setjmp_syscall, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(savectx, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(qsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(getcontext, "iK*", "fj", "setjmp.h", ALL_LANGUAGES)
-
-LIBBUILTIN(_longjmp, "vJi", "fr", "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h", ALL_GNU_LANGUAGES)
-// non-standard but very common
-LIBBUILTIN(strlcpy, "zc*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(strlcat, "zc*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
-// id objc_msgSend(id, SEL, ...)
-LIBBUILTIN(objc_msgSend, "GGH.", "f", "objc/message.h", OBJC_LANG)
-// long double objc_msgSend_fpret(id self, SEL op, ...)
-LIBBUILTIN(objc_msgSend_fpret, "LdGH.", "f", "objc/message.h", OBJC_LANG)
-// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
-LIBBUILTIN(objc_msgSend_fp2ret, "XLdGH.", "f", "objc/message.h", OBJC_LANG)
-// void objc_msgSend_stret (id, SEL, ...)
-LIBBUILTIN(objc_msgSend_stret, "vGH.", "f", "objc/message.h", OBJC_LANG)
-// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
-LIBBUILTIN(objc_msgSendSuper, "GM*H.", "f", "objc/message.h", OBJC_LANG)
-// void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...)
-LIBBUILTIN(objc_msgSendSuper_stret, "vM*H.", "f", "objc/message.h", OBJC_LANG)
-// id objc_getClass(const char *name)
-LIBBUILTIN(objc_getClass, "GcC*", "f", "objc/runtime.h", OBJC_LANG)
-// id objc_getMetaClass(const char *name)
-LIBBUILTIN(objc_getMetaClass, "GcC*", "f", "objc/runtime.h", OBJC_LANG)
-// void objc_enumerationMutation(id)
-LIBBUILTIN(objc_enumerationMutation, "vG", "f", "objc/runtime.h", OBJC_LANG)
-
-// id objc_read_weak(id *location)
-LIBBUILTIN(objc_read_weak, "GG*", "f", "objc/objc-auto.h", OBJC_LANG)
-// id objc_assign_weak(id value, id *location)
-LIBBUILTIN(objc_assign_weak, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
-// id objc_assign_ivar(id value, id dest, ptrdiff_t offset)
-LIBBUILTIN(objc_assign_ivar, "GGGY", "f", "objc/objc-auto.h", OBJC_LANG)
-// id objc_assign_global(id val, id *dest)
-LIBBUILTIN(objc_assign_global, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
-// id objc_assign_strongCast(id val, id *dest
-LIBBUILTIN(objc_assign_strongCast, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
-
-// id objc_exception_extract(void *localExceptionData)
-LIBBUILTIN(objc_exception_extract, "Gv*", "f", "objc/objc-exception.h", OBJC_LANG)
-// void objc_exception_try_enter(void *localExceptionData)
-LIBBUILTIN(objc_exception_try_enter, "vv*", "f", "objc/objc-exception.h", OBJC_LANG)
-// void objc_exception_try_exit(void *localExceptionData)
-LIBBUILTIN(objc_exception_try_exit, "vv*", "f", "objc/objc-exception.h", OBJC_LANG)
-// int objc_exception_match(Class exceptionClass, id exception)
-LIBBUILTIN(objc_exception_match, "iGG", "f", "objc/objc-exception.h", OBJC_LANG)
-// void objc_exception_throw(id exception)
-LIBBUILTIN(objc_exception_throw, "vG", "f", "objc/objc-exception.h", OBJC_LANG)
-
-// int objc_sync_enter(id obj)
-LIBBUILTIN(objc_sync_enter, "iG", "f", "objc/objc-sync.h", OBJC_LANG)
-// int objc_sync_exit(id obj)
-LIBBUILTIN(objc_sync_exit, "iG", "f", "objc/objc-sync.h", OBJC_LANG)
-
-BUILTIN(__builtin_objc_memmove_collectable, "v*v*vC*z", "nF")
-
-// void NSLog(NSString *fmt, ...)
-LIBBUILTIN(NSLog, "vG.", "fp:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG)
-// void NSLogv(NSString *fmt, va_list args)
-LIBBUILTIN(NSLogv, "vGa", "fP:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG)
-
-// Builtin math library functions
-LIBBUILTIN(atan2, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atan2f, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atan2l, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(abs, "ii", "fnc", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(labs, "LiLi", "fnc", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(llabs, "LLiLLi", "fnc", "stdlib.h", ALL_LANGUAGES)
-
-LIBBUILTIN(copysign, "ddd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(copysignf, "fff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(copysignl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(fabs, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fabsf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fabsl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(fmod, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmodf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmodl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(frexp, "ddi*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(frexpf, "ffi*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(frexpl, "LdLdi*", "fn", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(ldexp, "ddi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ldexpf, "ffi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ldexpl, "LdLdi", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(modf, "ddd*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(modff, "fff*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(modfl, "LdLdLd*", "fn", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(nan, "dcC*", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nanf, "fcC*", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nanl, "LdcC*", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(pow, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(powf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(powl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(acos, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(acosf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(acosl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(acosh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(acoshf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(acoshl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(asin, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(asinf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(asinl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(asinh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(asinhf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(asinhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(atan, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atanf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atanl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(atanh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cbrt, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cbrtf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cbrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ceilf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ceill, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cos, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cosf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cosl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cosh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(coshf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(coshl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(erf, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(erff, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(erfl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(erfc, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(erfcf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(erfcl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(exp, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(expf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(expl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(exp2, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(exp2f, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(exp2l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(expm1, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(expm1f, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(expm1l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(fdim, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fdimf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fdiml, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(floor, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(floorf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(floorl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(fma, "dddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmaf, "ffff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmal, "LdLdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(fmax, "ddd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmaxf, "fff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmaxl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(fmin, "ddd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fminf, "fff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fminl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(hypot, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(hypotf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(hypotl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(ilogb, "id", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ilogbf, "if", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ilogbl, "iLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(lgamma, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lgammaf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(llrint, "LLid", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(llrintf, "LLif", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(llrintl, "LLiLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(llround, "LLid", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(llroundf, "LLif", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(llroundl, "LLiLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(log, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(logf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(logl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(log10, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log10f, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log10l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(log1p, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log1pf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log1pl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(log2, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log2f, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log2l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(logb, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(logbf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(logbl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(lrint, "Lid", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lrintf, "Lif", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lrintl, "LiLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(lround, "Lid", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lroundf, "Lif", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lroundl, "LiLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(nearbyint, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nearbyintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nearbyintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(nextafter, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nextafterf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nextafterl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(nexttoward, "ddLd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nexttowardf, "ffLd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nexttowardl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(remainder, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(remainderf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(remainderl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(rint, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(rintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(round, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(roundf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(roundl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(scalbln, "ddLi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(scalblnf, "ffLi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(scalblnl, "LdLdLi", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(scalbn, "ddi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(scalbnf, "ffi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(scalbnl, "LdLdi", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(sin, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sinf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sinl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(sinh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sinhf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sinhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(sqrt, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sqrtf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sqrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(tan, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tanf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tanl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(tanh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(tgamma, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tgammaf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(trunc, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(truncf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cabs, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cabsf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cabsl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cacos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cacosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(carg, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cargf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cargl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(casin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(casinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(catan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(catanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(ccos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(ccosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cexp, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cexpf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cexpl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cimagl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(conj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(conjf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(conjl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(clog, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(clogf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(clogl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cproj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cprojf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cprojl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(cpow, "XdXdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cpowf, "XfXfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cpowl, "XLdXLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(csin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(csinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(csqrt, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csqrtf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csqrtl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(ctan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-LIBBUILTIN(ctanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-
-// __sinpi and friends are OS X specific library functions, but otherwise much
-// like the standard (non-complex) sin (etc).
-LIBBUILTIN(__sinpi, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__sinpif, "ff", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(__cospi, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__cospif, "ff", "fne", "math.h", ALL_LANGUAGES)
-
-LIBBUILTIN(__tanpi, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__tanpif, "ff", "fne", "math.h", ALL_LANGUAGES)
-
-// Similarly, __exp10 is OS X only
-LIBBUILTIN(__exp10, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__exp10f, "ff", "fne", "math.h", ALL_LANGUAGES)
-
-// Blocks runtime Builtin math library functions
-LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
-LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
-// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.
-
-// Annotation function
-BUILTIN(__builtin_annotation, "v.", "tn")
-
-// Invariants
-BUILTIN(__builtin_assume, "vb", "n")
-
-// Multiprecision Arithmetic Builtins.
-BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n")
-BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n")
-BUILTIN(__builtin_addc, "UiUiCUiCUiCUi*", "n")
-BUILTIN(__builtin_addcl, "ULiULiCULiCULiCULi*", "n")
-BUILTIN(__builtin_addcll, "ULLiULLiCULLiCULLiCULLi*", "n")
-BUILTIN(__builtin_subcb, "UcUcCUcCUcCUc*", "n")
-BUILTIN(__builtin_subcs, "UsUsCUsCUsCUs*", "n")
-BUILTIN(__builtin_subc, "UiUiCUiCUiCUi*", "n")
-BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n")
-BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n")
-
-// Checked Arithmetic Builtins for Security.
-BUILTIN(__builtin_add_overflow, "v.", "nt")
-BUILTIN(__builtin_sub_overflow, "v.", "nt")
-BUILTIN(__builtin_mul_overflow, "v.", "nt")
-BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "n")
-BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "n")
-BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "n")
-BUILTIN(__builtin_usub_overflow, "bUiCUiCUi*", "n")
-BUILTIN(__builtin_usubl_overflow, "bULiCULiCULi*", "n")
-BUILTIN(__builtin_usubll_overflow, "bULLiCULLiCULLi*", "n")
-BUILTIN(__builtin_umul_overflow, "bUiCUiCUi*", "n")
-BUILTIN(__builtin_umull_overflow, "bULiCULiCULi*", "n")
-BUILTIN(__builtin_umulll_overflow, "bULLiCULLiCULLi*", "n")
-BUILTIN(__builtin_sadd_overflow, "bSiCSiCSi*", "n")
-BUILTIN(__builtin_saddl_overflow, "bSLiCSLiCSLi*", "n")
-BUILTIN(__builtin_saddll_overflow, "bSLLiCSLLiCSLLi*", "n")
-BUILTIN(__builtin_ssub_overflow, "bSiCSiCSi*", "n")
-BUILTIN(__builtin_ssubl_overflow, "bSLiCSLiCSLi*", "n")
-BUILTIN(__builtin_ssubll_overflow, "bSLLiCSLLiCSLLi*", "n")
-BUILTIN(__builtin_smul_overflow, "bSiCSiCSi*", "n")
-BUILTIN(__builtin_smull_overflow, "bSLiCSLiCSLi*", "n")
-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")
-
-// Safestack builtins
-BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
-BUILTIN(__builtin___get_unsafe_stack_ptr, "v*", "Fn")
-
-// Nontemporal loads/stores builtins
-BUILTIN(__builtin_nontemporal_store, "v.", "t")
-BUILTIN(__builtin_nontemporal_load, "v.", "t")
-
-#undef BUILTIN
-#undef LIBBUILTIN
-#undef LANGBUILTIN
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
deleted file mode 100644
index c0a6af9..0000000
--- a/include/clang/Basic/Builtins.h
+++ /dev/null
@@ -1,220 +0,0 @@
-//===--- Builtins.h - Builtin function header -------------------*- 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 enum values for all the target-independent builtin
-/// functions.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_BUILTINS_H
-#define LLVM_CLANG_BASIC_BUILTINS_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include <cstring>
-
-// VC++ defines 'alloca' as an object-like macro, which interferes with our
-// builtins.
-#undef alloca
-
-namespace clang {
-class TargetInfo;
-class IdentifierTable;
-class ASTContext;
-class QualType;
-class LangOptions;
-
-enum LanguageID {
- GNU_LANG = 0x1, // builtin requires GNU mode.
- C_LANG = 0x2, // builtin for c only.
- CXX_LANG = 0x4, // builtin for cplusplus only.
- OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
- MS_LANG = 0x10, // builtin requires MS mode.
- ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
- ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode.
- ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode.
-};
-
-namespace Builtin {
-enum ID {
- NotBuiltin = 0, // This is not a builtin function.
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/Builtins.def"
- FirstTSBuiltin
-};
-
-struct Info {
- const char *Name, *Type, *Attributes, *HeaderName;
- LanguageID Langs;
- const char *Features;
-};
-
-/// \brief Holds information about both target-independent and
-/// target-specific builtins, allowing easy queries by clients.
-///
-/// Builtins from an optional auxiliary target are stored in
-/// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
-/// be translated back with getAuxBuiltinID() before use.
-class Context {
- llvm::ArrayRef<Info> TSRecords;
- llvm::ArrayRef<Info> AuxTSRecords;
-
-public:
- Context() {}
-
- /// \brief 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
- /// 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,
- /// e.g. "__builtin_abs".
- const char *getName(unsigned ID) const {
- return getRecord(ID).Name;
- }
-
- /// \brief 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
- bool isTSBuiltin(unsigned ID) const {
- return ID >= Builtin::FirstTSBuiltin;
- }
-
- /// \brief 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.
- bool isNoThrow(unsigned ID) const {
- return strchr(getRecord(ID).Attributes, 'n') != nullptr;
- }
-
- /// \brief 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.
- bool isReturnsTwice(unsigned ID) const {
- return strchr(getRecord(ID).Attributes, 'j') != nullptr;
- }
-
- /// \brief 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,
- /// 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
- /// function, such as "malloc", where we know the signature a
- /// priori.
- bool isPredefinedLibFunction(unsigned ID) const {
- return strchr(getRecord(ID).Attributes, 'f') != nullptr;
- }
-
- /// \brief 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.
- bool hasCustomTypechecking(unsigned ID) const {
- return strchr(getRecord(ID).Attributes, 't') != nullptr;
- }
-
- /// \brief 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,
- /// 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
- /// 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
- /// 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
- /// 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
- /// read memory, except for possibly errno.
- ///
- /// Such functions can be const when the MathErrno lang option is disabled.
- bool isConstWithoutErrno(unsigned ID) const {
- return strchr(getRecord(ID).Attributes, 'e') != nullptr;
- }
-
- const char *getRequiredFeatures(unsigned ID) const {
- return getRecord(ID).Features;
- }
-
- /// \brief 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
- /// for AuxTarget).
- unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
-
- /// Returns true if this is a libc/libm function without the '__builtin_'
- /// prefix.
- static bool isBuiltinFunc(const char *Name);
-
-private:
- const Info &getRecord(unsigned ID) const;
-
- /// \brief 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.
- bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
- const char *Fmt) const;
-};
-
-}
-
-/// \brief Kinds of BuiltinTemplateDecl.
-enum BuiltinTemplateKind : int {
- /// \brief This names the __make_integer_seq BuiltinTemplateDecl.
- BTK__make_integer_seq
-};
-
-} // end namespace clang
-#endif
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
deleted file mode 100644
index b440443..0000000
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ /dev/null
@@ -1,65 +0,0 @@
-//==- BuiltinsAArch64.def - AArch64 Builtin function 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 the AArch64-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-// In libgcc
-BUILTIN(__clear_cache, "vv*v*", "i")
-
-BUILTIN(__builtin_arm_ldrex, "v.", "t")
-BUILTIN(__builtin_arm_ldaex, "v.", "t")
-BUILTIN(__builtin_arm_strex, "i.", "t")
-BUILTIN(__builtin_arm_stlex, "i.", "t")
-BUILTIN(__builtin_arm_clrex, "v", "")
-
-// Bit manipulation
-BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
-BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc")
-
-// HINT
-BUILTIN(__builtin_arm_nop, "v", "")
-BUILTIN(__builtin_arm_yield, "v", "")
-BUILTIN(__builtin_arm_wfe, "v", "")
-BUILTIN(__builtin_arm_wfi, "v", "")
-BUILTIN(__builtin_arm_sev, "v", "")
-BUILTIN(__builtin_arm_sevl, "v", "")
-
-// CRC32
-BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc")
-BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc")
-
-// Memory barrier
-BUILTIN(__builtin_arm_dmb, "vUi", "nc")
-BUILTIN(__builtin_arm_dsb, "vUi", "nc")
-BUILTIN(__builtin_arm_isb, "vUi", "nc")
-
-// Prefetch
-BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc")
-
-// System Registers
-BUILTIN(__builtin_arm_rsr, "UicC*", "nc")
-BUILTIN(__builtin_arm_rsr64, "LUicC*", "nc")
-BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc")
-BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
-BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
-BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
-BUILTIN(__builtin_thread_pointer, "v*", "nc")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def
deleted file mode 100644
index bb9931f..0000000
--- a/include/clang/Basic/BuiltinsAMDGPU.def
+++ /dev/null
@@ -1,36 +0,0 @@
-//==- BuiltinsAMDGPU.def - AMDGPU Builtin function 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 the R600-specific builtin function database. Users of this
-// file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-BUILTIN(__builtin_amdgpu_div_scale, "dddbb*", "n")
-BUILTIN(__builtin_amdgpu_div_scalef, "fffbb*", "n")
-BUILTIN(__builtin_amdgpu_div_fmas, "ddddb", "nc")
-BUILTIN(__builtin_amdgpu_div_fmasf, "ffffb", "nc")
-BUILTIN(__builtin_amdgpu_div_fixup, "dddd", "nc")
-BUILTIN(__builtin_amdgpu_div_fixupf, "ffff", "nc")
-BUILTIN(__builtin_amdgpu_trig_preop, "ddi", "nc")
-BUILTIN(__builtin_amdgpu_trig_preopf, "ffi", "nc")
-BUILTIN(__builtin_amdgpu_rcp, "dd", "nc")
-BUILTIN(__builtin_amdgpu_rcpf, "ff", "nc")
-BUILTIN(__builtin_amdgpu_rsq, "dd", "nc")
-BUILTIN(__builtin_amdgpu_rsqf, "ff", "nc")
-BUILTIN(__builtin_amdgpu_rsq_clamped, "dd", "nc")
-BUILTIN(__builtin_amdgpu_rsq_clampedf, "ff", "nc")
-BUILTIN(__builtin_amdgpu_ldexp, "ddi", "nc")
-BUILTIN(__builtin_amdgpu_ldexpf, "ffi", "nc")
-BUILTIN(__builtin_amdgpu_class, "bdi", "nc")
-BUILTIN(__builtin_amdgpu_classf, "bfi", "nc")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
deleted file mode 100644
index 3e8e2bf..0000000
--- a/include/clang/Basic/BuiltinsARM.def
+++ /dev/null
@@ -1,114 +0,0 @@
-//===--- BuiltinsARM.def - ARM Builtin function 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 the ARM-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-#if defined(BUILTIN) && !defined(LANGBUILTIN)
-# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
-#endif
-
-// In libgcc
-BUILTIN(__clear_cache, "vv*v*", "i")
-BUILTIN(__builtin_thread_pointer, "v*", "")
-
-// Saturating arithmetic
-BUILTIN(__builtin_arm_qadd, "iii", "nc")
-BUILTIN(__builtin_arm_qsub, "iii", "nc")
-BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
-BUILTIN(__builtin_arm_usat, "UiUiUi", "nc")
-
-// Bit manipulation
-BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
-
-// Store and load exclusive
-BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "")
-BUILTIN(__builtin_arm_strexd, "iLLUiv*", "")
-
-BUILTIN(__builtin_arm_ldrex, "v.", "t")
-BUILTIN(__builtin_arm_ldaex, "v.", "t")
-BUILTIN(__builtin_arm_strex, "i.", "t")
-BUILTIN(__builtin_arm_stlex, "i.", "t")
-BUILTIN(__builtin_arm_clrex, "v", "")
-
-// VFP
-BUILTIN(__builtin_arm_get_fpscr, "Ui", "nc")
-BUILTIN(__builtin_arm_set_fpscr, "vUi", "nc")
-BUILTIN(__builtin_arm_vcvtr_f, "ffi", "nc")
-BUILTIN(__builtin_arm_vcvtr_d, "fdi", "nc")
-
-// Coprocessor
-BUILTIN(__builtin_arm_mcr, "vUIiUIiUiUIiUIiUIi", "")
-BUILTIN(__builtin_arm_mcr2, "vUIiUIiUiUIiUIiUIi", "")
-BUILTIN(__builtin_arm_mrc, "UiUIiUIiUIiUIiUIi", "")
-BUILTIN(__builtin_arm_mrc2, "UiUIiUIiUIiUIiUIi", "")
-BUILTIN(__builtin_arm_cdp, "vUiUiUiUiUiUi", "")
-BUILTIN(__builtin_arm_cdp2, "vUiUiUiUiUiUi", "")
-BUILTIN(__builtin_arm_mcrr, "vUIiUIiUiUiUIi", "")
-BUILTIN(__builtin_arm_mcrr2, "vUIiUIiUiUiUIi", "")
-
-// CRC32
-BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc")
-BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
-
-// HINT
-BUILTIN(__builtin_arm_nop, "v", "")
-BUILTIN(__builtin_arm_yield, "v", "")
-BUILTIN(__builtin_arm_wfe, "v", "")
-BUILTIN(__builtin_arm_wfi, "v", "")
-BUILTIN(__builtin_arm_sev, "v", "")
-BUILTIN(__builtin_arm_sevl, "v", "")
-BUILTIN(__builtin_arm_dbg, "vUi", "")
-
-// Data barrier
-BUILTIN(__builtin_arm_dmb, "vUi", "nc")
-BUILTIN(__builtin_arm_dsb, "vUi", "nc")
-BUILTIN(__builtin_arm_isb, "vUi", "nc")
-
-// Prefetch
-BUILTIN(__builtin_arm_prefetch, "vvC*UiUi", "nc")
-
-// System registers (ACLE)
-BUILTIN(__builtin_arm_rsr, "UicC*", "nc")
-BUILTIN(__builtin_arm_rsr64, "LLUicC*", "nc")
-BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc")
-BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
-BUILTIN(__builtin_arm_wsr64, "vcC*LLUi", "nc")
-BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
-
-// MSVC
-LANGBUILTIN(__emit, "vIUiC", "", 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)
-
-LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__ldrexd, "WiWiCD*", "", ALL_MS_LANGUAGES)
-LANGBUILTIN(_MoveFromCoprocessor, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
-LANGBUILTIN(_MoveFromCoprocessor2, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
-LANGBUILTIN(_MoveToCoprocessor, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
-LANGBUILTIN(_MoveToCoprocessor2, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
-
-#undef BUILTIN
-#undef LANGBUILTIN
diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def
deleted file mode 100644
index c071a46..0000000
--- a/include/clang/Basic/BuiltinsHexagon.def
+++ /dev/null
@@ -1,878 +0,0 @@
-//===-- BuiltinsHexagon.def - Hexagon Builtin function 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 the Hexagon-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-// The builtins below are not autogenerated from iset.py.
-// Make sure you do not overwrite these.
-
-BUILTIN(__builtin_SI_to_SXTHI_asrh, "ii", "")
-BUILTIN(__builtin_circ_ldd, "LLi*LLi*LLi*ii", "")
-
-// The builtins above are not autogenerated from iset.py.
-// Make sure you do not overwrite these.
-
-BUILTIN(__builtin_HEXAGON_C2_cmpeq,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgt,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgtu,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpeqp,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgtp,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgtup,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_rcmpeqi,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_rcmpneqi,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_rcmpeq,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_rcmpneq,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_bitsset,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_bitsclr,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_nbitsset,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_nbitsclr,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpeqi,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgti,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgtui,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgei,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgeui,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmplt,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpltu,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_bitsclri,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_nbitsclri,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_cmpneqi,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_cmpltei,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_cmplteui,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_cmpneq,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_cmplte,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_cmplteu,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_and,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_or,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_xor,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_andn,"bii","")
-BUILTIN(__builtin_HEXAGON_C2_not,"bi","")
-BUILTIN(__builtin_HEXAGON_C2_orn,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_and_and,"biii","")
-BUILTIN(__builtin_HEXAGON_C4_and_or,"biii","")
-BUILTIN(__builtin_HEXAGON_C4_or_and,"biii","")
-BUILTIN(__builtin_HEXAGON_C4_or_or,"biii","")
-BUILTIN(__builtin_HEXAGON_C4_and_andn,"biii","")
-BUILTIN(__builtin_HEXAGON_C4_and_orn,"biii","")
-BUILTIN(__builtin_HEXAGON_C4_or_andn,"biii","")
-BUILTIN(__builtin_HEXAGON_C4_or_orn,"biii","")
-BUILTIN(__builtin_HEXAGON_C2_pxfer_map,"bi","")
-BUILTIN(__builtin_HEXAGON_C2_any8,"bi","")
-BUILTIN(__builtin_HEXAGON_C2_all8,"bi","")
-BUILTIN(__builtin_HEXAGON_C2_vitpack,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_mux,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_muxii,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_muxir,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_muxri,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_vmux,"LLiiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_C2_mask,"LLii","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpbeq,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbgt,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbgti,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbeq,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbeqi,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbgtu,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbgtui,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbgt,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbgti,"bii","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpheq,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmphgt,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmphgtu,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpheqi,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmphgti,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmphgtui,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpheq,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmphgt,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmphgtu,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpheqi,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmphgti,"bii","")
-BUILTIN(__builtin_HEXAGON_A4_cmphgtui,"bii","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpweq,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpwgt,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu,"bLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpweqi,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpwgti,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui,"bLLii","")
-BUILTIN(__builtin_HEXAGON_A4_boundscheck,"biLLi","")
-BUILTIN(__builtin_HEXAGON_A4_tlbmatch,"bLLii","")
-BUILTIN(__builtin_HEXAGON_C2_tfrpr,"ii","")
-BUILTIN(__builtin_HEXAGON_C2_tfrrp,"bi","")
-BUILTIN(__builtin_HEXAGON_C4_fastcorner9,"bii","")
-BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not,"bii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s0,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s1,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s0,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s1,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s0,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s1,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s0,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s1,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s1,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s1,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s1,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s1,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpysmi,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_macsip,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_macsin,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyss_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyss_acc_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyss_nac_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_acc_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_nac_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_up,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_up,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpysu_up,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyss_rnd_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M4_mac_up_s1_sat,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_nac_up_s1_sat,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyi,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyui,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_maci,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_acci,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_accii,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_nacci,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_naccii,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_subacc,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyrr_addr,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyri_addr_u2,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyri_addr,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyri_addi,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyrr_addi,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2s_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2s_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2su_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2su_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0pack,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1pack,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2es_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2es_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2es,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrmac_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrmpy_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s0,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s1,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vrmpybuu,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vrmacbuu,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vrmpybsu,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vrmacbsu,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vmpybuu,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M5_vmpybsu,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M5_vmacbuu,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M5_vmacbsu,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M5_vdmpybsu,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vdmacbsu,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmacs_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmacs_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmpys_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmpys_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_cmacs_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmacs_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmacsc_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmacsc_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpys_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpys_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpysc_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpysc_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cnacs_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cnacs_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cnacsc_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cnacsc_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpys_acc_s1,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1rp,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M2_mmacls_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacls_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmachs_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmachs_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyl_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyl_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyh_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyh_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacls_rs0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacls_rs1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmachs_rs0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmachs_rs1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_hmmpyl_rs1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_hmmpyh_rs1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_hmmpyl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_hmmpyh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mmaculs_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmaculs_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyul_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyul_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0c,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0c,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_cmaci_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmacr_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0c,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0c,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyi_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyr_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M4_cmpyi_wh,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M4_cmpyr_wh,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M4_cmpyi_whc,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M4_cmpyr_whc,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_i,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_r,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_i,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_r,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_i,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_r,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vcrotate,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S4_vrcrotate_acc,"LLiLLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S4_vrcrotate,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S2_vcnegh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vrcnegh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_M4_pmpyw,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M4_vpmpyh,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M4_pmpyw_acc,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M4_vpmpyh_acc,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_A2_add,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_sub,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addsat,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subsat,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addi,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_l16_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_l16_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_l16_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_l16_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_aslh,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_asrh,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_addp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_addpsat,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_addsp,"LLiiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_subp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_neg,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_negsat,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_abs,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_abssat,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_vconj,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_negp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_absp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_max,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_maxu,"Uiii","")
-BUILTIN(__builtin_HEXAGON_A2_min,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_minu,"Uiii","")
-BUILTIN(__builtin_HEXAGON_A2_maxp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_maxup,"ULLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_minp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_minup,"ULLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_tfr,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_tfrsi,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_tfrp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_tfrpi,"LLii","")
-BUILTIN(__builtin_HEXAGON_A2_zxtb,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_sxtb,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_zxth,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_sxth,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_combinew,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A4_combineri,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A4_combineir,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A2_combineii,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A2_combine_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_combine_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_combine_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_combine_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_tfril,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_tfrih,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_and,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_or,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_xor,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_not,"ii","")
-BUILTIN(__builtin_HEXAGON_M2_xor_xacc,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_xor_xacc,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_andn,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_orn,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_andnp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_ornp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_addaddi,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_subaddi,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_and_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_and_andn,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_and_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_and_xor,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_or_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_or_andn,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_or_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_or_xor,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_or_andix,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_or_andi,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_or_ori,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_xor_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_xor_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_xor_andn,"iiii","")
-BUILTIN(__builtin_HEXAGON_A2_subri,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_andir,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_orir,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_andp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_orp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_xorp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_notp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_sxtw,"LLii","")
-BUILTIN(__builtin_HEXAGON_A2_sat,"iLLi","")
-BUILTIN(__builtin_HEXAGON_A2_roundsat,"iLLi","")
-BUILTIN(__builtin_HEXAGON_A2_sath,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_satuh,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_satub,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_satb,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_vaddub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddb_map,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddubs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddhs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vadduhs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A5_vaddhubs,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddws,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxaddsubw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxsubaddw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxaddsubh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxsubaddh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxaddsubhr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxsubaddhr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_svavgh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svavghs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svnavgh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svaddh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svaddhs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svadduhs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svsubh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svsubhs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svsubuhs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_vraddub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vraddub_acc,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vraddh,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vradduh,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubb_map,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsububs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubhs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubuhs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubws,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vabsh,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vabshsat,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vabsw,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vabswsat,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vabsdiffw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vabsdiffh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vrsadub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vrsadub_acc,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavguh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavgh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavgw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgwr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavgwr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgwcr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavgwcr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavghcr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavghcr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavguw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavguwr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgubr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavguhr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavghr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavghr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_round_ri,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_round_rr,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_round_ri_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_round_rr_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cround_ri,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cround_rr,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_vrminh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrmaxh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrminuh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrmaxuh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrminw,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrmaxw,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrminuw,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrmaxuw,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A2_vminb,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxb,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminuh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxuh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminuw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxuw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_modwrapu,"iii","")
-BUILTIN(__builtin_HEXAGON_F2_sfadd,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sfsub,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sfmpy,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sffma,"ffff","")
-BUILTIN(__builtin_HEXAGON_F2_sffma_sc,"ffffi","")
-BUILTIN(__builtin_HEXAGON_F2_sffms,"ffff","")
-BUILTIN(__builtin_HEXAGON_F2_sffma_lib,"ffff","")
-BUILTIN(__builtin_HEXAGON_F2_sffms_lib,"ffff","")
-BUILTIN(__builtin_HEXAGON_F2_sfcmpeq,"bff","")
-BUILTIN(__builtin_HEXAGON_F2_sfcmpgt,"bff","")
-BUILTIN(__builtin_HEXAGON_F2_sfcmpge,"bff","")
-BUILTIN(__builtin_HEXAGON_F2_sfcmpuo,"bff","")
-BUILTIN(__builtin_HEXAGON_F2_sfmax,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sfmin,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sfclass,"bfi","")
-BUILTIN(__builtin_HEXAGON_F2_sfimm_p,"fi","")
-BUILTIN(__builtin_HEXAGON_F2_sfimm_n,"fi","")
-BUILTIN(__builtin_HEXAGON_F2_sffixupn,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sffixupd,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sffixupr,"ff","")
-BUILTIN(__builtin_HEXAGON_F2_dfadd,"ddd","")
-BUILTIN(__builtin_HEXAGON_F2_dfsub,"ddd","")
-BUILTIN(__builtin_HEXAGON_F2_dfmpy,"ddd","")
-BUILTIN(__builtin_HEXAGON_F2_dffma,"dddd","")
-BUILTIN(__builtin_HEXAGON_F2_dffms,"dddd","")
-BUILTIN(__builtin_HEXAGON_F2_dffma_lib,"dddd","")
-BUILTIN(__builtin_HEXAGON_F2_dffms_lib,"dddd","")
-BUILTIN(__builtin_HEXAGON_F2_dffma_sc,"ddddi","")
-BUILTIN(__builtin_HEXAGON_F2_dfmax,"ddd","")
-BUILTIN(__builtin_HEXAGON_F2_dfmin,"ddd","")
-BUILTIN(__builtin_HEXAGON_F2_dfcmpeq,"bdd","")
-BUILTIN(__builtin_HEXAGON_F2_dfcmpgt,"bdd","")
-BUILTIN(__builtin_HEXAGON_F2_dfcmpge,"bdd","")
-BUILTIN(__builtin_HEXAGON_F2_dfcmpuo,"bdd","")
-BUILTIN(__builtin_HEXAGON_F2_dfclass,"bdi","")
-BUILTIN(__builtin_HEXAGON_F2_dfimm_p,"di","")
-BUILTIN(__builtin_HEXAGON_F2_dfimm_n,"di","")
-BUILTIN(__builtin_HEXAGON_F2_dffixupn,"ddd","")
-BUILTIN(__builtin_HEXAGON_F2_dffixupd,"ddd","")
-BUILTIN(__builtin_HEXAGON_F2_dffixupr,"dd","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2df,"df","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2sf,"fd","")
-BUILTIN(__builtin_HEXAGON_F2_conv_uw2sf,"fi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_uw2df,"di","")
-BUILTIN(__builtin_HEXAGON_F2_conv_w2sf,"fi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_w2df,"di","")
-BUILTIN(__builtin_HEXAGON_F2_conv_ud2sf,"fLLi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_ud2df,"dLLi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_d2sf,"fLLi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_d2df,"dLLi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw,"if","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2w,"if","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud,"LLif","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2d,"LLif","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2uw,"id","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2w,"id","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2ud,"LLid","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2d,"LLid","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw_chop,"if","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2w_chop,"if","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud_chop,"LLif","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2d_chop,"LLif","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2uw_chop,"id","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2w_chop,"id","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2ud_chop,"LLid","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2d_chop,"LLid","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_xor,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_xor,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_xor,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_xor,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_xacc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_xacc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_xacc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_xacc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S4_lsli,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_addasl_rrri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_andi_asl_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_ori_asl_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_addi_asl_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_subi_asl_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_andi_lsr_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_ori_lsr_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_addi_lsr_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_subi_lsr_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_valignib,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_valignrb,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vspliceib,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsplicerb,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsplatrh,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsplatrb,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_insert,"iiiii","")
-BUILTIN(__builtin_HEXAGON_S2_tableidxb_goodsyntax,"iiiii","")
-BUILTIN(__builtin_HEXAGON_S2_tableidxh_goodsyntax,"iiiii","")
-BUILTIN(__builtin_HEXAGON_S2_tableidxw_goodsyntax,"iiiii","")
-BUILTIN(__builtin_HEXAGON_S2_tableidxd_goodsyntax,"iiiii","")
-BUILTIN(__builtin_HEXAGON_A4_bitspliti,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A4_bitsplit,"LLiii","")
-BUILTIN(__builtin_HEXAGON_S4_extract,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_extractu,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_insertp,"LLiLLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S4_extractp,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S2_extractup,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S2_insert_rp,"iiiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_extract_rp,"iiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_extractu_rp,"iiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_insertp_rp,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_extractp_rp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_extractup_rp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_tstbit_i,"bii","")
-BUILTIN(__builtin_HEXAGON_S4_ntstbit_i,"bii","")
-BUILTIN(__builtin_HEXAGON_S2_setbit_i,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_togglebit_i,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_clrbit_i,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_tstbit_r,"bii","")
-BUILTIN(__builtin_HEXAGON_S4_ntstbit_r,"bii","")
-BUILTIN(__builtin_HEXAGON_S2_setbit_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_togglebit_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_clrbit_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S5_asrhub_sat,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S5_vasrhrnd_goodsyntax,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_svw_trun,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_svw_trun,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vrndpackwh,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vrndpackwhs,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsxtbh,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vzxtbh,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsathub,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_svsathub,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_svsathb,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_vsathb,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vtrunohb,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vtrunewh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vtrunowh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vtrunehb,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsxthw,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vzxthw,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsatwh,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsatwuh,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_packhl,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A2_swiz,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_vsathub_nopack,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsathb_nopack,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsatwh_nopack,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsatwuh_nopack,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_shuffob,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_shuffeb,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_shuffoh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_shuffeh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S5_popcountp,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S4_parity,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_parityp,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_lfsp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_clbnorm,"ii","")
-BUILTIN(__builtin_HEXAGON_S4_clbaddi,"iii","")
-BUILTIN(__builtin_HEXAGON_S4_clbpnorm,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S4_clbpaddi,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S2_clb,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_cl0,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_cl1,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_clbp,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_cl0p,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_cl1p,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_brev,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_brevp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_ct0,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_ct1,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_ct0p,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_ct1p,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsLe64.def b/include/clang/Basic/BuiltinsLe64.def
deleted file mode 100644
index 5328606..0000000
--- a/include/clang/Basic/BuiltinsLe64.def
+++ /dev/null
@@ -1,19 +0,0 @@
-//==- BuiltinsLe64.def - Le64 Builtin function 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 the Le64-specific builtin function database. Users of this
-// file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-BUILTIN(__clear_cache, "vv*v*", "i")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def
deleted file mode 100644
index 2d217f7..0000000
--- a/include/clang/Basic/BuiltinsMips.def
+++ /dev/null
@@ -1,900 +0,0 @@
-//===-- BuiltinsMips.def - Mips Builtin function 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 the MIPS-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-// MIPS DSP Rev 1
-
-// Add/subtract with optional saturation
-BUILTIN(__builtin_mips_addu_qb, "V4ScV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_addu_s_qb, "V4ScV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_subu_qb, "V4ScV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_subu_s_qb, "V4ScV4ScV4Sc", "n")
-
-BUILTIN(__builtin_mips_addq_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_addq_s_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_subq_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_subq_s_ph, "V2sV2sV2s", "n")
-
-BUILTIN(__builtin_mips_madd, "LLiLLiii", "nc")
-BUILTIN(__builtin_mips_maddu, "LLiLLiUiUi", "nc")
-BUILTIN(__builtin_mips_msub, "LLiLLiii", "nc")
-BUILTIN(__builtin_mips_msubu, "LLiLLiUiUi", "nc")
-
-BUILTIN(__builtin_mips_addq_s_w, "iii", "n")
-BUILTIN(__builtin_mips_subq_s_w, "iii", "n")
-
-BUILTIN(__builtin_mips_addsc, "iii", "n")
-BUILTIN(__builtin_mips_addwc, "iii", "n")
-
-BUILTIN(__builtin_mips_modsub, "iii", "nc")
-
-BUILTIN(__builtin_mips_raddu_w_qb, "iV4Sc", "nc")
-
-BUILTIN(__builtin_mips_absq_s_ph, "V2sV2s", "n")
-BUILTIN(__builtin_mips_absq_s_w, "ii", "n")
-
-BUILTIN(__builtin_mips_precrq_qb_ph, "V4ScV2sV2s", "nc")
-BUILTIN(__builtin_mips_precrqu_s_qb_ph, "V4ScV2sV2s", "n")
-BUILTIN(__builtin_mips_precrq_ph_w, "V2sii", "nc")
-BUILTIN(__builtin_mips_precrq_rs_ph_w, "V2sii", "n")
-BUILTIN(__builtin_mips_preceq_w_phl, "iV2s", "nc")
-BUILTIN(__builtin_mips_preceq_w_phr, "iV2s", "nc")
-BUILTIN(__builtin_mips_precequ_ph_qbl, "V2sV4Sc", "nc")
-BUILTIN(__builtin_mips_precequ_ph_qbr, "V2sV4Sc", "nc")
-BUILTIN(__builtin_mips_precequ_ph_qbla, "V2sV4Sc", "nc")
-BUILTIN(__builtin_mips_precequ_ph_qbra, "V2sV4Sc", "nc")
-BUILTIN(__builtin_mips_preceu_ph_qbl, "V2sV4Sc", "nc")
-BUILTIN(__builtin_mips_preceu_ph_qbr, "V2sV4Sc", "nc")
-BUILTIN(__builtin_mips_preceu_ph_qbla, "V2sV4Sc", "nc")
-BUILTIN(__builtin_mips_preceu_ph_qbra, "V2sV4Sc", "nc")
-
-BUILTIN(__builtin_mips_shll_qb, "V4ScV4Sci", "n")
-BUILTIN(__builtin_mips_shrl_qb, "V4ScV4Sci", "nc")
-BUILTIN(__builtin_mips_shll_ph, "V2sV2si", "n")
-BUILTIN(__builtin_mips_shll_s_ph, "V2sV2si", "n")
-BUILTIN(__builtin_mips_shra_ph, "V2sV2si", "nc")
-BUILTIN(__builtin_mips_shra_r_ph, "V2sV2si", "nc")
-BUILTIN(__builtin_mips_shll_s_w, "iii", "n")
-BUILTIN(__builtin_mips_shra_r_w, "iii", "nc")
-BUILTIN(__builtin_mips_shilo, "LLiLLii", "nc")
-
-BUILTIN(__builtin_mips_muleu_s_ph_qbl, "V2sV4ScV2s", "n")
-BUILTIN(__builtin_mips_muleu_s_ph_qbr, "V2sV4ScV2s", "n")
-BUILTIN(__builtin_mips_mulq_rs_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_muleq_s_w_phl, "iV2sV2s", "n")
-BUILTIN(__builtin_mips_muleq_s_w_phr, "iV2sV2s", "n")
-BUILTIN(__builtin_mips_mulsaq_s_w_ph, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_maq_s_w_phl, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_maq_s_w_phr, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_maq_sa_w_phl, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_maq_sa_w_phr, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_mult, "LLiii", "nc")
-BUILTIN(__builtin_mips_multu, "LLiUiUi", "nc")
-
-BUILTIN(__builtin_mips_dpau_h_qbl, "LLiLLiV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_dpau_h_qbr, "LLiLLiV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_dpsu_h_qbl, "LLiLLiV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_dpsu_h_qbr, "LLiLLiV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_dpaq_s_w_ph, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_dpsq_s_w_ph, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_dpaq_sa_l_w, "LLiLLiii", "n")
-BUILTIN(__builtin_mips_dpsq_sa_l_w, "LLiLLiii", "n")
-
-BUILTIN(__builtin_mips_cmpu_eq_qb, "vV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_cmpu_lt_qb, "vV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_cmpu_le_qb, "vV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_cmpgu_eq_qb, "iV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_cmpgu_lt_qb, "iV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_cmpgu_le_qb, "iV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_cmp_eq_ph, "vV2sV2s", "n")
-BUILTIN(__builtin_mips_cmp_lt_ph, "vV2sV2s", "n")
-BUILTIN(__builtin_mips_cmp_le_ph, "vV2sV2s", "n")
-
-BUILTIN(__builtin_mips_extr_s_h, "iLLii", "n")
-BUILTIN(__builtin_mips_extr_w, "iLLii", "n")
-BUILTIN(__builtin_mips_extr_rs_w, "iLLii", "n")
-BUILTIN(__builtin_mips_extr_r_w, "iLLii", "n")
-BUILTIN(__builtin_mips_extp, "iLLii", "n")
-BUILTIN(__builtin_mips_extpdp, "iLLii", "n")
-
-BUILTIN(__builtin_mips_wrdsp, "viIi", "n")
-BUILTIN(__builtin_mips_rddsp, "iIi", "n")
-BUILTIN(__builtin_mips_insv, "iii", "n")
-BUILTIN(__builtin_mips_bitrev, "ii", "nc")
-BUILTIN(__builtin_mips_packrl_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_repl_qb, "V4Sci", "nc")
-BUILTIN(__builtin_mips_repl_ph, "V2si", "nc")
-BUILTIN(__builtin_mips_pick_qb, "V4ScV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_pick_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_mthlip, "LLiLLii", "n")
-BUILTIN(__builtin_mips_bposge32, "i", "n")
-BUILTIN(__builtin_mips_lbux, "iv*i", "n")
-BUILTIN(__builtin_mips_lhx, "iv*i", "n")
-BUILTIN(__builtin_mips_lwx, "iv*i", "n")
-
-// MIPS DSP Rev 2
-
-BUILTIN(__builtin_mips_absq_s_qb, "V4ScV4Sc", "n")
-
-BUILTIN(__builtin_mips_addqh_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_addqh_r_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_addqh_w, "iii", "nc")
-BUILTIN(__builtin_mips_addqh_r_w, "iii", "nc")
-
-BUILTIN(__builtin_mips_addu_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_addu_s_ph, "V2sV2sV2s", "n")
-
-BUILTIN(__builtin_mips_adduh_qb, "V4ScV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_adduh_r_qb, "V4ScV4ScV4Sc", "nc")
-
-BUILTIN(__builtin_mips_append, "iiiIi", "nc")
-BUILTIN(__builtin_mips_balign, "iiiIi", "nc")
-
-BUILTIN(__builtin_mips_cmpgdu_eq_qb, "iV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_cmpgdu_lt_qb, "iV4ScV4Sc", "n")
-BUILTIN(__builtin_mips_cmpgdu_le_qb, "iV4ScV4Sc", "n")
-
-BUILTIN(__builtin_mips_dpa_w_ph, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_dps_w_ph, "LLiLLiV2sV2s", "nc")
-
-BUILTIN(__builtin_mips_dpaqx_s_w_ph, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_dpaqx_sa_w_ph, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_dpax_w_ph, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_dpsx_w_ph, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_dpsqx_s_w_ph, "LLiLLiV2sV2s", "n")
-BUILTIN(__builtin_mips_dpsqx_sa_w_ph, "LLiLLiV2sV2s", "n")
-
-BUILTIN(__builtin_mips_mul_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_mul_s_ph, "V2sV2sV2s", "n")
-
-BUILTIN(__builtin_mips_mulq_rs_w, "iii", "n")
-BUILTIN(__builtin_mips_mulq_s_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_mulq_s_w, "iii", "n")
-BUILTIN(__builtin_mips_mulsa_w_ph, "LLiLLiV2sV2s", "nc")
-
-BUILTIN(__builtin_mips_precr_qb_ph, "V4ScV2sV2s", "n")
-BUILTIN(__builtin_mips_precr_sra_ph_w, "V2siiIi", "nc")
-BUILTIN(__builtin_mips_precr_sra_r_ph_w, "V2siiIi", "nc")
-
-BUILTIN(__builtin_mips_prepend, "iiiIi", "nc")
-
-BUILTIN(__builtin_mips_shra_qb, "V4ScV4Sci", "nc")
-BUILTIN(__builtin_mips_shra_r_qb, "V4ScV4Sci", "nc")
-BUILTIN(__builtin_mips_shrl_ph, "V2sV2si", "nc")
-
-BUILTIN(__builtin_mips_subqh_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_subqh_r_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_subqh_w, "iii", "nc")
-BUILTIN(__builtin_mips_subqh_r_w, "iii", "nc")
-
-BUILTIN(__builtin_mips_subu_ph, "V2sV2sV2s", "n")
-BUILTIN(__builtin_mips_subu_s_ph, "V2sV2sV2s", "n")
-
-BUILTIN(__builtin_mips_subuh_qb, "V4ScV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_subuh_r_qb, "V4ScV4ScV4Sc", "nc")
-
-// MIPS MSA
-
-BUILTIN(__builtin_msa_add_a_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_add_a_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_add_a_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_add_a_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_adds_a_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_adds_a_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_adds_a_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_adds_a_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_adds_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_adds_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_adds_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_adds_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_adds_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_adds_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_adds_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_adds_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_addv_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_addv_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_addv_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_addv_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_addvi_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_addvi_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_addvi_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_addvi_d, "V2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_and_v, "V16UcV16UcV16Uc", "nc")
-
-BUILTIN(__builtin_msa_andi_b, "V16UcV16UcIUi", "nc")
-
-BUILTIN(__builtin_msa_asub_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_asub_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_asub_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_asub_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_asub_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_asub_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_asub_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_asub_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_ave_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_ave_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_ave_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_ave_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_ave_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_ave_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_ave_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_ave_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_aver_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_aver_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_aver_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_aver_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_aver_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_aver_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_aver_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_aver_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_bclr_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_bclr_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_bclr_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_bclr_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_bclri_b, "V16UcV16UcIUi", "nc")
-BUILTIN(__builtin_msa_bclri_h, "V8UsV8UsIUi", "nc")
-BUILTIN(__builtin_msa_bclri_w, "V4UiV4UiIUi", "nc")
-BUILTIN(__builtin_msa_bclri_d, "V2ULLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_binsl_b, "V16UcV16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_binsl_h, "V8UsV8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_binsl_w, "V4UiV4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_binsl_d, "V2ULLiV2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_binsli_b, "V16UcV16UcV16UcIUi", "nc")
-BUILTIN(__builtin_msa_binsli_h, "V8UsV8UsV8UsIUi", "nc")
-BUILTIN(__builtin_msa_binsli_w, "V4UiV4UiV4UiIUi", "nc")
-BUILTIN(__builtin_msa_binsli_d, "V2ULLiV2ULLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_binsr_b, "V16UcV16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_binsr_h, "V8UsV8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_binsr_w, "V4UiV4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_binsr_d, "V2ULLiV2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_binsri_b, "V16UcV16UcV16UcIUi", "nc")
-BUILTIN(__builtin_msa_binsri_h, "V8UsV8UsV8UsIUi", "nc")
-BUILTIN(__builtin_msa_binsri_w, "V4UiV4UiV4UiIUi", "nc")
-BUILTIN(__builtin_msa_binsri_d, "V2ULLiV2ULLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_bmnz_v, "V16UcV16UcV16UcV16Uc", "nc")
-
-BUILTIN(__builtin_msa_bmnzi_b, "V16UcV16UcV16UcIUi", "nc")
-
-BUILTIN(__builtin_msa_bmz_v, "V16UcV16UcV16UcV16Uc", "nc")
-
-BUILTIN(__builtin_msa_bmzi_b, "V16UcV16UcV16UcIUi", "nc")
-
-BUILTIN(__builtin_msa_bneg_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_bneg_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_bneg_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_bneg_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_bnegi_b, "V16UcV16UcIUi", "nc")
-BUILTIN(__builtin_msa_bnegi_h, "V8UsV8UsIUi", "nc")
-BUILTIN(__builtin_msa_bnegi_w, "V4UiV4UiIUi", "nc")
-BUILTIN(__builtin_msa_bnegi_d, "V2ULLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_bnz_b, "iV16Uc", "nc")
-BUILTIN(__builtin_msa_bnz_h, "iV8Us", "nc")
-BUILTIN(__builtin_msa_bnz_w, "iV4Ui", "nc")
-BUILTIN(__builtin_msa_bnz_d, "iV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_bnz_v, "iV16Uc", "nc")
-
-BUILTIN(__builtin_msa_bsel_v, "V16UcV16UcV16UcV16Uc", "nc")
-
-BUILTIN(__builtin_msa_bseli_b, "V16UcV16UcV16UcIUi", "nc")
-
-BUILTIN(__builtin_msa_bset_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_bset_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_bset_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_bset_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_bseti_b, "V16UcV16UcIUi", "nc")
-BUILTIN(__builtin_msa_bseti_h, "V8UsV8UsIUi", "nc")
-BUILTIN(__builtin_msa_bseti_w, "V4UiV4UiIUi", "nc")
-BUILTIN(__builtin_msa_bseti_d, "V2ULLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_bz_b, "iV16Uc", "nc")
-BUILTIN(__builtin_msa_bz_h, "iV8Us", "nc")
-BUILTIN(__builtin_msa_bz_w, "iV4Ui", "nc")
-BUILTIN(__builtin_msa_bz_d, "iV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_bz_v, "iV16Uc", "nc")
-
-BUILTIN(__builtin_msa_ceq_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_ceq_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_ceq_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_ceq_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_ceqi_b, "V16ScV16ScISi", "nc")
-BUILTIN(__builtin_msa_ceqi_h, "V8SsV8SsISi", "nc")
-BUILTIN(__builtin_msa_ceqi_w, "V4SiV4SiISi", "nc")
-BUILTIN(__builtin_msa_ceqi_d, "V2SLLiV2SLLiISi", "nc")
-
-BUILTIN(__builtin_msa_cfcmsa, "iIi", "n")
-
-BUILTIN(__builtin_msa_cle_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_cle_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_cle_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_cle_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_cle_u_b, "V16ScV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_cle_u_h, "V8SsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_cle_u_w, "V4SiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_cle_u_d, "V2SLLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_clei_s_b, "V16ScV16ScISi", "nc")
-BUILTIN(__builtin_msa_clei_s_h, "V8SsV8SsISi", "nc")
-BUILTIN(__builtin_msa_clei_s_w, "V4SiV4SiISi", "nc")
-BUILTIN(__builtin_msa_clei_s_d, "V2SLLiV2SLLiISi", "nc")
-
-BUILTIN(__builtin_msa_clei_u_b, "V16ScV16UcIUi", "nc")
-BUILTIN(__builtin_msa_clei_u_h, "V8SsV8UsIUi", "nc")
-BUILTIN(__builtin_msa_clei_u_w, "V4SiV4UiIUi", "nc")
-BUILTIN(__builtin_msa_clei_u_d, "V2SLLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_clt_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_clt_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_clt_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_clt_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_clt_u_b, "V16ScV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_clt_u_h, "V8SsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_clt_u_w, "V4SiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_clt_u_d, "V2SLLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_clti_s_b, "V16ScV16ScISi", "nc")
-BUILTIN(__builtin_msa_clti_s_h, "V8SsV8SsISi", "nc")
-BUILTIN(__builtin_msa_clti_s_w, "V4SiV4SiISi", "nc")
-BUILTIN(__builtin_msa_clti_s_d, "V2SLLiV2SLLiISi", "nc")
-
-BUILTIN(__builtin_msa_clti_u_b, "V16ScV16UcIUi", "nc")
-BUILTIN(__builtin_msa_clti_u_h, "V8SsV8UsIUi", "nc")
-BUILTIN(__builtin_msa_clti_u_w, "V4SiV4UiIUi", "nc")
-BUILTIN(__builtin_msa_clti_u_d, "V2SLLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_copy_s_b, "iV16ScIUi", "nc")
-BUILTIN(__builtin_msa_copy_s_h, "iV8SsIUi", "nc")
-BUILTIN(__builtin_msa_copy_s_w, "iV4SiIUi", "nc")
-BUILTIN(__builtin_msa_copy_s_d, "LLiV2SLLiIUi", "nc")
-
-BUILTIN(__builtin_msa_copy_u_b, "iV16UcIUi", "nc")
-BUILTIN(__builtin_msa_copy_u_h, "iV8UsIUi", "nc")
-BUILTIN(__builtin_msa_copy_u_w, "iV4UiIUi", "nc")
-BUILTIN(__builtin_msa_copy_u_d, "LLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_ctcmsa, "vIii", "n")
-
-BUILTIN(__builtin_msa_div_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_div_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_div_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_div_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_div_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_div_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_div_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_div_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_dotp_s_h, "V8SsV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_dotp_s_w, "V4SiV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_dotp_s_d, "V2SLLiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_dotp_u_h, "V8UsV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_dotp_u_w, "V4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_dotp_u_d, "V2ULLiV4UiV4Ui", "nc")
-
-BUILTIN(__builtin_msa_dpadd_s_h, "V8SsV8SsV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_dpadd_s_w, "V4SiV4SiV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_dpadd_s_d, "V2SLLiV2SLLiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_dpadd_u_h, "V8UsV8UsV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_dpadd_u_w, "V4UiV4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_dpadd_u_d, "V2ULLiV2ULLiV4UiV4Ui", "nc")
-
-BUILTIN(__builtin_msa_dpsub_s_h, "V8SsV8SsV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_dpsub_s_w, "V4SiV4SiV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_dpsub_s_d, "V2SLLiV2SLLiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_dpsub_u_h, "V8UsV8UsV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_dpsub_u_w, "V4UiV4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_dpsub_u_d, "V2ULLiV2ULLiV4UiV4Ui", "nc")
-
-BUILTIN(__builtin_msa_fadd_w, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fadd_d, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fcaf_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcaf_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fceq_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fceq_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fclass_w, "V4iV4f", "nc")
-BUILTIN(__builtin_msa_fclass_d, "V2LLiV2d", "nc")
-
-BUILTIN(__builtin_msa_fcle_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcle_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fclt_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fclt_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fcne_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcne_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fcor_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcor_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fcueq_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcueq_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fcule_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcule_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fcult_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcult_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fcun_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcun_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fcune_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fcune_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fdiv_w, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fdiv_d, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fexdo_h, "V8hV4fV4f", "nc")
-BUILTIN(__builtin_msa_fexdo_w, "V4fV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fexp2_w, "V4fV4fV4i", "nc")
-BUILTIN(__builtin_msa_fexp2_d, "V2dV2dV2LLi", "nc")
-
-BUILTIN(__builtin_msa_fexupl_w, "V4fV8h", "nc")
-BUILTIN(__builtin_msa_fexupl_d, "V2dV4f", "nc")
-
-BUILTIN(__builtin_msa_fexupr_w, "V4fV8h", "nc")
-BUILTIN(__builtin_msa_fexupr_d, "V2dV4f", "nc")
-
-BUILTIN(__builtin_msa_ffint_s_w, "V4fV4Si", "nc")
-BUILTIN(__builtin_msa_ffint_s_d, "V2dV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_ffint_u_w, "V4fV4Ui", "nc")
-BUILTIN(__builtin_msa_ffint_u_d, "V2dV2ULLi", "nc")
-
-// ffql uses integers since long _Fract is not implemented
-BUILTIN(__builtin_msa_ffql_w, "V4fV8Ss", "nc")
-BUILTIN(__builtin_msa_ffql_d, "V2dV4Si", "nc")
-
-// ffqr uses integers since long _Fract is not implemented
-BUILTIN(__builtin_msa_ffqr_w, "V4fV8Ss", "nc")
-BUILTIN(__builtin_msa_ffqr_d, "V2dV4Si", "nc")
-
-BUILTIN(__builtin_msa_fill_b, "V16Sci", "nc")
-BUILTIN(__builtin_msa_fill_h, "V8Ssi", "nc")
-BUILTIN(__builtin_msa_fill_w, "V4Sii", "nc")
-BUILTIN(__builtin_msa_fill_d, "V2SLLiLLi", "nc")
-
-BUILTIN(__builtin_msa_flog2_w, "V4fV4f", "nc")
-BUILTIN(__builtin_msa_flog2_d, "V2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fmadd_w, "V4fV4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fmadd_d, "V2dV2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fmax_w, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fmax_d, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fmax_a_w, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fmax_a_d, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fmin_w, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fmin_d, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fmin_a_w, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fmin_a_d, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fmsub_w, "V4fV4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fmsub_d, "V2dV2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fmul_w, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fmul_d, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_frint_w, "V4fV4f", "nc")
-BUILTIN(__builtin_msa_frint_d, "V2dV2d", "nc")
-
-BUILTIN(__builtin_msa_frcp_w, "V4fV4f", "nc")
-BUILTIN(__builtin_msa_frcp_d, "V2dV2d", "nc")
-
-BUILTIN(__builtin_msa_frsqrt_w, "V4fV4f", "nc")
-BUILTIN(__builtin_msa_frsqrt_d, "V2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsaf_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsaf_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fseq_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fseq_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsle_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsle_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fslt_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fslt_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsne_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsne_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsor_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsor_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsqrt_w, "V4fV4f", "nc")
-BUILTIN(__builtin_msa_fsqrt_d, "V2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsub_w, "V4fV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsub_d, "V2dV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsueq_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsueq_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsule_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsule_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsult_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsult_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsun_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsun_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_fsune_w, "V4iV4fV4f", "nc")
-BUILTIN(__builtin_msa_fsune_d, "V2LLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_ftint_s_w, "V4SiV4f", "nc")
-BUILTIN(__builtin_msa_ftint_s_d, "V2SLLiV2d", "nc")
-
-BUILTIN(__builtin_msa_ftint_u_w, "V4UiV4f", "nc")
-BUILTIN(__builtin_msa_ftint_u_d, "V2ULLiV2d", "nc")
-
-BUILTIN(__builtin_msa_ftq_h, "V4UiV4fV4f", "nc")
-BUILTIN(__builtin_msa_ftq_w, "V2ULLiV2dV2d", "nc")
-
-BUILTIN(__builtin_msa_ftrunc_s_w, "V4SiV4f", "nc")
-BUILTIN(__builtin_msa_ftrunc_s_d, "V2SLLiV2d", "nc")
-
-BUILTIN(__builtin_msa_ftrunc_u_w, "V4UiV4f", "nc")
-BUILTIN(__builtin_msa_ftrunc_u_d, "V2ULLiV2d", "nc")
-
-BUILTIN(__builtin_msa_hadd_s_h, "V8SsV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_hadd_s_w, "V4SiV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_hadd_s_d, "V2SLLiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_hadd_u_h, "V8UsV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_hadd_u_w, "V4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_hadd_u_d, "V2ULLiV4UiV4Ui", "nc")
-
-BUILTIN(__builtin_msa_hsub_s_h, "V8SsV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_hsub_s_w, "V4SiV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_hsub_s_d, "V2SLLiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_hsub_u_h, "V8UsV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_hsub_u_w, "V4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_hsub_u_d, "V2ULLiV4UiV4Ui", "nc")
-
-BUILTIN(__builtin_msa_ilvev_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_ilvev_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_ilvev_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_ilvev_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_ilvl_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_ilvl_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_ilvl_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_ilvl_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_ilvod_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_ilvod_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_ilvod_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_ilvod_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_ilvr_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_ilvr_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_ilvr_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_ilvr_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_insert_b, "V16ScV16ScIUii", "nc")
-BUILTIN(__builtin_msa_insert_h, "V8SsV8SsIUii", "nc")
-BUILTIN(__builtin_msa_insert_w, "V4SiV4SiIUii", "nc")
-BUILTIN(__builtin_msa_insert_d, "V2SLLiV2SLLiIUiLLi", "nc")
-
-BUILTIN(__builtin_msa_insve_b, "V16ScV16ScIUiV16Sc", "nc")
-BUILTIN(__builtin_msa_insve_h, "V8SsV8SsIUiV8Ss", "nc")
-BUILTIN(__builtin_msa_insve_w, "V4SiV4SiIUiV4Si", "nc")
-BUILTIN(__builtin_msa_insve_d, "V2SLLiV2SLLiIUiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_ld_b, "V16Scv*Ii", "nc")
-BUILTIN(__builtin_msa_ld_h, "V8Ssv*Ii", "nc")
-BUILTIN(__builtin_msa_ld_w, "V4Siv*Ii", "nc")
-BUILTIN(__builtin_msa_ld_d, "V2SLLiv*Ii", "nc")
-
-BUILTIN(__builtin_msa_ldi_b, "V16cIi", "nc")
-BUILTIN(__builtin_msa_ldi_h, "V8sIi", "nc")
-BUILTIN(__builtin_msa_ldi_w, "V4iIi", "nc")
-BUILTIN(__builtin_msa_ldi_d, "V2LLiIi", "nc")
-
-BUILTIN(__builtin_msa_madd_q_h, "V8SsV8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_madd_q_w, "V4SiV4SiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_maddr_q_h, "V8SsV8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_maddr_q_w, "V4SiV4SiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_maddv_b, "V16ScV16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_maddv_h, "V8SsV8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_maddv_w, "V4SiV4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_maddv_d, "V2SLLiV2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_max_a_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_max_a_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_max_a_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_max_a_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_max_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_max_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_max_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_max_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_max_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_max_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_max_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_max_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_maxi_s_b, "V16ScV16ScIi", "nc")
-BUILTIN(__builtin_msa_maxi_s_h, "V8SsV8SsIi", "nc")
-BUILTIN(__builtin_msa_maxi_s_w, "V4SiV4SiIi", "nc")
-BUILTIN(__builtin_msa_maxi_s_d, "V2SLLiV2SLLiIi", "nc")
-
-BUILTIN(__builtin_msa_maxi_u_b, "V16UcV16UcIi", "nc")
-BUILTIN(__builtin_msa_maxi_u_h, "V8UsV8UsIi", "nc")
-BUILTIN(__builtin_msa_maxi_u_w, "V4UiV4UiIi", "nc")
-BUILTIN(__builtin_msa_maxi_u_d, "V2ULLiV2ULLiIi", "nc")
-
-BUILTIN(__builtin_msa_min_a_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_min_a_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_min_a_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_min_a_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_min_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_min_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_min_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_min_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_min_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_min_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_min_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_min_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_mini_s_b, "V16ScV16ScIi", "nc")
-BUILTIN(__builtin_msa_mini_s_h, "V8SsV8SsIi", "nc")
-BUILTIN(__builtin_msa_mini_s_w, "V4SiV4SiIi", "nc")
-BUILTIN(__builtin_msa_mini_s_d, "V2SLLiV2SLLiIi", "nc")
-
-BUILTIN(__builtin_msa_mini_u_b, "V16UcV16UcIi", "nc")
-BUILTIN(__builtin_msa_mini_u_h, "V8UsV8UsIi", "nc")
-BUILTIN(__builtin_msa_mini_u_w, "V4UiV4UiIi", "nc")
-BUILTIN(__builtin_msa_mini_u_d, "V2ULLiV2ULLiIi", "nc")
-
-BUILTIN(__builtin_msa_mod_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_mod_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_mod_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_mod_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_mod_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_mod_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_mod_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_mod_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_move_v, "V16ScV16Sc", "nc")
-
-BUILTIN(__builtin_msa_msub_q_h, "V8SsV8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_msub_q_w, "V4SiV4SiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_msubr_q_h, "V8SsV8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_msubr_q_w, "V4SiV4SiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_msubv_b, "V16ScV16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_msubv_h, "V8SsV8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_msubv_w, "V4SiV4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_msubv_d, "V2SLLiV2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_mul_q_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_mul_q_w, "V4SiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_mulr_q_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_mulr_q_w, "V4SiV4SiV4Si", "nc")
-
-BUILTIN(__builtin_msa_mulv_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_mulv_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_mulv_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_mulv_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_nloc_b, "V16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_nloc_h, "V8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_nloc_w, "V4SiV4Si", "nc")
-BUILTIN(__builtin_msa_nloc_d, "V2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_nlzc_b, "V16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_nlzc_h, "V8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_nlzc_w, "V4SiV4Si", "nc")
-BUILTIN(__builtin_msa_nlzc_d, "V2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_nor_v, "V16UcV16UcV16Uc", "nc")
-
-BUILTIN(__builtin_msa_nori_b, "V16UcV16cIUi", "nc")
-
-BUILTIN(__builtin_msa_or_v, "V16UcV16UcV16Uc", "nc")
-
-BUILTIN(__builtin_msa_ori_b, "V16UcV16UcIUi", "nc")
-
-BUILTIN(__builtin_msa_pckev_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_pckev_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_pckev_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_pckev_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_pckod_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_pckod_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_pckod_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_pckod_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_pcnt_b, "V16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_pcnt_h, "V8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_pcnt_w, "V4SiV4Si", "nc")
-BUILTIN(__builtin_msa_pcnt_d, "V2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_sat_s_b, "V16ScV16ScIUi", "nc")
-BUILTIN(__builtin_msa_sat_s_h, "V8SsV8SsIUi", "nc")
-BUILTIN(__builtin_msa_sat_s_w, "V4SiV4SiIUi", "nc")
-BUILTIN(__builtin_msa_sat_s_d, "V2SLLiV2SLLiIUi", "nc")
-
-BUILTIN(__builtin_msa_sat_u_b, "V16UcV16UcIUi", "nc")
-BUILTIN(__builtin_msa_sat_u_h, "V8UsV8UsIUi", "nc")
-BUILTIN(__builtin_msa_sat_u_w, "V4UiV4UiIUi", "nc")
-BUILTIN(__builtin_msa_sat_u_d, "V2ULLiV2ULLiIUi", "nc")
-
-BUILTIN(__builtin_msa_shf_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_shf_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_shf_w, "V4iV4iIUi", "nc")
-
-BUILTIN(__builtin_msa_sld_b, "V16cV16cV16cUi", "nc")
-BUILTIN(__builtin_msa_sld_h, "V8sV8sV8sUi", "nc")
-BUILTIN(__builtin_msa_sld_w, "V4iV4iV4iUi", "nc")
-BUILTIN(__builtin_msa_sld_d, "V2LLiV2LLiV2LLiUi", "nc")
-
-BUILTIN(__builtin_msa_sldi_b, "V16cV16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_sldi_h, "V8sV8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_sldi_w, "V4iV4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_sldi_d, "V2LLiV2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_sll_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_sll_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_sll_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_sll_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_slli_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_slli_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_slli_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_slli_d, "V2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_splat_b, "V16cV16cUi", "nc")
-BUILTIN(__builtin_msa_splat_h, "V8sV8sUi", "nc")
-BUILTIN(__builtin_msa_splat_w, "V4iV4iUi", "nc")
-BUILTIN(__builtin_msa_splat_d, "V2LLiV2LLiUi", "nc")
-
-BUILTIN(__builtin_msa_splati_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_splati_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_splati_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_splati_d, "V2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_sra_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_sra_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_sra_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_sra_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_srai_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_srai_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_srai_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_srai_d, "V2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_srar_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_srar_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_srar_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_srar_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_srari_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_srari_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_srari_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_srari_d, "V2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_srl_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_srl_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_srl_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_srl_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_srli_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_srli_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_srli_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_srli_d, "V2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_srlr_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_srlr_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_srlr_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_srlr_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_srlri_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_srlri_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_srlri_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_srlri_d, "V2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_st_b, "vV16Scv*Ii", "nc")
-BUILTIN(__builtin_msa_st_h, "vV8Ssv*Ii", "nc")
-BUILTIN(__builtin_msa_st_w, "vV4Siv*Ii", "nc")
-BUILTIN(__builtin_msa_st_d, "vV2SLLiv*Ii", "nc")
-
-BUILTIN(__builtin_msa_subs_s_b, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_msa_subs_s_h, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_msa_subs_s_w, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_msa_subs_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_subs_u_b, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_subs_u_h, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_subs_u_w, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_subs_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_subsus_u_b, "V16UcV16UcV16Sc", "nc")
-BUILTIN(__builtin_msa_subsus_u_h, "V8UsV8UsV8Ss", "nc")
-BUILTIN(__builtin_msa_subsus_u_w, "V4UiV4UiV4Si", "nc")
-BUILTIN(__builtin_msa_subsus_u_d, "V2ULLiV2ULLiV2SLLi", "nc")
-
-BUILTIN(__builtin_msa_subsuu_s_b, "V16ScV16UcV16Uc", "nc")
-BUILTIN(__builtin_msa_subsuu_s_h, "V8SsV8UsV8Us", "nc")
-BUILTIN(__builtin_msa_subsuu_s_w, "V4SiV4UiV4Ui", "nc")
-BUILTIN(__builtin_msa_subsuu_s_d, "V2SLLiV2ULLiV2ULLi", "nc")
-
-BUILTIN(__builtin_msa_subv_b, "V16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_subv_h, "V8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_subv_w, "V4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_subv_d, "V2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_subvi_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_subvi_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_subvi_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_subvi_d, "V2LLiV2LLiIUi", "nc")
-
-BUILTIN(__builtin_msa_vshf_b, "V16cV16cV16cV16c", "nc")
-BUILTIN(__builtin_msa_vshf_h, "V8sV8sV8sV8s", "nc")
-BUILTIN(__builtin_msa_vshf_w, "V4iV4iV4iV4i", "nc")
-BUILTIN(__builtin_msa_vshf_d, "V2LLiV2LLiV2LLiV2LLi", "nc")
-
-BUILTIN(__builtin_msa_xor_v, "V16cV16cV16c", "nc")
-
-BUILTIN(__builtin_msa_xori_b, "V16cV16cIUi", "nc")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsNEON.def b/include/clang/Basic/BuiltinsNEON.def
deleted file mode 100644
index 7800ae69..0000000
--- a/include/clang/Basic/BuiltinsNEON.def
+++ /dev/null
@@ -1,21 +0,0 @@
-//===--- BuiltinsNEON.def - NEON Builtin function 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 the NEON-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-#define GET_NEON_BUILTINS
-#include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_BUILTINS
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def
deleted file mode 100644
index 3ab6413..0000000
--- a/include/clang/Basic/BuiltinsNVPTX.def
+++ /dev/null
@@ -1,569 +0,0 @@
-//===--- BuiltinsPTX.def - PTX Builtin function 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 the PTX-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-// Builtins retained from previous PTX back-end
-BUILTIN(__builtin_ptx_read_tid_x, "i", "nc")
-BUILTIN(__builtin_ptx_read_tid_y, "i", "nc")
-BUILTIN(__builtin_ptx_read_tid_z, "i", "nc")
-BUILTIN(__builtin_ptx_read_tid_w, "i", "nc")
-
-BUILTIN(__builtin_ptx_read_ntid_x, "i", "nc")
-BUILTIN(__builtin_ptx_read_ntid_y, "i", "nc")
-BUILTIN(__builtin_ptx_read_ntid_z, "i", "nc")
-BUILTIN(__builtin_ptx_read_ntid_w, "i", "nc")
-
-BUILTIN(__builtin_ptx_read_ctaid_x, "i", "nc")
-BUILTIN(__builtin_ptx_read_ctaid_y, "i", "nc")
-BUILTIN(__builtin_ptx_read_ctaid_z, "i", "nc")
-BUILTIN(__builtin_ptx_read_ctaid_w, "i", "nc")
-
-BUILTIN(__builtin_ptx_read_nctaid_x, "i", "nc")
-BUILTIN(__builtin_ptx_read_nctaid_y, "i", "nc")
-BUILTIN(__builtin_ptx_read_nctaid_z, "i", "nc")
-BUILTIN(__builtin_ptx_read_nctaid_w, "i", "nc")
-
-BUILTIN(__builtin_ptx_read_laneid, "i", "nc")
-BUILTIN(__builtin_ptx_read_warpid, "i", "nc")
-BUILTIN(__builtin_ptx_read_nwarpid, "i", "nc")
-
-BUILTIN(__builtin_ptx_read_smid, "i", "nc")
-BUILTIN(__builtin_ptx_read_nsmid, "i", "nc")
-BUILTIN(__builtin_ptx_read_gridid, "i", "nc")
-
-BUILTIN(__builtin_ptx_read_lanemask_eq, "i", "nc")
-BUILTIN(__builtin_ptx_read_lanemask_le, "i", "nc")
-BUILTIN(__builtin_ptx_read_lanemask_lt, "i", "nc")
-BUILTIN(__builtin_ptx_read_lanemask_ge, "i", "nc")
-BUILTIN(__builtin_ptx_read_lanemask_gt, "i", "nc")
-
-BUILTIN(__builtin_ptx_read_clock, "i", "n")
-BUILTIN(__builtin_ptx_read_clock64, "LLi", "n")
-
-BUILTIN(__builtin_ptx_read_pm0, "i", "n")
-BUILTIN(__builtin_ptx_read_pm1, "i", "n")
-BUILTIN(__builtin_ptx_read_pm2, "i", "n")
-BUILTIN(__builtin_ptx_read_pm3, "i", "n")
-
-BUILTIN(__builtin_ptx_bar_sync, "vi", "n")
-
-
-// Builtins exposed as part of NVVM
-// MISC
-
-BUILTIN(__nvvm_clz_i, "ii", "")
-BUILTIN(__nvvm_clz_ll, "iLLi", "")
-BUILTIN(__nvvm_popc_i, "ii", "")
-BUILTIN(__nvvm_popc_ll, "iLLi", "")
-BUILTIN(__nvvm_prmt, "UiUiUiUi", "")
-
-// Min Max
-
-BUILTIN(__nvvm_min_i, "iii", "")
-BUILTIN(__nvvm_min_ui, "UiUiUi", "")
-BUILTIN(__nvvm_min_ll, "LLiLLiLLi", "")
-BUILTIN(__nvvm_min_ull, "ULLiULLiULLi", "")
-
-BUILTIN(__nvvm_max_i, "iii", "")
-BUILTIN(__nvvm_max_ui, "UiUiUi", "")
-BUILTIN(__nvvm_max_ll, "LLiLLiLLi", "")
-BUILTIN(__nvvm_max_ull, "ULLiULLiULLi", "")
-
-BUILTIN(__nvvm_fmax_ftz_f, "fff", "")
-BUILTIN(__nvvm_fmax_f, "fff", "")
-BUILTIN(__nvvm_fmin_ftz_f, "fff", "")
-BUILTIN(__nvvm_fmin_f, "fff", "")
-
-BUILTIN(__nvvm_fmax_d, "ddd", "")
-BUILTIN(__nvvm_fmin_d, "ddd", "")
-
-// Multiplication
-
-BUILTIN(__nvvm_mulhi_i, "iii", "")
-BUILTIN(__nvvm_mulhi_ui, "UiUiUi", "")
-BUILTIN(__nvvm_mulhi_ll, "LLiLLiLLi", "")
-BUILTIN(__nvvm_mulhi_ull, "ULLiULLiULLi", "")
-
-BUILTIN(__nvvm_mul_rn_ftz_f, "fff", "")
-BUILTIN(__nvvm_mul_rn_f, "fff", "")
-BUILTIN(__nvvm_mul_rz_ftz_f, "fff", "")
-BUILTIN(__nvvm_mul_rz_f, "fff", "")
-BUILTIN(__nvvm_mul_rm_ftz_f, "fff", "")
-BUILTIN(__nvvm_mul_rm_f, "fff", "")
-BUILTIN(__nvvm_mul_rp_ftz_f, "fff", "")
-BUILTIN(__nvvm_mul_rp_f, "fff", "")
-
-BUILTIN(__nvvm_mul_rn_d, "ddd", "")
-BUILTIN(__nvvm_mul_rz_d, "ddd", "")
-BUILTIN(__nvvm_mul_rm_d, "ddd", "")
-BUILTIN(__nvvm_mul_rp_d, "ddd", "")
-
-BUILTIN(__nvvm_mul24_i, "iii", "")
-BUILTIN(__nvvm_mul24_ui, "UiUiUi", "")
-
-// Div
-
-BUILTIN(__nvvm_div_approx_ftz_f, "fff", "")
-BUILTIN(__nvvm_div_approx_f, "fff", "")
-
-BUILTIN(__nvvm_div_rn_ftz_f, "fff", "")
-BUILTIN(__nvvm_div_rn_f, "fff", "")
-BUILTIN(__nvvm_div_rz_ftz_f, "fff", "")
-BUILTIN(__nvvm_div_rz_f, "fff", "")
-BUILTIN(__nvvm_div_rm_ftz_f, "fff", "")
-BUILTIN(__nvvm_div_rm_f, "fff", "")
-BUILTIN(__nvvm_div_rp_ftz_f, "fff", "")
-BUILTIN(__nvvm_div_rp_f, "fff", "")
-
-BUILTIN(__nvvm_div_rn_d, "ddd", "")
-BUILTIN(__nvvm_div_rz_d, "ddd", "")
-BUILTIN(__nvvm_div_rm_d, "ddd", "")
-BUILTIN(__nvvm_div_rp_d, "ddd", "")
-
-// Brev
-
-BUILTIN(__nvvm_brev32, "UiUi", "")
-BUILTIN(__nvvm_brev64, "ULLiULLi", "")
-
-// Sad
-
-BUILTIN(__nvvm_sad_i, "iiii", "")
-BUILTIN(__nvvm_sad_ui, "UiUiUiUi", "")
-
-// Floor, Ceil
-
-BUILTIN(__nvvm_floor_ftz_f, "ff", "")
-BUILTIN(__nvvm_floor_f, "ff", "")
-BUILTIN(__nvvm_floor_d, "dd", "")
-
-BUILTIN(__nvvm_ceil_ftz_f, "ff", "")
-BUILTIN(__nvvm_ceil_f, "ff", "")
-BUILTIN(__nvvm_ceil_d, "dd", "")
-
-// Abs
-
-BUILTIN(__nvvm_abs_i, "ii", "")
-BUILTIN(__nvvm_abs_ll, "LLiLLi", "")
-
-BUILTIN(__nvvm_fabs_ftz_f, "ff", "")
-BUILTIN(__nvvm_fabs_f, "ff", "")
-BUILTIN(__nvvm_fabs_d, "dd", "")
-
-// Round
-
-BUILTIN(__nvvm_round_ftz_f, "ff", "")
-BUILTIN(__nvvm_round_f, "ff", "")
-BUILTIN(__nvvm_round_d, "dd", "")
-
-// Trunc
-
-BUILTIN(__nvvm_trunc_ftz_f, "ff", "")
-BUILTIN(__nvvm_trunc_f, "ff", "")
-BUILTIN(__nvvm_trunc_d, "dd", "")
-
-// Saturate
-
-BUILTIN(__nvvm_saturate_ftz_f, "ff", "")
-BUILTIN(__nvvm_saturate_f, "ff", "")
-BUILTIN(__nvvm_saturate_d, "dd", "")
-
-// Exp2, Log2
-
-BUILTIN(__nvvm_ex2_approx_ftz_f, "ff", "")
-BUILTIN(__nvvm_ex2_approx_f, "ff", "")
-BUILTIN(__nvvm_ex2_approx_d, "dd", "")
-
-BUILTIN(__nvvm_lg2_approx_ftz_f, "ff", "")
-BUILTIN(__nvvm_lg2_approx_f, "ff", "")
-BUILTIN(__nvvm_lg2_approx_d, "dd", "")
-
-// Sin, Cos
-
-BUILTIN(__nvvm_sin_approx_ftz_f, "ff", "")
-BUILTIN(__nvvm_sin_approx_f, "ff", "")
-
-BUILTIN(__nvvm_cos_approx_ftz_f, "ff", "")
-BUILTIN(__nvvm_cos_approx_f, "ff", "")
-
-// Fma
-
-BUILTIN(__nvvm_fma_rn_ftz_f, "ffff", "")
-BUILTIN(__nvvm_fma_rn_f, "ffff", "")
-BUILTIN(__nvvm_fma_rz_ftz_f, "ffff", "")
-BUILTIN(__nvvm_fma_rz_f, "ffff", "")
-BUILTIN(__nvvm_fma_rm_ftz_f, "ffff", "")
-BUILTIN(__nvvm_fma_rm_f, "ffff", "")
-BUILTIN(__nvvm_fma_rp_ftz_f, "ffff", "")
-BUILTIN(__nvvm_fma_rp_f, "ffff", "")
-BUILTIN(__nvvm_fma_rn_d, "dddd", "")
-BUILTIN(__nvvm_fma_rz_d, "dddd", "")
-BUILTIN(__nvvm_fma_rm_d, "dddd", "")
-BUILTIN(__nvvm_fma_rp_d, "dddd", "")
-
-// Rcp
-
-BUILTIN(__nvvm_rcp_rn_ftz_f, "ff", "")
-BUILTIN(__nvvm_rcp_rn_f, "ff", "")
-BUILTIN(__nvvm_rcp_rz_ftz_f, "ff", "")
-BUILTIN(__nvvm_rcp_rz_f, "ff", "")
-BUILTIN(__nvvm_rcp_rm_ftz_f, "ff", "")
-BUILTIN(__nvvm_rcp_rm_f, "ff", "")
-BUILTIN(__nvvm_rcp_rp_ftz_f, "ff", "")
-BUILTIN(__nvvm_rcp_rp_f, "ff", "")
-
-BUILTIN(__nvvm_rcp_rn_d, "dd", "")
-BUILTIN(__nvvm_rcp_rz_d, "dd", "")
-BUILTIN(__nvvm_rcp_rm_d, "dd", "")
-BUILTIN(__nvvm_rcp_rp_d, "dd", "")
-BUILTIN(__nvvm_rcp_approx_ftz_d, "dd", "")
-
-// Sqrt
-
-BUILTIN(__nvvm_sqrt_rn_ftz_f, "ff", "")
-BUILTIN(__nvvm_sqrt_rn_f, "ff", "")
-BUILTIN(__nvvm_sqrt_rz_ftz_f, "ff", "")
-BUILTIN(__nvvm_sqrt_rz_f, "ff", "")
-BUILTIN(__nvvm_sqrt_rm_ftz_f, "ff", "")
-BUILTIN(__nvvm_sqrt_rm_f, "ff", "")
-BUILTIN(__nvvm_sqrt_rp_ftz_f, "ff", "")
-BUILTIN(__nvvm_sqrt_rp_f, "ff", "")
-BUILTIN(__nvvm_sqrt_approx_ftz_f, "ff", "")
-BUILTIN(__nvvm_sqrt_approx_f, "ff", "")
-
-BUILTIN(__nvvm_sqrt_rn_d, "dd", "")
-BUILTIN(__nvvm_sqrt_rz_d, "dd", "")
-BUILTIN(__nvvm_sqrt_rm_d, "dd", "")
-BUILTIN(__nvvm_sqrt_rp_d, "dd", "")
-
-// Rsqrt
-
-BUILTIN(__nvvm_rsqrt_approx_ftz_f, "ff", "")
-BUILTIN(__nvvm_rsqrt_approx_f, "ff", "")
-BUILTIN(__nvvm_rsqrt_approx_d, "dd", "")
-
-// Add
-
-BUILTIN(__nvvm_add_rn_ftz_f, "fff", "")
-BUILTIN(__nvvm_add_rn_f, "fff", "")
-BUILTIN(__nvvm_add_rz_ftz_f, "fff", "")
-BUILTIN(__nvvm_add_rz_f, "fff", "")
-BUILTIN(__nvvm_add_rm_ftz_f, "fff", "")
-BUILTIN(__nvvm_add_rm_f, "fff", "")
-BUILTIN(__nvvm_add_rp_ftz_f, "fff", "")
-BUILTIN(__nvvm_add_rp_f, "fff", "")
-
-BUILTIN(__nvvm_add_rn_d, "ddd", "")
-BUILTIN(__nvvm_add_rz_d, "ddd", "")
-BUILTIN(__nvvm_add_rm_d, "ddd", "")
-BUILTIN(__nvvm_add_rp_d, "ddd", "")
-
-// Convert
-
-BUILTIN(__nvvm_d2f_rn_ftz, "fd", "")
-BUILTIN(__nvvm_d2f_rn, "fd", "")
-BUILTIN(__nvvm_d2f_rz_ftz, "fd", "")
-BUILTIN(__nvvm_d2f_rz, "fd", "")
-BUILTIN(__nvvm_d2f_rm_ftz, "fd", "")
-BUILTIN(__nvvm_d2f_rm, "fd", "")
-BUILTIN(__nvvm_d2f_rp_ftz, "fd", "")
-BUILTIN(__nvvm_d2f_rp, "fd", "")
-
-BUILTIN(__nvvm_d2i_rn, "id", "")
-BUILTIN(__nvvm_d2i_rz, "id", "")
-BUILTIN(__nvvm_d2i_rm, "id", "")
-BUILTIN(__nvvm_d2i_rp, "id", "")
-
-BUILTIN(__nvvm_d2ui_rn, "Uid", "")
-BUILTIN(__nvvm_d2ui_rz, "Uid", "")
-BUILTIN(__nvvm_d2ui_rm, "Uid", "")
-BUILTIN(__nvvm_d2ui_rp, "Uid", "")
-
-BUILTIN(__nvvm_i2d_rn, "di", "")
-BUILTIN(__nvvm_i2d_rz, "di", "")
-BUILTIN(__nvvm_i2d_rm, "di", "")
-BUILTIN(__nvvm_i2d_rp, "di", "")
-
-BUILTIN(__nvvm_ui2d_rn, "dUi", "")
-BUILTIN(__nvvm_ui2d_rz, "dUi", "")
-BUILTIN(__nvvm_ui2d_rm, "dUi", "")
-BUILTIN(__nvvm_ui2d_rp, "dUi", "")
-
-BUILTIN(__nvvm_f2i_rn_ftz, "if", "")
-BUILTIN(__nvvm_f2i_rn, "if", "")
-BUILTIN(__nvvm_f2i_rz_ftz, "if", "")
-BUILTIN(__nvvm_f2i_rz, "if", "")
-BUILTIN(__nvvm_f2i_rm_ftz, "if", "")
-BUILTIN(__nvvm_f2i_rm, "if", "")
-BUILTIN(__nvvm_f2i_rp_ftz, "if", "")
-BUILTIN(__nvvm_f2i_rp, "if", "")
-
-BUILTIN(__nvvm_f2ui_rn_ftz, "Uif", "")
-BUILTIN(__nvvm_f2ui_rn, "Uif", "")
-BUILTIN(__nvvm_f2ui_rz_ftz, "Uif", "")
-BUILTIN(__nvvm_f2ui_rz, "Uif", "")
-BUILTIN(__nvvm_f2ui_rm_ftz, "Uif", "")
-BUILTIN(__nvvm_f2ui_rm, "Uif", "")
-BUILTIN(__nvvm_f2ui_rp_ftz, "Uif", "")
-BUILTIN(__nvvm_f2ui_rp, "Uif", "")
-
-BUILTIN(__nvvm_i2f_rn, "fi", "")
-BUILTIN(__nvvm_i2f_rz, "fi", "")
-BUILTIN(__nvvm_i2f_rm, "fi", "")
-BUILTIN(__nvvm_i2f_rp, "fi", "")
-
-BUILTIN(__nvvm_ui2f_rn, "fUi", "")
-BUILTIN(__nvvm_ui2f_rz, "fUi", "")
-BUILTIN(__nvvm_ui2f_rm, "fUi", "")
-BUILTIN(__nvvm_ui2f_rp, "fUi", "")
-
-BUILTIN(__nvvm_lohi_i2d, "dii", "")
-
-BUILTIN(__nvvm_d2i_lo, "id", "")
-BUILTIN(__nvvm_d2i_hi, "id", "")
-
-BUILTIN(__nvvm_f2ll_rn_ftz, "LLif", "")
-BUILTIN(__nvvm_f2ll_rn, "LLif", "")
-BUILTIN(__nvvm_f2ll_rz_ftz, "LLif", "")
-BUILTIN(__nvvm_f2ll_rz, "LLif", "")
-BUILTIN(__nvvm_f2ll_rm_ftz, "LLif", "")
-BUILTIN(__nvvm_f2ll_rm, "LLif", "")
-BUILTIN(__nvvm_f2ll_rp_ftz, "LLif", "")
-BUILTIN(__nvvm_f2ll_rp, "LLif", "")
-
-BUILTIN(__nvvm_f2ull_rn_ftz, "ULLif", "")
-BUILTIN(__nvvm_f2ull_rn, "ULLif", "")
-BUILTIN(__nvvm_f2ull_rz_ftz, "ULLif", "")
-BUILTIN(__nvvm_f2ull_rz, "ULLif", "")
-BUILTIN(__nvvm_f2ull_rm_ftz, "ULLif", "")
-BUILTIN(__nvvm_f2ull_rm, "ULLif", "")
-BUILTIN(__nvvm_f2ull_rp_ftz, "ULLif", "")
-BUILTIN(__nvvm_f2ull_rp, "ULLif", "")
-
-BUILTIN(__nvvm_d2ll_rn, "LLid", "")
-BUILTIN(__nvvm_d2ll_rz, "LLid", "")
-BUILTIN(__nvvm_d2ll_rm, "LLid", "")
-BUILTIN(__nvvm_d2ll_rp, "LLid", "")
-
-BUILTIN(__nvvm_d2ull_rn, "ULLid", "")
-BUILTIN(__nvvm_d2ull_rz, "ULLid", "")
-BUILTIN(__nvvm_d2ull_rm, "ULLid", "")
-BUILTIN(__nvvm_d2ull_rp, "ULLid", "")
-
-BUILTIN(__nvvm_ll2f_rn, "fLLi", "")
-BUILTIN(__nvvm_ll2f_rz, "fLLi", "")
-BUILTIN(__nvvm_ll2f_rm, "fLLi", "")
-BUILTIN(__nvvm_ll2f_rp, "fLLi", "")
-
-BUILTIN(__nvvm_ull2f_rn, "fULLi", "")
-BUILTIN(__nvvm_ull2f_rz, "fULLi", "")
-BUILTIN(__nvvm_ull2f_rm, "fULLi", "")
-BUILTIN(__nvvm_ull2f_rp, "fULLi", "")
-
-BUILTIN(__nvvm_ll2d_rn, "dLLi", "")
-BUILTIN(__nvvm_ll2d_rz, "dLLi", "")
-BUILTIN(__nvvm_ll2d_rm, "dLLi", "")
-BUILTIN(__nvvm_ll2d_rp, "dLLi", "")
-
-BUILTIN(__nvvm_ull2d_rn, "dULLi", "")
-BUILTIN(__nvvm_ull2d_rz, "dULLi", "")
-BUILTIN(__nvvm_ull2d_rm, "dULLi", "")
-BUILTIN(__nvvm_ull2d_rp, "dULLi", "")
-
-BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "")
-BUILTIN(__nvvm_f2h_rn, "Usf", "")
-
-BUILTIN(__nvvm_h2f, "fUs", "")
-
-// Bitcast
-
-BUILTIN(__nvvm_bitcast_f2i, "if", "")
-BUILTIN(__nvvm_bitcast_i2f, "fi", "")
-
-BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "")
-BUILTIN(__nvvm_bitcast_d2ll, "LLid", "")
-
-// Sync
-
-BUILTIN(__syncthreads, "v", "")
-BUILTIN(__nvvm_bar0, "v", "")
-BUILTIN(__nvvm_bar0_popc, "ii", "")
-BUILTIN(__nvvm_bar0_and, "ii", "")
-BUILTIN(__nvvm_bar0_or, "ii", "")
-
-// Membar
-
-BUILTIN(__nvvm_membar_cta, "v", "")
-BUILTIN(__nvvm_membar_gl, "v", "")
-BUILTIN(__nvvm_membar_sys, "v", "")
-
-// Memcpy, Memset
-
-BUILTIN(__nvvm_memcpy, "vUc*Uc*zi","")
-BUILTIN(__nvvm_memset, "vUc*Uczi","")
-
-// Image
-
-BUILTIN(__builtin_ptx_read_image2Dfi_, "V4fiiii", "")
-BUILTIN(__builtin_ptx_read_image2Dff_, "V4fiiff", "")
-BUILTIN(__builtin_ptx_read_image2Dii_, "V4iiiii", "")
-BUILTIN(__builtin_ptx_read_image2Dif_, "V4iiiff", "")
-
-BUILTIN(__builtin_ptx_read_image3Dfi_, "V4fiiiiii", "")
-BUILTIN(__builtin_ptx_read_image3Dff_, "V4fiiffff", "")
-BUILTIN(__builtin_ptx_read_image3Dii_, "V4iiiiiii", "")
-BUILTIN(__builtin_ptx_read_image3Dif_, "V4iiiffff", "")
-
-BUILTIN(__builtin_ptx_write_image2Df_, "viiiffff", "")
-BUILTIN(__builtin_ptx_write_image2Di_, "viiiiiii", "")
-BUILTIN(__builtin_ptx_write_image2Dui_, "viiiUiUiUiUi", "")
-BUILTIN(__builtin_ptx_get_image_depthi_, "ii", "")
-BUILTIN(__builtin_ptx_get_image_heighti_, "ii", "")
-BUILTIN(__builtin_ptx_get_image_widthi_, "ii", "")
-BUILTIN(__builtin_ptx_get_image_channel_data_typei_, "ii", "")
-BUILTIN(__builtin_ptx_get_image_channel_orderi_, "ii", "")
-
-// Atomic
-//
-// We need the atom intrinsics because
-// - they are used in converging analysis
-// - 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")
-BUILTIN(__nvvm_atom_add_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_add_s_l, "LiLiD*3Li", "n")
-BUILTIN(__nvvm_atom_add_gen_l, "LiLiD*Li", "n")
-BUILTIN(__nvvm_atom_add_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_add_s_ll, "LLiLLiD*3LLi", "n")
-BUILTIN(__nvvm_atom_add_gen_ll, "LLiLLiD*LLi", "n")
-BUILTIN(__nvvm_atom_add_g_f, "ffD*1f", "n")
-BUILTIN(__nvvm_atom_add_s_f, "ffD*3f", "n")
-BUILTIN(__nvvm_atom_add_gen_f, "ffD*f", "n")
-BUILTIN(__nvvm_atom_add_g_d, "ddD*1d", "n")
-BUILTIN(__nvvm_atom_add_s_d, "ddD*3d", "n")
-BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n")
-
-BUILTIN(__nvvm_atom_sub_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_sub_s_i, "iiD*3i", "n")
-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")
-BUILTIN(__nvvm_atom_xchg_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_xchg_s_l, "LiLiD*3Li", "n")
-BUILTIN(__nvvm_atom_xchg_gen_l, "LiLiD*Li", "n")
-BUILTIN(__nvvm_atom_xchg_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_xchg_s_ll, "LLiLLiD*3LLi", "n")
-BUILTIN(__nvvm_atom_xchg_gen_ll, "LLiLLiD*LLi", "n")
-
-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")
-BUILTIN(__nvvm_atom_max_g_ui, "UiUiD*1Ui", "n")
-BUILTIN(__nvvm_atom_max_s_ui, "UiUiD*3Ui", "n")
-BUILTIN(__nvvm_atom_max_gen_ui, "UiUiD*Ui", "n")
-BUILTIN(__nvvm_atom_max_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_max_s_l, "LiLiD*3Li", "n")
-BUILTIN(__nvvm_atom_max_gen_l, "LiLiD*Li", "n")
-BUILTIN(__nvvm_atom_max_g_ul, "ULiULiD*1ULi", "n")
-BUILTIN(__nvvm_atom_max_s_ul, "ULiULiD*3ULi", "n")
-BUILTIN(__nvvm_atom_max_gen_ul, "ULiULiD*ULi", "n")
-BUILTIN(__nvvm_atom_max_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_max_s_ll, "LLiLLiD*3LLi", "n")
-BUILTIN(__nvvm_atom_max_gen_ll, "LLiLLiD*LLi", "n")
-BUILTIN(__nvvm_atom_max_g_ull, "ULLiULLiD*1ULLi", "n")
-BUILTIN(__nvvm_atom_max_s_ull, "ULLiULLiD*3ULLi", "n")
-BUILTIN(__nvvm_atom_max_gen_ull, "ULLiULLiD*ULLi", "n")
-
-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")
-BUILTIN(__nvvm_atom_min_g_ui, "UiUiD*1Ui", "n")
-BUILTIN(__nvvm_atom_min_s_ui, "UiUiD*3Ui", "n")
-BUILTIN(__nvvm_atom_min_gen_ui, "UiUiD*Ui", "n")
-BUILTIN(__nvvm_atom_min_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_min_s_l, "LiLiD*3Li", "n")
-BUILTIN(__nvvm_atom_min_gen_l, "LiLiD*Li", "n")
-BUILTIN(__nvvm_atom_min_g_ul, "ULiULiD*1ULi", "n")
-BUILTIN(__nvvm_atom_min_s_ul, "ULiULiD*3ULi", "n")
-BUILTIN(__nvvm_atom_min_gen_ul, "ULiULiD*ULi", "n")
-BUILTIN(__nvvm_atom_min_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_min_s_ll, "LLiLLiD*3LLi", "n")
-BUILTIN(__nvvm_atom_min_gen_ll, "LLiLLiD*LLi", "n")
-BUILTIN(__nvvm_atom_min_g_ull, "ULLiULLiD*1ULLi", "n")
-BUILTIN(__nvvm_atom_min_s_ull, "ULLiULLiD*3ULLi", "n")
-BUILTIN(__nvvm_atom_min_gen_ull, "ULLiULLiD*ULLi", "n")
-
-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")
-BUILTIN(__nvvm_atom_dec_g_ui, "UiUiD*1Ui", "n")
-BUILTIN(__nvvm_atom_dec_s_ui, "UiUiD*3Ui", "n")
-BUILTIN(__nvvm_atom_dec_gen_ui, "UiUiD*Ui", "n")
-
-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")
-BUILTIN(__nvvm_atom_and_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_and_s_l, "LiLiD*3Li", "n")
-BUILTIN(__nvvm_atom_and_gen_l, "LiLiD*Li", "n")
-BUILTIN(__nvvm_atom_and_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_and_s_ll, "LLiLLiD*3LLi", "n")
-BUILTIN(__nvvm_atom_and_gen_ll, "LLiLLiD*LLi", "n")
-
-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")
-BUILTIN(__nvvm_atom_or_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_or_s_l, "LiLiD*3Li", "n")
-BUILTIN(__nvvm_atom_or_gen_l, "LiLiD*Li", "n")
-BUILTIN(__nvvm_atom_or_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_or_s_ll, "LLiLLiD*3LLi", "n")
-BUILTIN(__nvvm_atom_or_gen_ll, "LLiLLiD*LLi", "n")
-
-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")
-BUILTIN(__nvvm_atom_xor_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_xor_s_l, "LiLiD*3Li", "n")
-BUILTIN(__nvvm_atom_xor_gen_l, "LiLiD*Li", "n")
-BUILTIN(__nvvm_atom_xor_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_xor_s_ll, "LLiLLiD*3LLi", "n")
-BUILTIN(__nvvm_atom_xor_gen_ll, "LLiLLiD*LLi", "n")
-
-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")
-BUILTIN(__nvvm_atom_cas_g_l, "LiLiD*1LiLi", "n")
-BUILTIN(__nvvm_atom_cas_s_l, "LiLiD*3LiLi", "n")
-BUILTIN(__nvvm_atom_cas_gen_l, "LiLiD*LiLi", "n")
-BUILTIN(__nvvm_atom_cas_g_ll, "LLiLLiD*1LLiLLi", "n")
-BUILTIN(__nvvm_atom_cas_s_ll, "LLiLLiD*3LLiLLi", "n")
-BUILTIN(__nvvm_atom_cas_gen_ll, "LLiLLiD*LLiLLi", "n")
-
-// Compiler Error Warn
-BUILTIN(__nvvm_compiler_error, "vcC*4", "n")
-BUILTIN(__nvvm_compiler_warn, "vcC*4", "n")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
deleted file mode 100644
index 5681c1f2..0000000
--- a/include/clang/Basic/BuiltinsPPC.def
+++ /dev/null
@@ -1,379 +0,0 @@
-//===--- BuiltinsPPC.def - PowerPC Builtin function 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 the PowerPC-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: this needs to be the full list supported by GCC. Right now, I'm just
-// adding stuff on demand.
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
-
-// This is just a placeholder, the types and attributes are wrong.
-BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "")
-
-BUILTIN(__builtin_altivec_vaddsbs, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vaddubs, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vaddeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vaddcuq, "V1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vaddecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
-
-BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vsubeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vsubcuq, "V1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vsubecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
-
-BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vavgsh, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vavguh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vavgsw, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vavguw, "V4UiV4UiV4Ui", "")
-
-BUILTIN(__builtin_altivec_vrfip, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcfsx, "V4fV4ii", "")
-BUILTIN(__builtin_altivec_vcfux, "V4fV4ii", "")
-BUILTIN(__builtin_altivec_vctsxs, "V4SiV4fi", "")
-BUILTIN(__builtin_altivec_vctuxs, "V4UiV4fi", "")
-
-BUILTIN(__builtin_altivec_dss, "vUi", "")
-BUILTIN(__builtin_altivec_dssall, "v", "")
-BUILTIN(__builtin_altivec_dst, "vvC*iUi", "")
-BUILTIN(__builtin_altivec_dstt, "vvC*iUi", "")
-BUILTIN(__builtin_altivec_dstst, "vvC*iUi", "")
-BUILTIN(__builtin_altivec_dststt, "vvC*iUi", "")
-
-BUILTIN(__builtin_altivec_vexptefp, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vrfim, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_lvx, "V4iivC*", "")
-BUILTIN(__builtin_altivec_lvxl, "V4iivC*", "")
-BUILTIN(__builtin_altivec_lvebx, "V16civC*", "")
-BUILTIN(__builtin_altivec_lvehx, "V8sivC*", "")
-BUILTIN(__builtin_altivec_lvewx, "V4iivC*", "")
-
-BUILTIN(__builtin_altivec_vlogefp, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_lvsl, "V16cUcvC*", "")
-BUILTIN(__builtin_altivec_lvsr, "V16cUcvC*", "")
-
-BUILTIN(__builtin_altivec_vmaddfp, "V4fV4fV4fV4f", "")
-BUILTIN(__builtin_altivec_vmhaddshs, "V8sV8sV8sV8s", "")
-BUILTIN(__builtin_altivec_vmhraddshs, "V8sV8sV8sV8s", "")
-
-BUILTIN(__builtin_altivec_vmsumubm, "V4UiV16UcV16UcV4Ui", "")
-BUILTIN(__builtin_altivec_vmsummbm, "V4SiV16ScV16UcV4Si", "")
-BUILTIN(__builtin_altivec_vmsumuhm, "V4UiV8UsV8UsV4Ui", "")
-BUILTIN(__builtin_altivec_vmsumshm, "V4SiV8SsV8SsV4Si", "")
-BUILTIN(__builtin_altivec_vmsumuhs, "V4UiV8UsV8UsV4Ui", "")
-BUILTIN(__builtin_altivec_vmsumshs, "V4SiV8SsV8SsV4Si", "")
-
-BUILTIN(__builtin_altivec_vmuleub, "V8UsV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vmulesb, "V8SsV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vmuleuh, "V4UiV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vmulesh, "V4SiV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vmuleuw, "V2ULLiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vmulesw, "V2SLLiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vmuloub, "V8UsV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vmulosb, "V8SsV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vmulouw, "V2ULLiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vmulosw, "V2SLLiV4SiV4Si", "")
-
-BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vpkpx, "V8sV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vpkuhus, "V16UcV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vpkshss, "V16ScV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vpkuwus, "V8UsV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vpkswss, "V8SsV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vpkshus, "V16UcV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vpkswus, "V8UsV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vpksdss, "V4SiV2SLLiV2SLLi", "")
-BUILTIN(__builtin_altivec_vpksdus, "V4UiV2SLLiV2SLLi", "")
-BUILTIN(__builtin_altivec_vpkudus, "V4UiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vpkudum, "V4UiV2ULLiV2ULLi", "")
-
-BUILTIN(__builtin_altivec_vperm_4si, "V4iV4iV4iV16Uc", "")
-
-BUILTIN(__builtin_altivec_stvx, "vV4iiv*", "")
-BUILTIN(__builtin_altivec_stvxl, "vV4iiv*", "")
-BUILTIN(__builtin_altivec_stvebx, "vV16civ*", "")
-BUILTIN(__builtin_altivec_stvehx, "vV8siv*", "")
-BUILTIN(__builtin_altivec_stvewx, "vV4iiv*", "")
-
-BUILTIN(__builtin_altivec_vcmpbfp, "V4iV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpgefp, "V4iV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpequb, "V16cV16cV16c", "")
-BUILTIN(__builtin_altivec_vcmpequh, "V8sV8sV8s", "")
-BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "")
-BUILTIN(__builtin_altivec_vcmpequd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vcmpgtuh, "V8sV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vcmpgtsw, "V4iV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vcmpgtuw, "V4iV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vcmpgtsd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vcmpgtud, "V2LLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vcmpgtfp, "V4iV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vmaxsb, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vmaxub, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vmaxsh, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vmaxuh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vmaxsw, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vmaxuw, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vmaxsd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vmaxud, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vmaxfp, "V4fV4fV4f", "")
-
-BUILTIN(__builtin_altivec_mfvscr, "V8Us", "")
-
-BUILTIN(__builtin_altivec_vminsb, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vminub, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vminsh, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vminuh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vminsw, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vminuw, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vminsd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vminud, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "")
-
-BUILTIN(__builtin_altivec_mtvscr, "vV4i", "")
-
-BUILTIN(__builtin_altivec_vrefp, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vrlb, "V16cV16cV16Uc", "")
-BUILTIN(__builtin_altivec_vrlh, "V8sV8sV8Us", "")
-BUILTIN(__builtin_altivec_vrlw, "V4iV4iV4Ui", "")
-BUILTIN(__builtin_altivec_vrld, "V2LLiV2LLiV2ULLi", "")
-
-BUILTIN(__builtin_altivec_vsel_4si, "V4iV4iV4iV4Ui", "")
-
-BUILTIN(__builtin_altivec_vsl, "V4iV4iV4i", "")
-BUILTIN(__builtin_altivec_vslo, "V4iV4iV4i", "")
-
-BUILTIN(__builtin_altivec_vsrab, "V16cV16cV16Uc", "")
-BUILTIN(__builtin_altivec_vsrah, "V8sV8sV8Us", "")
-BUILTIN(__builtin_altivec_vsraw, "V4iV4iV4Ui", "")
-
-BUILTIN(__builtin_altivec_vsr, "V4iV4iV4i", "")
-BUILTIN(__builtin_altivec_vsro, "V4iV4iV4i", "")
-
-BUILTIN(__builtin_altivec_vrfin, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vrsqrtefp, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vsubcuw, "V4UiV4UiV4Ui", "")
-
-BUILTIN(__builtin_altivec_vsum4sbs, "V4SiV16ScV4Si", "")
-BUILTIN(__builtin_altivec_vsum4ubs, "V4UiV16UcV4Ui", "")
-BUILTIN(__builtin_altivec_vsum4shs, "V4SiV8SsV4Si", "")
-
-BUILTIN(__builtin_altivec_vsum2sws, "V4SiV4SiV4Si", "")
-
-BUILTIN(__builtin_altivec_vsumsws, "V4SiV4SiV4Si", "")
-
-BUILTIN(__builtin_altivec_vrfiz, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vupkhsb, "V8sV16c", "")
-BUILTIN(__builtin_altivec_vupkhpx, "V4UiV8s", "")
-BUILTIN(__builtin_altivec_vupkhsh, "V4iV8s", "")
-BUILTIN(__builtin_altivec_vupkhsw, "V2LLiV4i", "")
-
-BUILTIN(__builtin_altivec_vupklsb, "V8sV16c", "")
-BUILTIN(__builtin_altivec_vupklpx, "V4UiV8s", "")
-BUILTIN(__builtin_altivec_vupklsh, "V4iV8s", "")
-BUILTIN(__builtin_altivec_vupklsw, "V2LLiV4i", "")
-
-BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpequb_p, "iiV16cV16c", "")
-BUILTIN(__builtin_altivec_vcmpequh_p, "iiV8sV8s", "")
-BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "")
-BUILTIN(__builtin_altivec_vcmpequd_p, "iiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vcmpgtuh_p, "iiV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vcmpgtsw_p, "iiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vcmpgtuw_p, "iiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vcmpgtsd_p, "iiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vcmpgtud_p, "iiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vgbbd, "V16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vbpermq, "V2ULLiV16UcV16Uc", "")
-
-// P8 Crypto built-ins.
-BUILTIN(__builtin_altivec_crypto_vsbox, "V2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vpermxor, "V16UcV16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_crypto_vshasigmaw, "V4UiV4UiIiIi", "")
-BUILTIN(__builtin_altivec_crypto_vshasigmad, "V2ULLiV2ULLiIiIi", "")
-BUILTIN(__builtin_altivec_crypto_vcipher, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vcipherlast, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vncipher, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vncipherlast, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vpmsumb, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_crypto_vpmsumh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_crypto_vpmsumw, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_crypto_vpmsumd, "V2ULLiV2ULLiV2ULLi", "")
-
-BUILTIN(__builtin_altivec_vclzb, "V16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vclzh, "V8UsV8Us", "")
-BUILTIN(__builtin_altivec_vclzw, "V4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vclzd, "V2ULLiV2ULLi", "")
-
-// VSX built-ins.
-
-BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "")
-BUILTIN(__builtin_vsx_lxvw4x, "V4iivC*", "")
-
-BUILTIN(__builtin_vsx_stxvd2x, "vV2div*", "")
-BUILTIN(__builtin_vsx_stxvw4x, "vV4iiv*", "")
-
-BUILTIN(__builtin_vsx_xvmaxdp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvmaxsp, "V4fV4fV4f", "")
-BUILTIN(__builtin_vsx_xsmaxdp, "ddd", "")
-
-BUILTIN(__builtin_vsx_xvmindp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvminsp, "V4fV4fV4f", "")
-BUILTIN(__builtin_vsx_xsmindp, "ddd", "")
-
-BUILTIN(__builtin_vsx_xvdivdp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvdivsp, "V4fV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvrdpip, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspip, "V4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvcmpeqdp, "V2ULLiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpeqsp, "V4UiV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvcmpeqdp_p, "iiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpeqsp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvcmpgedp, "V2ULLiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpgesp, "V4UiV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvcmpgedp_p, "iiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpgesp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvcmpgtdp, "V2ULLiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpgtsp, "V4UiV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvcmpgtdp_p, "iiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpgtsp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvrdpim, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspim, "V4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvrdpi, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspi, "V4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvrdpic, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspic, "V4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvrdpiz, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspiz, "V4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvmaddadp, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvmaddasp, "V4fV4fV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvmsubadp, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvmsubasp, "V4fV4fV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvmuldp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvmulsp, "V4fV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvnmaddadp, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvnmaddasp, "V4fV4fV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvnmsubadp, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvnmsubasp, "V4fV4fV4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvredp, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvresp, "V4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvrsqrtedp, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrsqrtesp, "V4fV4f", "")
-
-BUILTIN(__builtin_vsx_xvsqrtdp, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvsqrtsp, "V4fV4f", "")
-
-BUILTIN(__builtin_vsx_xxleqv, "V4UiV4UiV4Ui", "")
-
-BUILTIN(__builtin_vsx_xvcpsgndp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "")
-
-// HTM builtins
-BUILTIN(__builtin_tbegin, "UiUIi", "")
-BUILTIN(__builtin_tend, "UiUIi", "")
-
-BUILTIN(__builtin_tabort, "UiUi", "")
-BUILTIN(__builtin_tabortdc, "UiUiUiUi", "")
-BUILTIN(__builtin_tabortdci, "UiUiUii", "")
-BUILTIN(__builtin_tabortwc, "UiUiUiUi", "")
-BUILTIN(__builtin_tabortwci, "UiUiUii", "")
-
-BUILTIN(__builtin_tcheck, "Ui", "")
-BUILTIN(__builtin_treclaim, "UiUi", "")
-BUILTIN(__builtin_trechkpt, "Ui", "")
-BUILTIN(__builtin_tsr, "UiUi", "")
-
-BUILTIN(__builtin_tendall, "Ui", "")
-BUILTIN(__builtin_tresume, "Ui", "")
-BUILTIN(__builtin_tsuspend, "Ui", "")
-
-BUILTIN(__builtin_get_texasr, "LUi", "c")
-BUILTIN(__builtin_get_texasru, "LUi", "c")
-BUILTIN(__builtin_get_tfhar, "LUi", "c")
-BUILTIN(__builtin_get_tfiar, "LUi", "c")
-
-BUILTIN(__builtin_set_texasr, "vLUi", "c")
-BUILTIN(__builtin_set_texasru, "vLUi", "c")
-BUILTIN(__builtin_set_tfhar, "vLUi", "c")
-BUILTIN(__builtin_set_tfiar, "vLUi", "c")
-
-BUILTIN(__builtin_ttest, "LUi", "")
-
-// Scalar built-ins
-BUILTIN(__builtin_divwe, "SiSiSi", "")
-BUILTIN(__builtin_divweu, "UiUiUi", "")
-BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "")
-BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "")
-BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "")
-
-// FIXME: Obviously incomplete.
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsSystemZ.def b/include/clang/Basic/BuiltinsSystemZ.def
deleted file mode 100644
index 68d5a1c..0000000
--- a/include/clang/Basic/BuiltinsSystemZ.def
+++ /dev/null
@@ -1,252 +0,0 @@
-//===-- BuiltinsSystemZ.def - SystemZ Builtin function 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 the SystemZ-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-// Transactional-memory intrinsics
-BUILTIN(__builtin_tbegin, "iv*", "j")
-BUILTIN(__builtin_tbegin_nofloat, "iv*", "j")
-BUILTIN(__builtin_tbeginc, "v", "nj")
-BUILTIN(__builtin_tabort, "vi", "r")
-BUILTIN(__builtin_tend, "i", "n")
-BUILTIN(__builtin_tx_nesting_depth, "i", "nc")
-BUILTIN(__builtin_tx_assist, "vi", "n")
-BUILTIN(__builtin_non_tx_store, "vULi*ULi", "")
-
-// Vector intrinsics.
-// These all map directly to z instructions, except that some variants ending
-// in "s" have a final "int *" that receives the post-instruction CC value.
-
-// Vector support instructions (chapter 21 of the PoP)
-BUILTIN(__builtin_s390_lcbb, "UivC*Ii", "nc")
-BUILTIN(__builtin_s390_vlbb, "V16ScvC*Ii", "")
-BUILTIN(__builtin_s390_vll, "V16ScUivC*", "")
-BUILTIN(__builtin_s390_vstl, "vV16ScUiv*", "")
-BUILTIN(__builtin_s390_vperm, "V16UcV16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vpdi, "V2ULLiV2ULLiV2ULLiIi", "nc")
-BUILTIN(__builtin_s390_vpksh, "V16ScV8SsV8Ss", "nc")
-BUILTIN(__builtin_s390_vpkshs, "V16ScV8SsV8Ssi*", "nc")
-BUILTIN(__builtin_s390_vpksf, "V8SsV4SiV4Si", "nc")
-BUILTIN(__builtin_s390_vpksfs, "V8SsV4SiV4Sii*", "nc")
-BUILTIN(__builtin_s390_vpksg, "V4SiV2SLLiV2SLLi", "nc")
-BUILTIN(__builtin_s390_vpksgs, "V4SiV2SLLiV2SLLii*", "nc")
-BUILTIN(__builtin_s390_vpklsh, "V16UcV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vpklshs, "V16UcV8UsV8Usi*", "nc")
-BUILTIN(__builtin_s390_vpklsf, "V8UsV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vpklsfs, "V8UsV4UiV4Uii*", "nc")
-BUILTIN(__builtin_s390_vpklsg, "V4UiV2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vpklsgs, "V4UiV2ULLiV2ULLii*", "nc")
-BUILTIN(__builtin_s390_vuphb, "V8SsV16Sc", "nc")
-BUILTIN(__builtin_s390_vuphh, "V4SiV8Ss", "nc")
-BUILTIN(__builtin_s390_vuphf, "V2SLLiV4Si", "nc")
-BUILTIN(__builtin_s390_vuplb, "V8SsV16Sc", "nc")
-BUILTIN(__builtin_s390_vuplhw, "V4SiV8Ss", "nc")
-BUILTIN(__builtin_s390_vuplf, "V2SLLiV4Si", "nc")
-BUILTIN(__builtin_s390_vuplhb, "V8UsV16Uc", "nc")
-BUILTIN(__builtin_s390_vuplhh, "V4UiV8Us", "nc")
-BUILTIN(__builtin_s390_vuplhf, "V2ULLiV4Ui", "nc")
-BUILTIN(__builtin_s390_vupllb, "V8UsV16Uc", "nc")
-BUILTIN(__builtin_s390_vupllh, "V4UiV8Us", "nc")
-BUILTIN(__builtin_s390_vupllf, "V2ULLiV4Ui", "nc")
-
-// Vector integer instructions (chapter 22 of the PoP)
-BUILTIN(__builtin_s390_vaq, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vacq, "V16UcV16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vaccb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vacch, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vaccf, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vaccg, "V2ULLiV2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vaccq, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vacccq, "V16UcV16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vavgb, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_s390_vavgh, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_s390_vavgf, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_s390_vavgg, "V2SLLiV2SLLiV2SLLi", "nc")
-BUILTIN(__builtin_s390_vavglb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vavglh, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vavglf, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vavglg, "V2ULLiV2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vceqbs, "V16ScV16ScV16Sci*", "nc")
-BUILTIN(__builtin_s390_vceqhs, "V8SsV8SsV8Ssi*", "nc")
-BUILTIN(__builtin_s390_vceqfs, "V4SiV4SiV4Sii*", "nc")
-BUILTIN(__builtin_s390_vceqgs, "V2SLLiV2SLLiV2SLLii*", "nc")
-BUILTIN(__builtin_s390_vchbs, "V16ScV16ScV16Sci*", "nc")
-BUILTIN(__builtin_s390_vchhs, "V8SsV8SsV8Ssi*", "nc")
-BUILTIN(__builtin_s390_vchfs, "V4SiV4SiV4Sii*", "nc")
-BUILTIN(__builtin_s390_vchgs, "V2SLLiV2SLLiV2SLLii*", "nc")
-BUILTIN(__builtin_s390_vchlbs, "V16ScV16UcV16Uci*", "nc")
-BUILTIN(__builtin_s390_vchlhs, "V8SsV8UsV8Usi*", "nc")
-BUILTIN(__builtin_s390_vchlfs, "V4SiV4UiV4Uii*", "nc")
-BUILTIN(__builtin_s390_vchlgs, "V2SLLiV2ULLiV2ULLii*", "nc")
-BUILTIN(__builtin_s390_vcksm, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vclzb, "V16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vclzh, "V8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vclzf, "V4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vclzg, "V2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vctzb, "V16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vctzh, "V8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vctzf, "V4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vctzg, "V2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_verimb, "V16UcV16UcV16UcV16UcIi", "nc")
-BUILTIN(__builtin_s390_verimh, "V8UsV8UsV8UsV8UsIi", "nc")
-BUILTIN(__builtin_s390_verimf, "V4UiV4UiV4UiV4UiIi", "nc")
-BUILTIN(__builtin_s390_verimg, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "nc")
-BUILTIN(__builtin_s390_verllb, "V16UcV16UcUi", "nc")
-BUILTIN(__builtin_s390_verllh, "V8UsV8UsUi", "nc")
-BUILTIN(__builtin_s390_verllf, "V4UiV4UiUi", "nc")
-BUILTIN(__builtin_s390_verllg, "V2ULLiV2ULLiUi", "nc")
-BUILTIN(__builtin_s390_verllvb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_verllvh, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_verllvf, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_verllvg, "V2ULLiV2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vgfmb, "V8UsV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vgfmh, "V4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vgfmf, "V2ULLiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vgfmg, "V16UcV2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vgfmab, "V8UsV16UcV16UcV8Us", "nc")
-BUILTIN(__builtin_s390_vgfmah, "V4UiV8UsV8UsV4Ui", "nc")
-BUILTIN(__builtin_s390_vgfmaf, "V2ULLiV4UiV4UiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vgfmag, "V16UcV2ULLiV2ULLiV16Uc", "nc")
-BUILTIN(__builtin_s390_vmahb, "V16ScV16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_s390_vmahh, "V8SsV8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_s390_vmahf, "V4SiV4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_s390_vmalhb, "V16UcV16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vmalhh, "V8UsV8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vmalhf, "V4UiV4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vmaeb, "V8SsV16ScV16ScV8Ss", "nc")
-BUILTIN(__builtin_s390_vmaeh, "V4SiV8SsV8SsV4Si", "nc")
-BUILTIN(__builtin_s390_vmaef, "V2SLLiV4SiV4SiV2SLLi", "nc")
-BUILTIN(__builtin_s390_vmaleb, "V8UsV16UcV16UcV8Us", "nc")
-BUILTIN(__builtin_s390_vmaleh, "V4UiV8UsV8UsV4Ui", "nc")
-BUILTIN(__builtin_s390_vmalef, "V2ULLiV4UiV4UiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vmaob, "V8SsV16ScV16ScV8Ss", "nc")
-BUILTIN(__builtin_s390_vmaoh, "V4SiV8SsV8SsV4Si", "nc")
-BUILTIN(__builtin_s390_vmaof, "V2SLLiV4SiV4SiV2SLLi", "nc")
-BUILTIN(__builtin_s390_vmalob, "V8UsV16UcV16UcV8Us", "nc")
-BUILTIN(__builtin_s390_vmaloh, "V4UiV8UsV8UsV4Ui", "nc")
-BUILTIN(__builtin_s390_vmalof, "V2ULLiV4UiV4UiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vmhb, "V16ScV16ScV16Sc", "nc")
-BUILTIN(__builtin_s390_vmhh, "V8SsV8SsV8Ss", "nc")
-BUILTIN(__builtin_s390_vmhf, "V4SiV4SiV4Si", "nc")
-BUILTIN(__builtin_s390_vmlhb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vmlhh, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vmlhf, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vmeb, "V8SsV16ScV16Sc", "nc")
-BUILTIN(__builtin_s390_vmeh, "V4SiV8SsV8Ss", "nc")
-BUILTIN(__builtin_s390_vmef, "V2SLLiV4SiV4Si", "nc")
-BUILTIN(__builtin_s390_vmleb, "V8UsV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vmleh, "V4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vmlef, "V2ULLiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vmob, "V8SsV16ScV16Sc", "nc")
-BUILTIN(__builtin_s390_vmoh, "V4SiV8SsV8Ss", "nc")
-BUILTIN(__builtin_s390_vmof, "V2SLLiV4SiV4Si", "nc")
-BUILTIN(__builtin_s390_vmlob, "V8UsV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vmloh, "V4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vmlof, "V2ULLiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vpopctb, "V16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vpopcth, "V8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vpopctf, "V4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vpopctg, "V2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vsq, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsbcbiq, "V16UcV16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsbiq, "V16UcV16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vscbib, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vscbih, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vscbif, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vscbig, "V2ULLiV2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vscbiq, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsl, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vslb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsldb, "V16UcV16UcV16UcIi", "nc")
-BUILTIN(__builtin_s390_vsra, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsrab, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsrl, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsrlb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsumb, "V4UiV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vsumh, "V4UiV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vsumgh, "V2ULLiV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vsumgf, "V2ULLiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vsumqf, "V16UcV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vsumqg, "V16UcV2ULLiV2ULLi", "nc")
-BUILTIN(__builtin_s390_vtm, "iV16UcV16Uc", "nc")
-
-// Vector string instructions (chapter 23 of the PoP)
-BUILTIN(__builtin_s390_vfaeb, "V16UcV16UcV16UcIi", "nc")
-BUILTIN(__builtin_s390_vfaebs, "V16UcV16UcV16UcIii*", "nc")
-BUILTIN(__builtin_s390_vfaeh, "V8UsV8UsV8UsIi", "nc")
-BUILTIN(__builtin_s390_vfaehs, "V8UsV8UsV8UsIii*", "nc")
-BUILTIN(__builtin_s390_vfaef, "V4UiV4UiV4UiIi", "nc")
-BUILTIN(__builtin_s390_vfaefs, "V4UiV4UiV4UiIii*", "nc")
-BUILTIN(__builtin_s390_vfaezb, "V16UcV16UcV16UcIi", "nc")
-BUILTIN(__builtin_s390_vfaezbs, "V16UcV16UcV16UcIii*", "nc")
-BUILTIN(__builtin_s390_vfaezh, "V8UsV8UsV8UsIi", "nc")
-BUILTIN(__builtin_s390_vfaezhs, "V8UsV8UsV8UsIii*", "nc")
-BUILTIN(__builtin_s390_vfaezf, "V4UiV4UiV4UiIi", "nc")
-BUILTIN(__builtin_s390_vfaezfs, "V4UiV4UiV4UiIii*", "nc")
-BUILTIN(__builtin_s390_vfeeb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vfeebs, "V16UcV16UcV16Uci*", "nc")
-BUILTIN(__builtin_s390_vfeeh, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vfeehs, "V8UsV8UsV8Usi*", "nc")
-BUILTIN(__builtin_s390_vfeef, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vfeefs, "V4UiV4UiV4Uii*", "nc")
-BUILTIN(__builtin_s390_vfeezb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vfeezbs, "V16UcV16UcV16Uci*", "nc")
-BUILTIN(__builtin_s390_vfeezh, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vfeezhs, "V8UsV8UsV8Usi*", "nc")
-BUILTIN(__builtin_s390_vfeezf, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vfeezfs, "V4UiV4UiV4Uii*", "nc")
-BUILTIN(__builtin_s390_vfeneb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vfenebs, "V16UcV16UcV16Uci*", "nc")
-BUILTIN(__builtin_s390_vfeneh, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vfenehs, "V8UsV8UsV8Usi*", "nc")
-BUILTIN(__builtin_s390_vfenef, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vfenefs, "V4UiV4UiV4Uii*", "nc")
-BUILTIN(__builtin_s390_vfenezb, "V16UcV16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vfenezbs, "V16UcV16UcV16Uci*", "nc")
-BUILTIN(__builtin_s390_vfenezh, "V8UsV8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vfenezhs, "V8UsV8UsV8Usi*", "nc")
-BUILTIN(__builtin_s390_vfenezf, "V4UiV4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vfenezfs, "V4UiV4UiV4Uii*", "nc")
-BUILTIN(__builtin_s390_vistrb, "V16UcV16Uc", "nc")
-BUILTIN(__builtin_s390_vistrbs, "V16UcV16Uci*", "nc")
-BUILTIN(__builtin_s390_vistrh, "V8UsV8Us", "nc")
-BUILTIN(__builtin_s390_vistrhs, "V8UsV8Usi*", "nc")
-BUILTIN(__builtin_s390_vistrf, "V4UiV4Ui", "nc")
-BUILTIN(__builtin_s390_vistrfs, "V4UiV4Uii*", "nc")
-BUILTIN(__builtin_s390_vstrcb, "V16UcV16UcV16UcV16UcIi", "nc")
-BUILTIN(__builtin_s390_vstrcbs, "V16UcV16UcV16UcV16UcIii*", "nc")
-BUILTIN(__builtin_s390_vstrch, "V8UsV8UsV8UsV8UsIi", "nc")
-BUILTIN(__builtin_s390_vstrchs, "V8UsV8UsV8UsV8UsIii*", "nc")
-BUILTIN(__builtin_s390_vstrcf, "V4UiV4UiV4UiV4UiIi", "nc")
-BUILTIN(__builtin_s390_vstrcfs, "V4UiV4UiV4UiV4UiIii*", "nc")
-BUILTIN(__builtin_s390_vstrczb, "V16UcV16UcV16UcV16UcIi", "nc")
-BUILTIN(__builtin_s390_vstrczbs, "V16UcV16UcV16UcV16UcIii*", "nc")
-BUILTIN(__builtin_s390_vstrczh, "V8UsV8UsV8UsV8UsIi", "nc")
-BUILTIN(__builtin_s390_vstrczhs, "V8UsV8UsV8UsV8UsIii*", "nc")
-BUILTIN(__builtin_s390_vstrczf, "V4UiV4UiV4UiV4UiIi", "nc")
-BUILTIN(__builtin_s390_vstrczfs, "V4UiV4UiV4UiV4UiIii*", "nc")
-
-// Vector floating-point instructions (chapter 24 of the PoP)
-BUILTIN(__builtin_s390_vfcedbs, "V2SLLiV2dV2di*", "nc")
-BUILTIN(__builtin_s390_vfchdbs, "V2SLLiV2dV2di*", "nc")
-BUILTIN(__builtin_s390_vfchedbs, "V2SLLiV2dV2di*", "nc")
-BUILTIN(__builtin_s390_vfidb, "V2dV2dIiIi", "nc")
-BUILTIN(__builtin_s390_vflndb, "V2dV2d", "nc")
-BUILTIN(__builtin_s390_vflpdb, "V2dV2d", "nc")
-BUILTIN(__builtin_s390_vfmadb, "V2dV2dV2dV2d", "nc")
-BUILTIN(__builtin_s390_vfmsdb, "V2dV2dV2dV2d", "nc")
-BUILTIN(__builtin_s390_vfsqdb, "V2dV2d", "nc")
-BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def
deleted file mode 100644
index 9754335..0000000
--- a/include/clang/Basic/BuiltinsWebAssembly.def
+++ /dev/null
@@ -1,24 +0,0 @@
-// BuiltinsWebAssembly.def - WebAssembly builtin function database -*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file defines the WebAssembly-specific builtin function database.
-/// Users of this file must define the BUILTIN macro to make use of this
-/// information.
-///
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-// Note that memory_size is not "c" (readnone) because it must be sequenced with
-// respect to grow_memory calls.
-BUILTIN(__builtin_wasm_memory_size, "z", "n")
-BUILTIN(__builtin_wasm_grow_memory, "vz", "n")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
deleted file mode 100644
index f738cc1..0000000
--- a/include/clang/Basic/BuiltinsX86.def
+++ /dev/null
@@ -1,1577 +0,0 @@
-//===--- BuiltinsX86.def - X86 Builtin function 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 the X86-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-// FIXME: Ideally we would be able to pull this information from what
-// LLVM already knows about X86 builtins. We need to match the LLVM
-// definition anyway, since code generation will lower to the
-// intrinsic if one exists.
-
-#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
-# define TARGET_BUILTIN(ID, TYPE, ATTRS, 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?
-BUILTIN(__builtin_cpu_supports, "bcC*", "nc")
-
-// Win64-compatible va_list functions
-BUILTIN(__builtin_ms_va_start, "vc*&.", "nt")
-BUILTIN(__builtin_ms_va_end, "vc*&", "n")
-BUILTIN(__builtin_ms_va_copy, "vc*&c*&", "n")
-
-// Undefined Values
-//
-TARGET_BUILTIN(__builtin_ia32_undef128, "V2d", "nc", "")
-TARGET_BUILTIN(__builtin_ia32_undef256, "V4d", "nc", "")
-TARGET_BUILTIN(__builtin_ia32_undef512, "V8d", "nc", "")
-
-// FLAGS
-//
-TARGET_BUILTIN(__builtin_ia32_readeflags_u32, "Ui", "n", "")
-TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
-TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "")
-TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "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")
-// 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")
-
-// MMX
-//
-// All MMX instructions will be generated via builtins. Any MMX vector
-// types (<1 x i64>, <2 x i32>, etc.) that aren't used by these builtins will be
-// expanded by the back-end.
-// FIXME: _mm_prefetch must be a built-in because it takes a compile-time constant
-// 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")
-
-// 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")
-
-// 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")
-
-// 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")
-
-// 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_cmpps, "V4fV4fV4fIc", "", "sse")
-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_cmpss, "V4fV4fV4fIc", "", "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_cmppd, "V2dV2dV2dIc", "", "sse2")
-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_cmpsd, "V2dV2dV2dIc", "", "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_pavgb128, "V16cV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pavgw128, "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_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_storeups, "vf*V4f", "", "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_movntps, "vf*V4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_sfence, "v", "", "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_storeupd, "vd*V2d", "", "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_movntpd, "vd*V2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_movntdq, "vV2LLi*V2LLi", "", "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_cvtdq2pd, "V2dV4i", "", "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_cvtsd2si64, "LLiV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtps2pd, "V2dV4f", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_lfence, "v", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_mfence, "v", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pause, "v", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "", "sse2")
-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, "V16cV16cV16cIc", "", "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_pmovzxbd128, "V4iV16c", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbq128, "V2LLiV16c", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbw128, "V8sV16c", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmovzxdq128, "V2LLiV4i", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwd128, "V4iV8s", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwq128, "V2LLiV8s", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmulld128, "V4iV4iV4i", "", "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_movntdqa, "V2LLiV2LLiC*", "", "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")
-
-// 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_crc32di, "ULLiULLiULLi", "", "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")
-
-// 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")
-
-// CLMUL
-TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "", "pclmul")
-
-// 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_cmppd256, "V4dV4dV4dIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2pd256, "V4dV4i", "", "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_cvtps2pd256, "V4dV4f", "", "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_storeupd256, "vd*V4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_storeups256, "vf*V8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_storedqu256, "vc*V32c", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_movntdq256, "vV4LLi*V4LLi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_movntpd256, "vd*V4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_movntps256, "vf*V8f", "", "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")
-
-// 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, "V32cV32cV32cIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "", "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_pmovsxbw256, "V16sV16c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbd256, "V8iV16c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbq256, "V4LLiV16c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovsxwd256, "V8iV8s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovsxwq256, "V4LLiV8s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovsxdq256, "V4LLiV4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbw256, "V16sV16c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbd256, "V8iV16c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbq256, "V4LLiV16c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwd256, "V8iV8s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwq256, "V4LLiV8s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovzxdq256, "V4LLiV4i", "", "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_pslldqi256, "V4LLiV4LLiIi", "", "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_psrldqi256, "V4LLiV4LLiIi", "", "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_movntdqa256, "V4LLiV4LLiC*", "", "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")
-
-// 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")
-
-// F16C
-TARGET_BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "", "f16c")
-TARGET_BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "", "f16c")
-TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512, "V16sV16fIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "", "f16c")
-TARGET_BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "", "f16c")
-TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512, "V16fV16s", "", "avx512f")
-
-// 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_rdfsbase64, "ULLi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "", "fsgsbase")
-
-// FXSR
-TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "", "fxsr")
-TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "", "fxsr")
-TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "", "fxsr")
-TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "", "fxsr")
-
-// XSAVE
-TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "", "xsaveopt")
-TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt")
-TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "", "xsaves")
-TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves")
-TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec")
-TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec")
-TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves")
-TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves")
-
-// ADX
-TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx")
-TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
-TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "", "adx")
-TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "adx")
-TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "", "adx")
-TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "adx")
-
-// RDSEED
-TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "", "rdseed")
-TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "", "rdseed")
-TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "", "rdseed")
-
-// BMI
-TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "", "bmi")
-TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "", "bmi")
-
-// BMI2
-TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
-
-// TBM
-TARGET_BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "", "tbm")
-TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
-
-// 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")
-
-// FMA
-TARGET_BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubss, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubsd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddss, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddsd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubss, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubsd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd256, "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")
-
-// 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_vpcmov, "V2LLiV2LLiV2LLiV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcmov_256, "V4LLiV4LLiV4LLiV4LLi", "", "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")
-
-BUILTIN(__builtin_ia32_rdpmc, "ULLii", "")
-BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
-BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
-// PKU
-TARGET_BUILTIN(__builtin_ia32_rdpkru, "Ui", "", "pku")
-TARGET_BUILTIN(__builtin_ia32_wrpkru, "vUi", "", "pku")
-
-// AVX-512
-TARGET_BUILTIN(__builtin_ia32_sqrtpd512_mask, "V8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_sqrtps512_mask, "V16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14sd, "V2dV2dV2dV2dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14ss, "V4fV4fV4fV4fUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_rsqrt28sd_round, "V2dV2dV2dV2dUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rsqrt28ss_round, "V4fV4fV4fV4fUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "", "avx512er")
-
-TARGET_BUILTIN(__builtin_ia32_rcp14sd, "V2dV2dV2dV2dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rcp14ss, "V4fV4fV4fV4fUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_rcp28sd_round, "V2dV2dV2dV2dUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rcp28ss_round, "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_pcmpeqb512_mask, "LLiV64cV64cLLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqw512_mask, "iV32sV32si", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pcmpeqb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqd256_mask, "cV8iV8ic", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqq256_mask, "cV4LLiV4LLic", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqw256_mask, "sV16sV16ss", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqb128_mask, "sV16cV16cs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqd128_mask, "cV4iV4ic", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqq128_mask, "cV2LLiV2LLic", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pcmpgtb512_mask, "LLiV64cV64cLLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtd512_mask, "sV16iV16is", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtq512_mask, "cV8LLiV8LLic", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtw512_mask, "iV32sV32si", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pcmpgtb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtd256_mask, "cV8iV8ic", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtq256_mask, "cV4LLiV4LLic", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtw256_mask, "sV16sV16ss", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtb128_mask, "sV16cV16cs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtd128_mask, "cV4iV4ic", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtq128_mask, "cV2LLiV2LLic", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw")
-
-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_cvtdq2pd512_mask, "V8dV8iV8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2pd512_mask, "V8dV8iV8dUc", "", "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_pandd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pandq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pord512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_porq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pxord512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pxorq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "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_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmuludq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_blendmd_512_mask, "V16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_blendmq_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_blendmps_512_mask, "V16fV16fV16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_blendmpd_512_mask, "V8dV8dV8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16ivC*V16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLivC*V8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16fvC*V16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fvC*V16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8dvC*V8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dvC*V8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vv*V8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vv*V16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vv*V8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vv*V8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vv*V16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vv*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_alignq512_mask, "V8LLiV8LLiV8LLiIiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_alignd512_mask, "V16iV16iV16iIiV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*UsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*UsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*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_paddd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_paddq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psubd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psubq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_paddd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_paddq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psubd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psubq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmuldq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmuldq128_mask, "V2LLiV4iV4iV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmuludq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmuludq128_mask, "V2LLiV4iV4iV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmulld256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmulld128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pandd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pandd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pandnd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pandnd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pord256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pord128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pxord256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pxord128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pandq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pandq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pandnq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pandnq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_porq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_porq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pxorq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pxorq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_paddb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmullw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmullw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmullw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pandnd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pandnq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_paddq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psubq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_paddd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psubd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_pmulld512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmullq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_pmullq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_pmullq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
-
-TARGET_BUILTIN(__builtin_ia32_blendmb_512_mask, "V64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_blendmw_512_mask, "V32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packssdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packsswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packusdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packuswb512_mask, "V64cV32sV32sV64cULLi", "", "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_pavgb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgw512_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_mask, "V64cV64cV64cV64cULLi", "", "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_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_blendmb_128_mask, "V16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_blendmb_256_mask, "V32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_blendmw_128_mask, "V8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_blendmw_256_mask, "V16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsb128_mask, "V16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsb256_mask, "V32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsw128_mask, "V8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsw256_mask, "V16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packssdw128_mask, "V8sV4iV4iV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packssdw256_mask, "V16sV8iV8iV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packsswb128_mask, "V16cV8sV8sV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packsswb256_mask, "V32cV16sV16sV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packusdw128_mask, "V8sV4iV4iV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packusdw256_mask, "V16sV8iV8iV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packuswb128_mask, "V16cV8sV8sV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packuswb256_mask, "V32cV16sV16sV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxub128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxub256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminub128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminub256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pshufb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pshufb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-
-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, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_divss_round, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_mulss_round, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_subss_round, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_maxss_round, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_minss_round, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_addsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_divsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_mulsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_subsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_maxsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_minsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_addpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_addpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_addps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_addps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_blendmd_128_mask, "V4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_blendmd_256_mask, "V8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_blendmpd_128_mask, "V2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_blendmpd_256_mask, "V4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_blendmps_128_mask, "V4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_blendmps_256_mask, "V8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_blendmq_128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_blendmq_256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl")
-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_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_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_cvtdq2pd128_mask, "V2dV4iV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2pd256_mask, "V4dV4iV4dUc", "", "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_cvtudq2pd128_mask, "V2dV4iV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2pd256_mask, "V4dV4iV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_divpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_divpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_divps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_divps256_mask, "V8fV8fV8fV8fUc", "", "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_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_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_maxpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_maxpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_maxps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_maxps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_minpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_minpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_minps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_minps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_mulpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_mulpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_mulps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_mulps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pabsd128_mask, "V4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pabsd256_mask, "V8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pabsq128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pabsq256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxsd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxsd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxud128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxud256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminsd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminsd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminud128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminud256_mask, "V8iV8iV8iV8iUc", "", "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, "vv*UcV2LLiV2dIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2LLiV2LLiIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4LLiV4dIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4LLiV4LLiIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2LLiV4fIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2LLiV4iIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4LLiV4fIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4LLiV4iIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vv*UcV4iV2dIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2LLiIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vv*UcV4iV4dIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4LLiIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vv*UcV4iV4fIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vv*UcV4iV4iIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vv*UcV8iV8fIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vv*UcV8iV8iIi", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_sqrtpd128_mask, "V2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_sqrtpd256_mask, "V4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_sqrtps128_mask, "V4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_sqrtps256_mask, "V8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_subpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_subpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_subps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_subps256_mask, "V8fV8fV8fV8fUc", "", "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_pmovswb512_mask, "V32cV32sV32cUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpckhbw512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpckhwd512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpcklbw512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpcklwd512_mask, "V32sV32sV32sV32sUi", "", "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_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_pmaddubsw128_mask, "V8sV16cV16cV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaddubsw256_mask, "V16sV32cV32cV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd128_mask, "V4iV8sV8sV4iUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd256_mask, "V8iV16sV16sV8iUc", "", "avx512vl,avx512bw")
-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_pmulhrsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhrsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpckhbw128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpckhbw256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpckhwd128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpckhwd256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpcklbw128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpcklbw256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpcklwd128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_punpcklwd256_mask, "V16sV16sV16sV16sUs", "", "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")
-
-#undef BUILTIN
-#undef TARGET_BUILTIN
diff --git a/include/clang/Basic/BuiltinsXCore.def b/include/clang/Basic/BuiltinsXCore.def
deleted file mode 100644
index 672d205..0000000
--- a/include/clang/Basic/BuiltinsXCore.def
+++ /dev/null
@@ -1,22 +0,0 @@
-//===--- BuiltinsXCore.def - XCore Builtin function 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 the XCore-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-BUILTIN(__builtin_bitrev, "UiUi", "nc")
-BUILTIN(__builtin_getid, "Si", "nc")
-BUILTIN(__builtin_getps, "UiUi", "n")
-BUILTIN(__builtin_setps, "vUiUi", "n")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
deleted file mode 100644
index e4929b5..0000000
--- a/include/clang/Basic/CMakeLists.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-macro(clang_diag_gen component)
- clang_tablegen(Diagnostic${component}Kinds.inc
- -gen-clang-diags-defs -clang-component=${component}
- SOURCE Diagnostic.td
- TARGET ClangDiagnostic${component})
-endmacro(clang_diag_gen)
-
-clang_diag_gen(Analysis)
-clang_diag_gen(AST)
-clang_diag_gen(Comment)
-clang_diag_gen(Common)
-clang_diag_gen(Driver)
-clang_diag_gen(Frontend)
-clang_diag_gen(Lex)
-clang_diag_gen(Parse)
-clang_diag_gen(Sema)
-clang_diag_gen(Serialization)
-clang_tablegen(DiagnosticGroups.inc -gen-clang-diag-groups
- SOURCE Diagnostic.td
- TARGET ClangDiagnosticGroups)
-
-clang_tablegen(DiagnosticIndexName.inc -gen-clang-diags-index-name
- SOURCE Diagnostic.td
- TARGET ClangDiagnosticIndexName)
-
-clang_tablegen(AttrList.inc -gen-clang-attr-list
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE Attr.td
- TARGET ClangAttrList)
-
-clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE Attr.td
- TARGET ClangAttrHasAttributeImpl
- )
-
-# ARM NEON
-clang_tablegen(arm_neon.inc -gen-arm-neon-sema
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE arm_neon.td
- TARGET ClangARMNeon)
diff --git a/include/clang/Basic/CapturedStmt.h b/include/clang/Basic/CapturedStmt.h
deleted file mode 100644
index c4a289b..0000000
--- a/include/clang/Basic/CapturedStmt.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//===--- CapturedStmt.h - Types for CapturedStmts ---------------*- 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_BASIC_CAPTUREDSTMT_H
-#define LLVM_CLANG_BASIC_CAPTUREDSTMT_H
-
-namespace clang {
-
-/// \brief The different kinds of captured statement.
-enum CapturedRegionKind {
- CR_Default,
- CR_OpenMP
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_BASIC_CAPTUREDSTMT_H
diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h
deleted file mode 100644
index dd9c554..0000000
--- a/include/clang/Basic/CharInfo.h
+++ /dev/null
@@ -1,198 +0,0 @@
-//===--- clang/Basic/CharInfo.h - Classifying ASCII Characters ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_CHARINFO_H
-#define LLVM_CLANG_BASIC_CHARINFO_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace clang {
-namespace charinfo {
- extern const uint16_t InfoTable[256];
-
- enum {
- CHAR_HORZ_WS = 0x0001, // '\t', '\f', '\v'. Note, no '\0'
- CHAR_VERT_WS = 0x0002, // '\r', '\n'
- CHAR_SPACE = 0x0004, // ' '
- CHAR_DIGIT = 0x0008, // 0-9
- CHAR_XLETTER = 0x0010, // a-f,A-F
- CHAR_UPPER = 0x0020, // A-Z
- CHAR_LOWER = 0x0040, // a-z
- CHAR_UNDER = 0x0080, // _
- CHAR_PERIOD = 0x0100, // .
- CHAR_RAWDEL = 0x0200, // {}[]#<>%:;?*+-/^&|~!=,"'
- CHAR_PUNCT = 0x0400 // `$@()
- };
-
- enum {
- CHAR_XUPPER = CHAR_XLETTER | CHAR_UPPER,
- CHAR_XLOWER = CHAR_XLETTER | CHAR_LOWER
- };
-} // end namespace charinfo
-
-/// Returns true if this is an ASCII character.
-LLVM_READNONE static inline bool isASCII(char c) {
- return static_cast<unsigned char>(c) <= 127;
-}
-
-/// Returns true if this is a valid first character of a C identifier,
-/// which is [a-zA-Z_].
-LLVM_READONLY static inline bool isIdentifierHead(unsigned char c,
- bool AllowDollar = false) {
- using namespace charinfo;
- if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_UNDER))
- return true;
- return AllowDollar && c == '$';
-}
-
-/// Returns true if this is a body character of a C identifier,
-/// which is [a-zA-Z0-9_].
-LLVM_READONLY static inline bool isIdentifierBody(unsigned char c,
- bool AllowDollar = false) {
- using namespace charinfo;
- if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER))
- return true;
- return AllowDollar && c == '$';
-}
-
-/// Returns true if this character is horizontal ASCII whitespace:
-/// ' ', '\\t', '\\f', '\\v'.
-///
-/// Note that this returns false for '\\0'.
-LLVM_READONLY static inline bool isHorizontalWhitespace(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_SPACE)) != 0;
-}
-
-/// Returns true if this character is vertical ASCII whitespace: '\\n', '\\r'.
-///
-/// Note that this returns false for '\\0'.
-LLVM_READONLY static inline bool isVerticalWhitespace(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & CHAR_VERT_WS) != 0;
-}
-
-/// Return true if this character is horizontal or vertical ASCII whitespace:
-/// ' ', '\\t', '\\f', '\\v', '\\n', '\\r'.
-///
-/// Note that this returns false for '\\0'.
-LLVM_READONLY static inline bool isWhitespace(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_VERT_WS|CHAR_SPACE)) != 0;
-}
-
-/// Return true if this character is an ASCII digit: [0-9]
-LLVM_READONLY static inline bool isDigit(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & CHAR_DIGIT) != 0;
-}
-
-/// Return true if this character is a lowercase ASCII letter: [a-z]
-LLVM_READONLY static inline bool isLowercase(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & CHAR_LOWER) != 0;
-}
-
-/// Return true if this character is an uppercase ASCII letter: [A-Z]
-LLVM_READONLY static inline bool isUppercase(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & CHAR_UPPER) != 0;
-}
-
-/// Return true if this character is an ASCII letter: [a-zA-Z]
-LLVM_READONLY static inline bool isLetter(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER)) != 0;
-}
-
-/// Return true if this character is an ASCII letter or digit: [a-zA-Z0-9]
-LLVM_READONLY static inline bool isAlphanumeric(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & (CHAR_DIGIT|CHAR_UPPER|CHAR_LOWER)) != 0;
-}
-
-/// Return true if this character is an ASCII hex digit: [0-9a-fA-F]
-LLVM_READONLY static inline bool isHexDigit(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & (CHAR_DIGIT|CHAR_XLETTER)) != 0;
-}
-
-/// Return true if this character is an ASCII punctuation character.
-///
-/// Note that '_' is both a punctuation character and an identifier character!
-LLVM_READONLY static inline bool isPunctuation(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & (CHAR_UNDER|CHAR_PERIOD|CHAR_RAWDEL|CHAR_PUNCT)) != 0;
-}
-
-/// Return true if this character is an ASCII printable character; that is, a
-/// character that should take exactly one column to print in a fixed-width
-/// terminal.
-LLVM_READONLY static inline bool isPrintable(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|CHAR_PUNCT|
- CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL|CHAR_SPACE)) != 0;
-}
-
-/// Return true if this is the body character of a C preprocessing number,
-/// which is [a-zA-Z0-9_.].
-LLVM_READONLY static inline bool isPreprocessingNumberBody(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] &
- (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER|CHAR_PERIOD)) != 0;
-}
-
-/// Return true if this is the body character of a C++ raw string delimiter.
-LLVM_READONLY static inline bool isRawStringDelimBody(unsigned char c) {
- using namespace charinfo;
- return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|
- CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL)) != 0;
-}
-
-
-/// Converts the given ASCII character to its lowercase equivalent.
-///
-/// If the character is not an uppercase character, it is returned as is.
-LLVM_READONLY static inline char toLowercase(char c) {
- if (isUppercase(c))
- return c + 'a' - 'A';
- return c;
-}
-
-/// Converts the given ASCII character to its uppercase equivalent.
-///
-/// If the character is not a lowercase character, it is returned as is.
-LLVM_READONLY static inline char toUppercase(char c) {
- if (isLowercase(c))
- return c + 'A' - 'a';
- return 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 static inline bool isValidIdentifier(StringRef S) {
- if (S.empty() || !isIdentifierHead(S[0]))
- return false;
-
- for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I)
- if (!isIdentifierBody(*I))
- return false;
-
- return true;
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/CommentNodes.td b/include/clang/Basic/CommentNodes.td
deleted file mode 100644
index 7bf32b7..0000000
--- a/include/clang/Basic/CommentNodes.td
+++ /dev/null
@@ -1,27 +0,0 @@
-class Comment<bit abstract = 0> {
- bit Abstract = abstract;
-}
-
-class DComment<Comment base, bit abstract = 0> : Comment<abstract> {
- Comment Base = base;
-}
-
-def InlineContentComment : Comment<1>;
- def TextComment : DComment<InlineContentComment>;
- def InlineCommandComment : DComment<InlineContentComment>;
- def HTMLTagComment : DComment<InlineContentComment, 1>;
- def HTMLStartTagComment : DComment<HTMLTagComment>;
- def HTMLEndTagComment : DComment<HTMLTagComment>;
-
-def BlockContentComment : Comment<1>;
- def ParagraphComment : DComment<BlockContentComment>;
- def BlockCommandComment : DComment<BlockContentComment>;
- def ParamCommandComment : DComment<BlockCommandComment>;
- def TParamCommandComment : DComment<BlockCommandComment>;
- def VerbatimBlockComment : DComment<BlockCommandComment>;
- def VerbatimLineComment : DComment<BlockCommandComment>;
-
-def VerbatimBlockLineComment : Comment;
-
-def FullComment : Comment;
-
diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h
deleted file mode 100644
index 92419f9..0000000
--- a/include/clang/Basic/CommentOptions.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===--- CommentOptions.h - Options for parsing comments -----*- 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::CommentOptions interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_COMMENTOPTIONS_H
-#define LLVM_CLANG_BASIC_COMMENTOPTIONS_H
-
-#include <string>
-#include <vector>
-
-namespace clang {
-
-/// \brief Options for controlling comment parsing.
-struct CommentOptions {
- typedef std::vector<std::string> BlockCommandNamesTy;
-
- /// \brief 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;
-
- CommentOptions() : ParseAllComments(false) { }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
deleted file mode 100644
index 723ea54..0000000
--- a/include/clang/Basic/DeclNodes.td
+++ /dev/null
@@ -1,88 +0,0 @@
-class AttrSubject;
-
-class Decl<bit abstract = 0> : AttrSubject {
- bit Abstract = abstract;
-}
-
-class DDecl<Decl base, bit abstract = 0> : Decl<abstract> {
- Decl Base = base;
-}
-
-class DeclContext { }
-
-def TranslationUnit : Decl, DeclContext;
-def ExternCContext : Decl, DeclContext;
-def Named : Decl<1>;
- def Namespace : DDecl<Named>, DeclContext;
- def UsingDirective : DDecl<Named>;
- def NamespaceAlias : DDecl<Named>;
- def Label : DDecl<Named>;
- def Type : DDecl<Named, 1>;
- def TypedefName : DDecl<Type, 1>;
- def Typedef : DDecl<TypedefName>;
- def TypeAlias : DDecl<TypedefName>;
- def ObjCTypeParam : DDecl<TypedefName>;
- def UnresolvedUsingTypename : DDecl<Type>;
- def Tag : DDecl<Type, 1>, DeclContext;
- def Enum : DDecl<Tag>;
- def Record : DDecl<Tag>;
- def CXXRecord : DDecl<Record>;
- def ClassTemplateSpecialization : DDecl<CXXRecord>;
- def ClassTemplatePartialSpecialization
- : DDecl<ClassTemplateSpecialization>;
- def TemplateTypeParm : DDecl<Type>;
- def Value : DDecl<Named, 1>;
- def EnumConstant : DDecl<Value>;
- def UnresolvedUsingValue : DDecl<Value>;
- def IndirectField : DDecl<Value>;
- def Declarator : DDecl<Value, 1>;
- def Field : DDecl<Declarator>;
- def ObjCIvar : DDecl<Field>;
- def ObjCAtDefsField : DDecl<Field>;
- def MSProperty : DDecl<Declarator>;
- def Function : DDecl<Declarator>, DeclContext;
- def CXXMethod : DDecl<Function>;
- def CXXConstructor : DDecl<CXXMethod>;
- def CXXDestructor : DDecl<CXXMethod>;
- def CXXConversion : DDecl<CXXMethod>;
- def Var : DDecl<Declarator>;
- def VarTemplateSpecialization : DDecl<Var>;
- def VarTemplatePartialSpecialization
- : DDecl<VarTemplateSpecialization>;
- def ImplicitParam : DDecl<Var>;
- def ParmVar : DDecl<Var>;
- def NonTypeTemplateParm : DDecl<Declarator>;
- def Template : DDecl<Named, 1>;
- def RedeclarableTemplate : DDecl<Template, 1>;
- def FunctionTemplate : DDecl<RedeclarableTemplate>;
- def ClassTemplate : DDecl<RedeclarableTemplate>;
- def VarTemplate : DDecl<RedeclarableTemplate>;
- def TypeAliasTemplate : DDecl<RedeclarableTemplate>;
- def TemplateTemplateParm : DDecl<Template>;
- def BuiltinTemplate : DDecl<Template>;
- def Using : DDecl<Named>;
- def UsingShadow : DDecl<Named>;
- def ObjCMethod : DDecl<Named>, DeclContext;
- def ObjCContainer : DDecl<Named, 1>, DeclContext;
- def ObjCCategory : DDecl<ObjCContainer>;
- def ObjCProtocol : DDecl<ObjCContainer>;
- def ObjCInterface : DDecl<ObjCContainer>;
- def ObjCImpl : DDecl<ObjCContainer, 1>;
- def ObjCCategoryImpl : DDecl<ObjCImpl>;
- def ObjCImplementation : DDecl<ObjCImpl>;
- def ObjCProperty : DDecl<Named>;
- def ObjCCompatibleAlias : DDecl<Named>;
-def LinkageSpec : Decl, DeclContext;
-def ObjCPropertyImpl : Decl;
-def FileScopeAsm : Decl;
-def AccessSpec : Decl;
-def Friend : Decl;
-def FriendTemplate : Decl;
-def StaticAssert : Decl;
-def Block : Decl, DeclContext;
-def Captured : Decl, DeclContext;
-def ClassScopeFunctionSpecialization : Decl;
-def Import : Decl;
-def OMPThreadPrivate : Decl;
-def Empty : Decl;
-
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
deleted file mode 100644
index 1d6c19b..0000000
--- a/include/clang/Basic/Diagnostic.h
+++ /dev/null
@@ -1,1414 +0,0 @@
-//===--- Diagnostic.h - C Language Family Diagnostic 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 Diagnostic-related interfaces.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_H
-#define LLVM_CLANG_BASIC_DIAGNOSTIC_H
-
-#include "clang/Basic/DiagnosticIDs.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/Specifiers.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/iterator_range.h"
-#include <list>
-#include <vector>
-
-namespace clang {
- class DeclContext;
- class DiagnosticBuilder;
- class DiagnosticConsumer;
- class DiagnosticErrorTrap;
- class DiagnosticOptions;
- class IdentifierInfo;
- class LangOptions;
- class Preprocessor;
- class StoredDiagnostic;
- namespace tok {
- enum TokenKind : unsigned short;
- }
-
-/// \brief 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
-/// introduction, removal, or modification of a particular (small!)
-/// amount of code will correct a compilation error. The compiler
-/// should also provide full recovery from such errors, such that
-/// suppressing the diagnostic output can still result in successful
-/// compilation.
-class FixItHint {
-public:
- /// \brief 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
- /// location.
- CharSourceRange InsertFromRange;
-
- /// \brief The actual code to insert at the insertion location, as a
- /// string.
- std::string CodeToInsert;
-
- bool BeforePreviousInsertions;
-
- /// \brief Empty code modification hint, indicating that no code
- /// modification is known.
- FixItHint() : BeforePreviousInsertions(false) { }
-
- bool isNull() const {
- return !RemoveRange.isValid();
- }
-
- /// \brief Create a code modification hint that inserts the given
- /// code string at a specific location.
- static FixItHint CreateInsertion(SourceLocation InsertionLoc,
- StringRef Code,
- bool BeforePreviousInsertions = false) {
- FixItHint Hint;
- Hint.RemoveRange =
- CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
- Hint.CodeToInsert = Code;
- Hint.BeforePreviousInsertions = BeforePreviousInsertions;
- return Hint;
- }
-
- /// \brief Create a code modification hint that inserts the given
- /// code from \p FromRange at a specific location.
- static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
- CharSourceRange FromRange,
- bool BeforePreviousInsertions = false) {
- FixItHint Hint;
- Hint.RemoveRange =
- CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
- Hint.InsertFromRange = FromRange;
- Hint.BeforePreviousInsertions = BeforePreviousInsertions;
- return Hint;
- }
-
- /// \brief Create a code modification hint that removes the given
- /// source range.
- static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
- FixItHint Hint;
- Hint.RemoveRange = RemoveRange;
- return Hint;
- }
- static FixItHint CreateRemoval(SourceRange RemoveRange) {
- return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
- }
-
- /// \brief Create a code modification hint that replaces the given
- /// source range with the given code string.
- static FixItHint CreateReplacement(CharSourceRange RemoveRange,
- StringRef Code) {
- FixItHint Hint;
- Hint.RemoveRange = RemoveRange;
- Hint.CodeToInsert = Code;
- return Hint;
- }
-
- static FixItHint CreateReplacement(SourceRange RemoveRange,
- StringRef Code) {
- return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
- }
-};
-
-/// \brief 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
-/// the user. DiagnosticsEngine is tied to one translation unit and one
-/// SourceManager.
-class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
- DiagnosticsEngine(const DiagnosticsEngine &) = delete;
- void operator=(const DiagnosticsEngine &) = delete;
-
-public:
- /// \brief The level of the diagnostic, after it has been through mapping.
- enum Level {
- Ignored = DiagnosticIDs::Ignored,
- Note = DiagnosticIDs::Note,
- Remark = DiagnosticIDs::Remark,
- Warning = DiagnosticIDs::Warning,
- Error = DiagnosticIDs::Error,
- Fatal = DiagnosticIDs::Fatal
- };
-
- 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 *
- };
-
- /// \brief Represents on argument value, which is a union discriminated
- /// by ArgumentKind, with a value.
- typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
-
-private:
- unsigned char AllExtensionsSilenced; // Used by __extension__
- bool IgnoreAllWarnings; // Ignore all warnings: -w
- bool WarningsAsErrors; // Treat warnings like errors.
- bool EnableAllWarnings; // Enable all warnings.
- bool ErrorsAsFatal; // Treat errors like fatal errors.
- bool SuppressSystemWarnings; // Suppress warnings in system headers.
- 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.
- diag::Severity ExtBehavior; // Map extensions to warnings or errors?
- IntrusiveRefCntPtr<DiagnosticIDs> Diags;
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
- DiagnosticConsumer *Client;
- std::unique_ptr<DiagnosticConsumer> Owner;
- SourceManager *SourceMgr;
-
- /// \brief 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.
- /// The high bit is set when the mapping was established as a user mapping.
- /// If the high bit is clear, then the low bits are set to the default
- /// value, and should be mapped with -pedantic, -Werror, etc.
- ///
- /// A new DiagState is created and kept around when diagnostic pragmas modify
- /// the state so that we know what is the diagnostic state at any given
- /// source location.
- class DiagState {
- llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap;
-
- public:
- typedef llvm::DenseMap<unsigned, DiagnosticMapping>::iterator iterator;
- typedef llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator
- const_iterator;
-
- void setMapping(diag::kind Diag, DiagnosticMapping Info) {
- DiagMap[Diag] = Info;
- }
-
- DiagnosticMapping &getOrAddMapping(diag::kind Diag);
-
- const_iterator begin() const { return DiagMap.begin(); }
- const_iterator end() const { return DiagMap.end(); }
- };
-
- /// \brief Keeps and automatically disposes all DiagStates that we create.
- std::list<DiagState> DiagStates;
-
- /// \brief 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
- /// modifications done through the command-line.
- struct DiagStatePoint {
- DiagState *State;
- FullSourceLoc Loc;
- DiagStatePoint(DiagState *State, FullSourceLoc Loc)
- : State(State), Loc(Loc) { }
-
- bool operator<(const DiagStatePoint &RHS) const {
- // If Loc is invalid it means it came from <command-line>, in which case
- // we regard it as coming before any valid source location.
- if (RHS.Loc.isInvalid())
- return false;
- if (Loc.isInvalid())
- return true;
- return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
- }
- };
-
- /// \brief A sorted vector of all DiagStatePoints representing changes in
- /// diagnostic state due to diagnostic pragmas.
- ///
- /// The vector is always sorted according to the SourceLocation of the
- /// DiagStatePoint.
- typedef std::vector<DiagStatePoint> DiagStatePointsTy;
- mutable DiagStatePointsTy DiagStatePoints;
-
- /// \brief Keeps the DiagState that was active during each diagnostic 'push'
- /// so we can get back at it when we 'pop'.
- std::vector<DiagState *> DiagStateOnPushStack;
-
- DiagState *GetCurDiagState() const {
- assert(!DiagStatePoints.empty());
- return DiagStatePoints.back().State;
- }
-
- void PushDiagStatePoint(DiagState *State, SourceLocation L) {
- FullSourceLoc Loc(L, getSourceManager());
- // Make sure that DiagStatePoints is always sorted according to Loc.
- assert(Loc.isValid() && "Adding invalid loc point");
- assert(!DiagStatePoints.empty() &&
- (DiagStatePoints.back().Loc.isInvalid() ||
- DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
- "Previous point loc comes after or is the same as new one");
- DiagStatePoints.push_back(DiagStatePoint(State, Loc));
- }
-
- /// \brief Finds the DiagStatePoint that contains the diagnostic state of
- /// the given source location.
- DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
-
- /// \brief 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.
- /// 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.
- bool FatalErrorOccurred;
-
- /// \brief Indicates that an unrecoverable error has occurred.
- bool UnrecoverableErrorOccurred;
-
- /// \brief 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.
- ///
- /// 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
-
- /// \brief A function pointer that converts an opaque diagnostic
- /// argument to a strings.
- ///
- /// This takes the modifiers and argument that was present in the diagnostic.
- ///
- /// The PrevArgs array indicates the previous arguments formatted for this
- /// diagnostic. Implementations of this function can use this information to
- /// avoid redundancy across arguments.
- ///
- /// This is a hack to avoid a layering violation between libbasic and libsema.
- typedef void (*ArgToStringFnTy)(
- ArgumentKind Kind, intptr_t Val,
- StringRef Modifier, StringRef Argument,
- ArrayRef<ArgumentValue> PrevArgs,
- SmallVectorImpl<char> &Output,
- void *Cookie,
- ArrayRef<intptr_t> QualTypeVals);
- void *ArgToStringCookie;
- ArgToStringFnTy ArgToStringFn;
-
- /// \brief 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.
- std::string DelayedDiagArg1;
-
- /// \brief Second string argument for the delayed diagnostic.
- std::string DelayedDiagArg2;
-
- /// \brief 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
- /// and '='.
- std::string FlagValue;
-
-public:
- explicit DiagnosticsEngine(
- const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
- DiagnosticOptions *DiagOpts,
- DiagnosticConsumer *client = nullptr,
- bool ShouldOwnClient = true);
- ~DiagnosticsEngine();
-
- const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
- return Diags;
- }
-
- /// \brief Retrieve the diagnostic options.
- DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
-
- typedef llvm::iterator_range<DiagState::const_iterator> diag_mapping_range;
-
- /// \brief Get the current set of diagnostic mappings.
- diag_mapping_range getDiagnosticMappings() const {
- const DiagState &DS = *GetCurDiagState();
- return diag_mapping_range(DS.begin(), DS.end());
- }
-
- DiagnosticConsumer *getClient() { return Client; }
- const DiagnosticConsumer *getClient() const { return Client; }
-
- /// \brief 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
- /// 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) { SourceMgr = SrcMgr; }
-
- //===--------------------------------------------------------------------===//
- // DiagnosticsEngine characterization methods, used by a client to customize
- // how diagnostics are emitted.
- //
-
- /// \brief 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,
- /// 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.
- ///
- /// \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
- /// emit before giving up.
- ///
- /// Zero disables the limit.
- void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
-
- /// \brief 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
- /// notes to emit along with a given diagnostic.
- unsigned getTemplateBacktraceLimit() const {
- return TemplateBacktraceLimit;
- }
-
- /// \brief 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
- /// notes to emit along with a given diagnostic.
- unsigned getConstexprBacktraceLimit() const {
- return ConstexprBacktraceLimit;
- }
-
- /// \brief When set to true, any unmapped warnings are ignored.
- ///
- /// If this and WarningsAsErrors are both set, then this one wins.
- void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
- bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
-
- /// \brief When set to true, any unmapped ignored warnings are no longer
- /// ignored.
- ///
- /// If this and IgnoreAllWarnings are both set, then that one wins.
- void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; }
- bool getEnableAllWarnings() const { return EnableAllWarnings; }
-
- /// \brief When set to true, any warnings reported are issued as errors.
- void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
- bool getWarningsAsErrors() const { return WarningsAsErrors; }
-
- /// \brief When set to true, any error reported is made a fatal error.
- void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
- bool getErrorsAsFatal() const { return ErrorsAsFatal; }
-
- /// \brief When set to true mask warnings that come from system headers.
- void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
- bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
-
- /// \brief 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) {
- SuppressAllDiagnostics = Val;
- }
- bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
-
- /// \brief 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
- /// 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
- /// into the output.
- void setShowColors(bool Val = false) { ShowColors = Val; }
- bool getShowColors() { return ShowColors; }
-
- /// \brief Specify which overload candidates to show when overload resolution
- /// fails.
- ///
- /// By default, we show all candidates.
- void setShowOverloads(OverloadsShown Val) {
- ShowOverloads = Val;
- }
- OverloadsShown getShowOverloads() const { return ShowOverloads; }
-
- /// \brief Pretend that the last diagnostic issued was ignored, so any
- /// subsequent notes will be suppressed.
- ///
- /// This can be used by clients who suppress diagnostics themselves.
- void setLastDiagnosticIgnored() {
- if (LastDiagLevel == DiagnosticIDs::Fatal)
- FatalErrorOccurred = true;
- LastDiagLevel = DiagnosticIDs::Ignored;
- }
-
- /// \brief 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
- /// mapped onto ignore/warning/error.
- ///
- /// This corresponds to the GCC -pedantic and -pedantic-errors option.
- void setExtensionHandlingBehavior(diag::Severity H) { ExtBehavior = H; }
- diag::Severity getExtensionHandlingBehavior() const { return ExtBehavior; }
-
- /// \brief Counter bumped when an __extension__ block is/ encountered.
- ///
- /// When non-zero, all extension diagnostics are entirely silenced, no
- /// matter how they are mapped.
- void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
- void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
- bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
-
- /// \brief This allows the client to specify that certain warnings are
- /// ignored.
- ///
- /// Notes can never be mapped, errors can only be mapped to fatal, and
- /// WARNINGs and EXTENSIONs can be mapped arbitrarily.
- ///
- /// \param Loc The source location that this change of diagnostic state should
- /// 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
- /// have the specified mapping.
- ///
- /// \returns true (and ignores the request) if "Group" was unknown, false
- /// otherwise.
- ///
- /// \param Flavor The flavor of group to affect. -Rfoo does not affect the
- /// state of the -Wfoo group and vice versa.
- ///
- /// \param Loc The source location that this change of diagnostic state should
- /// take affect. It can be null if we are setting the state from command-line.
- bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
- diag::Severity Map,
- SourceLocation Loc = SourceLocation());
-
- /// \brief 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.
- ///
- /// 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
- /// flavor.
- ///
- /// Mainly to be used by -Wno-everything to disable all warnings but allow
- /// subsequent -W options to enable specific warnings.
- void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map,
- SourceLocation Loc = SourceLocation());
-
- bool hasErrorOccurred() const { return ErrorOccurred; }
-
- /// \brief 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.
- bool hasUnrecoverableErrorOccurred() const {
- return FatalErrorOccurred || UnrecoverableErrorOccurred;
- }
-
- unsigned getNumWarnings() const { return NumWarnings; }
-
- void setNumWarnings(unsigned NumWarnings) {
- this->NumWarnings = NumWarnings;
- }
-
- /// \brief 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
- /// created, otherwise the existing ID is returned.
- ///
- /// \param FormatString A fixed diagnostic format string that will be hashed
- /// and mapped to a unique DiagID.
- template <unsigned N>
- unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
- return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
- StringRef(FormatString, N - 1));
- }
-
- /// \brief 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,
- ArrayRef<ArgumentValue> PrevArgs,
- SmallVectorImpl<char> &Output,
- ArrayRef<intptr_t> QualTypeVals) const {
- ArgToStringFn(Kind, Val, Modifier, Argument, PrevArgs, Output,
- ArgToStringCookie, QualTypeVals);
- }
-
- void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
- ArgToStringFn = Fn;
- ArgToStringCookie = Cookie;
- }
-
- /// \brief 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
- /// configuration.
- void Reset();
-
- //===--------------------------------------------------------------------===//
- // DiagnosticsEngine classification and reporting interfaces.
- //
-
- /// \brief 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
- /// specified location \p Loc.
- ///
- /// \param Loc The source location we are interested in finding out the
- /// diagnostic state. Can be null in order to query the latest state.
- bool isIgnored(unsigned DiagID, SourceLocation Loc) const {
- return Diags->getDiagnosticSeverity(DiagID, Loc, *this) ==
- diag::Severity::Ignored;
- }
-
- /// \brief Based on the way the client configured the DiagnosticsEngine
- /// object, classify the specified diagnostic ID into a Level, consumable by
- /// the DiagnosticConsumer.
- ///
- /// To preserve invariant assumptions, this function should not be used to
- /// influence parse or semantic analysis actions. Instead consider using
- /// \c isIgnored().
- ///
- /// \param Loc The source location we are interested in finding out the
- /// diagnostic state. Can be null in order to query the latest state.
- Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
- return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
- }
-
- /// \brief Issue the message to the client.
- ///
- /// This actually returns an instance of DiagnosticBuilder which emits the
- /// diagnostics (through @c ProcessDiag) when it is destroyed.
- ///
- /// \param DiagID A member of the @c diag::kind enum.
- /// \param Loc Represents the source location associated with the diagnostic,
- /// which can be an invalid location if no position information is available.
- inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID);
- inline DiagnosticBuilder Report(unsigned DiagID);
-
- void Report(const StoredDiagnostic &storedDiag);
-
- /// \brief Determine whethere there is already a diagnostic in flight.
- bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
-
- /// \brief 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
- /// report a problem (e.g., with an inconsistent file system
- /// state), this routine sets a "delayed" diagnostic that will be
- /// emitted after the current diagnostic completes. This should
- /// only be used for fatal errors detected at inconvenient
- /// times. If emitting a delayed diagnostic causes a second delayed
- /// diagnostic to be introduced, that second delayed diagnostic
- /// will be ignored.
- ///
- /// \param DiagID The ID of the diagnostic being delayed.
- ///
- /// \param Arg1 A string argument that will be provided to the
- /// diagnostic. A copy of this string will be stored in the
- /// DiagnosticsEngine object itself.
- ///
- /// \param Arg2 A string argument that will be provided to the
- /// diagnostic. A copy of this string will be stored in the
- /// DiagnosticsEngine object itself.
- void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
- StringRef Arg2 = "");
-
- /// \brief Clear out the current diagnostic.
- void Clear() { CurDiagID = ~0U; }
-
- /// \brief 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 DiagnosticErrorTrap;
-
- /// \brief The location of the current diagnostic that is in flight.
- SourceLocation CurDiagLoc;
-
- /// \brief The ID of the current diagnostic that is in flight.
- ///
- /// This is set to ~0U when there is no diagnostic in flight.
- unsigned CurDiagID;
-
- enum {
- /// \brief 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
- /// anyway.
- MaxArguments = 10,
- };
-
- /// \brief The number of entries in Arguments.
- signed char NumDiagArgs;
-
- /// \brief 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
- /// 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.
- ///
- /// 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.
- SmallVector<CharSourceRange, 8> DiagRanges;
-
- /// \brief If valid, provides a hint with some code to insert, remove,
- /// or modify at a particular position.
- SmallVector<FixItHint, 8> DiagFixItHints;
-
- DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
- bool isPragma = L.isValid();
- DiagnosticMapping Mapping =
- DiagnosticMapping::Make(Map, /*IsUser=*/true, isPragma);
-
- // If this is a pragma mapping, then set the diagnostic mapping flags so
- // that we override command line options.
- if (isPragma) {
- Mapping.setNoWarningAsError(true);
- Mapping.setNoErrorAsFatal(true);
- }
-
- return Mapping;
- }
-
- /// \brief Used to report a diagnostic that is finally fully formed.
- ///
- /// \returns true if the diagnostic was emitted, false if it was suppressed.
- bool ProcessDiag() {
- return Diags->ProcessDiag(*this);
- }
-
- /// @name Diagnostic Emission
- /// @{
-protected:
- // 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.
- ///
- /// \param Force Emit the diagnostic regardless of suppression settings.
- bool EmitCurrentDiagnostic(bool Force = false);
-
- unsigned getCurrentDiagID() const { return CurDiagID; }
-
- SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
-
- /// @}
-
- friend class ASTReader;
- friend class ASTWriter;
-};
-
-/// \brief RAII class that determines when any errors have occurred
-/// between the time the instance was created and the time it was
-/// queried.
-class DiagnosticErrorTrap {
- DiagnosticsEngine &Diag;
- unsigned NumErrors;
- unsigned NumUnrecoverableErrors;
-
-public:
- explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
- : Diag(Diag) { reset(); }
-
- /// \brief 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
- /// object instance was created.
- bool hasUnrecoverableErrorOccurred() const {
- return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
- }
-
- /// \brief Set to initial state of "no errors occurred".
- void reset() {
- NumErrors = Diag.TrapNumErrorsOccurred;
- NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// DiagnosticBuilder
-//===----------------------------------------------------------------------===//
-
-/// \brief 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
-/// the currently "in flight" diagnostic. When the temporary for the builder
-/// is destroyed, the diagnostic is issued.
-///
-/// Note that many of these will be created as temporary objects (many call
-/// sites), so we want them to be small and we never want their address taken.
-/// This ensures that compilers with somewhat reasonable optimizers will promote
-/// the common fields to registers, eliminating increments of the NumArgs field,
-/// for example.
-class DiagnosticBuilder {
- mutable DiagnosticsEngine *DiagObj = nullptr;
- mutable unsigned NumArgs = 0;
-
- /// \brief 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
- /// call to ForceEmit.
- mutable bool IsForceEmit = false;
-
- void operator=(const DiagnosticBuilder &) = delete;
- friend class DiagnosticsEngine;
-
- DiagnosticBuilder() = default;
-
- explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
- : DiagObj(diagObj), IsActive(true) {
- assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
- diagObj->DiagRanges.clear();
- diagObj->DiagFixItHints.clear();
- }
-
- friend class PartialDiagnostic;
-
-protected:
- void FlushCounts() {
- DiagObj->NumDiagArgs = NumArgs;
- }
-
- /// \brief Clear out the current diagnostic.
- void Clear() const {
- DiagObj = nullptr;
- IsActive = false;
- IsForceEmit = false;
- }
-
- /// \brief Determine whether this diagnostic is still active.
- bool isActive() const { return IsActive; }
-
- /// \brief 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.
- ///
- /// \returns true if a diagnostic was emitted, false if the
- /// diagnostic was suppressed.
- bool Emit() {
- // If this diagnostic is inactive, then its soul was stolen by the copy ctor
- // (or by a subclass, as in SemaDiagnosticBuilder).
- if (!isActive()) return false;
-
- // When emitting diagnostics, we set the final argument count into
- // the DiagnosticsEngine object.
- FlushCounts();
-
- // Process the diagnostic.
- bool Result = DiagObj->EmitCurrentDiagnostic(IsForceEmit);
-
- // This diagnostic is dead.
- Clear();
-
- return Result;
- }
-
-public:
- /// Copy constructor. When copied, this "takes" the diagnostic info from the
- /// input and neuters it.
- DiagnosticBuilder(const DiagnosticBuilder &D) {
- DiagObj = D.DiagObj;
- IsActive = D.IsActive;
- IsForceEmit = D.IsForceEmit;
- D.Clear();
- NumArgs = D.NumArgs;
- }
-
- /// \brief Retrieve an empty diagnostic builder.
- static DiagnosticBuilder getEmpty() {
- return DiagnosticBuilder();
- }
-
- /// \brief Emits the diagnostic.
- ~DiagnosticBuilder() {
- Emit();
- }
-
- /// \brief Forces the diagnostic to be emitted.
- const DiagnosticBuilder &setForceEmit() const {
- IsForceEmit = true;
- return *this;
- }
-
- /// \brief 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:
- /// \code
- /// return Diag(...);
- /// \endcode
- operator bool() const { return true; }
-
- void AddString(StringRef S) const {
- assert(isActive() && "Clients must not add to cleared diagnostic!");
- assert(NumArgs < DiagnosticsEngine::MaxArguments &&
- "Too many arguments to diagnostic!");
- DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
- DiagObj->DiagArgumentsStr[NumArgs++] = S;
- }
-
- void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
- assert(isActive() && "Clients must not add to cleared diagnostic!");
- assert(NumArgs < DiagnosticsEngine::MaxArguments &&
- "Too many arguments to diagnostic!");
- DiagObj->DiagArgumentsKind[NumArgs] = Kind;
- DiagObj->DiagArgumentsVal[NumArgs++] = V;
- }
-
- void AddSourceRange(const CharSourceRange &R) const {
- assert(isActive() && "Clients must not add to cleared diagnostic!");
- DiagObj->DiagRanges.push_back(R);
- }
-
- void AddFixItHint(const FixItHint &Hint) const {
- assert(isActive() && "Clients must not add to cleared diagnostic!");
- if (!Hint.isNull())
- DiagObj->DiagFixItHints.push_back(Hint);
- }
-
- void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; }
-};
-
-struct AddFlagValue {
- explicit AddFlagValue(StringRef V) : Val(V) {}
- StringRef Val;
-};
-
-/// \brief 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).
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const AddFlagValue V) {
- DB.addFlagValue(V.Val);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- StringRef S) {
- DB.AddString(S);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const char *Str) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
- DiagnosticsEngine::ak_c_string);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
- DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
- return DB;
-}
-
-// We use enable_if here to prevent that this overload is selected for
-// pointers or other arguments that are implicitly convertible to bool.
-template <typename T>
-inline
-typename std::enable_if<std::is_same<T, bool>::value,
- const DiagnosticBuilder &>::type
-operator<<(const DiagnosticBuilder &DB, T I) {
- DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- unsigned I) {
- DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- tok::TokenKind I) {
- DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const IdentifierInfo *II) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
- DiagnosticsEngine::ak_identifierinfo);
- return DB;
-}
-
-// Adds a DeclContext to the diagnostic. The enable_if template magic is here
-// so that we only match those arguments that are (statically) DeclContexts;
-// other arguments that derive from DeclContext (e.g., RecordDecls) will not
-// match.
-template<typename T>
-inline
-typename std::enable_if<std::is_same<T, DeclContext>::value,
- const DiagnosticBuilder &>::type
-operator<<(const DiagnosticBuilder &DB, T *DC) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
- DiagnosticsEngine::ak_declcontext);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- SourceRange R) {
- DB.AddSourceRange(CharSourceRange::getTokenRange(R));
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- ArrayRef<SourceRange> Ranges) {
- for (SourceRange R : Ranges)
- DB.AddSourceRange(CharSourceRange::getTokenRange(R));
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const CharSourceRange &R) {
- DB.AddSourceRange(R);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const FixItHint &Hint) {
- DB.AddFixItHint(Hint);
- return DB;
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- ArrayRef<FixItHint> Hints) {
- for (const FixItHint &Hint : Hints)
- DB.AddFixItHint(Hint);
- return DB;
-}
-
-/// A nullability kind paired with a bit indicating whether it used a
-/// context-sensitive keyword.
-typedef std::pair<NullabilityKind, bool> DiagNullabilityKind;
-
-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!");
- CurDiagLoc = Loc;
- CurDiagID = DiagID;
- FlagValue.clear();
- return DiagnosticBuilder(this);
-}
-
-inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
- return Report(SourceLocation(), DiagID);
-}
-
-//===----------------------------------------------------------------------===//
-// Diagnostic
-//===----------------------------------------------------------------------===//
-
-/// A little helper class (which is basically a smart pointer that forwards
-/// info from DiagnosticsEngine) that allows clients to enquire about the
-/// currently in-flight diagnostic.
-class Diagnostic {
- const DiagnosticsEngine *DiagObj;
- StringRef StoredDiagMessage;
-public:
- explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
- Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
- : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
-
- const DiagnosticsEngine *getDiags() const { return DiagObj; }
- unsigned getID() const { return DiagObj->CurDiagID; }
- const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
- bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
- SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
-
- unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
-
- /// \brief Return the kind of the specified index.
- ///
- /// Based on the kind of argument, the accessors below can be used to get
- /// the value.
- ///
- /// \pre Idx < getNumArgs()
- DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Argument index out of range!");
- return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
- }
-
- /// \brief 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 &&
- "invalid argument accessor!");
- return DiagObj->DiagArgumentsStr[Idx];
- }
-
- /// \brief 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 &&
- "invalid argument accessor!");
- return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
- }
-
- /// \brief Return the specified signed integer argument.
- /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
- int getArgSInt(unsigned Idx) const {
- assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
- "invalid argument accessor!");
- return (int)DiagObj->DiagArgumentsVal[Idx];
- }
-
- /// \brief Return the specified unsigned integer argument.
- /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
- unsigned getArgUInt(unsigned Idx) const {
- assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
- "invalid argument accessor!");
- return (unsigned)DiagObj->DiagArgumentsVal[Idx];
- }
-
- /// \brief Return the specified IdentifierInfo argument.
- /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo
- const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
- assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
- "invalid argument accessor!");
- return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
- }
-
- /// \brief 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 &&
- "invalid argument accessor!");
- return DiagObj->DiagArgumentsVal[Idx];
- }
-
- /// \brief Return the number of source ranges associated with this diagnostic.
- unsigned getNumRanges() const {
- return DiagObj->DiagRanges.size();
- }
-
- /// \pre Idx < getNumRanges()
- const CharSourceRange &getRange(unsigned Idx) const {
- assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
- return DiagObj->DiagRanges[Idx];
- }
-
- /// \brief Return an array reference for this diagnostic's ranges.
- ArrayRef<CharSourceRange> getRanges() const {
- return DiagObj->DiagRanges;
- }
-
- unsigned getNumFixItHints() const {
- return DiagObj->DiagFixItHints.size();
- }
-
- const FixItHint &getFixItHint(unsigned Idx) const {
- assert(Idx < getNumFixItHints() && "Invalid index!");
- return DiagObj->DiagFixItHints[Idx];
- }
-
- ArrayRef<FixItHint> getFixItHints() const {
- return DiagObj->DiagFixItHints;
- }
-
- /// \brief 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
- /// 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
- * corresponding source manager is destroyed.
- */
-class StoredDiagnostic {
- unsigned ID;
- DiagnosticsEngine::Level Level;
- FullSourceLoc Loc;
- std::string Message;
- std::vector<CharSourceRange> Ranges;
- std::vector<FixItHint> FixIts;
-
-public:
- StoredDiagnostic() = default;
- StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
- StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
- StringRef Message);
- StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
- StringRef Message, FullSourceLoc Loc,
- ArrayRef<CharSourceRange> Ranges,
- ArrayRef<FixItHint> Fixits);
-
- /// \brief Evaluates true when this object stores a diagnostic.
- explicit operator bool() const { return Message.size() > 0; }
-
- unsigned getID() const { return ID; }
- DiagnosticsEngine::Level getLevel() const { return Level; }
- const FullSourceLoc &getLocation() const { return Loc; }
- StringRef getMessage() const { return Message; }
-
- void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
-
- typedef std::vector<CharSourceRange>::const_iterator range_iterator;
- range_iterator range_begin() const { return Ranges.begin(); }
- range_iterator range_end() const { return Ranges.end(); }
- unsigned range_size() const { return Ranges.size(); }
-
- ArrayRef<CharSourceRange> getRanges() const {
- return llvm::makeArrayRef(Ranges);
- }
-
-
- typedef std::vector<FixItHint>::const_iterator fixit_iterator;
- fixit_iterator fixit_begin() const { return FixIts.begin(); }
- fixit_iterator fixit_end() const { return FixIts.end(); }
- unsigned fixit_size() const { return FixIts.size(); }
-
- ArrayRef<FixItHint> getFixIts() const {
- return llvm::makeArrayRef(FixIts);
- }
-};
-
-/// \brief Abstract interface, implemented by clients of the front-end, which
-/// formats and prints fully processed diagnostics.
-class DiagnosticConsumer {
-protected:
- unsigned NumWarnings; ///< Number of warnings reported
- unsigned NumErrors; ///< Number of errors reported
-
-public:
- DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { }
-
- unsigned getNumErrors() const { return NumErrors; }
- unsigned getNumWarnings() const { return NumWarnings; }
- virtual void clear() { NumWarnings = NumErrors = 0; }
-
- virtual ~DiagnosticConsumer();
-
- /// \brief 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
- /// file, for example during the parsing of command line options. However,
- /// diagnostics with source range information are required to only be emitted
- /// in between BeginSourceFile() and EndSourceFile().
- ///
- /// \param LangOpts The language options for the source file being processed.
- /// \param PP The preprocessor object being used for the source; this is
- /// optional, e.g., it may not be present when processing AST source files.
- virtual void BeginSourceFile(const LangOptions &LangOpts,
- const Preprocessor *PP = nullptr) {}
-
- /// \brief 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
- /// source files has ended.
- virtual void finish() {}
-
- /// \brief 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
- /// capturing it to a log as needed.
- ///
- /// The default implementation just keeps track of the total number of
- /// warnings and errors.
- virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info);
-};
-
-/// \brief A diagnostic client that ignores all diagnostics.
-class IgnoringDiagConsumer : public DiagnosticConsumer {
- virtual void anchor();
- void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) override {
- // Just ignore it.
- }
-};
-
-/// \brief Diagnostic consumer that forwards diagnostics along to an
-/// existing, already-initialized diagnostic consumer.
-///
-class ForwardingDiagnosticConsumer : public DiagnosticConsumer {
- DiagnosticConsumer &Target;
-
-public:
- ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {}
-
- ~ForwardingDiagnosticConsumer() override;
-
- void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) override;
- void clear() override;
-
- bool IncludeInDiagnosticCounts() const override;
-};
-
-// Struct used for sending info about how a type should be printed.
-struct TemplateDiffTypes {
- intptr_t FromType;
- intptr_t ToType;
- unsigned PrintTree : 1;
- 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;
-};
-
-/// Special character that the diagnostic printer will use to toggle the bold
-/// 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
-
-#endif
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
deleted file mode 100644
index 48cbf09..0000000
--- a/include/clang/Basic/Diagnostic.td
+++ /dev/null
@@ -1,127 +0,0 @@
-//===--- Diagnostic.td - C Language Family Diagnostic Handling ------------===//
-//
-// 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 core definitions for the diagnostics
-// and diagnostic control.
-//
-//===----------------------------------------------------------------------===//
-
-// Define the diagnostic severities.
-class Severity<string N> {
- string Name = N;
-}
-def SEV_Ignored : Severity<"Ignored">;
-def SEV_Remark : Severity<"Remark">;
-def SEV_Warning : Severity<"Warning">;
-def SEV_Error : Severity<"Error">;
-def SEV_Fatal : Severity<"Fatal">;
-
-// Define the diagnostic classes.
-class DiagClass;
-def CLASS_NOTE : DiagClass;
-def CLASS_REMARK : DiagClass;
-def CLASS_WARNING : DiagClass;
-def CLASS_EXTENSION : DiagClass;
-def CLASS_ERROR : DiagClass;
-
-// Responses to a diagnostic in a SFINAE context.
-class SFINAEResponse;
-def SFINAE_SubstitutionFailure : SFINAEResponse;
-def SFINAE_Suppress : SFINAEResponse;
-def SFINAE_Report : SFINAEResponse;
-def SFINAE_AccessControl : SFINAEResponse;
-
-// Diagnostic Categories. These can be applied to groups or individual
-// diagnostics to specify a category.
-class DiagCategory<string Name> {
- string CategoryName = Name;
-}
-
-// Diagnostic Groups.
-class DiagGroup<string Name, list<DiagGroup> subgroups = []> {
- string GroupName = Name;
- list<DiagGroup> SubGroups = subgroups;
- string CategoryName = "";
-}
-class InGroup<DiagGroup G> { DiagGroup Group = G; }
-//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
-
-
-// This defines all of the named diagnostic categories.
-include "DiagnosticCategories.td"
-
-// This defines all of the named diagnostic groups.
-include "DiagnosticGroups.td"
-
-
-// All diagnostics emitted by the compiler are an indirect subclass of this.
-class Diagnostic<string text, DiagClass DC, Severity defaultmapping> {
- /// Component is specified by the file with a big let directive.
- string Component = ?;
- string Text = text;
- DiagClass Class = DC;
- SFINAEResponse SFINAE = SFINAE_Suppress;
- bit AccessControl = 0;
- bit WarningNoWerror = 0;
- bit ShowInSystemHeader = 0;
- Severity DefaultSeverity = defaultmapping;
- DiagGroup Group;
- string CategoryName = "";
-}
-
-class SFINAEFailure {
- SFINAEResponse SFINAE = SFINAE_SubstitutionFailure;
-}
-class NoSFINAE {
- SFINAEResponse SFINAE = SFINAE_Report;
-}
-class AccessControl {
- SFINAEResponse SFINAE = SFINAE_AccessControl;
-}
-
-class ShowInSystemHeader {
- bit ShowInSystemHeader = 1;
-}
-
-class SuppressInSystemHeader {
- bit ShowInSystemHeader = 0;
-}
-
-// FIXME: ExtWarn and Extension should also be SFINAEFailure by default.
-class Error<string str> : Diagnostic<str, CLASS_ERROR, SEV_Error>, SFINAEFailure {
- bit ShowInSystemHeader = 1;
-}
-class Warning<string str> : Diagnostic<str, CLASS_WARNING, SEV_Warning>;
-class Remark<string str> : Diagnostic<str, CLASS_REMARK, SEV_Ignored>;
-class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, SEV_Ignored>;
-class ExtWarn<string str> : Diagnostic<str, CLASS_EXTENSION, SEV_Warning>;
-class Note<string str> : Diagnostic<str, CLASS_NOTE, SEV_Fatal/*ignored*/>;
-
-
-class DefaultIgnore { Severity DefaultSeverity = SEV_Ignored; }
-class DefaultWarn { Severity DefaultSeverity = SEV_Warning; }
-class DefaultError { Severity DefaultSeverity = SEV_Error; }
-class DefaultFatal { Severity DefaultSeverity = SEV_Fatal; }
-class DefaultWarnNoWerror {
- bit WarningNoWerror = 1;
-}
-class DefaultRemark { Severity DefaultSeverity = SEV_Remark; }
-
-// Definitions for Diagnostics.
-include "DiagnosticASTKinds.td"
-include "DiagnosticAnalysisKinds.td"
-include "DiagnosticCommentKinds.td"
-include "DiagnosticCommonKinds.td"
-include "DiagnosticDriverKinds.td"
-include "DiagnosticFrontendKinds.td"
-include "DiagnosticLexKinds.td"
-include "DiagnosticParseKinds.td"
-include "DiagnosticSemaKinds.td"
-include "DiagnosticSerializationKinds.td"
-
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
deleted file mode 100644
index 0b37030..0000000
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ /dev/null
@@ -1,266 +0,0 @@
-//==--- DiagnosticASTKinds.td - libast diagnostics ------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-let Component = "AST" in {
-
-// Constant expression diagnostics. These (and their users) belong in Sema.
-def note_expr_divide_by_zero : Note<"division by zero">;
-def note_constexpr_invalid_cast : Note<
- "%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of"
- " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression">;
-def note_constexpr_invalid_downcast : Note<
- "cannot cast object of dynamic type %0 to type %1">;
-def note_constexpr_overflow : Note<
- "value %0 is outside the range of representable values of type %1">;
-def note_constexpr_negative_shift : Note<"negative shift count %0">;
-def note_constexpr_large_shift : Note<
- "shift count %0 >= width of type %1 (%2 bit%s2)">;
-def note_constexpr_lshift_of_negative : Note<"left shift of negative value %0">;
-def note_constexpr_lshift_discards : Note<"signed left shift discards bits">;
-def note_constexpr_invalid_function : Note<
- "%select{non-constexpr|undefined}0 %select{function|constructor}1 %2 cannot "
- "be used in a constant expression">;
-def note_constexpr_no_return : Note<
- "control reached end of constexpr function">;
-def note_constexpr_virtual_call : Note<
- "cannot evaluate virtual function call in a constant expression">;
-def note_constexpr_virtual_base : Note<
- "cannot construct object of type %0 with virtual base class "
- "in a constant expression">;
-def note_constexpr_nonliteral : Note<
- "non-literal type %0 cannot be used in a constant expression">;
-def note_constexpr_non_global : Note<
- "%select{pointer|reference}0 to %select{|subobject of }1"
- "%select{temporary|%3}2 is not a constant expression">;
-def note_constexpr_uninitialized : Note<
- "%select{|sub}0object of type %1 is not initialized">;
-def note_constexpr_array_index : Note<"cannot refer to element %0 of "
- "%select{array of %2 elements|non-array object}1 in a constant expression">;
-def note_constexpr_float_arithmetic : Note<
- "floating point arithmetic produces %select{an infinity|a NaN}0">;
-def note_constexpr_pointer_subtraction_not_same_array : Note<
- "subtracted pointers are not elements of the same array">;
-def note_constexpr_pointer_subtraction_zero_size : Note<
- "subtraction of pointers to type %0 of zero size">;
-def note_constexpr_pointer_comparison_base_classes : Note<
- "comparison of addresses of subobjects of different base classes "
- "has unspecified value">;
-def note_constexpr_pointer_comparison_base_field : Note<
- "comparison of address of base class subobject %0 of class %1 to field %2 "
- "has unspecified value">;
-def note_constexpr_pointer_comparison_differing_access : Note<
- "comparison of address of fields %0 and %2 of %4 with differing access "
- "specifiers (%1 vs %3) has unspecified value">;
-def note_constexpr_compare_virtual_mem_ptr : Note<
- "comparison of pointer to virtual member function %0 has unspecified value">;
-def note_constexpr_past_end : Note<
- "dereferenced pointer past the end of %select{|subobject of }0"
- "%select{temporary|%2}1 is not a constant expression">;
-def note_constexpr_past_end_subobject : Note<
- "cannot %select{access base class of|access derived class of|access field of|"
- "access array element of|ERROR|call member function on|"
- "access real component of|access imaginary component of}0 "
- "pointer past the end of object">;
-def note_constexpr_null_subobject : Note<
- "cannot %select{access base class of|access derived class of|access field of|"
- "access array element of|perform pointer arithmetic on|"
- "call member function on|access real component of|"
- "access imaginary component of}0 null pointer">;
-def note_constexpr_var_init_non_constant : Note<
- "initializer of %0 is not a constant expression">;
-def note_constexpr_typeid_polymorphic : Note<
- "typeid applied to expression of polymorphic type %0 is "
- "not allowed in a constant expression">;
-def note_constexpr_void_comparison : Note<
- "comparison between unequal pointers to void has unspecified result">;
-def note_constexpr_temporary_here : Note<"temporary created here">;
-def note_constexpr_conditional_never_const : Note<
- "both arms of conditional operator are unable to produce a "
- "constant expression">;
-def note_constexpr_depth_limit_exceeded : Note<
- "constexpr evaluation exceeded maximum depth of %0 calls">;
-def note_constexpr_call_limit_exceeded : Note<
- "constexpr evaluation hit maximum call limit">;
-def note_constexpr_step_limit_exceeded : Note<
- "constexpr evaluation hit maximum step limit; possible infinite loop?">;
-def note_constexpr_this : Note<
- "%select{|implicit }0use of 'this' pointer is only allowed within the "
- "evaluation of a call to a 'constexpr' member function">;
-def note_constexpr_lifetime_ended : Note<
- "%select{read of|assignment to|increment of|decrement of}0 "
- "%select{temporary|variable}1 whose lifetime has ended">;
-def note_constexpr_access_uninit : Note<
- "%select{read of|assignment to|increment of|decrement of}0 "
- "object outside its lifetime is not allowed in a constant expression">;
-def note_constexpr_use_uninit_reference : Note<
- "use of reference outside its lifetime "
- "is not allowed in a constant expression">;
-def note_constexpr_modify_const_type : Note<
- "modification of object of const-qualified type %0 is not allowed "
- "in a constant expression">;
-def note_constexpr_access_volatile_type : Note<
- "%select{read of|assignment to|increment of|decrement of}0 "
- "volatile-qualified type %1 is not allowed in a constant expression">;
-def note_constexpr_access_volatile_obj : Note<
- "%select{read of|assignment to|increment of|decrement of}0 volatile "
- "%select{temporary|object %2|member %2}1 is not allowed in "
- "a constant expression">;
-def note_constexpr_ltor_mutable : Note<
- "read of mutable member %0 is not allowed in a constant expression">;
-def note_constexpr_ltor_non_const_int : Note<
- "read of non-const variable %0 is not allowed in a constant expression">;
-def note_constexpr_ltor_non_constexpr : Note<
- "read of non-constexpr variable %0 is not allowed in a constant expression">;
-def note_constexpr_access_null : Note<
- "%select{read of|assignment to|increment of|decrement of}0 "
- "dereferenced null pointer is not allowed in a constant expression">;
-def note_constexpr_access_past_end : Note<
- "%select{read of|assignment to|increment of|decrement of}0 "
- "dereferenced one-past-the-end pointer is not allowed in a constant expression">;
-def note_constexpr_access_inactive_union_member : Note<
- "%select{read of|assignment to|increment of|decrement of}0 "
- "member %1 of union with %select{active member %3|no active member}2 "
- "is not allowed in a constant expression">;
-def note_constexpr_access_static_temporary : Note<
- "%select{read of|assignment to|increment of|decrement of}0 temporary "
- "is not allowed in a constant expression outside the expression that "
- "created the temporary">;
-def note_constexpr_modify_global : Note<
- "a constant expression cannot modify an object that is visible outside "
- "that expression">;
-def note_constexpr_stmt_expr_unsupported : Note<
- "this use of statement expressions is not supported in a "
- "constant expression">;
-def note_constexpr_calls_suppressed : Note<
- "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to "
- "see all)">;
-def note_constexpr_call_here : Note<"in call to '%0'">;
-def note_constexpr_baa_insufficient_alignment : Note<
- "%select{alignment of|offset of the aligned pointer from}0 the base pointee "
- "object (%1 %plural{1:byte|:bytes}1) is %select{less than|not a multiple of}0 the "
- "asserted %2 %plural{1:byte|:bytes}2">;
-def note_constexpr_baa_value_insufficient_alignment : Note<
- "value of the aligned pointer (%0) is not a multiple of the asserted %1 "
- "%plural{1:byte|:bytes}1">;
-
-def warn_integer_constant_overflow : Warning<
- "overflow in expression; result is %0 with type %1">,
- InGroup<DiagGroup<"integer-overflow">>;
-
-// inline asm related.
-let CategoryName = "Inline Assembly Issue" in {
- def err_asm_invalid_escape : Error<
- "invalid %% escape in inline assembly string">;
- def err_asm_unknown_symbolic_operand_name : Error<
- "unknown symbolic operand name in inline assembly string">;
-
- def err_asm_unterminated_symbolic_operand_name : Error<
- "unterminated symbolic operand name in inline assembly string">;
- def err_asm_empty_symbolic_operand_name : Error<
- "empty symbolic operand name in inline assembly string">;
- def err_asm_invalid_operand_number : Error<
- "invalid operand number in inline asm string">;
-}
-
-// vtable related.
-let CategoryName = "VTable ABI Issue" in {
- def err_vftable_ambiguous_component : Error<
- "ambiguous vftable component for %0 introduced via covariant thunks; "
- "this is an inherent limitation of the ABI">;
- def note_covariant_thunk : Note<
- "covariant thunk required by %0">;
-}
-
-// Importing ASTs
-def err_odr_variable_type_inconsistent : Error<
- "external variable %0 declared with incompatible types in different "
- "translation units (%1 vs. %2)">;
-def err_odr_variable_multiple_def : Error<
- "external variable %0 defined in multiple translation units">;
-def note_odr_value_here : Note<"declared here with type %0">;
-def note_odr_defined_here : Note<"also defined here">;
-def err_odr_function_type_inconsistent : Error<
- "external function %0 declared with incompatible types in different "
- "translation units (%1 vs. %2)">;
-def warn_odr_tag_type_inconsistent : Warning<
- "type %0 has incompatible definitions in different translation units">,
- InGroup<DiagGroup<"odr">>;
-def note_odr_tag_kind_here: Note<
- "%0 is a %select{struct|interface|union|class|enum}1 here">;
-def note_odr_field : Note<"field %0 has type %1 here">;
-def note_odr_missing_field : Note<"no corresponding field here">;
-def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">;
-def note_odr_not_bit_field : Note<"field %0 is not a bit-field">;
-def note_odr_base : Note<"class has base type %0">;
-def note_odr_virtual_base : Note<
- "%select{non-virtual|virtual}0 derivation here">;
-def note_odr_missing_base : Note<"no corresponding base class here">;
-def note_odr_number_of_bases : Note<
- "class has %0 base %plural{1:class|:classes}0">;
-def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
-def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
-
-def err_odr_field_type_inconsistent : Error<
- "field %0 declared with incompatible types in different "
- "translation units (%1 vs. %2)">;
-
-// Importing Objective-C ASTs
-def err_odr_ivar_type_inconsistent : Error<
- "instance variable %0 declared with incompatible types in different "
- "translation units (%1 vs. %2)">;
-def err_odr_objc_superclass_inconsistent : Error<
- "class %0 has incompatible superclasses">;
-def note_odr_objc_superclass : Note<"inherits from superclass %0 here">;
-def note_odr_objc_missing_superclass : Note<"no corresponding superclass here">;
-def err_odr_objc_method_result_type_inconsistent : Error<
- "%select{class|instance}0 method %1 has incompatible result types in "
- "different translation units (%2 vs. %3)">;
-def err_odr_objc_method_num_params_inconsistent : Error<
- "%select{class|instance}0 method %1 has a different number of parameters in "
- "different translation units (%2 vs. %3)">;
-def err_odr_objc_method_param_type_inconsistent : Error<
- "%select{class|instance}0 method %1 has a parameter with a different types "
- "in different translation units (%2 vs. %3)">;
-def err_odr_objc_method_variadic_inconsistent : Error<
- "%select{class|instance}0 method %1 is variadic in one translation unit "
- "and not variadic in another">;
-def note_odr_objc_method_here : Note<
- "%select{class|instance}0 method %1 also declared here">;
-def err_odr_objc_property_type_inconsistent : Error<
- "property %0 declared with incompatible types in different "
- "translation units (%1 vs. %2)">;
-def err_odr_objc_property_impl_kind_inconsistent : Error<
- "property %0 is implemented with %select{@synthesize|@dynamic}1 in one "
- "translation but %select{@dynamic|@synthesize}1 in another translation unit">;
-def note_odr_objc_property_impl_kind : Note<
- "property %0 is implemented with %select{@synthesize|@dynamic}1 here">;
-def err_odr_objc_synthesize_ivar_inconsistent : Error<
- "property %0 is synthesized to different ivars in different translation "
- "units (%1 vs. %2)">;
-def note_odr_objc_synthesize_ivar_here : Note<
- "property is synthesized to ivar %0 here">;
-
-// Importing C++ ASTs
-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<
- "template parameter list also declared here">;
-def err_odr_different_template_parameter_kind : Error<
- "template parameter has different kinds in different translation units">;
-def note_odr_template_parameter_here : Note<
- "template parameter declared here">;
-def err_odr_parameter_pack_non_pack : Error<
- "parameter kind mismatch; parameter is %select{not a|a}0 parameter pack">;
-def note_odr_parameter_pack_non_pack : Note<
- "%select{parameter|parameter pack}0 declared here">;
-def err_odr_non_type_parameter_type_inconsistent : Error<
- "non-type template parameter declared with incompatible types in different "
- "translation units (%0 vs. %1)">;
-def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
-}
diff --git a/include/clang/Basic/DiagnosticAnalysisKinds.td b/include/clang/Basic/DiagnosticAnalysisKinds.td
deleted file mode 100644
index 5461212..0000000
--- a/include/clang/Basic/DiagnosticAnalysisKinds.td
+++ /dev/null
@@ -1,12 +0,0 @@
-//==--- DiagnosticAnalysisKinds.td - libanalysis diagnostics --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-let Component = "Analysis" in {
-
-}
diff --git a/include/clang/Basic/DiagnosticCategories.h b/include/clang/Basic/DiagnosticCategories.h
deleted file mode 100644
index 4dd067b..0000000
--- a/include/clang/Basic/DiagnosticCategories.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//===- DiagnosticCategories.h - Diagnostic Categories Enumerators-*- 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_BASIC_DIAGNOSTICCATEGORIES_H
-#define LLVM_CLANG_BASIC_DIAGNOSTICCATEGORIES_H
-
-namespace clang {
- namespace diag {
- enum {
-#define GET_CATEGORY_TABLE
-#define CATEGORY(X, ENUM) ENUM,
-#include "clang/Basic/DiagnosticGroups.inc"
-#undef CATEGORY
-#undef GET_CATEGORY_TABLE
- DiagCat_NUM_CATEGORIES
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/DiagnosticCategories.td b/include/clang/Basic/DiagnosticCategories.td
deleted file mode 100644
index 37b8569..0000000
--- a/include/clang/Basic/DiagnosticCategories.td
+++ /dev/null
@@ -1,11 +0,0 @@
-//==--- DiagnosticCategories.td - Diagnostic Category Definitions ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-class CatInlineAsm : DiagCategory<"Inline Assembly Issue">;
-class CatBackend : DiagCategory<"Backend Issue">;
diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td
deleted file mode 100644
index ab24582..0000000
--- a/include/clang/Basic/DiagnosticCommentKinds.td
+++ /dev/null
@@ -1,172 +0,0 @@
-//==--- DiagnosticCommentKinds.td - diagnostics related to comments -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-let Component = "Comment" in {
-let CategoryName = "Documentation Issue" in {
-
-// HTML parsing errors. These are under -Wdocumentation to make sure the user
-// knows that we didn't parse something as they might expect.
-
-def warn_doc_html_start_tag_expected_quoted_string : Warning<
- "expected quoted string after equals sign">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_html_start_tag_expected_ident_or_greater : Warning<
- "HTML start tag prematurely ended, expected attribute name or '>'">,
- InGroup<Documentation>, DefaultIgnore;
-
-def note_doc_html_tag_started_here : Note<
- "HTML tag started here">;
-
-// HTML semantic errors
-
-def warn_doc_html_end_forbidden : Warning<
- "HTML end tag '%0' is forbidden">,
- InGroup<DocumentationHTML>, DefaultIgnore;
-
-def warn_doc_html_end_unbalanced : Warning<
- "HTML end tag does not match any start tag">,
- InGroup<DocumentationHTML>, DefaultIgnore;
-
-def warn_doc_html_start_end_mismatch : Warning<
- "HTML start tag '%0' closed by '%1'">,
- InGroup<DocumentationHTML>, DefaultIgnore;
-
-def note_doc_html_end_tag : Note<
- "end tag">;
-
-def warn_doc_html_missing_end_tag : Warning<
- "HTML tag '%0' requires an end tag">,
- InGroup<DocumentationHTML>, DefaultIgnore;
-
-// Commands
-
-def warn_doc_block_command_empty_paragraph : Warning<
- "empty paragraph passed to '%select{\\|@}0%1' command">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_block_command_duplicate : Warning<
- "duplicated command '%select{\\|@}0%1'">,
- InGroup<Documentation>, DefaultIgnore;
-
-def note_doc_block_command_previous : Note<
- "previous command '%select{\\|@}0%1' here">;
-
-def note_doc_block_command_previous_alias : Note<
- "previous command '%select{\\|@}0%1' (an alias of '\\%2') here">;
-
-// \param command
-
-def warn_doc_param_invalid_direction : Warning<
- "unrecognized parameter passing direction, "
- "valid directions are '[in]', '[out]' and '[in,out]'">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_param_spaces_in_direction : Warning<
- "whitespace is not allowed in parameter passing direction">,
- InGroup<DocumentationPedantic>, DefaultIgnore;
-
-def warn_doc_param_not_attached_to_a_function_decl : Warning<
- "'%select{\\|@}0param' command used in a comment that is not attached to "
- "a function declaration">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_function_method_decl_mismatch : Warning<
- "'%select{\\|@}0%select{function|functiongroup|method|methodgroup|callback}1' "
- "command should be used in a comment attached to "
- "%select{a function|a function|an Objective-C method|an Objective-C method|"
- "a pointer to function}2 declaration">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_api_container_decl_mismatch : Warning<
- "'%select{\\|@}0%select{class|interface|protocol|struct|union}1' "
- "command should not be used in a comment attached to a "
- "non-%select{class|interface|protocol|struct|union}2 declaration">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_container_decl_mismatch : Warning<
- "'%select{\\|@}0%select{classdesign|coclass|dependency|helper"
- "|helperclass|helps|instancesize|ownership|performance|security|superclass}1' "
- "command should not be used in a comment attached to a non-container declaration">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_param_duplicate : Warning<
- "parameter '%0' is already documented">,
- InGroup<Documentation>, DefaultIgnore;
-
-def note_doc_param_previous : Note<
- "previous documentation">;
-
-def warn_doc_param_not_found : Warning<
- "parameter '%0' not found in the function declaration">,
- InGroup<Documentation>, DefaultIgnore;
-
-def note_doc_param_name_suggestion : Note<
- "did you mean '%0'?">;
-
-// tparam command
-
-def warn_doc_tparam_not_attached_to_a_template_decl : Warning<
- "'%select{\\|@}0tparam' command used in a comment that is not attached to "
- "a template declaration">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_tparam_duplicate : Warning<
- "template parameter '%0' is already documented">,
- InGroup<Documentation>, DefaultIgnore;
-
-def note_doc_tparam_previous : Note<
- "previous documentation">;
-
-def warn_doc_tparam_not_found : Warning<
- "template parameter '%0' not found in the template declaration">,
- InGroup<Documentation>, DefaultIgnore;
-
-def note_doc_tparam_name_suggestion : Note<
- "did you mean '%0'?">;
-
-// \returns command
-
-def warn_doc_returns_not_attached_to_a_function_decl : Warning<
- "'%select{\\|@}0%1' command used in a comment that is not attached to "
- "a function or method declaration">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_doc_returns_attached_to_a_void_function : Warning<
- "'%select{\\|@}0%1' command used in a comment that is attached to a "
- "%select{function returning void|constructor|destructor|"
- "method returning void}2">,
- InGroup<Documentation>, DefaultIgnore;
-
-// \deprecated command
-
-def warn_doc_deprecated_not_sync : Warning<
- "declaration is marked with '\\deprecated' command but does not have "
- "a deprecation attribute">,
- InGroup<DocumentationDeprecatedSync>, DefaultIgnore;
-
-def note_add_deprecation_attr : Note<
- "add a deprecation attribute to the declaration to silence this warning">;
-
-// verbatim block commands
-
-def warn_verbatim_block_end_without_start : Warning<
- "'%select{\\|@}0%1' command does not terminate a verbatim text block">,
- InGroup<Documentation>, DefaultIgnore;
-
-def warn_unknown_comment_command_name : Warning<
- "unknown command tag name">,
- InGroup<DocumentationUnknownCommand>, DefaultIgnore;
-
-def warn_correct_comment_command_name : Warning<
- "unknown command tag name '%0'; did you mean '%1'?">,
- InGroup<DocumentationUnknownCommand>, DefaultIgnore;
-
-} // end of documentation issue category
-} // end of AST component
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
deleted file mode 100644
index ccc271a..0000000
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ /dev/null
@@ -1,217 +0,0 @@
-//==--- DiagnosticCommonKinds.td - common diagnostics ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Common Helpers
-//===----------------------------------------------------------------------===//
-
-let Component = "Common" in {
-
-// Basic.
-
-def fatal_too_many_errors
- : Error<"too many errors emitted, stopping now">, DefaultFatal;
-
-def note_declared_at : Note<"declared here">;
-def note_previous_definition : Note<"previous definition is here">;
-def note_previous_declaration : Note<"previous declaration is here">;
-def note_previous_implicit_declaration : Note<
- "previous implicit declaration is here">;
-def note_previous_use : Note<"previous use is here">;
-def note_duplicate_case_prev : Note<"previous case defined here">;
-def note_forward_declaration : Note<"forward declaration of %0">;
-def note_type_being_defined : Note<
- "definition of %0 is not complete until the closing '}'">;
-/// note_matching - this is used as a continuation of a previous diagnostic,
-/// e.g. to specify the '(' when we expected a ')'.
-def note_matching : Note<"to match this %0">;
-
-def note_using : Note<"using">;
-def note_possibility : Note<"one possibility">;
-def note_also_found : Note<"also found">;
-
-// Parse && Lex
-
-let CategoryName = "Lexical or Preprocessor Issue" in {
-
-def err_expected_colon_after_setter_name : Error<
- "method name referenced in property setter attribute "
- "must end with ':'">;
-def err_expected_string_literal : Error<"expected string literal "
- "%select{in %1|for diagnostic message in static_assert|"
- "for optional message in 'availability' attribute}0">;
-def err_invalid_string_udl : Error<
- "string literal with user-defined suffix cannot be used here">;
-def err_invalid_character_udl : Error<
- "character literal with user-defined suffix cannot be used here">;
-def err_invalid_numeric_udl : Error<
- "numeric literal with user-defined suffix cannot be used here">;
-
-}
-
-// Parse && Sema
-
-let CategoryName = "Parse Issue" in {
-
-def err_expected : Error<"expected %0">;
-def err_expected_either : Error<"expected %0 or %1">;
-def err_expected_after : Error<"expected %1 after %0">;
-
-def err_param_redefinition : Error<"redefinition of parameter %0">;
-def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">;
-def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">,
- InGroup<DuplicateArgDecl>, DefaultIgnore;
-def err_invalid_storage_class_in_func_decl : Error<
- "invalid storage class specifier in function declarator">;
-def err_expected_namespace_name : Error<"expected namespace name">;
-def ext_variadic_templates : ExtWarn<
- "variadic templates are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_variadic_templates :
- Warning<"variadic templates are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_default_special_members : Error<
- "only special member functions may be defaulted">;
-def err_deleted_non_function : Error<
- "only functions can have deleted definitions">;
-def err_module_not_found : Error<"module '%0' not found">, DefaultFatal;
-def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal;
-def err_module_build_disabled: Error<
- "module '%0' is needed but has not been provided, and implicit use of module "
- "files is disabled">, DefaultFatal;
-def err_module_unavailable : Error<
- "module '%0' %select{is incompatible with|requires}1 feature '%2'">;
-def err_module_header_missing : Error<
- "%select{|umbrella }0header '%1' not found">;
-def err_module_lock_failure : Error<
- "could not acquire lock file for module '%0'">, DefaultFatal;
-def err_module_lock_timeout : Error<
- "timed out waiting to acquire lock file for module '%0'">, DefaultFatal;
-def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
- DefaultFatal;
-def note_pragma_entered_here : Note<"#pragma entered here">;
-def note_decl_hiding_tag_type : Note<
- "%1 %0 is hidden by a non-type declaration of %0 here">;
-def err_attribute_not_type_attr : Error<
- "%0 attribute cannot be applied to types">;
-def err_enum_template : Error<"enumeration cannot be a template">;
-
-}
-
-let CategoryName = "Nullability Issue" in {
-
-def warn_nullability_duplicate : Warning<
- "duplicate nullability specifier %0">,
- InGroup<Nullability>;
-
-def warn_conflicting_nullability_attr_overriding_ret_types : Warning<
- "conflicting nullability specifier on return types, %0 "
- "conflicts with existing specifier %1">,
- InGroup<Nullability>;
-
-def warn_conflicting_nullability_attr_overriding_param_types : Warning<
- "conflicting nullability specifier on parameter types, %0 "
- "conflicts with existing specifier %1">,
- InGroup<Nullability>;
-
-def err_nullability_conflicting : Error<
- "nullability specifier %0 conflicts with existing specifier %1">;
-
-}
-
-// Sema && Lex
-def ext_c99_longlong : Extension<
- "'long long' is an extension when C99 mode is not enabled">,
- InGroup<LongLong>;
-def ext_cxx11_longlong : Extension<
- "'long long' is a C++11 extension">,
- InGroup<CXX11LongLong>;
-def warn_cxx98_compat_longlong : Warning<
- "'long long' is incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def err_integer_literal_too_large : Error<
- "integer literal is too large to be represented in any %select{signed |}0"
- "integer type">;
-def ext_integer_literal_too_large_for_signed : ExtWarn<
- "integer literal is too large to be represented in a signed integer type, "
- "interpreting as unsigned">,
- InGroup<ImplicitlyUnsignedLiteral>;
-def warn_old_implicitly_unsigned_long : Warning<
- "integer literal is too large to be represented in type 'long', "
- "interpreting as 'unsigned long' per C89; this literal will "
- "%select{have type 'long long'|be ill-formed}0 in C99 onwards">,
- InGroup<C99Compat>;
-def warn_old_implicitly_unsigned_long_cxx : Warning<
- "integer literal is too large to be represented in type 'long', "
- "interpreting as 'unsigned long' per C++98; this literal will "
- "%select{have type 'long long'|be ill-formed}0 in C++11 onwards">,
- InGroup<CXX11Compat>;
-def ext_old_implicitly_unsigned_long_cxx : ExtWarn<
- "integer literal is too large to be represented in type 'long' and is "
- "subject to undefined behavior under C++98, interpreting as 'unsigned long'; "
- "this literal will %select{have type 'long long'|be ill-formed}0 "
- "in C++11 onwards">,
- InGroup<CXX11Compat>;
-
-// SEH
-def err_seh_expected_handler : Error<
- "expected '__except' or '__finally' block">;
-def err_seh___except_block : Error<
- "%0 only allowed in __except block or filter expression">;
-def err_seh___except_filter : Error<
- "%0 only allowed in __except filter expression">;
-def err_seh___finally_block : Error<
- "%0 only allowed in __finally block">;
-
-// Sema && AST
-def note_invalid_subexpr_in_const_expr : Note<
- "subexpression not valid in a constant expression">;
-
-// Targets
-
-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 err_target_unknown_abi : Error<"unknown target ABI '%0'">;
-def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">;
-def err_target_unsupported_fpmath : Error<
- "the '%0' unit is not supported with this instruction set">;
-def err_target_unsupported_unaligned : Error<
- "the %0 sub-architecture does not support unaligned accesses">;
-def err_opt_not_valid_with_opt : Error<
- "option '%0' cannot be specified with '%1'">;
-
-// Source manager
-def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
-def err_file_modified : Error<
- "file '%0' modified since it was first processed">, DefaultFatal;
-def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but "
- "encoding is not supported">, DefaultFatal;
-def err_unable_to_rename_temp : Error<
- "unable to rename temporary '%0' to output file '%1': '%2'">;
-def err_unable_to_make_temp : Error<
- "unable to make temporary file: %0">;
-
-// Modules
-def err_module_format_unhandled : Error<
- "no handler registered for module format '%0'">, DefaultFatal;
-
-// TransformActions
-// TODO: Use a custom category name to distinguish rewriter errors.
-def err_mt_message : Error<"[rewriter] %0">, SuppressInSystemHeader;
-def warn_mt_message : Warning<"[rewriter] %0">;
-def note_mt_message : Note<"[rewriter] %0">;
-
-// ARCMigrate
-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">;
-
-// 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
deleted file mode 100644
index ce270bf..0000000
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ /dev/null
@@ -1,226 +0,0 @@
-//==--- DiagnosticDriverKinds.td - libdriver diagnostics ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-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_for_target : Error<
- "unsupported option '%0' for target '%1'">;
-def err_drv_unsupported_option_argument : Error<
- "unsupported argument '%1' to option '%0'">;
-def err_drv_unknown_stdin_type : Error<
- "-E or -x required when input is from standard input">;
-def err_drv_unknown_stdin_type_clang_cl : Error<
- "use /Tc or /Tp to set input type for standard input">;
-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_thread_model_for_target : Error<
- "invalid thread model '%0' in '%1' for this target">;
-def err_drv_invalid_linker_name : Error<
- "invalid linker name in argument '%0'">;
-def err_drv_invalid_rtlib_name : Error<
- "invalid runtime library name in argument '%0'">;
-def err_drv_unsupported_rtlib_for_platform : Error<
- "unsupported runtime library '%0' for platform '%1'">;
-def err_drv_invalid_stdlib_name : Error<
- "invalid library name in argument '%0'">;
-def err_drv_invalid_output_with_multiple_archs : Error<
- "cannot use '%0' output with multiple -arch options">;
-def err_drv_no_input_files : Error<"no input files">;
-def err_drv_use_of_Z_option : Error<
- "unsupported use of internal gcc -Z option '%0'">;
-def err_drv_output_argument_with_multiple_files : Error<
- "cannot specify -o when generating multiple output files">;
-def err_drv_out_file_argument_with_multiple_sources : Error<
- "cannot specify '%0%1' when compiling multiple source files">;
-def err_no_external_assembler : Error<
- "there is no external assembler that can be used on this platform">;
-def err_drv_unable_to_remove_file : Error<
- "unable to remove file: %0">;
-def err_drv_command_failure : Error<
- "unable to execute command: %0">;
-def err_drv_invalid_darwin_version : Error<
- "invalid Darwin version number: %0">;
-def err_drv_missing_argument : Error<
- "argument to '%0' is missing (expected %1 value%s1)">;
-def err_drv_invalid_Xarch_argument_with_args : Error<
- "invalid Xarch argument: '%0', options requiring arguments are unsupported">;
-def err_drv_invalid_Xarch_argument_isdriver : Error<
- "invalid Xarch argument: '%0', cannot change driver behavior inside Xarch argument">;
-def err_drv_argument_only_allowed_with : Error<
- "invalid argument '%0' only allowed with '%1'">;
-def err_drv_argument_not_allowed_with : Error<
- "invalid argument '%0' not allowed with '%1'">;
-def err_drv_invalid_version_number : Error<
- "invalid version number in '%0'">;
-def err_drv_no_linker_llvm_support : Error<
- "'%0': unable to pass LLVM bit-code files to linker">;
-def err_drv_no_ast_support : Error<
- "'%0': unable to use AST files with this tool">;
-def err_drv_no_module_support : Error<
- "'%0': unable to use module files with this tool">;
-def err_drv_clang_unsupported : Error<
- "the clang compiler does not support '%0'">;
-def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error<
- "the clang compiler does not support '%0' for C++ on Darwin/i386">;
-def err_drv_command_failed : Error<
- "%0 command failed with exit code %1 (use -v to see invocation)">;
-def err_drv_command_signalled : Error<
- "%0 command failed due to signal (use -v to see invocation)">;
-def err_drv_force_crash : Error<
- "failing because environment variable '%0' is set">;
-def err_drv_invalid_mfloat_abi : Error<
- "invalid float ABI '%0'">;
-def err_drv_invalid_libcxx_deployment : Error<
- "invalid deployment target for -stdlib=libc++ (requires %0 or later)">;
-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_target_unsupported_arch
- : Error<"the target architecture '%0' is not supported by the target '%1'">;
-
-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_invalid_value : Error<"invalid value '%1' in '%0'">;
-def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
-def err_drv_invalid_remap_file : Error<
- "invalid option '%0' not of the form <from-file>;<to-file>">;
-def err_drv_invalid_gcc_output_type : Error<
- "invalid output type '%0' for use with gcc tool">;
-def err_drv_cc_print_options_failure : Error<
- "unable to open CC_PRINT_OPTIONS file: %0">;
-def err_drv_preamble_format : Error<
- "incorrect format for -preamble-bytes=N,END">;
-def err_drv_conflicting_deployment_targets : Error<
- "conflicting deployment targets, both '%0' and '%1' are present in environment">;
-def err_drv_objc_gc_arr : Error<
- "cannot specify both '-fobjc-arc' and '%0'">;
-def err_arc_unsupported_on_runtime : Error<
- "-fobjc-arc is not supported on platforms using the legacy runtime">;
-def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this
- "-fobjc-arc is not supported on versions of OS X prior to 10.6">;
-def err_objc_weak_with_gc : Error<
- "-fobjc-weak is not supported in Objective-C garbage collection">;
-def err_objc_weak_unsupported : Error<
- "-fobjc-weak is not supported on the current deployment target">;
-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_emit_llvm_link : Error<
- "-emit-llvm cannot be used when linking">;
-def err_drv_optimization_remark_pattern : Error<
- "%0 in '%1'">;
-def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, please use [no]simd instead">;
-def err_drv_invalid_omp_target : Error<"OpenMP target is invalid: '%0'">;
-def err_drv_omp_host_ir_file_not_found : Error<
- "The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">;
-
-def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
-def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">,
- InGroup<LibLTO>;
-def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">,
- InGroup<InvalidCommandLineArgument>;
-def warn_ignored_gcc_optimization : Warning<"optimization flag '%0' is not supported">,
- InGroup<IgnoredOptimizationArgument>;
-def warn_c_kext : Warning<
- "ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
-def warn_drv_input_file_unused : Warning<
- "%0: '%1' input unused%select{ when '%3' is present|}2">,
- InGroup<UnusedCommandLineArgument>;
-def warn_drv_input_file_unused_by_cpp : Warning<
- "%0: '%1' input unused in cpp mode">,
- InGroup<UnusedCommandLineArgument>;
-def warn_drv_preprocessed_input_file_unused : Warning<
- "%0: previously preprocessed input%select{ unused when '%2' is present|}1">,
- InGroup<UnusedCommandLineArgument>;
-def warn_drv_unused_argument : Warning<
- "argument unused during compilation: '%0'">,
- InGroup<UnusedCommandLineArgument>;
-def warn_drv_empty_joined_argument : Warning<
- "joined argument expects additional value: '%0'">,
- InGroup<UnusedCommandLineArgument>;
-def warn_drv_clang_unsupported : Warning<
- "the clang compiler does not support '%0'">;
-def warn_drv_deprecated_arg : Warning<
- "argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
-def warn_drv_assuming_mfloat_abi_is : Warning<
- "unknown platform, assuming -mfloat-abi=%0">;
-def warn_ignoring_ftabstop_value : Warning<
- "ignoring invalid -ftabstop value '%0', using default value %1">;
-def warn_drv_overriding_flag_option : Warning<
- "overriding '%0' option with '%1'">,
- InGroup<DiagGroup<"overriding-t-option">>;
-def warn_drv_treating_input_as_cxx : Warning<
- "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
- InGroup<Deprecated>;
-def warn_drv_objc_gc_unsupported : Warning<
- "Objective-C garbage collection is not supported on this platform, ignoring '%0'">;
-def warn_drv_pch_not_first_include : Warning<
- "precompiled header '%0' was ignored because '%1' is not first '-include'">;
-def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
- InGroup<DiagGroup<"missing-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<DiagGroup<"auto-disable-vptr-sanitizer">>;
-
-def note_drv_command_failed_diag_msg : Note<
- "diagnostic msg: %0">;
-def note_drv_t_option_is_global : Note<
- "The last /TC or /TP option takes precedence over earlier instances">;
-def note_drv_address_sanitizer_debug_runtime : Note<
- "AddressSanitizer doesn't support linking with debug runtime libraries yet">;
-
-def err_analyzer_config_no_value : Error<
- "analyzer-config option '%0' has a key but no value">;
-def err_analyzer_config_multiple_values : Error<
- "analyzer-config option '%0' should contain only one '='">;
-
-def err_drv_modules_validate_once_requires_timestamp : Error<
- "option '-fmodules-validate-once-per-build-session' requires "
- "'-fbuild-session-timestamp=<seconds since Epoch>' or '-fbuild-session-file=<file>'">;
-
-def err_test_module_file_extension_format : Error<
- "-ftest-module-file-extension argument '%0' is not of the required form "
- "'blockname:major:minor:hashed:user info'">;
-
-def warn_drv_invoking_fallback : Warning<"falling back to %0">,
- InGroup<Fallback>;
-
-def warn_target_unsupported_nan2008 : Warning<
- "ignoring '-mnan=2008' option because the '%0' architecture does not support it">,
- InGroup<UnsupportedNan>;
-def warn_target_unsupported_nanlegacy : Warning<
- "ignoring '-mnan=legacy' option because the '%0' architecture does not support it">,
- InGroup<UnsupportedNan>;
-
-def warn_drv_unable_to_find_directory_expected : Warning<
- "unable to find %0 directory, expected to be in '%1'">,
- InGroup<InvalidOrNonExistentDirectory>, DefaultIgnore;
-
-def warn_drv_ps4_force_pic : Warning<
- "option '%0' was ignored by the PS4 toolchain, using '-fPIC'">,
- InGroup<OptionIgnored>;
-
-def warn_drv_ps4_sdk_dir : Warning<
- "environment variable SCE_PS4_SDK_DIR is set, but points to invalid or nonexistent directory '%0'">,
- InGroup<InvalidOrNonExistentDirectory>;
-
-def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">;
-}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
deleted file mode 100644
index 033834b..0000000
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ /dev/null
@@ -1,219 +0,0 @@
-//==--- DiagnosticFrontendKinds.td - frontend diagnostics -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-class BackendInfo : CatBackend, ShowInSystemHeader;
-
-let Component = "Frontend" in {
-
-def err_fe_error_opening : Error<"error opening '%0': %1">;
-def err_fe_error_reading : Error<"error reading '%0'">;
-def err_fe_error_reading_stdin : Error<"error reading stdin: %0">;
-def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
-
-def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
-def warn_fe_inline_asm : Warning<"%0">, CatInlineAsm, InGroup<BackendInlineAsm>;
-def note_fe_inline_asm : Note<"%0">, CatInlineAsm;
-def note_fe_inline_asm_here : Note<"instantiated into assembly here">;
-def err_fe_cannot_link_module : Error<"cannot link module '%0': %1">,
- DefaultFatal;
-
-def warn_fe_frame_larger_than : Warning<"stack frame size of %0 bytes in %q1">,
- BackendInfo, InGroup<BackendFrameLargerThanEQ>;
-def warn_fe_backend_frame_larger_than: Warning<"%0">,
- BackendInfo, InGroup<BackendFrameLargerThanEQ>;
-def err_fe_backend_frame_larger_than: Error<"%0">, BackendInfo;
-def note_fe_backend_frame_larger_than: Note<"%0">, BackendInfo;
-
-def warn_fe_backend_plugin: Warning<"%0">, BackendInfo, InGroup<BackendPlugin>;
-def err_fe_backend_plugin: Error<"%0">, BackendInfo;
-def remark_fe_backend_plugin: Remark<"%0">, BackendInfo, InGroup<RemarkBackendPlugin>;
-def note_fe_backend_plugin: Note<"%0">, BackendInfo;
-
-def warn_fe_override_module : Warning<
- "overriding the module target triple with %0">,
- InGroup<DiagGroup<"override-module">>;
-
-def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo,
- InGroup<BackendOptimizationRemark>;
-def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo,
- InGroup<BackendOptimizationRemarkMissed>;
-def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo,
- InGroup<BackendOptimizationRemarkAnalysis>;
-def remark_fe_backend_optimization_remark_analysis_fpcommute : Remark<"%0; "
- "allow reordering by specifying '#pragma clang loop vectorize(enable)' "
- "before the loop or by providing the compiler option '-ffast-math'.">,
- BackendInfo, InGroup<BackendOptimizationRemarkAnalysis>;
-def remark_fe_backend_optimization_remark_analysis_aliasing : Remark<"%0; "
- "allow reordering by specifying '#pragma clang loop vectorize(enable)' "
- "before the loop. If the arrays will always be independent specify "
- "'#pragma clang loop vectorize(assume_safety)' before the loop or provide "
- "the '__restrict__' qualifier with the independent array arguments. "
- "Erroneous results will occur if these options are incorrectly applied!">,
- BackendInfo, InGroup<BackendOptimizationRemarkAnalysis>;
-def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo,
- InGroup<BackendOptimizationFailure>, DefaultWarn;
-def note_fe_backend_optimization_remark_invalid_loc : Note<"could "
- "not determine the original source location for %0:%1:%2">;
-
-def remark_sanitize_address_insert_extra_padding_accepted : Remark<
- "-fsanitize-address-field-padding applied to %0">, ShowInSystemHeader,
- InGroup<SanitizeAddressRemarks>;
-def remark_sanitize_address_insert_extra_padding_rejected : Remark<
- "-fsanitize-address-field-padding ignored for %0 because it "
- "%select{is not C++|is packed|is a union|is trivially copyable|"
- "has trivial destructor|is standard layout|is in a blacklisted file|"
- "is blacklisted}1">, ShowInSystemHeader,
- InGroup<SanitizeAddressRemarks>;
-
-def err_fe_invalid_code_complete_file : Error<
- "cannot locate code-completion file %0">, DefaultFatal;
-def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
- DefaultFatal;
-def err_fe_dependency_file_requires_MT : Error<
- "-dependency-file requires at least one -MT or -MQ option">;
-def err_fe_invalid_plugin_name : Error<
- "unable to find plugin '%0'">;
-def err_fe_expected_compiler_job : Error<
- "unable to handle compilation, expected exactly one compiler job in '%0'">;
-def err_fe_expected_clang_command : Error<
- "expected a clang compiler command">;
-def err_fe_remap_missing_to_file : Error<
- "could not remap file '%0' to the contents of file '%1'">, DefaultFatal;
-def err_fe_remap_missing_from_file : Error<
- "could not remap from missing file '%0'">, DefaultFatal;
-def err_fe_unable_to_load_pch : Error<
- "unable to load PCH file">;
-def err_fe_unable_to_load_plugin : Error<
- "unable to load plugin '%0': '%1'">;
-def err_fe_unable_to_create_target : Error<
- "unable to create target: '%0'">;
-def err_fe_unable_to_interface_with_target : Error<
- "unable to interface with target machine">;
-def err_fe_unable_to_open_output : Error<
- "unable to open output file '%0': '%1'">;
-def err_fe_pth_file_has_no_source_header : Error<
- "PTH file '%0' does not designate an original source header file for -include-pth">;
-def warn_fe_macro_contains_embedded_newline : Warning<
- "macro '%0' contains embedded newline; text after the newline is ignored">;
-def warn_fe_cc_print_header_failure : Warning<
- "unable to open CC_PRINT_HEADERS file: %0 (using stderr)">;
-def warn_fe_cc_log_diagnostics_failure : Warning<
- "unable to open CC_LOG_DIAGNOSTICS file: %0 (using stderr)">;
-def err_fe_no_pch_in_dir : Error<
- "no suitable precompiled header file found in directory '%0'">;
-def err_fe_action_not_available : Error<
- "action %0 not compiled in">;
-
-def warn_fe_serialized_diag_merge_failure : Warning<
- "unable to merge a subprocess's serialized diagnostics">,
- InGroup<SerializedDiagnostics>;
-def warn_fe_serialized_diag_failure : Warning<
- "unable to open file %0 for serializing diagnostics (%1)">,
- InGroup<SerializedDiagnostics>;
-
-def err_verify_missing_line : Error<
- "missing or invalid line number following '@' in expected %0">;
-def err_verify_missing_file : Error<
- "file '%0' could not be located in expected %1">;
-def err_verify_invalid_range : Error<
- "invalid range following '-' in expected %0">;
-def err_verify_missing_start : Error<
- "cannot find start ('{{') of expected %0">;
-def err_verify_missing_end : Error<
- "cannot find end ('}}') of expected %0">;
-def err_verify_invalid_content : Error<
- "invalid expected %0: %1">;
-def err_verify_missing_regex : Error<
- "cannot find start of regex ('{{') in %0">;
-def err_verify_inconsistent_diags : Error<
- "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: "
- "%2">;
-def err_verify_invalid_no_diags : Error<
- "%select{expected|'expected-no-diagnostics'}0 directive cannot follow "
- "%select{'expected-no-diagnostics' directive|other expected directives}0">;
-def err_verify_no_directives : Error<
- "no expected directives found: consider use of 'expected-no-diagnostics'">;
-
-def note_fixit_applied : Note<"FIX-IT applied suggested code changes">;
-def note_fixit_in_macro : Note<
- "FIX-IT unable to apply suggested code changes in a macro">;
-def note_fixit_failed : Note<
- "FIX-IT unable to apply suggested code changes">;
-def note_fixit_unfixed_error : Note<"FIX-IT detected an error it cannot fix">;
-def warn_fixit_no_changes : Note<
- "FIX-IT detected errors it could not fix; no output will be generated">;
-
-// PCH reader
-def err_relocatable_without_isysroot : Error<
- "must specify system root with -isysroot when building a relocatable "
- "PCH file">;
-
-def warn_unknown_diag_option : Warning<
- "unknown %select{warning|remark}0 option '%1'%select{|; did you mean '%3'?}2">,
- InGroup<UnknownWarningOption>;
-def warn_unknown_warning_specifier : Warning<
- "unknown %0 warning specifier: '%1'">,
- InGroup<UnknownWarningOption>;
-
-def err_unknown_analyzer_checker : Error<
- "no analyzer checkers are associated with '%0'">;
-def note_suggest_disabling_all_checkers : Note<
- "use -analyzer-disable-all-checks to disable all static analyzer checkers">;
-
-def warn_incompatible_analyzer_plugin_api : Warning<
- "checker plugin '%0' is not compatible with this version of the analyzer">,
- InGroup<DiagGroup<"analyzer-incompatible-plugin"> >;
-def note_incompatible_analyzer_plugin_api : Note<
- "current API version is '%0', but plugin was compiled with version '%1'">;
-
-def warn_module_config_mismatch : Warning<
- "module file %0 cannot be loaded due to a configuration mismatch with the current "
- "compilation">, InGroup<DiagGroup<"module-file-config-mismatch">>, DefaultError;
-def err_module_map_not_found : Error<"module map file '%0' not found">,
- DefaultFatal;
-def err_missing_module_name : Error<
- "no module name provided; specify one with -fmodule-name=">,
- DefaultFatal;
-def err_missing_module : Error<
- "no module named '%0' declared in module map file '%1'">, DefaultFatal;
-def err_no_submodule : Error<"no submodule named %0 in module '%1'">;
-def err_no_submodule_suggest : Error<
- "no submodule named %0 in module '%1'; did you mean '%2'?">;
-def warn_missing_submodule : Warning<"missing submodule '%0'">,
- InGroup<IncompleteUmbrella>;
-def err_module_cannot_create_includes : Error<
- "cannot create includes file for module %0: %1">;
-def warn_module_config_macro_undef : Warning<
- "%select{definition|#undef}0 of configuration macro '%1' has no effect on "
- "the import of '%2'; pass '%select{-D%1=...|-U%1}0' on the command line "
- "to configure the module">,
- InGroup<ConfigMacros>;
-def note_module_def_undef_here : Note<
- "macro was %select{defined|#undef'd}0 here">;
-def remark_module_build : Remark<"building module '%0' as '%1'">,
- InGroup<ModuleBuild>;
-def remark_module_build_done : Remark<"finished building module '%0'">,
- InGroup<ModuleBuild>;
-def err_modules_embed_file_not_found :
- Error<"file '%0' specified by '-fmodules-embed-file=' not found">,
- DefaultFatal;
-
-def err_test_module_file_extension_version : Error<
- "test module file extension '%0' has different version (%1.%2) than expected "
- "(%3.%4)">;
-
-def err_conflicting_module_names : Error<
- "conflicting module names specified: '-fmodule-name=%0' and "
- "'-fmodule-implementation-of %1'">;
-
-def err_missing_vfs_overlay_file : Error<
- "virtual filesystem overlay file '%0' not found">, DefaultFatal;
-def err_invalid_vfs_overlay : Error<
- "invalid virtual filesystem overlay file '%0'">, DefaultFatal;
-}
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
deleted file mode 100644
index 8e5f57d..0000000
--- a/include/clang/Basic/DiagnosticGroups.td
+++ /dev/null
@@ -1,848 +0,0 @@
-//==--- DiagnosticGroups.td - Diagnostic Group Definitions ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-def ImplicitFunctionDeclare : DiagGroup<"implicit-function-declaration">;
-def ImplicitInt : DiagGroup<"implicit-int">;
-
-// Aggregation warning settings.
-def Implicit : DiagGroup<"implicit", [
- ImplicitFunctionDeclare,
- ImplicitInt
-]>;
-
-// Empty DiagGroups are recognized by clang but ignored.
-def : DiagGroup<"abi">;
-def AbsoluteValue : DiagGroup<"absolute-value">;
-def AddressOfTemporary : DiagGroup<"address-of-temporary">;
-def : DiagGroup<"aggregate-return">;
-def GNUAlignofExpression : DiagGroup<"gnu-alignof-expression">;
-def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
-def GNUAnonymousStruct : DiagGroup<"gnu-anonymous-struct">;
-def GNUAutoType : DiagGroup<"gnu-auto-type">;
-def ArrayBounds : DiagGroup<"array-bounds">;
-def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">;
-def Availability : DiagGroup<"availability">;
-def Section : DiagGroup<"section">;
-def AutoImport : DiagGroup<"auto-import">;
-def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">;
-def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
-def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">;
-def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">;
-def BitFieldWidth : DiagGroup<"bitfield-width">;
-def ConstantConversion :
- DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >;
-def LiteralConversion : DiagGroup<"literal-conversion">;
-def StringConversion : DiagGroup<"string-conversion">;
-def SignConversion : DiagGroup<"sign-conversion">;
-def PointerBoolConversion : DiagGroup<"pointer-bool-conversion">;
-def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">;
-def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion,
- UndefinedBoolConversion]>;
-def IntConversion : DiagGroup<"int-conversion">;
-def EnumConversion : DiagGroup<"enum-conversion">;
-def FloatConversion : DiagGroup<"float-conversion">;
-def DoublePromotion : DiagGroup<"double-promotion">;
-def EnumTooLarge : DiagGroup<"enum-too-large">;
-def UnsupportedNan : DiagGroup<"unsupported-nan">;
-def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">;
-def NullConversion : DiagGroup<"null-conversion">;
-def ImplicitConversionFloatingPointToBool :
- DiagGroup<"implicit-conversion-floating-point-to-bool">;
-def ObjCLiteralConversion : DiagGroup<"objc-literal-conversion">;
-def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
-def MacroRedefined : DiagGroup<"macro-redefined">;
-def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
-def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
-def C99Compat : DiagGroup<"c99-compat">;
-def CXXCompat: DiagGroup<"c++-compat">;
-def ExternCCompat : DiagGroup<"extern-c-compat">;
-def KeywordCompat : DiagGroup<"keyword-compat">;
-def GNUCaseRange : DiagGroup<"gnu-case-range">;
-def CastAlign : DiagGroup<"cast-align">;
-def CastQual : DiagGroup<"cast-qual">;
-def : DiagGroup<"char-align">;
-def Comment : DiagGroup<"comment">;
-def GNUComplexInteger : DiagGroup<"gnu-complex-integer">;
-def GNUConditionalOmittedOperand : DiagGroup<"gnu-conditional-omitted-operand">;
-def ConfigMacros : DiagGroup<"config-macros">;
-def : DiagGroup<"ctor-dtor-privacy">;
-def GNUDesignator : DiagGroup<"gnu-designator">;
-def GNUStringLiteralOperatorTemplate :
- DiagGroup<"gnu-string-literal-operator-template">;
-
-def DeleteIncomplete : DiagGroup<"delete-incomplete">;
-def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
-def AbstractFinalClass : DiagGroup<"abstract-final-class">;
-
-def CXX11CompatDeprecatedWritableStr :
- DiagGroup<"c++11-compat-deprecated-writable-strings">;
-
-def DeprecatedAttributes : DiagGroup<"deprecated-attributes">;
-def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
-def UnavailableDeclarations : DiagGroup<"unavailable-declarations">;
-def PartialAvailability : DiagGroup<"partial-availability">;
-def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
-def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
-def DeprecatedRegister : DiagGroup<"deprecated-register">;
-def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
- [CXX11CompatDeprecatedWritableStr]>;
-// FIXME: Why is DeprecatedImplementations not in this group?
-def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
- DeprecatedDeclarations,
- DeprecatedIncrementBool,
- DeprecatedRegister,
- DeprecatedWritableStr]>,
- DiagCategory<"Deprecations">;
-
-def LibLTO : DiagGroup<"liblto">;
-def : DiagGroup<"disabled-optimization">;
-def : DiagGroup<"discard-qual">;
-def : DiagGroup<"div-by-zero">;
-
-def DocumentationHTML : DiagGroup<"documentation-html">;
-def DocumentationUnknownCommand : DiagGroup<"documentation-unknown-command">;
-def DocumentationPedantic : DiagGroup<"documentation-pedantic",
- [DocumentationUnknownCommand]>;
-def DocumentationDeprecatedSync : DiagGroup<"documentation-deprecated-sync">;
-def Documentation : DiagGroup<"documentation",
- [DocumentationHTML,
- DocumentationDeprecatedSync]>;
-
-def EmptyBody : DiagGroup<"empty-body">;
-def Exceptions : DiagGroup<"exceptions">;
-
-def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">;
-def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">;
-def ExtraTokens : DiagGroup<"extra-tokens">;
-def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">;
-def ExtraSemi : DiagGroup<"extra-semi", [CXX11ExtraSemi]>;
-
-def GNUFlexibleArrayInitializer : DiagGroup<"gnu-flexible-array-initializer">;
-def GNUFlexibleArrayUnionMember : DiagGroup<"gnu-flexible-array-union-member">;
-def GNUFoldingConstant : DiagGroup<"gnu-folding-constant">;
-def FormatExtraArgs : DiagGroup<"format-extra-args">;
-def FormatZeroLength : DiagGroup<"format-zero-length">;
-
-// Warnings for C++1y code which is not compatible with prior C++ standards.
-def CXXPre14Compat : DiagGroup<"c++98-c++11-compat">;
-def CXXPre14CompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic",
- [CXXPre14Compat]>;
-def CXXPre1zCompat : DiagGroup<"c++98-c++11-c++14-compat">;
-def CXXPre1zCompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
- [CXXPre1zCompat]>;
-
-def CXX98CompatBindToTemporaryCopy :
- DiagGroup<"c++98-compat-bind-to-temporary-copy">;
-def CXX98CompatLocalTypeTemplateArgs :
- DiagGroup<"c++98-compat-local-type-template-args">;
-def CXX98CompatUnnamedTypeTemplateArgs :
- DiagGroup<"c++98-compat-unnamed-type-template-args">;
-
-def CXX98Compat : DiagGroup<"c++98-compat",
- [CXX98CompatLocalTypeTemplateArgs,
- CXX98CompatUnnamedTypeTemplateArgs,
- CXXPre14Compat,
- CXXPre1zCompat]>;
-// Warnings for C++11 features which are Extensions in C++98 mode.
-def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
- [CXX98Compat,
- CXX98CompatBindToTemporaryCopy,
- CXXPre14CompatPedantic,
- CXXPre1zCompatPedantic]>;
-
-def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
-
-def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">;
-
-// Original name of this warning in Clang
-def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;
-
-// Name of this warning in GCC
-def : DiagGroup<"narrowing", [CXX11Narrowing]>;
-
-def CXX11CompatReservedUserDefinedLiteral :
- DiagGroup<"c++11-compat-reserved-user-defined-literal">;
-def ReservedUserDefinedLiteral :
- DiagGroup<"reserved-user-defined-literal",
- [CXX11CompatReservedUserDefinedLiteral]>;
-
-def CXX11Compat : DiagGroup<"c++11-compat",
- [CXX11Narrowing,
- CXX11CompatReservedUserDefinedLiteral,
- CXX11CompatDeprecatedWritableStr,
- CXXPre14Compat,
- CXXPre1zCompat]>;
-def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
-def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
- [CXXPre14CompatPedantic,
- CXXPre1zCompatPedantic]>;
-
-def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre1zCompat]>;
-def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
- [CXXPre1zCompatPedantic]>;
-
-def CXX1zCompat : DiagGroup<"c++1z-compat", [DeprecatedRegister,
- DeprecatedIncrementBool]>;
-
-def : DiagGroup<"effc++">;
-def DivZero : DiagGroup<"division-by-zero">;
-def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
-def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
-def FourByteMultiChar : DiagGroup<"four-char-constants">;
-def GlobalConstructors : DiagGroup<"global-constructors">;
-def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">;
-def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">;
-def LogicalNotParentheses: DiagGroup<"logical-not-parentheses">;
-def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">;
-def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">;
-def DanglingElse: DiagGroup<"dangling-else">;
-def DanglingField : DiagGroup<"dangling-field">;
-def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
-def FlagEnum : DiagGroup<"flag-enum">;
-def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>;
-def InfiniteRecursion : DiagGroup<"infinite-recursion">;
-def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">;
-def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
-def : DiagGroup<"import">;
-def GNUIncludeNext : DiagGroup<"gnu-include-next">;
-def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">;
-def IncompatiblePointerTypesDiscardsQualifiers
- : DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
-def IncompatiblePointerTypes
- : DiagGroup<"incompatible-pointer-types",
- [IncompatiblePointerTypesDiscardsQualifiers]>;
-def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
-def NonModularIncludeInFrameworkModule
- : DiagGroup<"non-modular-include-in-framework-module">;
-def NonModularIncludeInModule : DiagGroup<"non-modular-include-in-module",
- [NonModularIncludeInFrameworkModule]>;
-def IncompleteModule : DiagGroup<"incomplete-module",
- [IncompleteUmbrella, NonModularIncludeInModule]>;
-
-def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">;
-def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
-def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
-def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
-def : DiagGroup<"init-self">;
-def : DiagGroup<"inline">;
-def : DiagGroup<"invalid-pch">;
-def GNULabelsAsValue : DiagGroup<"gnu-label-as-value">;
-def LiteralRange : DiagGroup<"literal-range">;
-def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args",
- [CXX98CompatLocalTypeTemplateArgs]>;
-def RangeLoopAnalysis : DiagGroup<"range-loop-analysis">;
-def ForLoopAnalysis : DiagGroup<"for-loop-analysis">;
-def LoopAnalysis : DiagGroup<"loop-analysis", [ForLoopAnalysis,
- RangeLoopAnalysis]>;
-def MalformedWarningCheck : DiagGroup<"malformed-warning-check">;
-def Main : DiagGroup<"main">;
-def MainReturnType : DiagGroup<"main-return-type">;
-def MissingBraces : DiagGroup<"missing-braces">;
-def MissingDeclarations: DiagGroup<"missing-declarations">;
-def : DiagGroup<"missing-format-attribute">;
-def : DiagGroup<"missing-include-dirs">;
-def MissingNoreturn : DiagGroup<"missing-noreturn">;
-def MultiChar : DiagGroup<"multichar">;
-def : DiagGroup<"nested-externs">;
-def CXX11LongLong : DiagGroup<"c++11-long-long">;
-def LongLong : DiagGroup<"long-long", [CXX11LongLong]>;
-def ImplicitlyUnsignedLiteral : DiagGroup<"implicitly-unsigned-literal">;
-def MethodSignatures : DiagGroup<"method-signatures">;
-def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">;
-def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
-def MismatchedTags : DiagGroup<"mismatched-tags">;
-def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
-def ModuleBuild : DiagGroup<"module-build">;
-def ModuleConflict : DiagGroup<"module-conflict">;
-def ModuleFileExtension : DiagGroup<"module-file-extension">;
-def NewlineEOF : DiagGroup<"newline-eof">;
-def Nullability : DiagGroup<"nullability">;
-def NullabilityDeclSpec : DiagGroup<"nullability-declspec">;
-def NullableToNonNullConversion : DiagGroup<"nullable-to-nonnull-conversion">;
-def NullabilityCompleteness : DiagGroup<"nullability-completeness">;
-def NullArithmetic : DiagGroup<"null-arithmetic">;
-def NullCharacter : DiagGroup<"null-character">;
-def NullDereference : DiagGroup<"null-dereference">;
-def InitializerOverrides : DiagGroup<"initializer-overrides">;
-def NonNull : DiagGroup<"nonnull">;
-def NonPODVarargs : DiagGroup<"non-pod-varargs">;
-def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
-def : DiagGroup<"nonportable-cfstrings">;
-def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
-def OveralignedType : DiagGroup<"over-aligned">;
-def OldStyleCast : DiagGroup<"old-style-cast">;
-def : DiagGroup<"old-style-definition">;
-def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">;
-def : DiagGroup<"overflow">;
-def ForwardClassReceiver : DiagGroup<"receiver-forward-class">;
-def MethodAccess : DiagGroup<"objc-method-access">;
-def ObjCReceiver : DiagGroup<"receiver-expr">;
-// FIXME: Remove this when Xcode removes the warning setting.
-def : DiagGroup<"receiver-is-weak">;
-def OperatorNewReturnsNull : DiagGroup<"new-returns-null">;
-def OverlengthStrings : DiagGroup<"overlength-strings">;
-def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
-def PrivateExtern : DiagGroup<"private-extern">;
-def SelTypeCast : DiagGroup<"cast-of-sel-type">;
-def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">;
-def BadFunctionCast : DiagGroup<"bad-function-cast">;
-def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
-def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
-def ObjCProtocolQualifiers : DiagGroup<"objc-protocol-qualifiers">;
-def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
-def ObjCDesignatedInit : DiagGroup<"objc-designated-initializers">;
-def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">;
-def ObjCReadonlyPropertyHasSetter : DiagGroup<"objc-readonly-with-setter-property">;
-def ObjCInvalidIBOutletProperty : DiagGroup<"invalid-iboutlet">;
-def ObjCRootClass : DiagGroup<"objc-root-class">;
-def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">;
-def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
-def ObjCMultipleMethodNames : DiagGroup<"objc-multiple-method-names">;
-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 PointerArith : DiagGroup<"pointer-arith">;
-def PoundWarning : DiagGroup<"#warnings">;
-def PoundPragmaMessage : DiagGroup<"#pragma-messages">,
- DiagCategory<"#pragma message Directive">;
-def : DiagGroup<"pointer-to-int-cast">;
-def : DiagGroup<"redundant-decls">;
-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 SelfMove : DiagGroup<"self-move">;
-def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
-def Sentinel : DiagGroup<"sentinel">;
-def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
-def Shadow : DiagGroup<"shadow">;
-def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
-def : DiagGroup<"sign-promo">;
-def SignCompare : DiagGroup<"sign-compare">;
-def : DiagGroup<"stack-protector">;
-def : DiagGroup<"switch-default">;
-def : DiagGroup<"synth">;
-def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
-def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">;
-def SizeofPointerMemaccess : DiagGroup<"sizeof-pointer-memaccess">;
-def StaticInInline : DiagGroup<"static-in-inline">;
-def StaticLocalInInline : DiagGroup<"static-local-in-inline">;
-def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">;
-def StaticFloatInit : DiagGroup<"static-float-init", [GNUStaticFloatInit]>;
-def GNUStatementExpression : DiagGroup<"gnu-statement-expression">;
-def StringCompare : DiagGroup<"string-compare">;
-def StringPlusInt : DiagGroup<"string-plus-int">;
-def StringPlusChar : DiagGroup<"string-plus-char">;
-def StrncatSize : DiagGroup<"strncat-size">;
-def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
-def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
-def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
-def TautologicalUndefinedCompare : DiagGroup<"tautological-undefined-compare">;
-def TautologicalCompare : DiagGroup<"tautological-compare",
- [TautologicalOutOfRangeCompare,
- TautologicalPointerCompare,
- TautologicalOverlapCompare,
- TautologicalUndefinedCompare]>;
-def HeaderHygiene : DiagGroup<"header-hygiene">;
-def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
-def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
-def GNUUnionCast : DiagGroup<"gnu-union-cast">;
-def GNUVariableSizedTypeNotAtEnd : DiagGroup<"gnu-variable-sized-type-not-at-end">;
-def Varargs : DiagGroup<"varargs">;
-
-def Unsequenced : DiagGroup<"unsequenced">;
-// GCC name for -Wunsequenced
-def : DiagGroup<"sequence-point", [Unsequenced]>;
-
-// Preprocessor warnings.
-def AmbiguousMacro : DiagGroup<"ambiguous-macro">;
-def KeywordAsMacro : DiagGroup<"keyword-macro">;
-def ReservedIdAsMacro : DiagGroup<"reserved-id-macro">;
-
-// Just silence warnings about -Wstrict-aliasing for now.
-def : DiagGroup<"strict-aliasing=0">;
-def : DiagGroup<"strict-aliasing=1">;
-def : DiagGroup<"strict-aliasing=2">;
-def : DiagGroup<"strict-aliasing">;
-
-// Just silence warnings about -Wstrict-overflow for now.
-def : DiagGroup<"strict-overflow=0">;
-def : DiagGroup<"strict-overflow=1">;
-def : DiagGroup<"strict-overflow=2">;
-def : DiagGroup<"strict-overflow=3">;
-def : DiagGroup<"strict-overflow=4">;
-def : DiagGroup<"strict-overflow=5">;
-def : DiagGroup<"strict-overflow">;
-
-def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
-def : DiagGroup<"strict-prototypes">;
-def StrictSelector : DiagGroup<"strict-selector-match">;
-def MethodDuplicate : DiagGroup<"duplicate-method-match">;
-def ObjCCStringFormat : DiagGroup<"cstring-format-directive">;
-def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
-def SwitchBool : DiagGroup<"switch-bool">;
-def SwitchEnum : DiagGroup<"switch-enum">;
-def Switch : DiagGroup<"switch">;
-def ImplicitFallthroughPerFunction :
- DiagGroup<"implicit-fallthrough-per-function">;
-def ImplicitFallthrough : DiagGroup<"implicit-fallthrough",
- [ImplicitFallthroughPerFunction]>;
-def InvalidPPToken : DiagGroup<"invalid-pp-token">;
-def Trigraphs : DiagGroup<"trigraphs">;
-
-def : DiagGroup<"type-limits">;
-def UndefinedReinterpretCast : DiagGroup<"undefined-reinterpret-cast">;
-def ReinterpretBaseClass : DiagGroup<"reinterpret-base-class">;
-def Unicode : DiagGroup<"unicode">;
-def UninitializedMaybe : DiagGroup<"conditional-uninitialized">;
-def UninitializedSometimes : DiagGroup<"sometimes-uninitialized">;
-def UninitializedStaticSelfInit : DiagGroup<"static-self-init">;
-def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes,
- UninitializedStaticSelfInit]>;
-def UnknownPragmas : DiagGroup<"unknown-pragmas">;
-def IgnoredPragmas : DiagGroup<"ignored-pragmas">;
-def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>;
-def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
-def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
-def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">;
-def UnknownAttributes : DiagGroup<"unknown-attributes">;
-def IgnoredAttributes : DiagGroup<"ignored-attributes">;
-def Attributes : DiagGroup<"attributes", [UnknownAttributes,
- IgnoredAttributes]>;
-def UnknownSanitizers : DiagGroup<"unknown-sanitizers">;
-def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
- [CXX98CompatUnnamedTypeTemplateArgs]>;
-def UnsupportedFriend : DiagGroup<"unsupported-friend">;
-def UnusedArgument : DiagGroup<"unused-argument">;
-def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument">;
-def IgnoredOptimizationArgument : DiagGroup<"ignored-optimization-argument">;
-def InvalidCommandLineArgument : DiagGroup<"invalid-command-line-argument",
- [IgnoredOptimizationArgument]>;
-def UnusedComparison : DiagGroup<"unused-comparison">;
-def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
-def UnneededInternalDecl : DiagGroup<"unneeded-internal-declaration">;
-def UnneededMemberFunction : DiagGroup<"unneeded-member-function">;
-def UnusedPrivateField : DiagGroup<"unused-private-field">;
-def UnusedFunction : DiagGroup<"unused-function", [UnneededInternalDecl]>;
-def UnusedMemberFunction : DiagGroup<"unused-member-function",
- [UnneededMemberFunction]>;
-def UnusedLabel : DiagGroup<"unused-label">;
-def UnusedParameter : DiagGroup<"unused-parameter">;
-def UnusedResult : DiagGroup<"unused-result">;
-def PotentiallyEvaluatedExpression : DiagGroup<"potentially-evaluated-expression">;
-def UnevaluatedExpression : DiagGroup<"unevaluated-expression",
- [PotentiallyEvaluatedExpression]>;
-def UnusedValue : DiagGroup<"unused-value", [UnusedComparison, UnusedResult,
- UnevaluatedExpression]>;
-def UnusedConstVariable : DiagGroup<"unused-const-variable">;
-def UnusedVariable : DiagGroup<"unused-variable",
- [UnusedConstVariable]>;
-def UnusedLocalTypedef : DiagGroup<"unused-local-typedef">;
-def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">;
-def UnusedGetterReturnValue : DiagGroup<"unused-getter-return-value">;
-def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
-def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
-def Reorder : DiagGroup<"reorder">;
-def UndeclaredSelector : DiagGroup<"undeclared-selector">;
-def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
-def CustomAtomic : DiagGroup<"custom-atomic-properties">;
-def AtomicProperties : DiagGroup<"atomic-properties",
- [ImplicitAtomic, CustomAtomic]>;
-def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">;
-def ARCRetainCycles : DiagGroup<"arc-retain-cycles">;
-def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">;
-def AutomaticReferenceCounting : DiagGroup<"arc",
- [ARCUnsafeRetainedAssign,
- ARCRetainCycles,
- ARCNonPodMemAccess]>;
-def ARCRepeatedUseOfWeakMaybe : DiagGroup<"arc-maybe-repeated-use-of-weak">;
-def ARCRepeatedUseOfWeak : DiagGroup<"arc-repeated-use-of-weak",
- [ARCRepeatedUseOfWeakMaybe]>;
-def ObjCBridge : DiagGroup<"bridge-cast">;
-
-def DeallocInCategory:DiagGroup<"dealloc-in-category">;
-def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">;
-def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>;
-def Protocol : DiagGroup<"protocol">;
-def AtProtocol : DiagGroup<"at-protocol">;
-def PropertyAccessDotSyntax: DiagGroup<"property-access-dot-syntax">;
-def PropertyAttr : DiagGroup<"property-attribute-mismatch">;
-def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
-def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
-def VariadicMacros : DiagGroup<"variadic-macros">;
-def VectorConversion : DiagGroup<"vector-conversion">; // clang specific
-def VexingParse : DiagGroup<"vexing-parse">;
-def VLA : DiagGroup<"vla">;
-def VLAExtension : DiagGroup<"vla-extension">;
-def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
-def Visibility : DiagGroup<"visibility">;
-def ZeroLengthArray : DiagGroup<"zero-length-array">;
-def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
-def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">;
-def Fallback : DiagGroup<"fallback">;
-
-// This covers both the deprecated case (in C++98)
-// and the extension case (in C++11 onwards).
-def WritableStrings : DiagGroup<"writable-strings", [DeprecatedWritableStr]>;
-
-// GCC calls -Wdeprecated-writable-strings -Wwrite-strings.
-//
-// Bizarrely, this warning flag enables -fconst-strings in C. This is
-// GCC-compatible, but really weird.
-//
-// FIXME: Should this affect C++11 (where this is an error,
-// not just deprecated) or not?
-def GCCWriteStrings : DiagGroup<"write-strings" , [WritableStrings]>;
-
-def CharSubscript : DiagGroup<"char-subscripts">;
-def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
-def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
-
-// Unreachable code warning groups.
-//
-// The goal is make -Wunreachable-code on by default, in -Wall, or at
-// least actively used, with more noisy versions of the warning covered
-// under separate flags.
-//
-def UnreachableCodeLoopIncrement : DiagGroup<"unreachable-code-loop-increment">;
-def UnreachableCode : DiagGroup<"unreachable-code",
- [UnreachableCodeLoopIncrement]>;
-def UnreachableCodeBreak : DiagGroup<"unreachable-code-break">;
-def UnreachableCodeReturn : DiagGroup<"unreachable-code-return">;
-def UnreachableCodeAggressive : DiagGroup<"unreachable-code-aggressive",
- [UnreachableCode,
- UnreachableCodeBreak,
- UnreachableCodeReturn]>;
-
-// Aggregation warning settings.
-
-// Populate -Waddress with warnings from other groups.
-def : DiagGroup<"address", [PointerBoolConversion,
- StringCompare,
- TautologicalPointerCompare]>;
-
-// -Widiomatic-parentheses contains warnings about 'idiomatic'
-// missing parentheses; it is off by default. We do not include it
-// in -Wparentheses because most users who use -Wparentheses explicitly
-// do not want these warnings.
-def ParenthesesOnEquality : DiagGroup<"parentheses-equality">;
-def Parentheses : DiagGroup<"parentheses",
- [LogicalOpParentheses,
- LogicalNotParentheses,
- BitwiseOpParentheses,
- ShiftOpParentheses,
- OverloadedShiftOpParentheses,
- ParenthesesOnEquality,
- DanglingElse]>;
-
-// -Wconversion has its own warnings, but we split a few out for
-// legacy reasons:
-// - some people want just 64-to-32 warnings
-// - conversion warnings with constant sources are on by default
-// - conversion warnings for literals are on by default
-// - bool-to-pointer conversion warnings are on by default
-// - __null-to-integer conversion warnings are on by default
-def Conversion : DiagGroup<"conversion",
- [BoolConversion,
- ConstantConversion,
- EnumConversion,
- FloatConversion,
- Shorten64To32,
- IntConversion,
- LiteralConversion,
- NonLiteralNullConversion, // (1-1)->pointer (etc)
- NullConversion, // NULL->non-pointer
- ObjCLiteralConversion,
- SignConversion,
- StringConversion]>,
- DiagCategory<"Value Conversion Issue">;
-
-def Unused : DiagGroup<"unused",
- [UnusedArgument, UnusedFunction, UnusedLabel,
- // UnusedParameter, (matches GCC's behavior)
- // UnusedMemberFunction, (clean-up llvm before enabling)
- UnusedPrivateField, UnusedLocalTypedef,
- UnusedValue, UnusedVariable, UnusedPropertyIvar]>,
- DiagCategory<"Unused Entity Issue">;
-
-// Format settings.
-def FormatInvalidSpecifier : DiagGroup<"format-invalid-specifier">;
-def FormatSecurity : DiagGroup<"format-security">;
-def FormatNonStandard : DiagGroup<"format-non-iso">;
-def FormatY2K : DiagGroup<"format-y2k">;
-def FormatPedantic : DiagGroup<"format-pedantic">;
-def Format : DiagGroup<"format",
- [FormatExtraArgs, FormatZeroLength, NonNull,
- FormatSecurity, FormatY2K, FormatInvalidSpecifier]>,
- DiagCategory<"Format String Issue">;
-def FormatNonLiteral : DiagGroup<"format-nonliteral">;
-def Format2 : DiagGroup<"format=2",
- [FormatNonLiteral, FormatSecurity, FormatY2K]>;
-
-def TypeSafety : DiagGroup<"type-safety">;
-
-def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">;
-def IntToPointerCast : DiagGroup<"int-to-pointer-cast",
- [IntToVoidPointerCast]>;
-
-def Move : DiagGroup<"move", [PessimizingMove, RedundantMove, SelfMove]>;
-
-def Extra : DiagGroup<"extra", [
- MissingFieldInitializers,
- IgnoredQualifiers,
- InitializerOverrides,
- SemiBeforeMethodBody,
- MissingMethodReturnType,
- SignCompare,
- UnusedParameter
- ]>;
-
-def Most : DiagGroup<"most", [
- CharSubscript,
- Comment,
- DeleteNonVirtualDtor,
- Format,
- Implicit,
- InfiniteRecursion,
- MismatchedTags,
- MissingBraces,
- Move,
- MultiChar,
- Reorder,
- ReturnType,
- SelfAssignment,
- SelfMove,
- SizeofArrayArgument,
- SizeofArrayDecay,
- StringPlusInt,
- Trigraphs,
- Uninitialized,
- UnknownPragmas,
- Unused,
- VolatileRegisterVar,
- ObjCMissingSuperCalls,
- ObjCDesignatedInit,
- OverloadedVirtual,
- PrivateExtern,
- SelTypeCast,
- ExternCCompat
- ]>;
-
-// Thread Safety warnings
-def ThreadSafetyAttributes : DiagGroup<"thread-safety-attributes">;
-def ThreadSafetyAnalysis : DiagGroup<"thread-safety-analysis">;
-def ThreadSafetyPrecise : DiagGroup<"thread-safety-precise">;
-def ThreadSafetyReference : DiagGroup<"thread-safety-reference">;
-def ThreadSafetyNegative : DiagGroup<"thread-safety-negative">;
-def ThreadSafety : DiagGroup<"thread-safety",
- [ThreadSafetyAttributes,
- ThreadSafetyAnalysis,
- ThreadSafetyPrecise,
- ThreadSafetyReference]>;
-def ThreadSafetyVerbose : DiagGroup<"thread-safety-verbose">;
-def ThreadSafetyBeta : DiagGroup<"thread-safety-beta">;
-
-// Uniqueness Analysis warnings
-def Consumed : DiagGroup<"consumed">;
-
-// Note that putting warnings in -Wall will not disable them by default. If a
-// warning should be active _only_ when -Wall is passed in, mark it as
-// DefaultIgnore in addition to putting it here.
-def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool]>;
-
-// Warnings that should be in clang-cl /w4.
-def : DiagGroup<"CL4", [All, Extra]>;
-
-// Warnings enabled by -pedantic. This is magically filled in by TableGen.
-def Pedantic : DiagGroup<"pedantic">;
-
-// Aliases.
-def : DiagGroup<"", [Extra]>; // -W = -Wextra
-def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wextra-tokens
-def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
-def : DiagGroup<"conversion-null",
- [NullConversion]>; // -Wconversion-null = -Wnull-conversion
-def : DiagGroup<"bool-conversions",
- [BoolConversion]>; // -Wbool-conversions = -Wbool-conversion
-def : DiagGroup<"int-conversions",
- [IntConversion]>; // -Wint-conversions = -Wint-conversion
-def : DiagGroup<"vector-conversions",
- [VectorConversion]>; // -Wvector-conversions = -Wvector-conversion
-def : DiagGroup<"unused-local-typedefs", [UnusedLocalTypedef]>;
- // -Wunused-local-typedefs = -Wunused-local-typedef
-
-// A warning group for warnings that we want to have on by default in clang,
-// but which aren't on by default in GCC.
-def NonGCC : DiagGroup<"non-gcc",
- [SignCompare, Conversion, LiteralRange]>;
-
-// A warning group for warnings about using C++11 features as extensions in
-// earlier C++ versions.
-def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace,
- CXX11LongLong]>;
-
-// A warning group for warnings about using C++14 features as extensions in
-// earlier C++ versions.
-def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral]>;
-
-// A warning group for warnings about using C++1z features as extensions in
-// earlier C++ versions.
-def CXX1z : DiagGroup<"c++1z-extensions">;
-
-def : DiagGroup<"c++0x-extensions", [CXX11]>;
-def : DiagGroup<"c++1y-extensions", [CXX14]>;
-
-def DelegatingCtorCycles :
- DiagGroup<"delegating-ctor-cycles">;
-
-// A warning group for warnings about using C11 features as extensions.
-def C11 : DiagGroup<"c11-extensions">;
-
-// A warning group for warnings about using C99 features as extensions.
-def C99 : DiagGroup<"c99-extensions">;
-
-// A warning group for warnings about GCC extensions.
-def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
- GNUAutoType,
- GNUBinaryLiteral, GNUCaseRange,
- GNUComplexInteger, GNUCompoundLiteralInitializer,
- GNUConditionalOmittedOperand, GNUDesignator,
- GNUEmptyInitializer, GNUEmptyStruct,
- VLAExtension, GNUFlexibleArrayInitializer,
- GNUFlexibleArrayUnionMember, GNUFoldingConstant,
- GNUImaginaryConstant, GNUIncludeNext,
- GNULabelsAsValue,
- RedeclaredClassMember, GNURedeclaredEnum,
- GNUStatementExpression, GNUStaticFloatInit,
- GNUStringLiteralOperatorTemplate,
- GNUUnionCast, GNUVariableSizedTypeNotAtEnd,
- ZeroLengthArray, GNUZeroLineDirective,
- GNUZeroVariadicMacroArguments]>;
-// A warning group for warnings about code that clang accepts but gcc doesn't.
-def GccCompat : DiagGroup<"gcc-compat">;
-
-// Warnings for Microsoft extensions.
-def MicrosoftCharize : DiagGroup<"microsoft-charize">;
-def MicrosoftInclude : DiagGroup<"microsoft-include">;
-def MicrosoftCppMacro : DiagGroup<"microsoft-cpp-macro">;
-def MicrosoftFixedEnum : DiagGroup<"microsoft-fixed-enum">;
-def MicrosoftSealed : DiagGroup<"microsoft-sealed">;
-def MicrosoftUnqualifiedFriend : DiagGroup<"microsoft-unqualified-friend">;
-def MicrosoftExceptionSpec : DiagGroup<"microsoft-exception-spec">;
-def MicrosoftUsingDecl : DiagGroup<"microsoft-using-decl">;
-def MicrosoftMutableReference : DiagGroup<"microsoft-mutable-reference">;
-def MicrosoftPureDefinition : DiagGroup<"microsoft-pure-definition">;
-def MicrosoftUnionMemberReference : DiagGroup<
- "microsoft-union-member-reference">;
-def MicrosoftExplicitConstructorCall : DiagGroup<
- "microsoft-explicit-constructor-call">;
-def MicrosoftEnumValue : DiagGroup<"microsoft-enum-value">;
-def MicrosoftDefaultArgRedefinition :
- DiagGroup<"microsoft-default-arg-redefinition">;
-def MicrosoftTemplate : DiagGroup<"microsoft-template">;
-def MicrosoftRedeclareStatic : DiagGroup<"microsoft-redeclare-static">;
-def MicrosoftEnumForwardReference :
- DiagGroup<"microsoft-enum-forward-reference">;
-def MicrosoftGoto : DiagGroup<"microsoft-goto">;
-def MicrosoftFlexibleArray : DiagGroup<"microsoft-flexible-array">;
-def MicrosoftExtraQualification : DiagGroup<"microsoft-extra-qualification">;
-def MicrosoftCast : DiagGroup<"microsoft-cast">;
-def MicrosoftConstInit : DiagGroup<"microsoft-const-init">;
-def MicrosoftVoidPseudoDtor : DiagGroup<"microsoft-void-pseudo-dtor">;
-def MicrosoftAnonTag : DiagGroup<"microsoft-anon-tag">;
-def MicrosoftCommentPaste : DiagGroup<"microsoft-comment-paste">;
-def MicrosoftEndOfFile : DiagGroup<"microsoft-end-of-file">;
-// Aliases.
-def : DiagGroup<"msvc-include", [MicrosoftInclude]>;
- // -Wmsvc-include = -Wmicrosoft-include
-
-// Warnings group for warnings about Microsoft extensions.
-def Microsoft : DiagGroup<"microsoft",
- [MicrosoftCharize, MicrosoftInclude, MicrosoftCppMacro, MicrosoftFixedEnum,
- MicrosoftSealed, MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec,
- MicrosoftUsingDecl, MicrosoftMutableReference, MicrosoftPureDefinition,
- MicrosoftUnionMemberReference, MicrosoftExplicitConstructorCall,
- MicrosoftEnumValue, MicrosoftDefaultArgRedefinition, MicrosoftTemplate,
- MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto,
- MicrosoftFlexibleArray, MicrosoftExtraQualification, MicrosoftCast,
- MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
- MicrosoftCommentPaste, MicrosoftEndOfFile]>;
-
-def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
-
-def ObjCProtocolMethodImpl : DiagGroup<"objc-protocol-method-implementation">;
-
-def ObjCNoPropertyAutoSynthesis : DiagGroup<"objc-property-synthesis">;
-
-// ObjC API warning groups.
-def ObjCRedundantLiteralUse : DiagGroup<"objc-redundant-literal-use">;
-def ObjCRedundantAPIUse : DiagGroup<"objc-redundant-api-use", [
- ObjCRedundantLiteralUse
- ]>;
-
-def ObjCCocoaAPI : DiagGroup<"objc-cocoa-api", [
- ObjCRedundantAPIUse
- ]>;
-
-def ObjCStringComparison : DiagGroup<"objc-string-compare">;
-def ObjCStringConcatenation : DiagGroup<"objc-string-concatenation">;
-def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [
- ObjCStringComparison
- ]>;
-
-// Inline ASM warnings.
-def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
-def ASM : DiagGroup<"asm", [
- ASMOperandWidths
- ]>;
-
-// OpenMP warnings.
-def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
-def OpenMPClauses : DiagGroup<"openmp-clauses">;
-def OpenMPLoopForm : DiagGroup<"openmp-loop-form">;
-
-// Backend warnings.
-def BackendInlineAsm : DiagGroup<"inline-asm">;
-def BackendFrameLargerThanEQ : DiagGroup<"frame-larger-than=">;
-def BackendPlugin : DiagGroup<"backend-plugin">;
-def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
-def BackendOptimizationRemark : DiagGroup<"pass">;
-def BackendOptimizationRemarkMissed : DiagGroup<"pass-missed">;
-def BackendOptimizationRemarkAnalysis : DiagGroup<"pass-analysis">;
-def BackendOptimizationFailure : DiagGroup<"pass-failed">;
-
-// Instrumentation based profiling warnings.
-def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
-def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
-
-// AddressSanitizer frontent instrumentation remarks.
-def SanitizeAddressRemarks : DiagGroup<"sanitize-address">;
-
-// Issues with serialized diagnostics.
-def SerializedDiagnostics : DiagGroup<"serialized-diagnostics">;
-
-// A warning group for warnings about code that clang accepts when
-// compiling CUDA C/C++ but which is not compatible with the CUDA spec.
-def CudaCompat : DiagGroup<"cuda-compat">;
-
-// A warning group for things that will change semantics in the future.
-def FutureCompat : DiagGroup<"future-compat">;
-
-def InvalidOrNonExistentDirectory : DiagGroup<"invalid-or-nonexistent-directory">;
-
-def OptionIgnored : DiagGroup<"option-ignored">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
deleted file mode 100644
index a675dfa..0000000
--- a/include/clang/Basic/DiagnosticIDs.h
+++ /dev/null
@@ -1,287 +0,0 @@
-//===--- DiagnosticIDs.h - Diagnostic IDs 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 Diagnostic IDs-related interfaces.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
-#define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
- class DiagnosticsEngine;
- class SourceLocation;
-
- // Import the diagnostic enums themselves.
- namespace diag {
- // Start position for diagnostics.
- enum {
- DIAG_START_COMMON = 0,
- DIAG_START_DRIVER = DIAG_START_COMMON + 300,
- DIAG_START_FRONTEND = DIAG_START_DRIVER + 100,
- DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100,
- DIAG_START_LEX = DIAG_START_SERIALIZATION + 120,
- DIAG_START_PARSE = DIAG_START_LEX + 300,
- DIAG_START_AST = DIAG_START_PARSE + 500,
- DIAG_START_COMMENT = DIAG_START_AST + 110,
- DIAG_START_SEMA = DIAG_START_COMMENT + 100,
- DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000,
- DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100
- };
-
- class CustomDiagInfo;
-
- /// \brief All of the diagnostics that can be emitted by the frontend.
- typedef unsigned kind;
-
- // Get typedefs for common diagnostics.
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM,
-#define COMMONSTART
-#include "clang/Basic/DiagnosticCommonKinds.inc"
- NUM_BUILTIN_COMMON_DIAGNOSTICS
-#undef DIAG
- };
-
- /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
- /// to either Ignore (nothing), Remark (emit a remark), Warning
- /// (emit a warning) or Error (emit as an error). It allows clients to
- /// map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
- enum class Severity {
- // NOTE: 0 means "uncomputed".
- Ignored = 1, ///< Do not present this diagnostic, ignore it.
- Remark = 2, ///< Present this diagnostic as a remark.
- Warning = 3, ///< Present this diagnostic as a warning.
- Error = 4, ///< Present this diagnostic as an error.
- Fatal = 5 ///< Present this diagnostic as a fatal error.
- };
-
- /// Flavors of diagnostics we can emit. Used to filter for a particular
- /// kind of diagnostic (for instance, for -W/-R flags).
- enum class Flavor {
- WarningOrError, ///< A diagnostic that indicates a problem or potential
- ///< problem. Can be made fatal by -Werror.
- Remark ///< A diagnostic that indicates normal progress through
- ///< compilation.
- };
- }
-
-class DiagnosticMapping {
- unsigned Severity : 3;
- unsigned IsUser : 1;
- unsigned IsPragma : 1;
- unsigned HasNoWarningAsError : 1;
- unsigned HasNoErrorAsFatal : 1;
-
-public:
- static DiagnosticMapping Make(diag::Severity Severity, bool IsUser,
- bool IsPragma) {
- DiagnosticMapping Result;
- Result.Severity = (unsigned)Severity;
- Result.IsUser = IsUser;
- Result.IsPragma = IsPragma;
- Result.HasNoWarningAsError = 0;
- Result.HasNoErrorAsFatal = 0;
- return Result;
- }
-
- diag::Severity getSeverity() const { return (diag::Severity)Severity; }
- void setSeverity(diag::Severity Value) { Severity = (unsigned)Value; }
-
- bool isUser() const { return IsUser; }
- bool isPragma() const { return IsPragma; }
-
- bool hasNoWarningAsError() const { return HasNoWarningAsError; }
- void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
-
- bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; }
- void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; }
-};
-
-/// \brief 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.
- enum Level {
- Ignored, Note, Remark, Warning, Error, Fatal
- };
-
-private:
- /// \brief 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
- /// level.
- ///
- /// If this is the first request for this diagnostic, it is registered and
- /// created, otherwise the existing ID is returned.
-
- // FIXME: Replace this function with a create-only facilty like
- // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
- // writing, nearly all callers of this function were invalid.
- unsigned getCustomDiagID(Level L, StringRef FormatString);
-
- //===--------------------------------------------------------------------===//
- // Diagnostic classification and reporting interfaces.
- //
-
- /// \brief 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
- /// 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
- /// default.
- static bool isDefaultMappingAsError(unsigned DiagID);
-
- /// \brief 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
- /// 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
- /// extension of some sort, and whether it is enabled by default.
- ///
- /// This also returns EnabledByDefault, which is set to indicate whether the
- /// diagnostic is ignored by default (in which case -pedantic enables it) or
- /// treated as a warning/error by default.
- ///
- static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
-
-
- /// \brief 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,
- /// or 0 if no category.
- static unsigned getCategoryNumberForDiag(unsigned DiagID);
-
- /// \brief Return the number of diagnostic categories.
- static unsigned getNumberOfCategories();
-
- /// \brief 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
- /// category.
- static bool isARCDiagnostic(unsigned DiagID);
-
- /// \brief 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
- /// 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.
- ///
- /// Warnings generally fall into this category.
- SFINAE_Suppress,
-
- /// \brief 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
- /// substitution failures in some contexts and reported in others.
- SFINAE_AccessControl
- };
-
- /// \brief Determines whether the given built-in diagnostic ID is
- /// for an error that is suppressed if it occurs during C++ template
- /// argument deduction.
- ///
- /// When an error is suppressed due to SFINAE, the template argument
- /// deduction fails but no diagnostic is emitted. Certain classes of
- /// errors, such as those errors that involve C++ access control,
- /// are not SFINAE errors.
- static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
-
- /// \brief 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.
- void getAllDiagnostics(diag::Flavor Flavor,
- SmallVectorImpl<diag::kind> &Diags) const;
-
- /// \brief 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
- /// the DiagnosticClient.
- ///
- /// The classification is based on the way the client configured the
- /// DiagnosticsEngine object.
- ///
- /// \param Loc The source location for which we are interested in finding out
- /// the diagnostic state. Can be null in order to query the latest state.
- DiagnosticIDs::Level
- getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
- const DiagnosticsEngine &Diag) const LLVM_READONLY;
-
- diag::Severity
- getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
- const DiagnosticsEngine &Diag) const LLVM_READONLY;
-
- /// \brief 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,
- /// ignoring suppression.
- void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const;
-
- /// \brief Whether the diagnostic may leave the AST in a state where some
- /// invariants can break.
- bool isUnrecoverable(unsigned DiagID) const;
-
- friend class DiagnosticsEngine;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
deleted file mode 100644
index ed6ff20..0000000
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ /dev/null
@@ -1,673 +0,0 @@
-//==--- DiagnosticLexKinds.td - liblex diagnostics ------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Lexer Diagnostics
-//===----------------------------------------------------------------------===//
-
-let Component = "Lex", CategoryName = "Lexical or Preprocessor Issue" in {
-
-def null_in_char_or_string : Warning<
- "null character(s) preserved in %select{char|string}0 literal">,
- InGroup<NullCharacter>;
-def null_in_file : Warning<"null character ignored">, InGroup<NullCharacter>;
-def warn_nested_block_comment : Warning<"'/*' within block comment">,
- InGroup<Comment>;
-def escaped_newline_block_comment_end : Warning<
- "escaped newline between */ characters at block comment end">,
- InGroup<Comment>;
-def backslash_newline_space : Warning<
- "backslash and newline separated by space">,
- InGroup<DiagGroup<"backslash-newline-escape">>;
-
-// Digraphs.
-def warn_cxx98_compat_less_colon_colon : Warning<
- "'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-// Trigraphs.
-def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>;
-def trigraph_ignored_block_comment : Warning<
- "ignored trigraph would end block comment">, InGroup<Trigraphs>;
-def trigraph_ends_block_comment : Warning<"trigraph ends block comment">,
- InGroup<Trigraphs>;
-def trigraph_converted : Warning<"trigraph converted to '%0' character">,
- InGroup<Trigraphs>;
-
-def ext_multi_line_line_comment : Extension<"multi-line // comment">,
- InGroup<Comment>;
-def ext_line_comment : Extension<
- "// comments are not allowed in this language">,
- InGroup<Comment>;
-def ext_no_newline_eof : Extension<"no newline at end of file">,
- InGroup<NewlineEOF>;
-def warn_no_newline_eof : Warning<"no newline at end of file">,
- InGroup<NewlineEOF>, DefaultIgnore;
-
-def warn_cxx98_compat_no_newline_eof : Warning<
- "C++98 requires newline at end of file">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-
-def ext_dollar_in_identifier : Extension<"'$' in identifier">,
- InGroup<DiagGroup<"dollar-in-identifier-extension">>;
-def ext_charize_microsoft : Extension<
- "charizing operator #@ is a Microsoft extension">,
- InGroup<MicrosoftCharize>;
-def ext_comment_paste_microsoft : Extension<
- "pasting two '/' tokens into a '//' comment is a Microsoft extension">,
- InGroup<MicrosoftCommentPaste>;
-def ext_ctrl_z_eof_microsoft : Extension<
- "treating Ctrl-Z as end-of-file is a Microsoft extension">,
- InGroup<MicrosoftEndOfFile>;
-
-def ext_token_used : Extension<"extension used">,
- InGroup<DiagGroup<"language-extension-token">>;
-
-def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">,
- InGroup<CXX11Compat>, DefaultIgnore;
-
-def ext_unterminated_char_or_string : ExtWarn<
- "missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>;
-def ext_empty_character : ExtWarn<"empty character constant">,
- InGroup<InvalidPPToken>;
-def err_unterminated_block_comment : Error<"unterminated /* comment">;
-def err_invalid_character_to_charify : Error<
- "invalid argument to convert to character">;
-def err_unterminated___pragma : Error<"missing terminating ')' character">;
-
-def err_conflict_marker : Error<"version control conflict marker in file">;
-
-def err_raw_delim_too_long : Error<
- "raw string delimiter longer than 16 characters"
- "; use PREFIX( )PREFIX to delimit raw string">;
-def err_invalid_char_raw_delim : Error<
- "invalid character '%0' character in raw string delimiter"
- "; use PREFIX( )PREFIX to delimit raw string">;
-def err_unterminated_raw_string : Error<
- "raw string missing terminating delimiter )%0\"">;
-def warn_cxx98_compat_raw_string_literal : Warning<
- "raw string literals are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-def ext_multichar_character_literal : ExtWarn<
- "multi-character character constant">, InGroup<MultiChar>;
-def ext_four_char_character_literal : Extension<
- "multi-character character constant">, InGroup<FourByteMultiChar>;
-
-
-// Unicode and UCNs
-def err_invalid_utf8 : Error<
- "source file is not valid UTF-8">;
-def err_non_ascii : Error<
- "non-ASCII characters are not allowed outside of literals and identifiers">;
-def ext_unicode_whitespace : ExtWarn<
- "treating Unicode character as whitespace">,
- InGroup<DiagGroup<"unicode-whitespace">>;
-
-def err_hex_escape_no_digits : Error<
- "\\%0 used with no following hex digits">;
-def warn_ucn_escape_no_digits : Warning<
- "\\%0 used with no following hex digits; "
- "treating as '\\' followed by identifier">, InGroup<Unicode>;
-def err_ucn_escape_incomplete : Error<
- "incomplete universal character name">;
-def warn_ucn_escape_incomplete : Warning<
- "incomplete universal character name; "
- "treating as '\\' followed by identifier">, InGroup<Unicode>;
-def note_ucn_four_not_eight : Note<"did you mean to use '\\u'?">;
-
-def err_ucn_escape_basic_scs : Error<
- "character '%0' cannot be specified by a universal character name">;
-def err_ucn_control_character : Error<
- "universal character name refers to a control character">;
-def err_ucn_escape_invalid : Error<"invalid universal character">;
-def warn_ucn_escape_surrogate : Warning<
- "universal character name refers to a surrogate character">,
- InGroup<Unicode>;
-
-def warn_c99_compat_unicode_id : Warning<
- "%select{using this character in an identifier|starting an identifier with "
- "this character}0 is incompatible with C99">,
- InGroup<C99Compat>, DefaultIgnore;
-def warn_cxx98_compat_unicode_id : Warning<
- "using this character in an identifier is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-def warn_cxx98_compat_literal_ucn_escape_basic_scs : Warning<
- "specifying character '%0' with a universal character name "
- "is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx98_compat_literal_ucn_control_character : Warning<
- "universal character name referring to a control character "
- "is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def warn_ucn_not_valid_in_c89 : Warning<
- "universal character names are only valid in C99 or C++; "
- "treating as '\\' followed by identifier">, InGroup<Unicode>;
-def warn_ucn_not_valid_in_c89_literal : ExtWarn<
- "universal character names are only valid in C99 or C++">, InGroup<Unicode>;
-
-
-// Literal
-def ext_nonstandard_escape : Extension<
- "use of non-standard escape character '\\%0'">;
-def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">,
- InGroup<DiagGroup<"unknown-escape-sequence">>;
-def err_invalid_digit : Error<
- "invalid digit '%0' in %select{decimal|octal|binary}1 constant">;
-def err_invalid_suffix_constant : Error<
- "invalid suffix '%0' on %select{integer|floating}1 constant">;
-def warn_cxx11_compat_digit_separator : Warning<
- "digit separators are incompatible with C++ standards before C++14">,
- InGroup<CXXPre14Compat>, DefaultIgnore;
-def err_digit_separator_not_between_digits : Error<
- "digit separator cannot appear at %select{start|end}0 of digit sequence">;
-def warn_extraneous_char_constant : Warning<
- "extraneous characters in character constant ignored">;
-def warn_char_constant_too_large : Warning<
- "character constant too long for its type">;
-def err_multichar_utf_character_literal : Error<
- "Unicode character literals may not contain multiple characters">;
-def err_exponent_has_no_digits : Error<"exponent has no digits">;
-def ext_imaginary_constant : Extension<
- "imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>;
-def err_hexconstant_requires: Error<
- "hexadecimal floating constants require %select{an exponent|a significand}0">;
-def ext_hexconstant_invalid : Extension<
- "hexadecimal floating constants are a C99 feature">, InGroup<C99>;
-def ext_binary_literal : Extension<
- "binary integer literals are a GNU extension">, InGroup<GNUBinaryLiteral>;
-def ext_binary_literal_cxx14 : Extension<
- "binary integer literals are a C++14 extension">, InGroup<CXX14BinaryLiteral>;
-def warn_cxx11_compat_binary_literal : Warning<
- "binary integer literals are incompatible with C++ standards before C++14">,
- InGroup<CXXPre14CompatPedantic>, DefaultIgnore;
-def err_pascal_string_too_long : Error<"Pascal string is too long">;
-def err_escape_too_large : Error<
- "%select{hex|octal}0 escape sequence out of range">;
-def ext_string_too_long : Extension<"string literal of length %0 exceeds "
- "maximum length %1 that %select{C90|ISO C99|C++}2 compilers are required to "
- "support">, InGroup<OverlengthStrings>;
-def err_character_too_large : Error<
- "character too large for enclosing character literal type">;
-def warn_c99_compat_unicode_literal : Warning<
- "unicode literals are incompatible with C99">,
- InGroup<C99Compat>, DefaultIgnore;
-def warn_cxx98_compat_unicode_literal : Warning<
- "unicode literals are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx14_compat_u8_character_literal : Warning<
- "unicode literals are incompatible with C++ standards before C++1z">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
-def warn_cxx11_compat_user_defined_literal : Warning<
- "identifier after literal will be treated as a user-defined literal suffix "
- "in C++11">, InGroup<CXX11Compat>, DefaultIgnore;
-def warn_cxx11_compat_reserved_user_defined_literal : Warning<
- "identifier after literal will be treated as a reserved user-defined literal "
- "suffix in C++11">,
- InGroup<CXX11CompatReservedUserDefinedLiteral>, DefaultIgnore;
-def ext_reserved_user_defined_literal : ExtWarn<
- "invalid suffix on literal; C++11 requires a space between literal and "
- "identifier">, InGroup<ReservedUserDefinedLiteral>, DefaultError;
-def ext_ms_reserved_user_defined_literal : ExtWarn<
- "invalid suffix on literal; C++11 requires a space between literal and "
- "identifier">, InGroup<ReservedUserDefinedLiteral>;
-def err_unsupported_string_concat : Error<
- "unsupported non-standard concatenation of string literals">;
-def err_string_concat_mixed_suffix : Error<
- "differing user-defined suffixes ('%0' and '%1') in string literal "
- "concatenation">;
-def err_pp_invalid_udl : Error<
- "%select{character|integer}0 literal with user-defined suffix "
- "cannot be used in preprocessor constant expression">;
-def err_bad_string_encoding : Error<
- "illegal character encoding in string literal">;
-def warn_bad_string_encoding : ExtWarn<
- "illegal character encoding in string literal">,
- InGroup<InvalidSourceEncoding>;
-def err_bad_character_encoding : Error<
- "illegal character encoding in character literal">;
-def warn_bad_character_encoding : ExtWarn<
- "illegal character encoding in character literal">,
- InGroup<InvalidSourceEncoding>;
-def err_lexing_string : Error<"failure when lexing a string">;
-
-
-//===----------------------------------------------------------------------===//
-// PTH Diagnostics
-//===----------------------------------------------------------------------===//
-def err_invalid_pth_file : Error<
- "invalid or corrupt PTH file '%0'">;
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Diagnostics
-//===----------------------------------------------------------------------===//
-
-let CategoryName = "User-Defined Issue" in {
-def pp_hash_warning : Warning<"%0">,
- InGroup<PoundWarning>, ShowInSystemHeader;
-def err_pp_hash_error : Error<"%0">;
-}
-
-def pp_include_next_in_primary : Warning<
- "#include_next in primary source file">,
- InGroup<DiagGroup<"include-next-outside-header">>;
-def pp_include_macros_out_of_predefines : Error<
- "the #__include_macros directive is only for internal use by -imacros">;
-def pp_include_next_absolute_path : Warning<
- "#include_next with absolute path">,
- InGroup<DiagGroup<"include-next-absolute-path">>;
-def ext_c99_whitespace_required_after_macro_name : ExtWarn<
- "ISO C99 requires whitespace after the macro name">, InGroup<C99>;
-def ext_missing_whitespace_after_macro_name : ExtWarn<
- "whitespace required after macro name">;
-def warn_missing_whitespace_after_macro_name : Warning<
- "whitespace recommended after macro name">;
-
-def pp_pragma_once_in_main_file : Warning<"#pragma once in main file">,
- InGroup<DiagGroup<"pragma-once-outside-header">>;
-def pp_pragma_sysheader_in_main_file : Warning<
- "#pragma system_header ignored in main file">,
- InGroup<DiagGroup<"pragma-system-header-outside-header">>;
-def pp_poisoning_existing_macro : Warning<"poisoning existing macro">;
-def pp_out_of_date_dependency : Warning<
- "current file is older than dependency %0">;
-def ext_pp_undef_builtin_macro : ExtWarn<"undefining builtin macro">,
- InGroup<BuiltinMacroRedefined>;
-def ext_pp_redef_builtin_macro : ExtWarn<"redefining builtin macro">,
- InGroup<BuiltinMacroRedefined>;
-def pp_disabled_macro_expansion : Warning<
- "disabled expansion of recursive macro">, DefaultIgnore,
- InGroup<DiagGroup<"disabled-macro-expansion">>;
-def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore,
- InGroup<DiagGroup<"unused-macros">>;
-def warn_pp_undef_identifier : Warning<
- "%0 is not defined, evaluates to 0">,
- InGroup<DiagGroup<"undef">>, DefaultIgnore;
-def warn_pp_ambiguous_macro : Warning<
- "ambiguous expansion of macro %0">, InGroup<AmbiguousMacro>;
-def note_pp_ambiguous_macro_chosen : Note<
- "expanding this definition of %0">;
-def note_pp_ambiguous_macro_other : Note<
- "other definition of %0">;
-def warn_pp_macro_hides_keyword : Extension<
- "keyword is hidden by macro definition">, InGroup<KeywordAsMacro>;
-def warn_pp_macro_is_reserved_id : Warning<
- "macro name is a reserved identifier">, DefaultIgnore,
- InGroup<ReservedIdAsMacro>;
-def warn_pp_objc_macro_redef_ignored : Warning<
- "ignoring redefinition of Objective-C qualifier macro">,
- InGroup<DiagGroup<"objc-macro-redefinition">>;
-
-def pp_invalid_string_literal : Warning<
- "invalid string literal, ignoring final '\\'">;
-def warn_pp_expr_overflow : Warning<
- "integer overflow in preprocessor expression">;
-def warn_pp_convert_to_positive : Warning<
- "%select{left|right}0 side of operator converted from negative value to "
- "unsigned: %1">;
-
-def ext_pp_import_directive : Extension<"#import is a language extension">,
- InGroup<DiagGroup<"import-preprocessor-directive-pedantic">>;
-def err_pp_import_directive_ms : Error<
- "#import of type library is an unsupported Microsoft feature">;
-def ext_pp_include_search_ms : ExtWarn<
- "#include resolved using non-portable Microsoft search rules as: %0">,
- InGroup<MicrosoftInclude>;
-
-def ext_pp_ident_directive : Extension<"#ident is a language extension">;
-def ext_pp_include_next_directive : Extension<
- "#include_next is a language extension">, InGroup<GNUIncludeNext>;
-def ext_pp_warning_directive : Extension<"#warning is a language extension">;
-
-def ext_pp_extra_tokens_at_eol : ExtWarn<
- "extra tokens at end of #%0 directive">, InGroup<ExtraTokens>;
-
-def ext_pp_comma_expr : Extension<"comma operator in operand of #if">;
-def ext_pp_bad_vaargs_use : Extension<
- "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro">;
-def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">, InGroup<MacroRedefined>;
-def ext_variadic_macro : Extension<"variadic macros are a C99 feature">,
- InGroup<VariadicMacros>;
-def warn_cxx98_compat_variadic_macro : Warning<
- "variadic macros are incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def ext_named_variadic_macro : Extension<
- "named variadic macros are a GNU extension">, InGroup<VariadicMacros>;
-def err_embedded_directive : Error<
- "embedding a #%0 directive within macro arguments is not supported">;
-def ext_embedded_directive : Extension<
- "embedding a directive within macro arguments has undefined behavior">,
- InGroup<DiagGroup<"embedded-directive">>;
-def ext_missing_varargs_arg : Extension<
- "must specify at least one argument for '...' parameter of variadic macro">,
- InGroup<GNUZeroVariadicMacroArguments>;
-def ext_empty_fnmacro_arg : Extension<
- "empty macro arguments are a C99 feature">, InGroup<C99>;
-def warn_cxx98_compat_empty_fnmacro_arg : Warning<
- "empty macro arguments are incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def note_macro_here : Note<"macro %0 defined here">;
-
-def err_pp_opencl_variadic_macros :
- Error<"variadic macros not supported in OpenCL">;
-
-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_file_not_found_not_fatal : Error<
- "'%0' file not found with <angled> include; use \"quotes\" instead">;
-def err_pp_error_opening_file : Error<
- "error opening file '%0': %1">, DefaultFatal;
-def err_pp_empty_filename : Error<"empty filename">;
-def err_pp_include_too_deep : Error<"#include nested too deeply">;
-def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">;
-def err_pp_macro_not_identifier : Error<"macro name must be an identifier">;
-def err_pp_missing_macro_name : Error<"macro name missing">;
-def err_pp_missing_rparen_in_macro_def : Error<
- "missing ')' in macro parameter list">;
-def err_pp_invalid_tok_in_arg_list : Error<
- "invalid token in macro parameter list">;
-def err_pp_expected_ident_in_arg_list : Error<
- "expected identifier in macro parameter list">;
-def err_pp_expected_comma_in_arg_list : Error<
- "expected comma in macro parameter list">;
-def err_pp_duplicate_name_in_arg_list : Error<
- "duplicate macro parameter name %0">;
-def err_pp_stringize_not_parameter : Error<
- "'#' is not followed by a macro parameter">;
-def err_pp_malformed_ident : Error<"invalid #ident directive">;
-def err_pp_unterminated_conditional : Error<
- "unterminated conditional directive">;
-def pp_err_else_after_else : Error<"#else after #else">;
-def pp_err_elif_after_else : Error<"#elif after #else">;
-def pp_err_else_without_if : Error<"#else without #if">;
-def pp_err_elif_without_if : Error<"#elif without #if">;
-def err_pp_endif_without_if : Error<"#endif without #if">;
-def err_pp_expected_value_in_expr : Error<"expected value in expression">;
-def err_pp_expected_rparen : Error<"expected ')' in preprocessor expression">;
-def err_pp_expected_eol : Error<
- "expected end of line in preprocessor expression">;
-def err_pp_expected_after : Error<"missing %1 after %0">;
-def err_pp_colon_without_question : Error<"':' without preceding '?'">;
-def err_pp_division_by_zero : Error<
- "division by zero in preprocessor expression">;
-def err_pp_remainder_by_zero : Error<
- "remainder by zero in preprocessor expression">;
-def err_pp_expr_bad_token_binop : Error<
- "token is not a valid binary operator in a preprocessor subexpression">;
-def err_pp_expr_bad_token_start_expr : Error<
- "invalid token at start of a preprocessor expression">;
-def err_pp_invalid_poison : Error<"can only poison identifier tokens">;
-def err_pp_used_poisoned_id : Error<"attempt to use a poisoned identifier">;
-
-def err_feature_check_malformed : Error<
- "builtin feature check macro requires a parenthesized identifier">;
-
-def err_warning_check_malformed : Error<
- "builtin warning check macro requires a parenthesized string">;
-def warn_has_warning_invalid_option :
- ExtWarn<"__has_warning expected option name (e.g. \"-Wundef\")">,
- InGroup<MalformedWarningCheck>;
-
-def err_pp_identifier_arg_not_identifier : Error<
- "cannot convert %0 token to an identifier">;
-
-def warn_pragma_include_alias_mismatch_angle :
- ExtWarn<"angle-bracketed include <%0> cannot be aliased to double-quoted "
- "include \"%1\"">, InGroup<UnknownPragmas>;
-def warn_pragma_include_alias_mismatch_quote :
- ExtWarn<"double-quoted include \"%0\" cannot be aliased to angle-bracketed "
- "include <%1>">, InGroup<UnknownPragmas>;
-def warn_pragma_include_alias_expected :
- ExtWarn<"pragma include_alias expected '%0'">,
- InGroup<UnknownPragmas>;
-def warn_pragma_include_alias_expected_filename :
- ExtWarn<"pragma include_alias expected include filename">,
- InGroup<UnknownPragmas>;
-
-// - #pragma warning(...)
-def warn_pragma_warning_expected :
- ExtWarn<"#pragma warning expected '%0'">,
- InGroup<UnknownPragmas>;
-def warn_pragma_warning_spec_invalid :
- ExtWarn<"#pragma warning expected 'push', 'pop', 'default', 'disable',"
- " 'error', 'once', 'suppress', 1, 2, 3, or 4">,
- InGroup<UnknownPragmas>;
-def warn_pragma_warning_push_level :
- ExtWarn<"#pragma warning(push, level) requires a level between 0 and 4">,
- InGroup<UnknownPragmas>;
-def warn_pragma_warning_expected_number :
- ExtWarn<"#pragma warning expected a warning number">,
- InGroup<UnknownPragmas>;
-
-def err__Pragma_malformed : Error<
- "_Pragma takes a parenthesized string literal">;
-def err_pragma_message_malformed : Error<
- "pragma %select{message|warning|error}0 requires parenthesized string">;
-def err_pragma_push_pop_macro_malformed : Error<
- "pragma %0 requires a parenthesized string">;
-def warn_pragma_pop_macro_no_push : Warning<
- "pragma pop_macro could not pop '%0', no matching push_macro">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_message : Warning<"%0">,
- InGroup<PoundPragmaMessage>, DefaultWarnNoWerror;
-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'">,
- InGroup<UnknownPragmas>;
-def warn_pragma_diagnostic_cannot_pop :
- ExtWarn<"pragma diagnostic pop could not pop, no matching push">,
- InGroup<UnknownPragmas>;
-def warn_pragma_diagnostic_invalid_option :
- ExtWarn<"pragma diagnostic expected option name (e.g. \"-Wundef\")">,
- InGroup<UnknownPragmas>;
-def warn_pragma_diagnostic_invalid_token :
- ExtWarn<"unexpected token in pragma diagnostic">,
- InGroup<UnknownPragmas>;
-def warn_pragma_diagnostic_unknown_warning :
- ExtWarn<"unknown warning group '%0', ignored">,
- InGroup<UnknownPragmas>;
-// - #pragma __debug
-def warn_pragma_debug_unexpected_command : Warning<
- "unexpected debug command '%0'">, InGroup<IgnoredPragmas>;
-
-def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
-def err_paste_at_start : Error<
- "'##' cannot appear at start of macro expansion">;
-def err_paste_at_end : Error<"'##' cannot appear at end of macro expansion">;
-def ext_paste_comma : Extension<
- "token pasting of ',' and __VA_ARGS__ is a GNU extension">, InGroup<GNUZeroVariadicMacroArguments>;
-def err_unterm_macro_invoc : Error<
- "unterminated function-like macro invocation">;
-def err_too_many_args_in_macro_invoc : Error<
- "too many arguments provided to function-like macro invocation">;
-def note_suggest_parens_for_macro : Note<
- "parentheses are required around macro argument containing braced "
- "initializer list">;
-def note_init_list_at_beginning_of_macro_argument : Note<
- "cannot use initializer list at the beginning of a macro argument">;
-def err_too_few_args_in_macro_invoc : Error<
- "too few arguments provided to function-like macro invocation">;
-def err_pp_bad_paste : Error<
- "pasting formed '%0', an invalid preprocessing token">;
-def ext_pp_bad_paste_ms : ExtWarn<
- "pasting formed '%0', an invalid preprocessing token">, DefaultError,
- InGroup<DiagGroup<"invalid-token-paste">>;
-def err_pp_operator_used_as_macro_name : Error<
- "C++ operator %0 (aka %1) used as a macro name">;
-def ext_pp_operator_used_as_macro_name : Extension<
- err_pp_operator_used_as_macro_name.Text>, InGroup<MicrosoftCppMacro>;
-def err_pp_illegal_floating_literal : Error<
- "floating point literal in preprocessor expression">;
-def err_pp_line_requires_integer : Error<
- "#line directive requires a positive integer argument">;
-def ext_pp_line_zero : Extension<
- "#line directive with zero argument is a GNU extension">,
- InGroup<GNUZeroLineDirective>;
-def err_pp_line_invalid_filename : Error<
- "invalid filename for #line directive">;
-def warn_pp_line_decimal : Warning<
- "%select{#line|GNU line marker}0 directive interprets number as decimal, not octal">;
-def err_pp_line_digit_sequence : Error<
- "%select{#line|GNU line marker}0 directive requires a simple digit sequence">;
-def err_pp_linemarker_requires_integer : Error<
- "line marker directive requires a positive integer argument">;
-def err_pp_linemarker_invalid_filename : Error<
- "invalid filename for line marker directive">;
-def err_pp_linemarker_invalid_flag : Error<
- "invalid flag line marker directive">;
-def err_pp_linemarker_invalid_pop : Error<
- "invalid line marker flag '2': cannot pop empty include stack">;
-def ext_pp_line_too_big : Extension<
- "C requires #line number to be less than %0, allowed as extension">;
-def warn_cxx98_compat_pp_line_too_big : Warning<
- "#line number greater than 32767 is incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-
-def err_pp_visibility_non_macro : Error<"no macro named %0">;
-
-def err_pp_arc_cf_code_audited_syntax : Error<"expected 'begin' or 'end'">;
-def err_pp_double_begin_of_arc_cf_code_audited : Error<
- "already inside '#pragma clang arc_cf_code_audited'">;
-def err_pp_unmatched_end_of_arc_cf_code_audited : Error<
- "not currently inside '#pragma clang arc_cf_code_audited'">;
-def err_pp_include_in_arc_cf_code_audited : Error<
- "cannot #include files inside '#pragma clang arc_cf_code_audited'">;
-def err_pp_eof_in_arc_cf_code_audited : Error<
- "'#pragma clang arc_cf_code_audited' was not ended within this file">;
-
-def warn_pp_date_time : Warning<
- "expansion of date or time macro is not reproducible">,
- ShowInSystemHeader, DefaultIgnore, InGroup<DiagGroup<"date-time">>;
-
-// Module map parsing
-def err_mmap_unknown_token : Error<"skipping stray token">;
-def err_mmap_expected_module : Error<"expected module declaration">;
-def err_mmap_expected_module_name : Error<"expected module name">;
-def err_mmap_expected_lbrace : Error<"expected '{' to start module '%0'">;
-def err_mmap_expected_rbrace : Error<"expected '}'">;
-def note_mmap_lbrace_match : Note<"to match this '{'">;
-def err_mmap_expected_rsquare : Error<"expected ']' to close attribute">;
-def note_mmap_lsquare_match : Note<"to match this ']'">;
-def err_mmap_expected_member : Error<
- "expected umbrella, header, submodule, or module export">;
-def err_mmap_expected_header : Error<"expected a header name after '%0'">;
-def err_mmap_expected_mmap_file : Error<"expected a module map file name">;
-def err_mmap_module_redefinition : Error<
- "redefinition of module '%0'">;
-def note_mmap_prev_definition : Note<"previously defined here">;
-def err_mmap_umbrella_dir_not_found : Error<
- "umbrella directory '%0' not found">;
-def err_mmap_umbrella_clash : Error<
- "umbrella for module '%0' already covers this directory">;
-def err_mmap_module_id : Error<
- "expected a module name or '*'">;
-def err_mmap_expected_library_name : Error<
- "expected %select{library|framework}0 name as a string">;
-def err_mmap_config_macro_submodule : Error<
- "configuration macros are only allowed in top-level modules">;
-def err_mmap_use_decl_submodule : Error<
- "use declarations are only allowed in top-level modules">;
-def err_mmap_expected_config_macro : Error<
- "expected configuration macro name after ','">;
-def err_mmap_expected_conflicts_comma : Error<
- "expected ',' after conflicting module name">;
-def err_mmap_expected_conflicts_message : Error<
- "expected a message describing the conflict with '%0'">;
-def err_mmap_missing_module_unqualified : Error<
- "no module named '%0' visible from '%1'">;
-def err_mmap_missing_module_qualified : Error<
- "no module named '%0' in '%1'">;
-def err_mmap_top_level_inferred_submodule : Error<
- "only submodules and framework modules may be inferred with wildcard syntax">;
-def err_mmap_inferred_no_umbrella : Error<
- "inferred submodules require a module with an umbrella">;
-def err_mmap_inferred_framework_submodule : Error<
- "inferred submodule cannot be a framework submodule">;
-def err_mmap_explicit_inferred_framework : Error<
- "inferred framework modules cannot be 'explicit'">;
-def err_mmap_missing_exclude_name : Error<
- "expected excluded module name">;
-def err_mmap_inferred_redef : Error<
- "redefinition of inferred submodule">;
-def err_mmap_expected_lbrace_wildcard : Error<
- "expected '{' to start inferred submodule">;
-def err_mmap_expected_inferred_member : Error<
- "expected %select{module exclusion with 'exclude'|'export *'}0">;
-def err_mmap_expected_export_wildcard : Error<
- "only '*' can be exported from an inferred submodule">;
-def err_mmap_explicit_top_level : Error<
- "'explicit' is not permitted on top-level modules">;
-def err_mmap_nested_submodule_id : Error<
- "qualified module name can only be used to define modules at the top level">;
-def err_mmap_expected_feature : Error<"expected a feature name">;
-def err_mmap_expected_attribute : Error<"expected an attribute name">;
-def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">,
- InGroup<IgnoredAttributes>;
-
-def warn_auto_module_import : Warning<
- "treating #%select{include|import|include_next|__include_macros}0 as an "
- "import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
-def note_implicit_top_level_module_import_here : Note<
- "submodule of top-level module '%0' implicitly imported here">;
-def warn_uncovered_module_header : Warning<
- "umbrella header for module '%0' does not include header '%1'">,
- InGroup<IncompleteUmbrella>;
-def err_expected_id_building_module : Error<
- "expected a module name in '__building_module' expression">;
-def warn_use_of_private_header_outside_module : Warning<
- "use of private header from outside its module: '%0'">,
- InGroup<DiagGroup<"private-header">>, DefaultError;
-def err_undeclared_use_of_module : Error<
- "module %0 does not depend on a module exporting '%1'">;
-def warn_non_modular_include_in_framework_module : Warning<
- "include of non-modular header inside framework module '%0'">,
- InGroup<NonModularIncludeInFrameworkModule>, DefaultIgnore;
-def warn_non_modular_include_in_module : Warning<
- "include of non-modular header inside module '%0'">,
- InGroup<NonModularIncludeInModule>, DefaultIgnore;
-def warn_module_conflict : Warning<
- "module '%0' conflicts with already-imported module '%1': %2">,
- InGroup<ModuleConflict>;
-
-def warn_header_guard : Warning<
- "%0 is used as a header guard here, followed by #define of a different macro">,
- InGroup<DiagGroup<"header-guard">>;
-def note_header_guard : Note<
- "%0 is defined here; did you mean %1?">;
-
-let CategoryName = "Nullability Issue" in {
-
-def err_pp_assume_nonnull_syntax : Error<"expected 'begin' or 'end'">;
-def err_pp_double_begin_of_assume_nonnull : Error<
- "already inside '#pragma clang assume_nonnull'">;
-def err_pp_unmatched_end_of_assume_nonnull : Error<
- "not currently inside '#pragma clang assume_nonnull'">;
-def err_pp_include_in_assume_nonnull : Error<
- "cannot #include files inside '#pragma clang assume_nonnull'">;
-def err_pp_eof_in_assume_nonnull : Error<
- "'#pragma clang assume_nonnull' was not ended within this file">;
-
-}
-
-}
diff --git a/include/clang/Basic/DiagnosticOptions.def b/include/clang/Basic/DiagnosticOptions.def
deleted file mode 100644
index f4ba6da..0000000
--- a/include/clang/Basic/DiagnosticOptions.def
+++ /dev/null
@@ -1,99 +0,0 @@
-//===--- DiagOptions.def - Diagnostic option 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 the diagnostic options. Users of this file
-// must define the DIAGOPT macro to make use of this information.
-// Optionally, the user may also define ENUM_DIAGOPT (for options
-// that have enumeration type and VALUE_DIAGOPT (for options that
-// describe a value rather than a flag). The SEMANTIC_* variants of these macros
-// indicate options that affect the processing of the program, rather than
-// simply the output.
-//
-//===----------------------------------------------------------------------===//
-#ifndef DIAGOPT
-# error Define the DIAGOPT macro to handle language options
-#endif
-
-#ifndef VALUE_DIAGOPT
-# define VALUE_DIAGOPT(Name, Bits, Default) \
-DIAGOPT(Name, Bits, Default)
-#endif
-
-#ifndef ENUM_DIAGOPT
-# define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-DIAGOPT(Name, Bits, Default)
-#endif
-
-#ifndef SEMANTIC_DIAGOPT
-# define SEMANTIC_DIAGOPT(Name, Bits, Default) DIAGOPT(Name, Bits, Default)
-#endif
-
-#ifndef SEMANTIC_VALUE_DIAGOPT
-# define SEMANTIC_VALUE_DIAGOPT(Name, Bits, Default) \
- VALUE_DIAGOPT(Name, Bits, Default)
-#endif
-
-#ifndef SEMANTIC_ENUM_DIAGOPT
-# define SEMANTIC_ENUM_DIAGOPT(Name, Type, Bits, Default) \
- ENUM_DIAGOPT(Name, Type, Bits, Default)
-#endif
-
-SEMANTIC_DIAGOPT(IgnoreWarnings, 1, 0) /// -w
-DIAGOPT(NoRewriteMacros, 1, 0) /// -Wno-rewrite-macros
-DIAGOPT(Pedantic, 1, 0) /// -pedantic
-DIAGOPT(PedanticErrors, 1, 0) /// -pedantic-errors
-DIAGOPT(ShowColumn, 1, 1) /// Show column number on diagnostics.
-DIAGOPT(ShowLocation, 1, 1) /// Show source location information.
-DIAGOPT(ShowCarets, 1, 1) /// Show carets in diagnostics.
-DIAGOPT(ShowFixits, 1, 1) /// Show fixit information.
-DIAGOPT(ShowSourceRanges, 1, 0) /// Show source ranges in numeric form.
-DIAGOPT(ShowParseableFixits, 1, 0) /// Show machine parseable fix-its.
-DIAGOPT(ShowPresumedLoc, 1, 0) /// Show presumed location for diagnostics.
-DIAGOPT(ShowOptionNames, 1, 0) /// Show the option name for mappable
- /// diagnostics.
-DIAGOPT(ShowNoteIncludeStack, 1, 0) /// Show include stacks for notes.
-VALUE_DIAGOPT(ShowCategories, 2, 0) /// Show categories: 0 -> none, 1 -> Number,
- /// 2 -> Full Name.
-
-ENUM_DIAGOPT(Format, TextDiagnosticFormat, 2, Clang) /// Format for diagnostics:
-
-DIAGOPT(ShowColors, 1, 0) /// Show diagnostics with ANSI color sequences.
-ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1,
- Ovl_All) /// Overload candidates to show.
-DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected
- /// diagnostics, indicated by markers in the
- /// input source file.
-ENUM_DIAGOPT(VerifyIgnoreUnexpected, DiagnosticLevelMask, 4,
- DiagnosticLevelMask::None) /// Ignore unexpected diagnostics of
- /// the specified levels when using
- /// -verify.
-DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing
-DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing
-DIAGOPT(CLFallbackMode, 1, 0) /// Format for clang-cl fallback mode
-
-VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted.
-/// Limit depth of macro expansion backtrace.
-VALUE_DIAGOPT(MacroBacktraceLimit, 32, DefaultMacroBacktraceLimit)
-/// Limit depth of instantiation backtrace.
-VALUE_DIAGOPT(TemplateBacktraceLimit, 32, DefaultTemplateBacktraceLimit)
-/// Limit depth of constexpr backtrace.
-VALUE_DIAGOPT(ConstexprBacktraceLimit, 32, DefaultConstexprBacktraceLimit)
-/// Limit number of times to perform spell checking.
-VALUE_DIAGOPT(SpellCheckingLimit, 32, DefaultSpellCheckingLimit)
-
-VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops.
-/// Column limit for formatting message diagnostics, or 0 if unused.
-VALUE_DIAGOPT(MessageLength, 32, 0)
-
-#undef DIAGOPT
-#undef ENUM_DIAGOPT
-#undef VALUE_DIAGOPT
-#undef SEMANTIC_DIAGOPT
-#undef SEMANTIC_ENUM_DIAGOPT
-#undef SEMANTIC_VALUE_DIAGOPT
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
deleted file mode 100644
index c9b0c5d..0000000
--- a/include/clang/Basic/DiagnosticOptions.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//===--- DiagnosticOptions.h ------------------------------------*- 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_BASIC_DIAGNOSTICOPTIONS_H
-#define LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include <string>
-#include <type_traits>
-#include <vector>
-
-namespace clang {
-
-/// \brief 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.
-};
-
-/// \brief A bitmask representing the diagnostic levels used by
-/// VerifyDiagnosticConsumer.
-enum class DiagnosticLevelMask : unsigned {
- None = 0,
- Note = 1 << 0,
- Remark = 1 << 1,
- Warning = 1 << 2,
- Error = 1 << 3,
- All = Note | Remark | Warning | Error
-};
-
-inline DiagnosticLevelMask operator~(DiagnosticLevelMask M) {
- using UT = std::underlying_type<DiagnosticLevelMask>::type;
- return static_cast<DiagnosticLevelMask>(~static_cast<UT>(M));
-}
-
-inline DiagnosticLevelMask operator|(DiagnosticLevelMask LHS,
- DiagnosticLevelMask RHS) {
- using UT = std::underlying_type<DiagnosticLevelMask>::type;
- return static_cast<DiagnosticLevelMask>(
- static_cast<UT>(LHS) | static_cast<UT>(RHS));
-}
-
-inline DiagnosticLevelMask operator&(DiagnosticLevelMask LHS,
- DiagnosticLevelMask RHS) {
- using UT = std::underlying_type<DiagnosticLevelMask>::type;
- return static_cast<DiagnosticLevelMask>(
- static_cast<UT>(LHS) & static_cast<UT>(RHS));
-}
-
-raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M);
-
-/// \brief Options for controlling the compiler diagnostics engine.
-class DiagnosticOptions : public RefCountedBase<DiagnosticOptions>{
-public:
- enum TextDiagnosticFormat { Clang, MSVC, Vi };
-
- // Default values.
- enum { DefaultTabStop = 8, MaxTabStop = 100,
- DefaultMacroBacktraceLimit = 6,
- DefaultTemplateBacktraceLimit = 10,
- DefaultConstexprBacktraceLimit = 10,
- DefaultSpellCheckingLimit = 50 };
-
- // Define simple diagnostic options (with no accessors).
-#define DIAGOPT(Name, Bits, Default) unsigned Name : Bits;
-#define ENUM_DIAGOPT(Name, Type, Bits, Default)
-#include "clang/Basic/DiagnosticOptions.def"
-
-protected:
- // Define diagnostic options of enumeration type. These are private, and will
- // have accessors (below).
-#define DIAGOPT(Name, Bits, Default)
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) unsigned Name : Bits;
-#include "clang/Basic/DiagnosticOptions.def"
-
-public:
- /// \brief The file to log diagnostic output to.
- std::string DiagnosticLogFile;
-
- /// \brief The file to serialize diagnostics to (non-appending).
- std::string DiagnosticSerializationFile;
-
- /// The list of -W... options used to alter the diagnostic mappings, with the
- /// prefixes removed.
- std::vector<std::string> Warnings;
-
- /// The list of -R... options used to alter the diagnostic mappings, with the
- /// prefixes removed.
- std::vector<std::string> Remarks;
-
-public:
- // Define accessors/mutators for diagnostic options of enumeration type.
-#define DIAGOPT(Name, Bits, Default)
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
- Type get##Name() const { return static_cast<Type>(Name); } \
- void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
-#include "clang/Basic/DiagnosticOptions.def"
-
- DiagnosticOptions() {
-#define DIAGOPT(Name, Bits, Default) Name = Default;
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) set##Name(Default);
-#include "clang/Basic/DiagnosticOptions.def"
- }
-};
-
-typedef DiagnosticOptions::TextDiagnosticFormat TextDiagnosticFormat;
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
deleted file mode 100644
index f8dee2f..0000000
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ /dev/null
@@ -1,985 +0,0 @@
-//==--- DiagnosticParseKinds.td - libparse diagnostics --------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Parser Diagnostics
-//===----------------------------------------------------------------------===//
-
-let Component = "Parse" in {
-
-def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">,
- CatInlineAsm;
-def warn_file_asm_volatile : Warning<
- "meaningless 'volatile' on asm outside function">, CatInlineAsm;
-
-let CategoryName = "Inline Assembly Issue" in {
-def err_asm_empty : Error<"__asm used with no assembly instructions">;
-def err_inline_ms_asm_parsing : Error<"%0">;
-def err_msasm_unsupported_arch : Error<
- "Unsupported architecture '%0' for MS-style inline assembly">;
-def err_msasm_unable_to_create_target : Error<
- "MS-style inline assembly is not available: %0">;
-def err_gnu_inline_asm_disabled : Error<
- "GNU-style inline assembly is disabled">;
-}
-
-let CategoryName = "Parse Issue" in {
-
-def ext_empty_translation_unit : Extension<
- "ISO C requires a translation unit to contain at least one declaration">,
- 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;
-def ext_extra_semi : Extension<
- "extra ';' %select{"
- "outside of a function|"
- "inside a %1|"
- "inside instance variable list|"
- "after member function definition}0">,
- InGroup<ExtraSemi>;
-def ext_extra_semi_cxx11 : Extension<
- "extra ';' outside of a function is a C++11 extension">,
- InGroup<CXX11ExtraSemi>;
-def warn_extra_semi_after_mem_fn_def : Warning<
- "extra ';' after member function definition">,
- InGroup<ExtraSemi>, DefaultIgnore;
-
-def ext_thread_before : Extension<"'__thread' before '%0'">;
-def ext_keyword_as_ident : ExtWarn<
- "keyword '%0' will be made available as an identifier "
- "%select{here|for the remainder of the translation unit}1">,
- InGroup<KeywordCompat>;
-
-def ext_nullability : Extension<
- "type nullability specifier %0 is a Clang extension">,
- InGroup<DiagGroup<"nullability-extension">>;
-
-def error_empty_enum : Error<"use of empty enum">;
-
-def ext_ident_list_in_param : Extension<
- "type-less parameter names in function declaration">;
-def ext_c99_variable_decl_in_for_loop : Extension<
- "variable declaration in for loop is a C99-specific feature">, InGroup<C99>;
-def ext_c99_compound_literal : Extension<
- "compound literals are a C99-specific feature">, InGroup<C99>;
-def ext_enumerator_list_comma_c : Extension<
- "commas at the end of enumerator lists are a C99-specific "
- "feature">, InGroup<C99>;
-def ext_enumerator_list_comma_cxx : Extension<
- "commas at the end of enumerator lists are a C++11 extension">,
- InGroup<CXX11>;
-def warn_cxx98_compat_enumerator_list_comma : Warning<
- "commas at the end of enumerator lists are incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def err_enumerator_list_missing_comma : Error<
- "missing ',' between enumerators">;
-def err_enumerator_unnamed_no_def : Error<
- "unnamed enumeration must be a definition">;
-def ext_cxx11_enum_fixed_underlying_type : Extension<
- "enumeration types with a fixed underlying type are a C++11 extension">,
- InGroup<CXX11>;
-def ext_c_enum_fixed_underlying_type : Extension<
- "enumeration types with a fixed underlying type are a Microsoft extension">,
- InGroup<MicrosoftFixedEnum>;
-def warn_cxx98_compat_enum_fixed_underlying_type : Warning<
- "enumeration types with a fixed underlying type are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx98_compat_alignof : Warning<
- "alignof expressions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_alignof_expr : ExtWarn<
- "%0 applied to an expression is a GNU extension">, InGroup<GNUAlignofExpression>;
-
-def warn_microsoft_dependent_exists : Warning<
- "dependent %select{__if_not_exists|__if_exists}0 declarations are ignored">,
- InGroup<DiagGroup<"microsoft-exists">>;
-def warn_microsoft_qualifiers_ignored : Warning<
- "qualifiers after comma in declarator list are ignored">,
- InGroup<IgnoredAttributes>;
-
-def ext_c11_generic_selection : Extension<
- "generic selections are a C11-specific feature">, InGroup<C11>;
-def err_duplicate_default_assoc : Error<
- "duplicate default generic association">;
-def note_previous_default_assoc : Note<
- "previous default generic association is here">;
-
-def ext_c11_alignment : Extension<
- "%0 is a C11-specific feature">, InGroup<C11>;
-
-def ext_c11_noreturn : Extension<
- "_Noreturn functions are a C11-specific feature">, InGroup<C11>;
-def err_c11_noreturn_misplaced : Error<
- "'_Noreturn' keyword must precede function declarator">;
-
-def ext_gnu_indirect_goto : Extension<
- "use of GNU indirect-goto extension">, InGroup<GNULabelsAsValue>;
-def ext_gnu_address_of_label : Extension<
- "use of GNU address-of-label extension">, InGroup<GNULabelsAsValue>;
-def err_stmtexpr_file_scope : Error<
- "statement expression not allowed at file scope">;
-def ext_gnu_statement_expr : Extension<
- "use of GNU statement expression extension">, InGroup<GNUStatementExpression>;
-def ext_gnu_conditional_expr : Extension<
- "use of GNU ?: conditional expression extension, omitting middle operand">, InGroup<GNUConditionalOmittedOperand>;
-def ext_gnu_empty_initializer : Extension<
- "use of GNU empty initializer extension">, InGroup<GNUEmptyInitializer>;
-def ext_gnu_array_range : Extension<"use of GNU array range extension">,
- InGroup<GNUDesignator>;
-def ext_gnu_missing_equal_designator : ExtWarn<
- "use of GNU 'missing =' extension in designator">,
- InGroup<GNUDesignator>;
-def err_expected_equal_designator : Error<"expected '=' or another designator">;
-def ext_gnu_old_style_field_designator : ExtWarn<
- "use of GNU old-style field designator extension">,
- InGroup<GNUDesignator>;
-def ext_gnu_case_range : Extension<"use of GNU case range extension">,
- InGroup<GNUCaseRange>;
-
-// Generic errors.
-def err_expected_expression : Error<"expected expression">;
-def err_expected_type : Error<"expected a type">;
-def err_expected_external_declaration : Error<"expected external declaration">;
-def err_extraneous_closing_brace : Error<"extraneous closing brace ('}')">;
-def err_expected_semi_declaration : Error<
- "expected ';' at end of declaration">;
-def err_expected_semi_decl_list : Error<
- "expected ';' at end of declaration list">;
-def ext_expected_semi_decl_list : ExtWarn<
- "expected ';' at end of declaration list">;
-def err_expected_member_name_or_semi : Error<
- "expected member name or ';' after declaration specifiers">;
-def err_function_declared_typedef : Error<
- "function definition declared 'typedef'">;
-def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">;
-def err_at_in_class : Error<"unexpected '@' in member specification">;
-def err_unexpected_semi : Error<"unexpected ';' before %0">;
-
-def err_expected_fn_body : Error<
- "expected function body after function declarator">;
-def warn_attribute_on_function_definition : Warning<
- "GCC does not allow %0 attribute in this position on a function definition">,
- InGroup<GccCompat>;
-def warn_gcc_attribute_location : Warning<
- "GCC does not allow an attribute in this position on a function declaration">,
- InGroup<GccCompat>;
-def warn_attribute_no_decl : Warning<
- "attribute %0 ignored, because it is not attached to a declaration">,
- InGroup<IgnoredAttributes>;
-def err_expected_method_body : Error<"expected method body">;
-def err_declspec_after_virtspec : Error<
- "'%0' qualifier may not appear after the virtual specifier '%1'">;
-def err_invalid_token_after_toplevel_declarator : Error<
- "expected ';' after top level declarator">;
-def err_invalid_token_after_declarator_suggest_equal : Error<
- "invalid %0 at end of declaration; did you mean '='?">;
-def err_expected_statement : Error<"expected statement">;
-def err_expected_lparen_after : Error<"expected '(' after '%0'">;
-def err_expected_rparen_after : Error<"expected ')' after '%0'">;
-def err_expected_punc : Error<"expected ')' or ',' after '%0'">;
-def err_expected_less_after : Error<"expected '<' after '%0'">;
-def err_expected_lbrace_in_compound_literal : Error<
- "expected '{' in compound literal">;
-def err_expected_while : Error<"expected 'while' in do/while loop">;
-
-def err_expected_semi_after_stmt : Error<"expected ';' after %0 statement">;
-def err_expected_semi_after_expr : Error<"expected ';' after expression">;
-def err_extraneous_token_before_semi : Error<"extraneous '%0' before ';'">;
-
-def err_expected_semi_after_method_proto : Error<
- "expected ';' after method prototype">;
-def err_expected_semi_after_namespace_name : Error<
- "expected ';' after namespace name">;
-def err_unexpected_namespace_attributes_alias : Error<
- "attributes cannot be specified on namespace alias">;
-def err_unexpected_nested_namespace_attribute : Error<
- "attributes cannot be specified on a nested namespace definition">;
-def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
-def err_namespace_nonnamespace_scope : Error<
- "namespaces can only be defined in global or namespace scope">;
-def ext_nested_namespace_definition : ExtWarn<
- "nested namespace definition is a C++1z extension; "
- "define each namespace separately">, InGroup<CXX1z>;
-def warn_cxx14_compat_nested_namespace_definition : Warning<
- "nested namespace definition is incompatible with C++ standards before C++1z">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
-def err_inline_nested_namespace_definition : Error<
- "nested namespace definition cannot be 'inline'">;
-def err_expected_semi_after_attribute_list : Error<
- "expected ';' after attribute list">;
-def err_expected_semi_after_static_assert : Error<
- "expected ';' after static_assert">;
-def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
-def err_single_decl_assign_in_for_range : Error<
- "range-based 'for' statement uses ':', not '='">;
-def warn_missing_selector_name : Warning<
- "%0 used as the name of the previous parameter rather than as part "
- "of the selector">,
- InGroup<DiagGroup<"missing-selector-name">>;
-def note_missing_selector_name : Note<
- "introduce a parameter name to make %0 part of the selector">;
-def note_force_empty_selector_name : Note<
- "or insert whitespace before ':' to use %0 as parameter name "
- "and have an empty entry in the selector">;
-def err_label_end_of_compound_statement : Error<
- "label at end of compound statement: expected statement">;
-def err_address_of_label_outside_fn : Error<
- "use of address-of-label extension outside of a function body">;
-def err_asm_operand_wide_string_literal : Error<
- "cannot use %select{unicode|wide}0 string literal in 'asm'">;
-def err_expected_selector_for_method : Error<
- "expected selector for Objective-C method">;
-def err_expected_property_name : Error<"expected property name">;
-
-def err_unexpected_at : Error<"unexpected '@' in program">;
-def err_atimport : Error<
-"use of '@import' when modules are disabled">;
-
-def err_invalid_reference_qualifier_application : Error<
- "'%0' qualifier may not be applied to a reference">;
-def err_illegal_decl_reference_to_reference : Error<
- "%0 declared as a reference to a reference">;
-def ext_rvalue_reference : ExtWarn<
- "rvalue references are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_rvalue_reference : Warning<
- "rvalue references are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_ref_qualifier : ExtWarn<
- "reference qualifiers on functions are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_ref_qualifier : Warning<
- "reference qualifiers on functions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_inline_namespace : ExtWarn<
- "inline namespaces are a C++11 feature">, InGroup<CXX11InlineNamespace>;
-def warn_cxx98_compat_inline_namespace : Warning<
- "inline namespaces are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_generalized_initializer_lists : ExtWarn<
- "generalized initializer lists are a C++11 extension">,
- InGroup<CXX11>;
-def warn_cxx98_compat_generalized_initializer_lists : Warning<
- "generalized initializer lists are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_init_list_bin_op : Error<"initializer list cannot be used on the "
- "%select{left|right}0 hand side of operator '%1'">;
-def warn_cxx98_compat_trailing_return_type : Warning<
- "trailing return types are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_auto_storage_class : ExtWarn<
- "'auto' storage class specifier is not permitted in C++11, and will not "
- "be supported in future releases">, InGroup<DiagGroup<"auto-storage-class">>;
-def ext_decltype_auto_type_specifier : ExtWarn<
- "'decltype(auto)' type specifier is a C++14 extension">, InGroup<CXX14>;
-def warn_cxx11_compat_decltype_auto_type_specifier : Warning<
- "'decltype(auto)' type specifier is incompatible with C++ standards before "
- "C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
-def ext_auto_type : Extension<
- "'__auto_type' is a GNU extension">,
- InGroup<GNUAutoType>;
-def ext_for_range : ExtWarn<
- "range-based for loop is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_for_range : Warning<
- "range-based for loop is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_for_range_identifier : Error<
- "range-based for loop requires type for loop variable">;
-def err_for_range_expected_decl : Error<
- "for range declaration must declare a variable">;
-def err_argument_required_after_attribute : Error<
- "argument required after attribute">;
-def err_missing_param : Error<"expected parameter declarator">;
-def err_missing_comma_before_ellipsis : Error<
- "C requires a comma prior to the ellipsis in a variadic function type">;
-def err_unexpected_typedef_ident : Error<
- "unexpected type name %0: expected identifier">;
-def warn_cxx98_compat_decltype : Warning<
- "'decltype' type specifier is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_unexpected_scope_on_base_decltype : Error<
- "unexpected namespace scope prior to decltype">;
-def err_expected_class_name : Error<"expected class name">;
-def err_expected_class_name_not_template :
- Error<"'typename' is redundant; base classes are implicitly types">;
-def err_unspecified_vla_size_with_static : Error<
- "'static' may not be used with an unspecified variable length array size">;
-def err_unspecified_size_with_static : Error<
- "'static' may not be used without an array size">;
-def err_expected_parentheses_around_typename : Error<
- "expected parentheses around type name in %0 expression">;
-
-def err_expected_case_before_expression: Error<
- "expected 'case' keyword before expression">;
-
-// Declarations.
-def err_typename_requires_specqual : Error<
- "type name requires a specifier or qualifier">;
-def err_typename_invalid_storageclass : Error<
- "type name does not allow storage class to be specified">;
-def err_typename_invalid_functionspec : Error<
- "type name does not allow function specifier to be specified">;
-def err_typename_invalid_constexpr : Error<
- "type name does not allow constexpr specifier to be specified">;
-def err_typename_identifiers_only : Error<
- "typename is allowed for identifiers only">;
-
-def err_friend_invalid_in_context : Error<
- "'friend' used outside of class">;
-def err_templated_using_directive_declaration : Error<
- "cannot template a using %select{directive|declaration}0">;
-def err_unexpected_colon_in_nested_name_spec : Error<
- "unexpected ':' in nested name specifier; did you mean '::'?">;
-def err_unexpected_token_in_nested_name_spec : Error<
- "'%0' cannot be a part of nested name specifier; did you mean ':'?">;
-def err_bool_redeclaration : Error<
- "redeclaration of C++ built-in type 'bool'">;
-def ext_c11_static_assert : Extension<
- "_Static_assert is a C11-specific feature">, InGroup<C11>;
-def warn_cxx98_compat_static_assert : Warning<
- "static_assert declarations are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_paren_after_colon_colon : Error<
- "unexpected parenthesis after '::'">;
-def err_function_definition_not_allowed : Error<
- "function definition is not allowed here">;
-def err_expected_end_of_enumerator : Error<
- "expected '= constant-expression' or end of enumerator definition">;
-def err_expected_coloncolon_after_super : Error<
- "expected '::' after '__super'">;
-
-/// Objective-C parser diagnostics
-def err_expected_minus_or_plus : Error<
- "method type specifier must start with '-' or '+'">;
-def err_objc_no_attributes_on_category : Error<
- "attributes may not be specified on a category">;
-def err_objc_missing_end : Error<"missing '@end'">;
-def note_objc_container_start : Note<
- "%select{class|protocol|category|class extension|implementation"
- "|category implementation}0 started here">;
-def warn_objc_protocol_qualifier_missing_id : Warning<
- "protocol has no object type specified; defaults to qualified 'id'">;
-def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">;
-def err_illegal_super_cast : Error<
- "cannot cast 'super' (it isn't an expression)">;
-def err_nsnumber_nonliteral_unary : Error<
- "@%0 must be followed by a number to form an NSNumber object">;
-def warn_cstyle_param : Warning<
- "use of C-style parameters in Objective-C method declarations"
- " is deprecated">, InGroup<DeprecatedDeclarations>;
-
-let CategoryName = "ARC Parse Issue" in {
-def err_arc_bridge_retain : Error<
- "unknown cast annotation __bridge_retain; did you mean __bridge_retained?">;
-// To be default mapped to an error later.
-def warn_arc_bridge_cast_nonarc : Warning<
- "'%0' casts have no effect when not using ARC">,
- InGroup<DiagGroup<"arc-bridge-casts-disallowed-in-nonarc">>;
-}
-
-def err_objc_illegal_visibility_spec : Error<
- "illegal visibility specification">;
-def err_objc_illegal_interface_qual : Error<"illegal interface qualifier">;
-def err_objc_expected_equal_for_getter : Error<
- "expected '=' for Objective-C getter">;
-def err_objc_expected_equal_for_setter : Error<
- "expected '=' for Objective-C setter">;
-def err_objc_expected_selector_for_getter_setter : Error<
- "expected selector for Objective-C %select{setter|getter}0">;
-def err_objc_property_requires_field_name : Error<
- "property requires fields to be named">;
-def err_objc_property_bitfield : Error<"property name cannot be a bitfield">;
-def err_objc_expected_property_attr : Error<"unknown property attribute %0">;
-def err_objc_properties_require_objc2 : Error<
- "properties are an Objective-C 2 feature">;
-def err_objc_unexpected_attr : Error<
- "prefix attribute must be followed by an interface or protocol">;
-def err_objc_postfix_attribute : Error <
- "postfix attributes are not allowed on Objective-C directives">;
-def err_objc_postfix_attribute_hint : Error <
- "postfix attributes are not allowed on Objective-C directives, place"
- " them in front of '%select{@interface|@protocol}0'">;
-def err_objc_directive_only_in_protocol : Error<
- "directive may only be specified in protocols only">;
-def err_missing_catch_finally : Error<
- "@try statement without a @catch and @finally clause">;
-def err_objc_concat_string : Error<"unexpected token after Objective-C string">;
-def err_expected_objc_container : Error<
- "'@end' must appear in an Objective-C context">;
-def err_unexpected_protocol_qualifier : Error<
- "@implementation declaration cannot be protocol qualified">;
-def err_objc_unexpected_atend : Error<
- "'@end' appears where closing brace '}' is expected">;
-def error_property_ivar_decl : Error<
- "property synthesize requires specification of an ivar">;
-def err_synthesized_property_name : Error<
- "expected a property name in @synthesize">;
-def warn_semicolon_before_method_body : Warning<
- "semicolon before method body is ignored">,
- InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore;
-def note_extra_comma_message_arg : Note<
- "comma separating Objective-C messaging arguments">;
-
-def err_expected_field_designator : Error<
- "expected a field designator, such as '.field = 4'">;
-
-def err_declaration_does_not_declare_param : Error<
- "declaration does not declare a parameter">;
-def err_no_matching_param : Error<"parameter named %0 is missing">;
-
-/// C++ parser diagnostics
-def err_invalid_operator_on_type : Error<
- "cannot use %select{dot|arrow}0 operator on a type">;
-def err_expected_unqualified_id : Error<
- "expected %select{identifier|unqualified-id}0">;
-def err_brackets_go_after_unqualified_id : Error<
- "brackets are not allowed here; to declare an array, "
- "place the brackets after the %select{identifier|name}0">;
-def err_unexpected_unqualified_id : Error<"type-id cannot have a name">;
-def err_func_def_no_params : Error<
- "function definition does not declare parameters">;
-def err_expected_lparen_after_type : Error<
- "expected '(' for function-style cast or type construction">;
-def err_expected_init_in_condition : Error<
- "variable declaration in condition must have an initializer">;
-def err_expected_init_in_condition_lparen : Error<
- "variable declaration in condition cannot have a parenthesized initializer">;
-def err_extraneous_rparen_in_condition : Error<
- "extraneous ')' after condition, expected a statement">;
-def warn_dangling_else : Warning<
- "add explicit braces to avoid dangling else">,
- InGroup<DanglingElse>;
-def err_expected_member_or_base_name : Error<
- "expected class member or base class name">;
-def err_expected_lbrace_after_base_specifiers : Error<
- "expected '{' after base class list">;
-def err_missing_end_of_definition : Error<
- "missing '}' at end of definition of %q0">;
-def note_missing_end_of_definition_before : Note<
- "still within definition of %q0 here">;
-def ext_ellipsis_exception_spec : Extension<
- "exception specification of '...' is a Microsoft extension">,
- InGroup<MicrosoftExceptionSpec>;
-def err_dynamic_and_noexcept_specification : Error<
- "cannot have both throw() and noexcept() clause on the same function">;
-def err_except_spec_unparsed : Error<
- "unexpected end of exception specification">;
-def warn_cxx98_compat_noexcept_decl : Warning<
- "noexcept specifications are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_expected_catch : Error<"expected catch">;
-def err_using_namespace_in_class : Error<
- "'using namespace' is not allowed in classes">;
-def err_constructor_bad_name : Error<
- "missing return type for function %0; did you mean the constructor name %1?">;
-def err_destructor_tilde_identifier : Error<
- "expected a class name after '~' to name a destructor">;
-def err_destructor_tilde_scope : Error<
- "'~' in destructor name should be after nested name specifier">;
-def err_destructor_template_id : Error<
- "destructor name %0 does not refer to a template">;
-def err_default_arg_unparsed : Error<
- "unexpected end of default argument expression">;
-def err_bracket_depth_exceeded : Error<
- "bracket nesting level exceeded maximum of %0">, DefaultFatal;
-def note_bracket_depth : Note<
- "use -fbracket-depth=N to increase maximum nesting level">;
-def err_misplaced_ellipsis_in_declaration : Error<
- "'...' must %select{immediately precede declared identifier|"
- "be innermost component of anonymous pack declaration}0">;
-def warn_misplaced_ellipsis_vararg : Warning<
- "'...' in this location creates a C-style varargs function"
- "%select{, not a function parameter pack|}0">,
- InGroup<DiagGroup<"ambiguous-ellipsis">>;
-def note_misplaced_ellipsis_vararg_existing_ellipsis : Note<
- "preceding '...' declares a function parameter pack">;
-def note_misplaced_ellipsis_vararg_add_ellipsis : Note<
- "place '...' %select{immediately before declared identifier|here}0 "
- "to declare a function parameter pack">;
-def note_misplaced_ellipsis_vararg_add_comma : Note<
- "insert ',' before '...' to silence this warning">;
-def ext_abstract_pack_declarator_parens : ExtWarn<
- "ISO C++11 requires a parenthesized pack declaration to have a name">,
- InGroup<DiagGroup<"anonymous-pack-parens">>;
-def err_function_is_not_record : Error<
- "unexpected %0 in function call; perhaps remove the %0?">;
-def err_super_in_using_declaration : Error<
- "'__super' cannot be used with a using declaration">;
-
-// C++ derived classes
-def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
-
-// C++ operator overloading
-def err_literal_operator_string_prefix : Error<
- "string literal after 'operator' cannot have an encoding prefix">;
-def err_literal_operator_string_not_empty : Error<
- "string literal after 'operator' must be '\"\"'">;
-def warn_cxx98_compat_literal_operator : Warning<
- "literal operators are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-// Classes.
-def err_anon_type_definition : Error<
- "declaration of anonymous %0 must be a definition">;
-def err_default_delete_in_multiple_declaration : Error<
- "'= %select{default|delete}0' is a function definition and must occur in a "
- "standalone declaration">;
-
-def warn_cxx98_compat_noexcept_expr : Warning<
- "noexcept expressions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx98_compat_nullptr : Warning<
- "'nullptr' is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-
-def warn_cxx14_compat_attribute : Warning<
- "attributes on %select{a namespace|an enumerator}0 declaration are "
- "incompatible with C++ standards before C++1z">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
-def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx98_compat_attribute : Warning<
- "C++11 attribute syntax is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_cxx11_attribute_forbids_arguments : Error<
- "attribute %0 cannot have an argument list">;
-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">;
-def err_cxx11_attribute_repeated : Error<
- "attribute %0 cannot appear multiple times in an attribute specifier">;
-def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
-def err_l_square_l_square_not_attribute : Error<
- "C++11 only allows consecutive left square brackets when "
- "introducing an attribute">;
-def err_ms_declspec_type : Error<
- "__declspec attributes must be an identifier or string literal">;
-def err_ms_property_no_getter_or_putter : Error<
- "property does not specify a getter or a putter">;
-def err_ms_property_unknown_accessor : Error<
- "expected 'get' or 'put' in property declaration">;
-def err_ms_property_has_set_accessor : Error<
- "putter for property must be specified as 'put', not 'set'">;
-def err_ms_property_missing_accessor_kind : Error<
- "missing 'get=' or 'put='">;
-def err_ms_property_expected_equal : Error<
- "expected '=' after '%0'">;
-def err_ms_property_duplicate_accessor : Error<
- "property declaration specifies '%0' accessor twice">;
-def err_ms_property_expected_accessor_name : Error<
- "expected name of accessor method">;
-def err_ms_property_expected_comma_or_rparen : Error<
- "expected ',' or ')' at end of property accessor list">;
-def err_ms_property_initializer : Error<
- "property declaration cannot have an in-class initializer">;
-
-/// C++ Templates
-def err_expected_template : Error<"expected template">;
-def err_unknown_template_name : Error<
- "unknown template name %0">;
-def err_expected_comma_greater : Error<
- "expected ',' or '>' in template-parameter-list">;
-def err_class_on_template_template_param : Error<
- "template template parameter requires 'class' after the parameter list">;
-def ext_template_template_param_typename : ExtWarn<
- "template template parameter using 'typename' is a C++1z extension">,
- InGroup<CXX1z>;
-def warn_cxx14_compat_template_template_param_typename : Warning<
- "template template parameter using 'typename' is "
- "incompatible with C++ standards before C++1z">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
-def err_template_spec_syntax_non_template : Error<
- "identifier followed by '<' indicates a class template specialization but "
- "%0 %select{does not refer to a template|refers to a function template|"
- "<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_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<
- "a space is required between a right angle bracket and an equals sign "
- "(use '> =')">;
-def warn_cxx11_right_shift_in_template_arg : Warning<
- "use of right-shift operator ('>>') in template argument will require "
- "parentheses in C++11">, InGroup<CXX11Compat>;
-def warn_cxx98_compat_two_right_angle_brackets : Warning<
- "consecutive right angle brackets are incompatible with C++98 (use '> >')">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_templated_invalid_declaration : Error<
- "a static_assert declaration cannot be a template">;
-def err_multiple_template_declarators : Error<
- "%select{|a template declaration|an explicit template specialization|"
- "an explicit template instantiation}0 can "
- "only %select{|declare|declare|instantiate}0 a single entity">;
-def err_explicit_instantiation_with_definition : Error<
- "explicit template instantiation cannot have a definition; if this "
- "definition is meant to be an explicit specialization, add '<>' after the "
- "'template' keyword">;
-def err_template_defn_explicit_instantiation : Error<
- "%select{function|class|variable}0 cannot be defined in an explicit instantiation; if this "
- "declaration is meant to be a %select{function|class|variable}0 definition, remove the 'template' keyword">;
-def err_friend_explicit_instantiation : Error<
- "friend cannot be declared in an explicit instantiation; if this "
- "declaration is meant to be a friend declaration, remove the 'template' keyword">;
-def err_explicit_instantiation_enum : Error<
- "enumerations cannot be explicitly instantiated">;
-def err_expected_template_parameter : Error<"expected template parameter">;
-
-def err_missing_dependent_template_keyword : Error<
- "use 'template' keyword to treat '%0' as a dependent template name">;
-def warn_missing_dependent_template_keyword : ExtWarn<
- "use 'template' keyword to treat '%0' as a dependent template name">;
-
-def ext_extern_template : Extension<
- "extern templates are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_extern_template : Warning<
- "extern templates are incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def warn_static_inline_explicit_inst_ignored : Warning<
- "ignoring '%select{static|inline}0' keyword on explicit template "
- "instantiation">, InGroup<DiagGroup<"static-inline-explicit-instantiation">>;
-
-// Constructor template diagnostics.
-def err_out_of_line_constructor_template_id : Error<
- "out-of-line constructor for %0 cannot have template arguments">;
-def err_out_of_line_template_id_type_names_constructor : Error<
- "qualified reference to %0 is a constructor name rather than a "
- "%select{template name|type}1 wherever a constructor can be declared">;
-
-def err_expected_qualified_after_typename : Error<
- "expected a qualified name after 'typename'">;
-def warn_expected_qualified_after_typename : ExtWarn<
- "expected a qualified name after 'typename'">;
-
-def err_typename_refers_to_non_type_template : Error<
- "typename specifier refers to a non-type template">;
-def err_expected_type_name_after_typename : Error<
- "expected an identifier or template-id after '::'">;
-def err_explicit_spec_non_template : Error<
- "explicit %select{specialization|instantiation}0 of non-template %1 %2">;
-
-def err_default_template_template_parameter_not_template : Error<
- "default template argument for a template template parameter must be a class "
- "template">;
-
-def ext_fold_expression : ExtWarn<
- "pack fold expression is a C++1z extension">,
- InGroup<CXX1z>;
-def warn_cxx14_compat_fold_expression : Warning<
- "pack fold expression is incompatible with C++ standards before C++1z">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
-def err_expected_fold_operator : Error<
- "expected a foldable binary operator in fold expression">;
-def err_fold_operator_mismatch : Error<
- "operators in fold expression must be the same">;
-
-def err_ctor_init_missing_comma : Error<
- "missing ',' between base or member initializers">;
-
-// C++ declarations
-def err_friend_decl_defines_type : Error<
- "cannot define a type in a friend declaration">;
-def err_missing_whitespace_digraph : Error<
- "found '<::' after a "
- "%select{template name|const_cast|dynamic_cast|reinterpret_cast|static_cast}0"
- " which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?">;
-
-def ext_defaulted_deleted_function : ExtWarn<
- "%select{defaulted|deleted}0 function definitions are a C++11 extension">,
- InGroup<CXX11>;
-def warn_cxx98_compat_defaulted_deleted_function : Warning<
- "%select{defaulted|deleted}0 function definitions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-// C++11 in-class member initialization
-def ext_nonstatic_member_init : ExtWarn<
- "in-class initialization of non-static data member is a C++11 extension">,
- InGroup<CXX11>;
-def warn_cxx98_compat_nonstatic_member_init : Warning<
- "in-class initialization of non-static data members is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_bitfield_member_init: Error<
- "bitfield member cannot have an in-class initializer">;
-def err_incomplete_array_member_init: Error<
- "array bound cannot be deduced from an in-class initializer">;
-
-// C++11 alias-declaration
-def ext_alias_declaration : ExtWarn<
- "alias declarations are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_alias_declaration : Warning<
- "alias declarations are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_alias_declaration_not_identifier : Error<
- "name defined in alias declaration must be an identifier">;
-def err_alias_declaration_specialization : Error<
- "%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">;
-
-// C++11 override control
-def ext_override_control_keyword : ExtWarn<
- "'%0' keyword is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_override_control_keyword : Warning<
- "'%0' keyword is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_override_control_interface : Error<
- "'%0' keyword not permitted with interface types">;
-def ext_ms_sealed_keyword : ExtWarn<
- "'sealed' keyword is a Microsoft extension">,
- InGroup<MicrosoftSealed>;
-
-def err_access_specifier_interface : Error<
- "interface types cannot specify '%select{private|protected}0' access">;
-
-def err_duplicate_virt_specifier : Error<
- "class member already marked '%0'">;
-
-def err_scoped_enum_missing_identifier : Error<
- "scoped enumeration requires a name">;
-def ext_scoped_enum : ExtWarn<
- "scoped enumerations are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_scoped_enum : Warning<
- "scoped enumerations are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-def err_expected_parameter_pack : Error<
- "expected the name of a parameter pack">;
-def err_paren_sizeof_parameter_pack : Error<
- "missing parentheses around the size of parameter pack %0">;
-def err_sizeof_parameter_pack : Error<
- "expected parenthesized parameter pack name in 'sizeof...' expression">;
-
-// C++11 lambda expressions
-def err_expected_comma_or_rsquare : Error<
- "expected ',' or ']' in lambda capture list">;
-def err_this_captured_by_reference : Error<
- "'this' cannot be captured by reference">;
-def err_expected_capture : Error<
- "expected variable name or 'this' in lambda capture list">;
-def err_expected_lambda_body : Error<"expected body of lambda expression">;
-def warn_cxx98_compat_lambda : Warning<
- "lambda expressions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_lambda_missing_parens : Error<
- "lambda requires '()' before %select{'mutable'|return type|"
- "attribute specifier}0">;
-
-// Availability attribute
-def err_expected_version : Error<
- "expected a version of the form 'major[.minor[.subminor]]'">;
-def warn_expected_consistent_version_separator : Warning<
- "use same version number separators '_' or '.'; as in "
- "'major[.minor[.subminor]]'">, InGroup<Availability>;
-def err_zero_version : Error<
- "version number must have non-zero major, minor, or sub-minor version">;
-def err_availability_expected_platform : Error<
- "expected a platform name, e.g., 'macosx'">;
-
-// objc_bridge_related attribute
-def err_objcbridge_related_expected_related_class : Error<
- "expected a related ObjectiveC class name, e.g., 'NSColor'">;
-def err_objcbridge_related_selector_name : Error<
- "expected a class method selector with single argument, e.g., 'colorWithCGColor:'">;
-
-def err_availability_expected_change : Error<
- "expected 'introduced', 'deprecated', or 'obsoleted'">;
-def err_availability_unknown_change : Error<
- "%0 is not an availability stage; use 'introduced', 'deprecated', or "
- "'obsoleted'">;
-def err_availability_redundant : Error<
- "redundant %0 availability change; only the last specified change will "
- "be used">;
-def warn_availability_and_unavailable : Warning<
- "'unavailable' availability overrides all other availability information">,
- InGroup<Availability>;
-
-// Type safety attributes
-def err_type_safety_unknown_flag : Error<
- "invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">;
-
-// Type traits
-def err_type_trait_arity : Error<
- "type trait requires %0%select{| or more}1 argument%select{|s}2; have "
- "%3 argument%s3">;
-
-// Language specific pragmas
-// - Generic warnings
-def warn_pragma_expected_lparen : Warning<
- "missing '(' after '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
-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_section_name : Warning<
- "expected a string literal for the section name in '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_expected_section_push_pop_or_name : Warning<
- "expected push, pop or a string literal for the section name in '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_expected_section_label_or_name : Warning<
- "expected a stack label or a string literal for the section name in '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_expected_init_seg : Warning<
- "expected 'compiler', 'lib', 'user', or a string literal for the section name in '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_expected_integer : Warning<
- "expected integer between %0 and %1 inclusive in '#pragma %2' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_ms_struct : Warning<
- "incorrect use of '#pragma ms_struct on|off' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_extra_tokens_at_eol : Warning<
- "extra tokens at end of '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_expected_punc : Warning<
- "expected ')' or ',' in '#pragma %0'">, InGroup<IgnoredPragmas>;
-def warn_pragma_expected_non_wide_string : Warning<
- "expected non-wide string literal in '#pragma %0'">, InGroup<IgnoredPragmas>;
-// - Generic errors
-def err_pragma_missing_argument : Error<
- "missing argument to '#pragma %0'%select{|; expected %2}1">;
-// - #pragma options
-def warn_pragma_options_expected_align : Warning<
- "expected 'align' following '#pragma options' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_align_expected_equal : Warning<
- "expected '=' following '#pragma %select{align|options align}0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_align_invalid_option : Warning<
- "invalid alignment option in '#pragma %select{align|options align}0' - ignored">,
- InGroup<IgnoredPragmas>;
-// - #pragma pack
-def warn_pragma_unsupported_action : Warning<
- "known but unsupported action '%1' for '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_invalid_specific_action : Warning<
- "unknown action '%1' for '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_expected_action_or_r_paren : Warning<
- "expected action or ')' in '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_invalid_action : Warning<
- "unknown action for '#pragma %0' - ignored">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_pack_malformed : Warning<
- "expected integer or identifier in '#pragma pack' - ignored">,
- InGroup<IgnoredPragmas>;
-// - #pragma unused
-def warn_pragma_unused_expected_var : Warning<
- "expected '#pragma unused' argument to be a variable name">,
- InGroup<IgnoredPragmas>;
-// - #pragma init_seg
-def warn_pragma_init_seg_unsupported_target : Warning<
- "'#pragma init_seg' is only supported when targeting a "
- "Microsoft environment">,
- InGroup<IgnoredPragmas>;
-// - #pragma fp_contract
-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 comment
-def err_pragma_comment_malformed : Error<
- "pragma comment requires parenthesized identifier and optional string">;
-def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">;
-// PS4 recognizes only #pragma comment(lib)
-def warn_pragma_comment_ignored : Warning<"'#pragma comment %0' ignored">,
- InGroup<IgnoredPragmas>;
-// - #pragma detect_mismatch
-def err_pragma_detect_mismatch_malformed : Error<
- "pragma detect_mismatch is malformed; it requires two comma-separated "
- "string literals">;
-// - #pragma pointers_to_members
-def err_pragma_pointers_to_members_unknown_kind : Error<
- "unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1"
- "'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'">;
-// - #pragma clang optimize on/off
-def err_pragma_optimize_invalid_argument : Error<
- "unexpected argument '%0' to '#pragma clang optimize'; "
- "expected 'on' or 'off'">;
-def err_pragma_optimize_extra_argument : Error<
- "unexpected extra argument '%0' to '#pragma clang optimize'">;
-
-// OpenCL EXTENSION pragma (OpenCL 1.1 [9.1])
-def warn_pragma_expected_colon : Warning<
- "missing ':' after %0 - ignoring">, InGroup<IgnoredPragmas>;
-def warn_pragma_expected_enable_disable : Warning<
- "expected 'enable' or 'disable' - ignoring">, InGroup<IgnoredPragmas>;
-def warn_pragma_unknown_extension : Warning<
- "unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
-
-// OpenCL error
-def err_opencl_taking_function_address_parser : Error<
- "taking address of function is not allowed">;
-
-// OpenMP support.
-def warn_pragma_omp_ignored : Warning<
- "unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;
-def warn_omp_extra_tokens_at_eol : Warning<
- "extra tokens at the end of '#pragma omp %0' are ignored">,
- InGroup<ExtraTokens>;
-def warn_pragma_expected_colon_r_paren : Warning<
- "missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>;
-def err_omp_unknown_directive : Error<
- "expected an OpenMP directive">;
-def err_omp_unexpected_directive : Error<
- "unexpected OpenMP directive '#pragma omp %0'">;
-def err_omp_expected_punc : Error<
- "expected ',' or ')' in '%0' %select{clause|directive}1">;
-def err_omp_unexpected_clause : Error<
- "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
-def err_omp_immediate_directive : Error<
- "'#pragma omp %0' %select{|with '%2' clause }1cannot be an immediate substatement">;
-def err_omp_expected_identifier_for_critical : Error<
- "expected identifier specifying the name of the 'omp critical' directive">;
-def err_omp_unknown_map_type : Error<
- "incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">;
-def err_omp_unknown_map_type_modifier : Error<
- "incorrect map type modifier, expected 'always'">;
-def err_omp_map_type_missing : Error<
- "missing map type">;
-
-// Pragma loop support.
-def err_pragma_loop_missing_argument : Error<
- "missing argument; expected %select{an integer value|"
- "'enable', %select{'assume_safety'|'full'}1 or 'disable'}0">;
-def err_pragma_loop_invalid_option : Error<
- "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
- "vectorize_width, interleave, interleave_count, unroll, or unroll_count">;
-def err_pragma_invalid_keyword : Error<
- "invalid argument; expected 'enable', %select{'assume_safety'|'full'}0 or 'disable'">;
-
-// Pragma unroll support.
-def warn_pragma_unroll_cuda_value_in_parens : Warning<
- "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
- InGroup<CudaCompat>;
-} // end of Parse Issue category.
-
-let CategoryName = "Modules Issue" in {
-def err_module_expected_ident : Error<
- "expected a module name after module import">;
-def err_module_expected_semi : Error<
- "expected ';' after module name">;
-def err_missing_before_module_end : Error<"expected %0 at end of module">;
-}
-
-let CategoryName = "Generics Issue" in {
-
-def err_objc_expected_type_parameter : Error<
- "expected type parameter name">;
-
-def err_objc_parameterized_implementation : Error<
- "@implementation cannot have type parameters">;
-
-def err_objc_type_args_after_protocols : Error<
- "protocol qualifiers must precede type arguments">;
-}
-
-let CategoryName = "Coroutines Issue" in {
-def err_for_co_await_not_range_for : Error<
- "'co_await' modifier can only be applied to range-based for loop">;
-}
-
-} // end of Parser diagnostics
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
deleted file mode 100644
index 59f5095..0000000
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ /dev/null
@@ -1,8221 +0,0 @@
-
-//==--- DiagnosticSemaKinds.td - libsema diagnostics ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Semantic Analysis
-//===----------------------------------------------------------------------===//
-
-let Component = "Sema" in {
-let CategoryName = "Semantic Issue" in {
-
-def note_previous_decl : Note<"%0 declared here">;
-def note_entity_declared_at : Note<"%0 declared here">;
-def note_callee_decl : Note<"%0 declared here">;
-def note_defined_here : Note<"%0 defined here">;
-
-// For loop analysis
-def warn_variables_not_in_loop_body : Warning<
- "variable%select{s| %1|s %1 and %2|s %1, %2, and %3|s %1, %2, %3, and %4}0 "
- "used in loop condition not modified in loop body">,
- InGroup<ForLoopAnalysis>, DefaultIgnore;
-def warn_redundant_loop_iteration : Warning<
- "variable %0 is %select{decremented|incremented}1 both in the loop header "
- "and in the loop body">,
- InGroup<ForLoopAnalysis>, DefaultIgnore;
-def note_loop_iteration_here : Note<"%select{decremented|incremented}0 here">;
-
-def warn_for_range_const_reference_copy : Warning<
- "loop variable %0 "
- "%diff{has type $ but is initialized with type $"
- "| is initialized with a value of a different type}1,2 resulting in a copy">,
- InGroup<RangeLoopAnalysis>, DefaultIgnore;
-def note_use_type_or_non_reference : Note<
- "use non-reference type %0 to keep the copy or type %1 to prevent copying">;
-def warn_for_range_variable_always_copy : Warning<
- "loop variable %0 is always a copy because the range of type %1 does not "
- "return a reference">,
- InGroup<RangeLoopAnalysis>, DefaultIgnore;
-def note_use_non_reference_type : Note<"use non-reference type %0">;
-def warn_for_range_copy : Warning<
- "loop variable %0 of type %1 creates a copy from type %2">,
- InGroup<RangeLoopAnalysis>, DefaultIgnore;
-def note_use_reference_type : Note<"use reference type %0 to prevent copying">;
-
-def warn_duplicate_enum_values : Warning<
- "element %0 has been implicitly assigned %1 which another element has "
- "been assigned">, InGroup<DiagGroup<"duplicate-enum">>, DefaultIgnore;
-def note_duplicate_element : Note<"element %0 also has value %1">;
-
-// Absolute value functions
-def warn_unsigned_abs : Warning<
- "taking the absolute value of unsigned type %0 has no effect">,
- InGroup<AbsoluteValue>;
-def note_remove_abs : Note<
- "remove the call to '%0' since unsigned values cannot be negative">;
-def warn_abs_too_small : Warning<
- "absolute value function %0 given an argument of type %1 but has parameter "
- "of type %2 which may cause truncation of value">, InGroup<AbsoluteValue>;
-def warn_wrong_absolute_value_type : Warning<
- "using %select{integer|floating point|complex}1 absolute value function %0 "
- "when argument is of %select{integer|floating point|complex}2 type">,
- InGroup<AbsoluteValue>;
-def note_replace_abs_function : Note<"use function '%0' instead">;
-def warn_pointer_abs : Warning<
- "taking the absolute value of %select{pointer|function|array}0 type %1 is suspicious">,
- InGroup<AbsoluteValue>;
-
-def warn_infinite_recursive_function : Warning<
- "all paths through this function will call itself">,
- InGroup<InfiniteRecursion>, DefaultIgnore;
-
-// Constant expressions
-def err_expr_not_ice : Error<
- "expression is not an %select{integer|integral}0 constant expression">;
-def ext_expr_not_ice : Extension<
- "expression is not an %select{integer|integral}0 constant expression; "
- "folding it to a constant is a GNU extension">, InGroup<GNUFoldingConstant>;
-def err_typecheck_converted_constant_expression : Error<
- "value of type %0 is not implicitly convertible to %1">;
-def err_typecheck_converted_constant_expression_disallowed : Error<
- "conversion from %0 to %1 is not allowed in a converted constant expression">;
-def err_typecheck_converted_constant_expression_indirect : Error<
- "conversion from %0 to %1 in converted constant expression would "
- "bind reference to a temporary">;
-def err_expr_not_cce : Error<
- "%select{case value|enumerator value|non-type template argument|array size}0 "
- "is not a constant expression">;
-def ext_cce_narrowing : ExtWarn<
- "%select{case value|enumerator value|non-type template argument|array size}0 "
- "%select{cannot be narrowed from type %2 to %3|"
- "evaluates to %2, which cannot be narrowed to type %3}1">,
- InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
-def err_ice_not_integral : Error<
- "integral constant expression must have integral or unscoped enumeration "
- "type, not %0">;
-def err_ice_incomplete_type : Error<
- "integral constant expression has incomplete class type %0">;
-def err_ice_explicit_conversion : Error<
- "integral constant expression requires explicit conversion from %0 to %1">;
-def note_ice_conversion_here : Note<
- "conversion to %select{integral|enumeration}0 type %1 declared here">;
-def err_ice_ambiguous_conversion : Error<
- "ambiguous conversion from type %0 to an integral or unscoped "
- "enumeration type">;
-def err_ice_too_large : Error<
- "integer constant expression evaluates to value %0 that cannot be "
- "represented in a %1-bit %select{signed|unsigned}2 integer type">;
-def err_expr_not_string_literal : Error<"expression is not a string literal">;
-
-// Semantic analysis of constant literals.
-def ext_predef_outside_function : Warning<
- "predefined identifier is only valid inside function">,
- InGroup<DiagGroup<"predefined-identifier-outside-function">>;
-def warn_float_overflow : Warning<
- "magnitude of floating-point constant too large for type %0; maximum is %1">,
- InGroup<LiteralRange>;
-def warn_float_underflow : Warning<
- "magnitude of floating-point constant too small for type %0; minimum is %1">,
- InGroup<LiteralRange>;
-def warn_double_const_requires_fp64 : Warning<
- "double precision constant requires cl_khr_fp64, casting to single precision">;
-
-// C99 variable-length arrays
-def ext_vla : Extension<"variable length arrays are a C99 feature">,
- InGroup<VLAExtension>;
-def warn_vla_used : Warning<"variable length array used">,
- InGroup<VLA>, DefaultIgnore;
-def err_vla_non_pod : Error<"variable length array of non-POD element type %0">;
-def err_vla_in_sfinae : Error<
- "variable length array cannot be formed during template argument deduction">;
-def err_array_star_in_function_definition : Error<
- "variable length array must be bound in function definition">;
-def err_vla_decl_in_file_scope : Error<
- "variable length array declaration not allowed at file scope">;
-def err_vla_decl_has_static_storage : Error<
- "variable length array declaration cannot have 'static' storage duration">;
-def err_vla_decl_has_extern_linkage : Error<
- "variable length array declaration cannot have 'extern' linkage">;
-def ext_vla_folded_to_constant : Extension<
- "variable length array folded to constant array as an extension">, InGroup<GNUFoldingConstant>;
-
-// C99 variably modified types
-def err_variably_modified_template_arg : Error<
- "variably modified type %0 cannot be used as a template argument">;
-def err_variably_modified_nontype_template_param : Error<
- "non-type template parameter of variably modified type %0">;
-def err_variably_modified_new_type : Error<
- "'new' cannot allocate object of variably modified type %0">;
-
-// C99 Designated Initializers
-def ext_designated_init : Extension<
- "designated initializers are a C99 feature">, InGroup<C99>;
-def err_array_designator_negative : Error<
- "array designator value '%0' is negative">;
-def err_array_designator_empty_range : Error<
- "array designator range [%0, %1] is empty">;
-def err_array_designator_non_array : Error<
- "array designator cannot initialize non-array type %0">;
-def err_array_designator_too_large : Error<
- "array designator index (%0) exceeds array bounds (%1)">;
-def err_field_designator_non_aggr : Error<
- "field designator cannot initialize a "
- "%select{non-struct, non-union|non-class}0 type %1">;
-def err_field_designator_unknown : Error<
- "field designator %0 does not refer to any field in type %1">;
-def err_field_designator_nonfield : Error<
- "field designator %0 does not refer to a non-static data member">;
-def note_field_designator_found : Note<"field designator refers here">;
-def err_designator_for_scalar_init : Error<
- "designator in initializer for scalar type %0">;
-def warn_subobject_initializer_overrides : Warning<
- "subobject initialization overrides initialization of other fields "
- "within its enclosing subobject">, InGroup<InitializerOverrides>;
-def warn_initializer_overrides : Warning<
- "initializer overrides prior initialization of this subobject">,
- InGroup<InitializerOverrides>;
-def note_previous_initializer : Note<
- "previous initialization %select{|with side effects }0is here"
- "%select{| (side effects may not occur at run time)}0">;
-def err_designator_into_flexible_array_member : Error<
- "designator into flexible array member subobject">;
-def note_flexible_array_member : Note<
- "initialized flexible array member %0 is here">;
-def ext_flexible_array_init : Extension<
- "flexible array initialization is a GNU extension">, InGroup<GNUFlexibleArrayInitializer>;
-
-// Declarations.
-def ext_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">,
- InGroup<DuplicateDeclSpecifier>;
-def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">,
- InGroup<DuplicateDeclSpecifier>;
-def ext_plain_complex : ExtWarn<
- "plain '_Complex' requires a type specifier; assuming '_Complex double'">;
-def ext_integer_complex : Extension<
- "complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;
-
-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">;
-def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">;
-def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">;
-
-def ext_auto_type_specifier : ExtWarn<
- "'auto' type specifier is a C++11 extension">, InGroup<CXX11>;
-def warn_auto_storage_class : Warning<
- "'auto' storage class specifier is redundant and incompatible with C++11">,
- InGroup<CXX11Compat>, DefaultIgnore;
-
-def warn_deprecated_register : Warning<
- "'register' storage class specifier is deprecated "
- "and incompatible with C++1z">, InGroup<DeprecatedRegister>;
-def ext_register_storage_class : ExtWarn<
- "ISO C++1z does not allow 'register' storage class specifier">,
- DefaultError, InGroup<Register>;
-
-def err_invalid_decl_spec_combination : Error<
- "cannot combine with previous '%0' declaration specifier">;
-def err_invalid_vector_decl_spec_combination : Error<
- "cannot combine with previous '%0' declaration specifier. "
- "'__vector' must be first">;
-def err_invalid_pixel_decl_spec_combination : Error<
- "'__pixel' must be preceded by '__vector'. "
- "'%0' declaration specifier not allowed here">;
-def err_invalid_vector_bool_decl_spec : Error<
- "cannot use '%0' with '__vector bool'">;
-def err_invalid_vector_long_decl_spec : Error<
- "cannot use 'long' with '__vector'">;
-def err_invalid_vector_float_decl_spec : Error<
- "cannot use 'float' with '__vector'">;
-def err_invalid_vector_double_decl_spec : Error <
- "use of 'double' with '__vector' requires VSX support to be enabled "
- "(available on POWER7 or later)">;
-def err_invalid_vector_long_long_decl_spec : Error <
- "use of 'long long' with '__vector bool' requires VSX support (available on "
- "POWER7 or later) or extended Altivec support (available on POWER8 or later) "
- "to be enabled">;
-def err_invalid_vector_long_double_decl_spec : Error<
- "cannot use 'long double' with '__vector'">;
-def warn_vector_long_decl_spec_combination : Warning<
- "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
-
-def err_use_of_tag_name_without_tag : Error<
- "must use '%1' tag to refer to type %0%select{| in this scope}2">;
-
-def err_redeclaration_different_type : Error<
- "redeclaration of %0 with a different type%diff{: $ vs $|}1,2">;
-def err_bad_variable_name : Error<
- "%0 cannot be the name of a variable or data member">;
-def err_bad_parameter_name : Error<
- "%0 cannot be the name of a parameter">;
-def err_parameter_name_omitted : Error<"parameter name omitted">;
-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_unused_parameter : Warning<"unused parameter %0">,
- InGroup<UnusedParameter>, DefaultIgnore;
-def warn_unused_variable : Warning<"unused variable %0">,
- InGroup<UnusedVariable>, DefaultIgnore;
-def warn_unused_local_typedef : Warning<
- "unused %select{typedef|type alias}0 %1">,
- InGroup<UnusedLocalTypedef>, DefaultIgnore;
-def warn_unused_property_backing_ivar :
- Warning<"ivar %0 which backs the property is not "
- "referenced in this property's accessor">,
- InGroup<UnusedPropertyIvar>, DefaultIgnore;
-def warn_unused_const_variable : Warning<"unused variable %0">,
- InGroup<UnusedConstVariable>, DefaultIgnore;
-def warn_unused_exception_param : Warning<"unused exception parameter %0">,
- InGroup<UnusedExceptionParameter>, DefaultIgnore;
-def warn_decl_in_param_list : Warning<
- "declaration of %0 will not be visible outside of this function">,
- InGroup<Visibility>;
-def warn_redefinition_in_param_list : Warning<
- "redefinition of %0 will not be visible outside of this function">,
- InGroup<Visibility>;
-def warn_empty_parens_are_function_decl : Warning<
- "empty parentheses interpreted as a function declaration">,
- InGroup<VexingParse>;
-def warn_parens_disambiguated_as_function_declaration : Warning<
- "parentheses were disambiguated as a function declaration">,
- InGroup<VexingParse>;
-def note_additional_parens_for_variable_declaration : Note<
- "add a pair of parentheses to declare a variable">;
-def note_empty_parens_function_call : Note<
- "change this ',' to a ';' to call %0">;
-def note_empty_parens_default_ctor : Note<
- "remove parentheses to declare a variable">;
-def note_empty_parens_zero_initialize : Note<
- "replace parentheses with an initializer to declare a variable">;
-def warn_unused_function : Warning<"unused function %0">,
- InGroup<UnusedFunction>, DefaultIgnore;
-def warn_unused_member_function : Warning<"unused member function %0">,
- InGroup<UnusedMemberFunction>, DefaultIgnore;
-def warn_used_but_marked_unused: Warning<"%0 was marked unused but was used">,
- InGroup<UsedButMarkedUnused>, DefaultIgnore;
-def warn_unneeded_internal_decl : Warning<
- "%select{function|variable}0 %1 is not needed and will not be emitted">,
- InGroup<UnneededInternalDecl>, DefaultIgnore;
-def warn_unneeded_static_internal_decl : Warning<
- "'static' function %0 declared in header file "
- "should be declared 'static inline'">,
- InGroup<UnneededInternalDecl>, DefaultIgnore;
-def warn_unneeded_member_function : Warning<
- "member function %0 is not needed and will not be emitted">,
- InGroup<UnneededMemberFunction>, DefaultIgnore;
-def warn_unused_private_field: Warning<"private field %0 is not used">,
- InGroup<UnusedPrivateField>, DefaultIgnore;
-
-def warn_parameter_size: Warning<
- "%0 is a large (%1 bytes) pass-by-value argument; "
- "pass it by reference instead ?">, InGroup<LargeByValueCopy>;
-def warn_return_value_size: Warning<
- "return value of %0 is a large (%1 bytes) pass-by-value object; "
- "pass it by reference instead ?">, InGroup<LargeByValueCopy>;
-def warn_return_value_udt: Warning<
- "%0 has C-linkage specified, but returns user-defined type %1 which is "
- "incompatible with C">, InGroup<ReturnTypeCLinkage>;
-def warn_return_value_udt_incomplete: Warning<
- "%0 has C-linkage specified, but returns incomplete type %1 which could be "
- "incompatible with C">, InGroup<ReturnTypeCLinkage>;
-def warn_implicit_function_decl : Warning<
- "implicit declaration of function %0">,
- InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
-def ext_implicit_function_decl : ExtWarn<
- "implicit declaration of function %0 is invalid in C99">,
- InGroup<ImplicitFunctionDeclare>;
-def note_function_suggestion : Note<"did you mean %0?">;
-
-def err_ellipsis_first_param : Error<
- "ISO C requires a named parameter before '...'">;
-def err_declarator_need_ident : Error<"declarator requires an identifier">;
-def err_language_linkage_spec_unknown : Error<"unknown linkage language">;
-def err_language_linkage_spec_not_ascii : Error<
- "string literal in language linkage specifier cannot have an "
- "encoding-prefix">;
-def warn_use_out_of_scope_declaration : Warning<
- "use of out-of-scope declaration of %0">;
-def err_inline_non_function : Error<
- "'inline' can only appear on functions">;
-def err_noreturn_non_function : Error<
- "'_Noreturn' can only appear on functions">;
-def warn_qual_return_type : Warning<
- "'%0' type qualifier%s1 on return type %plural{1:has|:have}1 no effect">,
- InGroup<IgnoredQualifiers>, DefaultIgnore;
-
-def warn_decl_shadow :
- Warning<"declaration shadows a %select{"
- "local variable|"
- "variable in %2|"
- "static data member of %2|"
- "field of %2}1">,
- InGroup<Shadow>, DefaultIgnore;
-
-// C++ using declarations
-def err_using_requires_qualname : Error<
- "using declaration requires a qualified name">;
-def err_using_typename_non_type : Error<
- "'typename' keyword used on a non-type">;
-def err_using_dependent_value_is_type : Error<
- "dependent using declaration resolved to type without 'typename'">;
-def err_using_decl_nested_name_specifier_is_not_class : Error<
- "using declaration in class refers into '%0', which is not a class">;
-def err_using_decl_nested_name_specifier_is_current_class : Error<
- "using declaration refers to its own class">;
-def err_using_decl_nested_name_specifier_is_not_base_class : Error<
- "using declaration refers into '%0', which is not a base class of %1">;
-def err_using_decl_constructor_not_in_direct_base : Error<
- "%0 is not a direct base of %1, cannot inherit constructors">;
-def err_using_decl_constructor_conflict : Error<
- "cannot inherit constructor, already inherited constructor with "
- "the same signature">;
-def note_using_decl_constructor_conflict_current_ctor : Note<
- "conflicting constructor">;
-def note_using_decl_constructor_conflict_previous_ctor : Note<
- "previous constructor">;
-def note_using_decl_constructor_conflict_previous_using : Note<
- "previously inherited here">;
-def warn_using_decl_constructor_ellipsis : Warning<
- "inheriting constructor does not inherit ellipsis">,
- InGroup<DiagGroup<"inherited-variadic-ctor">>;
-def note_using_decl_constructor_ellipsis : Note<
- "constructor declared with ellipsis here">;
-def err_using_decl_can_not_refer_to_class_member : Error<
- "using declaration cannot refer to class member">;
-def note_using_decl_class_member_workaround : Note<
- "use %select{an alias declaration|a typedef declaration|a reference}0 "
- "instead">;
-def err_using_decl_can_not_refer_to_namespace : Error<
- "using declaration cannot refer to namespace">;
-def err_using_decl_constructor : Error<
- "using declaration cannot refer to a constructor">;
-def warn_cxx98_compat_using_decl_constructor : Warning<
- "inheriting constructors are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_using_decl_destructor : Error<
- "using declaration cannot refer to a destructor">;
-def err_using_decl_template_id : Error<
- "using declaration cannot refer to a template specialization">;
-def note_using_decl_target : Note<"target of using declaration">;
-def note_using_decl_conflict : Note<"conflicting declaration">;
-def err_using_decl_redeclaration : Error<"redeclaration of using decl">;
-def err_using_decl_conflict : Error<
- "target of using declaration conflicts with declaration already in scope">;
-def err_using_decl_conflict_reverse : Error<
- "declaration conflicts with target of using declaration already in scope">;
-def note_using_decl : Note<"%select{|previous }0using declaration">;
-
-def warn_access_decl_deprecated : Warning<
- "access declarations are deprecated; use using declarations instead">,
- InGroup<Deprecated>;
-def err_access_decl : Error<
- "ISO C++11 does not allow access declarations; "
- "use using declarations instead">;
-def warn_exception_spec_deprecated : Warning<
- "dynamic exception specifications are deprecated">,
- InGroup<Deprecated>, DefaultIgnore;
-def note_exception_spec_deprecated : Note<"use '%0' instead">;
-def warn_deprecated_copy_operation : Warning<
- "definition of implicit copy %select{constructor|assignment operator}1 "
- "for %0 is deprecated because it has a user-declared "
- "%select{copy %select{assignment operator|constructor}1|destructor}2">,
- InGroup<Deprecated>, DefaultIgnore;
-
-def warn_global_constructor : Warning<
- "declaration requires a global constructor">,
- InGroup<GlobalConstructors>, DefaultIgnore;
-def warn_global_destructor : Warning<
- "declaration requires a global destructor">,
- InGroup<GlobalConstructors>, DefaultIgnore;
-def warn_exit_time_destructor : Warning<
- "declaration requires an exit-time destructor">,
- InGroup<ExitTimeDestructors>, DefaultIgnore;
-
-def err_invalid_thread : Error<
- "'%0' is only allowed on variable declarations">;
-def err_thread_non_global : Error<
- "'%0' variables must have global storage">;
-def err_thread_unsupported : Error<
- "thread-local storage is not supported for the current target">;
-
-def warn_maybe_falloff_nonvoid_function : Warning<
- "control may reach end of non-void function">,
- InGroup<ReturnType>;
-def warn_falloff_nonvoid_function : Warning<
- "control reaches end of non-void function">,
- InGroup<ReturnType>;
-def err_maybe_falloff_nonvoid_block : Error<
- "control may reach end of non-void block">;
-def err_falloff_nonvoid_block : Error<
- "control reaches end of non-void block">;
-def warn_suggest_noreturn_function : Warning<
- "%select{function|method}0 %1 could be declared with attribute 'noreturn'">,
- InGroup<MissingNoreturn>, DefaultIgnore;
-def warn_suggest_noreturn_block : Warning<
- "block could be declared with attribute 'noreturn'">,
- InGroup<MissingNoreturn>, DefaultIgnore;
-
-// Unreachable code.
-def warn_unreachable : Warning<
- "code will never be executed">,
- InGroup<UnreachableCode>, DefaultIgnore;
-def warn_unreachable_break : Warning<
- "'break' will never be executed">,
- InGroup<UnreachableCodeBreak>, DefaultIgnore;
-def warn_unreachable_return : Warning<
- "'return' will never be executed">,
- InGroup<UnreachableCodeReturn>, DefaultIgnore;
-def warn_unreachable_loop_increment : Warning<
- "loop will run at most once (loop increment never executed)">,
- InGroup<UnreachableCodeLoopIncrement>, DefaultIgnore;
-def note_unreachable_silence : Note<
- "silence by adding parentheses to mark code as explicitly dead">;
-
-/// Built-in functions.
-def ext_implicit_lib_function_decl : ExtWarn<
- "implicitly declaring library function '%0' with type %1">,
- InGroup<ImplicitFunctionDeclare>;
-def note_include_header_or_declare : Note<
- "include the header <%0> or explicitly provide a declaration for '%1'">;
-def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">;
-def warn_implicit_decl_requires_sysheader : Warning<
- "declaration of built-in function '%1' requires inclusion of the header <%0>">,
- InGroup<BuiltinRequiresHeader>;
-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_arm_invalid_specialreg : Error<"invalid special register for builtin">;
-def err_invalid_cpu_supports : Error<"invalid cpu feature string for builtin">;
-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 "
- "be inlined into function %0 that is compiled without support for "
- "'%2'">;
-def warn_builtin_unknown : Warning<"use of unknown builtin %0">,
- InGroup<ImplicitFunctionDeclare>, DefaultError;
-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">>;
-def note_bad_memaccess_silence : Note<
- "explicitly cast the pointer to silence this warning">;
-def warn_sizeof_pointer_expr_memaccess : Warning<
- "'%0' call operates on objects of type %1 while the size is based on a "
- "different type %2">,
- InGroup<SizeofPointerMemaccess>;
-def warn_sizeof_pointer_expr_memaccess_note : Note<
- "did you mean to %select{dereference the argument to 'sizeof' (and multiply "
- "it by the number of elements)|remove the addressof in the argument to "
- "'sizeof' (and multiply it by the number of elements)|provide an explicit "
- "length}0?">;
-def warn_sizeof_pointer_type_memaccess : Warning<
- "argument to 'sizeof' in %0 call is the same pointer type %1 as the "
- "%select{destination|source}2; expected %3 or an explicit length">,
- InGroup<SizeofPointerMemaccess>;
-def warn_strlcpycat_wrong_size : Warning<
- "size argument in %0 call appears to be size of the source; "
- "expected the size of the destination">,
- InGroup<DiagGroup<"strlcpy-strlcat-size">>;
-def note_strlcpycat_wrong_size : Note<
- "change size argument to be the size of the destination">;
-def warn_memsize_comparison : Warning<
- "size argument in %0 call is a comparison">,
- InGroup<DiagGroup<"memsize-comparison">>;
-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_strncat_large_size : Warning<
- "the value of the size argument in 'strncat' is too large, might lead to a "
- "buffer overflow">, InGroup<StrncatSize>;
-def warn_strncat_src_size : Warning<"size argument in 'strncat' call appears "
- "to be size of the source">, InGroup<StrncatSize>;
-def warn_strncat_wrong_size : Warning<
- "the value of the size argument to 'strncat' is wrong">, InGroup<StrncatSize>;
-def note_strncat_wrong_size : Note<
- "change the argument to be the free space in the destination buffer minus "
- "the terminating null byte">;
-
-def warn_assume_side_effects : Warning<
- "the argument to %0 has side effects that will be discarded">,
- InGroup<DiagGroup<"assume">>;
-
-def warn_memcpy_chk_overflow : Warning<
- "%0 will always overflow destination buffer">,
- InGroup<DiagGroup<"builtin-memcpy-chk-size">>;
-
-/// main()
-// static main() is not an error in C, just in C++.
-def warn_static_main : Warning<"'main' should not be declared static">,
- InGroup<Main>;
-def err_static_main : Error<"'main' is not allowed to be declared static">;
-def err_inline_main : Error<"'main' is not allowed to be declared inline">;
-def ext_variadic_main : ExtWarn<
- "'main' is not allowed to be declared variadic">, InGroup<Main>;
-def ext_noreturn_main : ExtWarn<
- "'main' is not allowed to be declared _Noreturn">, InGroup<Main>;
-def note_main_remove_noreturn : Note<"remove '_Noreturn'">;
-def err_constexpr_main : Error<
- "'main' is not allowed to be declared constexpr">;
-def err_deleted_main : Error<"'main' is not allowed to be deleted">;
-def err_mainlike_template_decl : Error<"%0 cannot be a template">;
-def err_main_returns_nonint : Error<"'main' must return 'int'">;
-def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,
- InGroup<MainReturnType>;
-def note_main_change_return_type : Note<"change return type to 'int'">;
-def err_main_surplus_args : Error<"too many parameters (%0) for 'main': "
- "must be 0, 2, or 3">;
-def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">,
- InGroup<Main>;
-def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
- "parameter of 'main' (%select{argument count|argument array|environment|"
- "platform-specific data}0) must be of type %1">;
-def err_main_global_variable :
- Error<"main cannot be declared as global variable">;
-def warn_main_redefined : Warning<"variable named 'main' with external linkage "
- "has undefined behavior">, InGroup<Main>;
-def ext_main_used : Extension<
- "ISO C++ does not allow 'main' to be used by a program">, InGroup<Main>;
-
-/// parser diagnostics
-def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
- InGroup<MissingDeclarations>;
-def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">,
- InGroup<MissingDeclarations>;
-def err_typedef_not_identifier : Error<"typedef name must be an identifier">;
-def err_typedef_changes_linkage : Error<"unsupported: typedef changes linkage"
- " of anonymous type, but linkage was already computed">;
-def note_typedef_changes_linkage : Note<"use a tag name here to establish "
- "linkage prior to definition">;
-def err_statically_allocated_object : Error<
- "interface type cannot be statically allocated">;
-def err_object_cannot_be_passed_returned_by_value : Error<
- "interface type %1 cannot be %select{returned|passed}0 by value"
- "; did you forget * in %1?">;
-def err_parameters_retval_cannot_have_fp16_type : Error<
- "%select{parameters|function return value}0 cannot have __fp16 type; did you forget * ?">;
-def err_opencl_half_load_store : Error<
- "%select{loading directly from|assigning directly to}0 pointer to type %1 is not allowed">;
-def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">;
-def err_opencl_half_declaration : Error<
- "declaring variable of type %0 is not allowed">;
-def err_opencl_half_param : Error<
- "declaring function parameter of type %0 is not allowed; did you forget * ?">;
-def err_opencl_half_return : Error<
- "declaring function return value of type %0 is not allowed; did you forget * ?">;
-def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
-def warn_pragma_options_align_reset_failed : Warning<
- "#pragma options align=reset failed: %0">,
- InGroup<IgnoredPragmas>;
-def err_pragma_options_align_mac68k_target_unsupported : Error<
- "mac68k alignment pragma is not supported on this target">;
-def warn_pragma_pack_invalid_alignment : Warning<
- "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">,
- InGroup<IgnoredPragmas>;
-// 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<
- "specifying both a name and alignment to 'pop' is undefined">;
-def warn_pragma_pop_failed : Warning<"#pragma %0(pop, ...) failed: %1">,
- InGroup<IgnoredPragmas>;
-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 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', "
- "this keyword can only be used inside class or member function scope">;
-def err_super_in_lambda_unsupported : Error<
- "use of '__super' inside a lambda is unsupported">;
-
-def warn_pragma_unused_undeclared_var : Warning<
- "undeclared variable %0 used as an argument for '#pragma unused'">,
- InGroup<IgnoredPragmas>;
-def warn_pragma_unused_expected_var_arg : Warning<
- "only variables can be arguments to '#pragma unused'">,
- InGroup<IgnoredPragmas>;
-def err_pragma_push_visibility_mismatch : Error<
- "#pragma visibility push with no matching #pragma visibility pop">;
-def note_surrounding_namespace_ends_here : Note<
- "surrounding namespace with visibility attribute ends here">;
-def err_pragma_pop_visibility_mismatch : Error<
- "#pragma visibility pop with no matching #pragma visibility push">;
-def note_surrounding_namespace_starts_here : Note<
- "surrounding namespace with visibility attribute starts here">;
-def err_pragma_loop_invalid_argument_type : Error<
- "invalid argument of type %0; expected an integer type">;
-def err_pragma_loop_invalid_argument_value : Error<
- "%select{invalid value '%0'; must be positive|value '%0' is too large}1">;
-def err_pragma_loop_compatibility : Error<
- "%select{incompatible|duplicate}0 directives '%1' and '%2'">;
-def err_pragma_loop_precedes_nonloop : Error<
- "expected a for, while, or do-while loop to follow '%0'">;
-
-/// Objective-C parser diagnostics
-def err_duplicate_class_def : Error<
- "duplicate interface definition for class %0">;
-def err_undef_superclass : Error<
- "cannot find interface declaration for %0, superclass of %1">;
-def err_forward_superclass : Error<
- "attempting to use the forward class %0 as superclass of %1">;
-def err_no_nsconstant_string_class : Error<
- "cannot find interface declaration for %0">;
-def err_recursive_superclass : Error<
- "trying to recursively use %0 as superclass of %1">;
-def err_conflicting_aliasing_type : Error<"conflicting types for alias %0">;
-def warn_undef_interface : Warning<"cannot find interface declaration for %0">;
-def warn_duplicate_protocol_def : Warning<"duplicate protocol definition of %0 is ignored">;
-def err_protocol_has_circular_dependency : Error<
- "protocol has circular dependency">;
-def err_undeclared_protocol : Error<"cannot find protocol declaration for %0">;
-def warn_undef_protocolref : Warning<"cannot find protocol definition for %0">;
-def warn_atprotocol_protocol : Warning<
- "@protocol is using a forward protocol declaration of %0">, InGroup<AtProtocol>;
-def warn_readonly_property : Warning<
- "attribute 'readonly' of property %0 restricts attribute "
- "'readwrite' of property inherited from %1">,
- InGroup<PropertyAttr>;
-
-def warn_property_attribute : Warning<
- "'%1' attribute on property %0 does not match the property inherited from %2">,
- InGroup<PropertyAttr>;
-def warn_property_types_are_incompatible : Warning<
- "property type %0 is incompatible with type %1 inherited from %2">,
- InGroup<DiagGroup<"incompatible-property-type">>;
-def warn_protocol_property_mismatch : Warning<
- "property of type %0 was selected for synthesis">,
- InGroup<DiagGroup<"protocol-property-synthesis-ambiguity">>;
-def err_undef_interface : Error<"cannot find interface declaration for %0">;
-def err_category_forward_interface : Error<
- "cannot define %select{category|class extension}0 for undefined class %1">;
-def err_class_extension_after_impl : Error<
- "cannot declare class extension for %0 after class implementation">;
-def note_implementation_declared : Note<
- "class implementation is declared here">;
-def note_while_in_implementation : Note<
- "detected while default synthesizing properties in class implementation">;
-def note_class_declared : Note<
- "class is declared here">;
-def note_receiver_class_declared : Note<
- "receiver is instance of class declared here">;
-def note_receiver_expr_here : Note<
- "receiver expression is here">;
-def note_receiver_is_id : Note<
- "receiver is treated with 'id' type for purpose of method lookup">;
-def note_suppressed_class_declare : Note<
- "class with specified objc_requires_property_definitions attribute is declared here">;
-def err_objc_root_class_subclass : Error<
- "objc_root_class attribute may only be specified on a root class declaration">;
-def warn_objc_root_class_missing : Warning<
- "class %0 defined without specifying a base class">,
- InGroup<ObjCRootClass>;
-def note_objc_needs_superclass : Note<
- "add a super class to fix this problem">;
-def warn_dup_category_def : Warning<
- "duplicate definition of category %1 on interface %0">;
-def err_conflicting_super_class : Error<"conflicting super class name %0">;
-def err_dup_implementation_class : Error<"reimplementation of class %0">;
-def err_dup_implementation_category : Error<
- "reimplementation of category %1 for class %0">;
-def err_conflicting_ivar_type : Error<
- "instance variable %0 has conflicting type%diff{: $ vs $|}1,2">;
-def err_duplicate_ivar_declaration : Error<
- "instance variable is already declared">;
-def warn_on_superclass_use : Warning<
- "class implementation may not have super class">;
-def err_conflicting_ivar_bitwidth : Error<
- "instance variable %0 has conflicting bit-field width">;
-def err_conflicting_ivar_name : Error<
- "conflicting instance variable names: %0 vs %1">;
-def err_inconsistent_ivar_count : Error<
- "inconsistent number of instance variables specified">;
-def warn_undef_method_impl : Warning<"method definition for %0 not found">,
- InGroup<DiagGroup<"incomplete-implementation">>;
-
-def warn_conflicting_overriding_ret_types : Warning<
- "conflicting return type in "
- "declaration of %0%diff{: $ vs $|}1,2">,
- InGroup<OverridingMethodMismatch>, DefaultIgnore;
-
-def warn_conflicting_ret_types : Warning<
- "conflicting return type in "
- "implementation of %0%diff{: $ vs $|}1,2">,
- InGroup<MismatchedReturnTypes>;
-
-def warn_conflicting_overriding_ret_type_modifiers : Warning<
- "conflicting distributed object modifiers on return type "
- "in declaration of %0">,
- InGroup<OverridingMethodMismatch>, DefaultIgnore;
-
-def warn_conflicting_ret_type_modifiers : Warning<
- "conflicting distributed object modifiers on return type "
- "in implementation of %0">,
- InGroup<DistributedObjectModifiers>;
-
-def warn_non_covariant_overriding_ret_types : Warning<
- "conflicting return type in "
- "declaration of %0: %1 vs %2">,
- InGroup<OverridingMethodMismatch>, DefaultIgnore;
-
-def warn_non_covariant_ret_types : Warning<
- "conflicting return type in "
- "implementation of %0: %1 vs %2">,
- InGroup<MethodSignatures>, DefaultIgnore;
-
-def warn_conflicting_overriding_param_types : Warning<
- "conflicting parameter types in "
- "declaration of %0%diff{: $ vs $|}1,2">,
- InGroup<OverridingMethodMismatch>, DefaultIgnore;
-
-def warn_conflicting_param_types : Warning<
- "conflicting parameter types in "
- "implementation of %0%diff{: $ vs $|}1,2">,
- InGroup<MismatchedParameterTypes>;
-
-def warn_conflicting_param_modifiers : Warning<
- "conflicting distributed object modifiers on parameter type "
- "in implementation of %0">,
- InGroup<DistributedObjectModifiers>;
-
-def warn_conflicting_overriding_param_modifiers : Warning<
- "conflicting distributed object modifiers on parameter type "
- "in declaration of %0">,
- InGroup<OverridingMethodMismatch>, DefaultIgnore;
-
-def warn_non_contravariant_overriding_param_types : Warning<
- "conflicting parameter types in "
- "declaration of %0: %1 vs %2">,
- InGroup<OverridingMethodMismatch>, DefaultIgnore;
-
-def warn_non_contravariant_param_types : Warning<
- "conflicting parameter types in "
- "implementation of %0: %1 vs %2">,
- InGroup<MethodSignatures>, DefaultIgnore;
-
-def warn_conflicting_overriding_variadic :Warning<
- "conflicting variadic declaration of method and its "
- "implementation">,
- InGroup<OverridingMethodMismatch>, DefaultIgnore;
-
-def warn_conflicting_variadic :Warning<
- "conflicting variadic declaration of method and its "
- "implementation">;
-
-def warn_category_method_impl_match:Warning<
- "category is implementing a method which will also be implemented"
- " by its primary class">, InGroup<ObjCProtocolMethodImpl>;
-
-def warn_implements_nscopying : Warning<
-"default assign attribute on property %0 which implements "
-"NSCopying protocol is not appropriate with -fobjc-gc[-only]">;
-
-def warn_multiple_method_decl : Warning<"multiple methods named %0 found">,
- InGroup<ObjCMultipleMethodNames>;
-def warn_strict_multiple_method_decl : Warning<
- "multiple methods named %0 found">, InGroup<StrictSelector>, DefaultIgnore;
-def warn_accessor_property_type_mismatch : Warning<
- "type of property %0 does not match type of accessor %1">;
-def not_conv_function_declared_at : Note<"type conversion function declared here">;
-def note_method_declared_at : Note<"method %0 declared here">;
-def note_property_attribute : Note<"property %0 is declared "
- "%select{deprecated|unavailable|partial}1 here">;
-def err_setter_type_void : Error<"type of setter must be void">;
-def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
-def warn_duplicate_method_decl :
- Warning<"multiple declarations of method %0 found and ignored">,
- InGroup<MethodDuplicate>, DefaultIgnore;
-def warn_objc_cdirective_format_string :
- Warning<"using %0 directive in %select{NSString|CFString}1 "
- "which is being passed as a formatting argument to the formatting "
- "%select{method|CFfunction}2">,
- InGroup<ObjCCStringFormat>, DefaultIgnore;
-def err_objc_var_decl_inclass :
- Error<"cannot declare variable inside @interface or @protocol">;
-def error_missing_method_context : Error<
- "missing context for method declaration">;
-def err_objc_property_attr_mutually_exclusive : Error<
- "property attributes '%0' and '%1' are mutually exclusive">;
-def err_objc_property_requires_object : Error<
- "property with '%0' attribute must be of object type">;
-def warn_objc_property_no_assignment_attribute : Warning<
- "no 'assign', 'retain', or 'copy' attribute is specified - "
- "'assign' is assumed">,
- InGroup<ObjCPropertyNoAttribute>;
-def warn_objc_isa_use : Warning<
- "direct access to Objective-C's isa is deprecated in favor of "
- "object_getClass()">, InGroup<DeprecatedObjCIsaUsage>;
-def warn_objc_isa_assign : Warning<
- "assignment to Objective-C's isa is deprecated in favor of "
- "object_setClass()">, InGroup<DeprecatedObjCIsaUsage>;
-def warn_objc_pointer_masking : Warning<
- "bitmasking for introspection of Objective-C object pointers is strongly "
- "discouraged">,
- InGroup<ObjCPointerIntrospect>;
-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">,
- InGroup<ObjCPropertyNoAttribute>;
-def warn_property_attr_mismatch : Warning<
- "property attribute in class extension does not match the primary class">,
- InGroup<PropertyAttr>;
-def warn_property_implicitly_mismatched : Warning <
- "primary property declaration is implicitly strong while redeclaration "
- "in class extension is weak">,
- InGroup<DiagGroup<"objc-property-implicit-mismatch">>;
-def warn_objc_property_copy_missing_on_block : Warning<
- "'copy' attribute must be specified for the block property "
- "when -fobjc-gc-only is specified">;
-def warn_objc_property_retain_of_block : Warning<
- "retain'ed block property does not copy the block "
- "- use copy attribute instead">, InGroup<ObjCRetainBlockProperty>;
-def warn_objc_readonly_property_has_setter : Warning<
- "setter cannot be specified for a readonly property">,
- InGroup<ObjCReadonlyPropertyHasSetter>;
-def warn_atomic_property_rule : Warning<
- "writable atomic property %0 cannot pair a synthesized %select{getter|setter}1 "
- "with a user defined %select{getter|setter}2">,
- InGroup<DiagGroup<"atomic-property-with-user-defined-accessor">>;
-def note_atomic_property_fixup_suggest : Note<"setter and getter must both be "
- "synthesized, or both be user defined,or the property must be nonatomic">;
-def err_atomic_property_nontrivial_assign_op : Error<
- "atomic property of reference type %0 cannot have non-trivial assignment"
- " operator">;
-def warn_cocoa_naming_owned_rule : Warning<
- "property follows Cocoa naming"
- " convention for returning 'owned' objects">,
- InGroup<DiagGroup<"objc-property-matches-cocoa-ownership-rule">>;
-def err_cocoa_naming_owned_rule : Error<
- "property follows Cocoa naming"
- " convention for returning 'owned' objects">;
-def note_cocoa_naming_declare_family : Note<
- "explicitly declare getter %objcinstance0 with '%1' to return an 'unowned' "
- "object">;
-def warn_auto_synthesizing_protocol_property :Warning<
- "auto property synthesis will not synthesize property %0"
- " declared in protocol %1">,
- InGroup<DiagGroup<"objc-protocol-property-synthesis">>;
-def warn_no_autosynthesis_shared_ivar_property : Warning <
- "auto property synthesis will not synthesize property "
- "%0 because it cannot share an ivar with another synthesized property">,
- InGroup<ObjCNoPropertyAutoSynthesis>;
-def warn_no_autosynthesis_property : Warning<
- "auto property synthesis will not synthesize property "
- "%0 because it is 'readwrite' but it will be synthesized 'readonly' "
- "via another property">,
- InGroup<ObjCNoPropertyAutoSynthesis>;
-def warn_autosynthesis_property_in_superclass : Warning<
- "auto property synthesis will not synthesize property "
- "%0; it will be implemented by its superclass, use @dynamic to "
- "acknowledge intention">,
- InGroup<ObjCNoPropertyAutoSynthesis>;
-def warn_autosynthesis_property_ivar_match :Warning<
- "autosynthesized property %0 will use %select{|synthesized}1 instance variable "
- "%2, not existing instance variable %3">,
- InGroup<DiagGroup<"objc-autosynthesis-property-ivar-name-match">>;
-def warn_missing_explicit_synthesis : Warning <
- "auto property synthesis is synthesizing property not explicitly synthesized">,
- InGroup<DiagGroup<"objc-missing-property-synthesis">>, DefaultIgnore;
-def warn_property_getter_owning_mismatch : Warning<
- "property declared as returning non-retained objects"
- "; getter returning retained objects">;
-def warn_property_redecl_getter_mismatch : Warning<
- "getter name mismatch between property redeclaration (%1) and its original "
- "declaration (%0)">, InGroup<PropertyAttr>;
-def error_property_setter_ambiguous_use : Error<
- "synthesized properties %0 and %1 both claim setter %2 -"
- " use of this setter will cause unexpected behavior">;
-def warn_default_atomic_custom_getter_setter : Warning<
- "atomic by default property %0 has a user defined %select{getter|setter}1 "
- "(property should be marked 'atomic' if this is intended)">,
- InGroup<CustomAtomic>, DefaultIgnore;
-def err_use_continuation_class : Error<
- "illegal redeclaration of property in class extension %0"
- " (attribute must be 'readwrite', while its primary must be 'readonly')">;
-def err_type_mismatch_continuation_class : Error<
- "type of property %0 in class extension does not match "
- "property type in primary class">;
-def err_use_continuation_class_redeclaration_readwrite : Error<
- "illegal redeclaration of 'readwrite' property in class extension %0"
- " (perhaps you intended this to be a 'readwrite' redeclaration of a "
- "'readonly' public property?)">;
-def err_continuation_class : Error<"class extension has no primary class">;
-def err_property_type : Error<"property cannot have array or function type %0">;
-def error_missing_property_context : Error<
- "missing context for property implementation declaration">;
-def error_bad_property_decl : Error<
- "property implementation must have its declaration in interface %0 or one of "
- "its extensions">;
-def error_category_property : Error<
- "property declared in category %0 cannot be implemented in "
- "class implementation">;
-def note_property_declare : Note<
- "property declared here">;
-def note_protocol_property_declare : Note<
- "it could also be property of type %0 declared here">;
-def note_property_synthesize : Note<
- "property synthesized here">;
-def error_synthesize_category_decl : Error<
- "@synthesize not allowed in a category's implementation">;
-def error_reference_property : Error<
- "property of reference type is not supported">;
-def error_missing_property_interface : Error<
- "property implementation in a category with no category declaration">;
-def error_bad_category_property_decl : Error<
- "property implementation must have its declaration in the category %0">;
-def error_bad_property_context : Error<
- "property implementation must be in a class or category implementation">;
-def error_missing_property_ivar_decl : Error<
- "synthesized property %0 must either be named the same as a compatible"
- " instance variable or must explicitly name an instance variable">;
-def err_arc_perform_selector_retains : Error<
- "performSelector names a selector which retains the object">;
-def warn_arc_perform_selector_leaks : Warning<
- "performSelector may cause a leak because its selector is unknown">,
- InGroup<DiagGroup<"arc-performSelector-leaks">>;
-def warn_dealloc_in_category : Warning<
-"-dealloc is being overridden in a category">,
-InGroup<DeallocInCategory>;
-def err_gc_weak_property_strong_type : Error<
- "weak attribute declared on a __strong type property in GC mode">;
-def warn_arc_repeated_use_of_weak : Warning <
- "weak %select{variable|property|implicit property|instance variable}0 %1 is "
- "accessed multiple times in this %select{function|method|block|lambda}2 "
- "but may be unpredictably set to nil; assign to a strong variable to keep "
- "the object alive">,
- InGroup<ARCRepeatedUseOfWeak>, DefaultIgnore;
-def warn_implicitly_retains_self : Warning <
- "block implicitly retains 'self'; explicitly mention 'self' to indicate "
- "this is intended behavior">,
- InGroup<DiagGroup<"implicit-retain-self">>, DefaultIgnore;
-def warn_arc_possible_repeated_use_of_weak : Warning <
- "weak %select{variable|property|implicit property|instance variable}0 %1 may "
- "be accessed multiple times in this %select{function|method|block|lambda}2 "
- "and may be unpredictably set to nil; assign to a strong variable to keep "
- "the object alive">,
- InGroup<ARCRepeatedUseOfWeakMaybe>, DefaultIgnore;
-def note_arc_weak_also_accessed_here : Note<
- "also accessed here">;
-def err_incomplete_synthesized_property : Error<
- "cannot synthesize property %0 with incomplete type %1">;
-
-def error_property_ivar_type : Error<
- "type of property %0 (%1) does not match type of instance variable %2 (%3)">;
-def error_property_accessor_type : Error<
- "type of property %0 (%1) does not match type of accessor %2 (%3)">;
-def error_ivar_in_superclass_use : Error<
- "property %0 attempting to use instance variable %1 declared in super class %2">;
-def error_weak_property : Error<
- "existing instance variable %1 for __weak property %0 must be __weak">;
-def error_strong_property : Error<
- "existing instance variable %1 for strong property %0 may not be __weak">;
-def error_dynamic_property_ivar_decl : Error<
- "dynamic property cannot have instance variable specification">;
-def error_duplicate_ivar_use : Error<
- "synthesized properties %0 and %1 both claim instance variable %2">;
-def error_property_implemented : Error<"property %0 is already implemented">;
-def warn_objc_missing_super_call : Warning<
- "method possibly missing a [super %0] call">,
- InGroup<ObjCMissingSuperCalls>;
-def error_dealloc_bad_result_type : Error<
- "dealloc return type must be correctly specified as 'void' under ARC, "
- "instead of %0">;
-def warn_undeclared_selector : Warning<
- "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
-def warn_undeclared_selector_with_typo : Warning<
- "undeclared selector %0; did you mean %1?">,
- InGroup<UndeclaredSelector>, DefaultIgnore;
-def warn_implicit_atomic_property : Warning<
- "property is assumed atomic by default">, InGroup<ImplicitAtomic>, DefaultIgnore;
-def note_auto_readonly_iboutlet_fixup_suggest : Note<
- "property should be changed to be readwrite">;
-def warn_auto_readonly_iboutlet_property : Warning<
- "readonly IBOutlet property %0 when auto-synthesized may "
- "not work correctly with 'nib' loader">,
- InGroup<DiagGroup<"readonly-iboutlet-property">>;
-def warn_auto_implicit_atomic_property : Warning<
- "property is assumed atomic when auto-synthesizing the property">,
- InGroup<ImplicitAtomic>, DefaultIgnore;
-def warn_unimplemented_selector: Warning<
- "no method with selector %0 is implemented in this translation unit">,
- InGroup<Selector>, DefaultIgnore;
-def warn_unimplemented_protocol_method : Warning<
- "method %0 in protocol %1 not implemented">, InGroup<Protocol>;
-def warning_multiple_selectors: Warning<
- "several methods with selector %0 of mismatched types are found "
- "for the @selector expression">,
- InGroup<SelectorTypeMismatch>, DefaultIgnore;
-
-def err_objc_kindof_nonobject : Error<
- "'__kindof' specifier cannot be applied to non-object type %0">;
-def err_objc_kindof_wrong_position : Error<
- "'__kindof' type specifier must precede the declarator">;
-
-// C++ declarations
-def err_static_assert_expression_is_not_constant : Error<
- "static_assert expression is not an integral constant expression">;
-def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;
-def ext_static_assert_no_message : ExtWarn<
- "static_assert with no message is a C++1z extension">, InGroup<CXX1z>;
-def warn_cxx14_compat_static_assert_no_message : Warning<
- "static_assert with no message is incompatible with C++ standards before C++1z">,
- DefaultIgnore, InGroup<CXXPre1zCompat>;
-
-def warn_inline_namespace_reopened_noninline : Warning<
- "inline namespace cannot be reopened as a non-inline namespace">;
-def err_inline_namespace_mismatch : Error<
- "%select{|non-}0inline namespace "
- "cannot be reopened as %select{non-|}0inline">;
-
-def err_unexpected_friend : Error<
- "friends can only be classes or functions">;
-def ext_enum_friend : ExtWarn<
- "befriending enumeration type %0 is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_enum_friend : Warning<
- "befriending enumeration type %0 is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_nonclass_type_friend : ExtWarn<
- "non-class friend type %0 is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_nonclass_type_friend : Warning<
- "non-class friend type %0 is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_friend_is_member : Error<
- "friends cannot be members of the declaring class">;
-def warn_cxx98_compat_friend_is_member : Warning<
- "friend declaration naming a member of the declaring class is incompatible "
- "with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def ext_unelaborated_friend_type : ExtWarn<
- "unelaborated friend declaration is a C++11 extension; specify "
- "'%select{struct|interface|union|class|enum}0' to befriend %1">,
- InGroup<CXX11>;
-def warn_cxx98_compat_unelaborated_friend_type : Warning<
- "befriending %1 without '%select{struct|interface|union|class|enum}0' "
- "keyword is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def err_qualified_friend_not_found : Error<
- "no function named %0 with type %1 was found in the specified scope">;
-def err_introducing_special_friend : Error<
- "must use a qualified name when declaring a %select{constructor|"
- "destructor|conversion operator}0 as a friend">;
-def err_tagless_friend_type_template : Error<
- "friend type templates must use an elaborated type">;
-def err_no_matching_local_friend : Error<
- "no matching function found in local scope">;
-def err_no_matching_local_friend_suggest : Error<
- "no matching function %0 found in local scope; did you mean %3?">;
-def err_partial_specialization_friend : Error<
- "partial specialization cannot be declared as a friend">;
-def err_qualified_friend_def : Error<
- "friend function definition cannot be qualified with '%0'">;
-def err_friend_def_in_local_class : Error<
- "friend function cannot be defined in a local class">;
-def err_friend_not_first_in_declaration : Error<
- "'friend' must appear first in a non-function declaration">;
-def err_using_decl_friend : Error<
- "cannot befriend target of using declaration">;
-def warn_template_qualified_friend_unsupported : Warning<
- "dependent nested name specifier '%0' for friend class declaration is "
- "not supported; turning off access control for %1">,
- InGroup<UnsupportedFriend>;
-def warn_template_qualified_friend_ignored : Warning<
- "dependent nested name specifier '%0' for friend template declaration is "
- "not supported; ignoring this friend declaration">,
- InGroup<UnsupportedFriend>;
-def ext_friend_tag_redecl_outside_namespace : ExtWarn<
- "unqualified friend declaration referring to type outside of the nearest "
- "enclosing namespace is a Microsoft extension; add a nested name specifier">,
- InGroup<MicrosoftUnqualifiedFriend>;
-def err_pure_friend : Error<"friend declaration cannot have a pure-specifier">;
-
-def err_invalid_member_in_interface : Error<
- "%select{data member |non-public member function |static member function |"
- "user-declared constructor|user-declared destructor|operator |"
- "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'">;
-
-def err_abstract_type_in_decl : Error<
- "%select{return|parameter|variable|field|instance variable|"
- "synthesized instance variable}0 type %1 is an abstract class">;
-def err_allocation_of_abstract_type : Error<
- "allocating an object of abstract class type %0">;
-def err_throw_abstract_type : Error<
- "cannot throw an object of abstract type %0">;
-def err_array_of_abstract_type : Error<"array of abstract class type %0">;
-def err_capture_of_abstract_type : Error<
- "by-copy capture of value of abstract type %0">;
-def err_capture_of_incomplete_type : Error<
- "by-copy capture of variable %0 with incomplete type %1">;
-def err_capture_default_non_local : Error<
- "non-local lambda expression cannot have a capture-default">;
-
-def err_multiple_final_overriders : Error<
- "virtual function %q0 has more than one final overrider in %1">;
-def note_final_overrider : Note<"final overrider of %q0 in %1">;
-
-def err_type_defined_in_type_specifier : Error<
- "%0 cannot be defined in a type specifier">;
-def err_type_defined_in_result_type : Error<
- "%0 cannot be defined in the result type of a function">;
-def err_type_defined_in_param_type : Error<
- "%0 cannot be defined in a parameter type">;
-def err_type_defined_in_alias_template : Error<
- "%0 cannot be defined in a type alias template">;
-def err_type_defined_in_condition : Error<
- "%0 cannot be defined in a condition">;
-
-def note_pure_virtual_function : Note<
- "unimplemented pure virtual method %0 in %1">;
-
-def note_pure_qualified_call_kext : Note<
- "qualified call to %0::%1 is treated as a virtual call to %1 due to -fapple-kext">;
-
-def err_deleted_decl_not_first : Error<
- "deleted definition must be first declaration">;
-
-def err_deleted_override : Error<
- "deleted function %0 cannot override a non-deleted function">;
-
-def err_non_deleted_override : Error<
- "non-deleted function %0 cannot override a deleted function">;
-
-def warn_weak_vtable : Warning<
- "%0 has no out-of-line virtual method definitions; its vtable will be "
- "emitted in every translation unit">,
- InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore;
-def warn_weak_template_vtable : Warning<
- "explicit template instantiation %0 will emit a vtable in every "
- "translation unit">,
- InGroup<DiagGroup<"weak-template-vtables">>, DefaultIgnore;
-
-def ext_using_undefined_std : ExtWarn<
- "using directive refers to implicitly-defined namespace 'std'">;
-
-// C++ exception specifications
-def err_exception_spec_in_typedef : Error<
- "exception specifications are not allowed in %select{typedefs|type aliases}0">;
-def err_distant_exception_spec : Error<
- "exception specifications are not allowed beyond a single level "
- "of indirection">;
-def err_incomplete_in_exception_spec : Error<
- "%select{|pointer to |reference to }0incomplete type %1 is not allowed "
- "in exception specification">;
-def err_rref_in_exception_spec : Error<
- "rvalue reference type %0 is not allowed in exception specification">;
-def err_mismatched_exception_spec : Error<
- "exception specification in declaration does not match previous declaration">;
-def ext_mismatched_exception_spec : ExtWarn<err_mismatched_exception_spec.Text>,
- InGroup<MicrosoftExceptionSpec>;
-def err_override_exception_spec : Error<
- "exception specification of overriding function is more lax than "
- "base version">;
-def ext_override_exception_spec : ExtWarn<err_override_exception_spec.Text>,
- InGroup<MicrosoftExceptionSpec>;
-def err_incompatible_exception_specs : Error<
- "target exception specification is not superset of source">;
-def err_deep_exception_specs_differ : Error<
- "exception specifications of %select{return|argument}0 types differ">;
-def err_missing_exception_specification : Error<
- "%0 is missing exception specification '%1'">;
-def ext_missing_exception_specification : ExtWarn<
- err_missing_exception_specification.Text>,
- InGroup<DiagGroup<"missing-exception-spec">>;
-def ext_ms_missing_exception_specification : ExtWarn<
- err_missing_exception_specification.Text>,
- InGroup<MicrosoftExceptionSpec>;
-def err_noexcept_needs_constant_expression : Error<
- "argument to noexcept specifier must be a constant expression">;
-def err_exception_spec_not_parsed : Error<
- "exception specification is not available until end of class definition">;
-
-// C++ access checking
-def err_class_redeclared_with_different_access : Error<
- "%0 redeclared with '%1' access">;
-def err_access : Error<
- "%1 is a %select{private|protected}0 member of %3">, AccessControl;
-def ext_ms_using_declaration_inaccessible : ExtWarn<
- "using declaration referring to inaccessible member '%0' (which refers "
- "to accessible member '%1') is a Microsoft compatibility extension">,
- AccessControl, InGroup<MicrosoftUsingDecl>;
-def err_access_ctor : Error<
- "calling a %select{private|protected}0 constructor of class %2">,
- AccessControl;
-def ext_rvalue_to_reference_access_ctor : Extension<
- "C++98 requires an accessible copy constructor for class %2 when binding "
- "a reference to a temporary; was %select{private|protected}0">,
- AccessControl, InGroup<BindToTemporaryCopy>;
-def err_access_base_ctor : Error<
- // The ERRORs represent other special members that aren't constructors, in
- // hopes that someone will bother noticing and reporting if they appear
- "%select{base class|inherited virtual base class}0 %1 has %select{private|"
- "protected}3 %select{default |copy |move |*ERROR* |*ERROR* "
- "|*ERROR*|}2constructor">, AccessControl;
-def err_access_field_ctor : Error<
- // The ERRORs represent other special members that aren't constructors, in
- // hopes that someone will bother noticing and reporting if they appear
- "field of type %0 has %select{private|protected}2 "
- "%select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}1constructor">,
- AccessControl;
-def err_access_friend_function : Error<
- "friend function %1 is a %select{private|protected}0 member of %3">,
- AccessControl;
-
-def err_access_dtor : Error<
- "calling a %select{private|protected}1 destructor of class %0">,
- AccessControl;
-def err_access_dtor_base :
- Error<"base class %0 has %select{private|protected}1 destructor">,
- AccessControl;
-def err_access_dtor_vbase :
- Error<"inherited virtual base class %1 has "
- "%select{private|protected}2 destructor">,
- AccessControl;
-def err_access_dtor_temp :
- Error<"temporary of type %0 has %select{private|protected}1 destructor">,
- AccessControl;
-def err_access_dtor_exception :
- Error<"exception object of type %0 has %select{private|protected}1 "
- "destructor">, AccessControl;
-def err_access_dtor_field :
- Error<"field of type %1 has %select{private|protected}2 destructor">,
- AccessControl;
-def err_access_dtor_var :
- Error<"variable of type %1 has %select{private|protected}2 destructor">,
- AccessControl;
-def err_access_dtor_ivar :
- Error<"instance variable of type %0 has %select{private|protected}1 "
- "destructor">,
- AccessControl;
-def note_previous_access_declaration : Note<
- "previously declared '%1' here">;
-def note_access_natural : Note<
- "%select{|implicitly }1declared %select{private|protected}0 here">;
-def note_access_constrained_by_path : Note<
- "constrained by %select{|implicitly }1%select{private|protected}0"
- " inheritance here">;
-def note_access_protected_restricted_noobject : Note<
- "must name member using the type of the current context %0">;
-def note_access_protected_restricted_ctordtor : Note<
- "protected %select{constructor|destructor}0 can only be used to "
- "%select{construct|destroy}0 a base class subobject">;
-def note_access_protected_restricted_object : Note<
- "can only access this member on an object of type %0">;
-def warn_cxx98_compat_sfinae_access_control : Warning<
- "substitution failure due to access control is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore, NoSFINAE;
-
-// C++ name lookup
-def err_incomplete_nested_name_spec : Error<
- "incomplete type %0 named in nested name specifier">;
-def err_dependent_nested_name_spec : Error<
- "nested name specifier for a declaration cannot depend on a template "
- "parameter">;
-def err_nested_name_member_ref_lookup_ambiguous : Error<
- "lookup of %0 in member access expression is ambiguous">;
-def ext_nested_name_member_ref_lookup_ambiguous : ExtWarn<
- "lookup of %0 in member access expression is ambiguous; using member of %1">,
- InGroup<AmbigMemberTemplate>;
-def note_ambig_member_ref_object_type : Note<
- "lookup in the object type %0 refers here">;
-def note_ambig_member_ref_scope : Note<
- "lookup from the current scope refers here">;
-def err_qualified_member_nonclass : Error<
- "qualified member access refers to a member in %0">;
-def err_incomplete_member_access : Error<
- "member access into incomplete type %0">;
-def err_incomplete_type : Error<
- "incomplete type %0 where a complete type is required">;
-def warn_cxx98_compat_enum_nested_name_spec : Warning<
- "enumeration type in nested name specifier is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_nested_name_spec_is_not_class : Error<
- "%0 cannot appear before '::' because it is not a class"
- "%select{ or namespace|, namespace, or enumeration}1; did you mean ':'?">;
-def ext_nested_name_spec_is_enum : ExtWarn<
- "use of enumeration in a nested name specifier is a C++11 extension">,
- InGroup<CXX11>;
-
-// C++ class members
-def err_storageclass_invalid_for_member : Error<
- "storage class specified for a member declaration">;
-def err_mutable_function : Error<"'mutable' cannot be applied to functions">;
-def err_mutable_reference : Error<"'mutable' cannot be applied to references">;
-def ext_mutable_reference : ExtWarn<
- "'mutable' on a reference type is a Microsoft extension">,
- InGroup<MicrosoftMutableReference>;
-def err_mutable_const : Error<"'mutable' and 'const' cannot be mixed">;
-def err_mutable_nonmember : Error<
- "'mutable' can only be applied to member variables">;
-def err_virtual_in_union : Error<
- "unions cannot have virtual functions">;
-def err_virtual_non_function : Error<
- "'virtual' can only appear on non-static member functions">;
-def err_virtual_out_of_class : Error<
- "'virtual' can only be specified inside the class definition">;
-def err_virtual_member_function_template : Error<
- "'virtual' cannot be specified on member function templates">;
-def err_static_overrides_virtual : Error<
- "'static' member function %0 overrides a virtual function in a base class">;
-def err_explicit_non_function : Error<
- "'explicit' can only appear on non-static member functions">;
-def err_explicit_out_of_class : Error<
- "'explicit' can only be specified inside the class definition">;
-def err_explicit_non_ctor_or_conv_function : Error<
- "'explicit' can only be applied to a constructor or conversion function">;
-def err_static_not_bitfield : Error<"static member %0 cannot be a bit-field">;
-def err_static_out_of_line : Error<
- "'static' can only be specified inside the class definition">;
-def err_storage_class_for_static_member : Error<
- "static data member definition cannot specify a storage class">;
-def err_typedef_not_bitfield : Error<"typedef member %0 cannot be a bit-field">;
-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_member_function_initialization : Error<
- "initializer on function does not look like a pure-specifier">;
-def err_non_virtual_pure : Error<
- "%0 is not virtual and cannot be declared pure">;
-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 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 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<
- "implicit %select{default constructor|copy constructor|move constructor|copy "
- "assignment operator|move assignment operator|destructor}0 for %1 first "
- "required here">;
-def note_inhctor_synthesized_at : Note<
- "inheriting constructor for %0 first required here">;
-def err_missing_default_ctor : Error<
- "%select{|implicit default |inheriting }0constructor for %1 must explicitly "
- "initialize the %select{base class|member}2 %3 which 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">;
-
-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">;
-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">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-def note_nontrivial_virtual_dtor : Note<
- "destructor for %0 is not trivial because it is virtual">;
-def note_nontrivial_has_virtual : Note<
- "because type %0 has a virtual %select{member function|base class}1">;
-def note_nontrivial_no_def_ctor : Note<
- "because %select{base class of |field of |}0type %1 has no "
- "default constructor">;
-def note_user_declared_ctor : Note<
- "implicit default constructor suppressed by user-declared constructor">;
-def note_nontrivial_no_copy : Note<
- "because no %select{<<ERROR>>|constructor|constructor|assignment operator|"
- "assignment operator|<<ERROR>>}2 can be used to "
- "%select{<<ERROR>>|copy|move|copy|move|<<ERROR>>}2 "
- "%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">;
-def note_nontrivial_in_class_init : Note<
- "because field %0 has an initializer">;
-def note_nontrivial_param_type : Note<
- "because its parameter is %diff{of type $, not $|of the wrong type}2,3">;
-def note_nontrivial_default_arg : Note<"because it has a default argument">;
-def note_nontrivial_variadic : Note<"because it is a variadic function">;
-def note_nontrivial_subobject : Note<
- "because the function selected to %select{construct|copy|move|copy|move|"
- "destroy}2 %select{base class|field}0 of type %1 is not trivial">;
-def note_nontrivial_objc_ownership : Note<
- "because type %0 has a member with %select{no|no|__strong|__weak|"
- "__autoreleasing}1 ownership">;
-
-def err_static_data_member_not_allowed_in_anon_struct : Error<
- "static data member %0 not allowed in anonymous struct">;
-def ext_static_data_member_in_union : ExtWarn<
- "static data member %0 in union is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_static_data_member_in_union : Warning<
- "static data member %0 in union is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_union_member_of_reference_type : ExtWarn<
- "union member %0 has reference type %1, which is a Microsoft extension">,
- InGroup<MicrosoftUnionMemberReference>;
-def err_union_member_of_reference_type : Error<
- "union member %0 has reference type %1">;
-def ext_anonymous_struct_union_qualified : Extension<
- "anonymous %select{struct|union}0 cannot be '%1'">;
-def err_different_return_type_for_overriding_virtual_function : Error<
- "virtual function %0 has a different return type "
- "%diff{($) than the function it overrides (which has return type $)|"
- "than the function it overrides}1,2">;
-def note_overridden_virtual_function : Note<
- "overridden virtual function is here">;
-def err_conflicting_overriding_cc_attributes : Error<
- "virtual function %0 has different calling convention attributes "
- "%diff{($) than the function it overrides (which has calling convention $)|"
- "than the function it overrides}1,2">;
-
-def err_covariant_return_inaccessible_base : Error<
- "invalid covariant return for virtual function: %1 is a "
- "%select{private|protected}2 base class of %0">, AccessControl;
-def err_covariant_return_ambiguous_derived_to_base_conv : Error<
- "return type of virtual function %3 is not covariant with the return type of "
- "the function it overrides (ambiguous conversion from derived class "
- "%0 to base class %1:%2)">;
-def err_covariant_return_not_derived : Error<
- "return type of virtual function %0 is not covariant with the return type of "
- "the function it overrides (%1 is not derived from %2)">;
-def err_covariant_return_incomplete : Error<
- "return type of virtual function %0 is not covariant with the return type of "
- "the function it overrides (%1 is incomplete)">;
-def err_covariant_return_type_different_qualifications : Error<
- "return type of virtual function %0 is not covariant with the return type of "
- "the function it overrides (%1 has different qualifiers than %2)">;
-def err_covariant_return_type_class_type_more_qualified : Error<
- "return type of virtual function %0 is not covariant with the return type of "
- "the function it overrides (class type %1 is more qualified than class "
- "type %2">;
-
-// C++ constructors
-def err_constructor_cannot_be : Error<"constructor cannot be declared '%0'">;
-def err_invalid_qualified_constructor : Error<
- "'%0' qualifier is not allowed on a constructor">;
-def err_ref_qualifier_constructor : Error<
- "ref-qualifier '%select{&&|&}0' is not allowed on a constructor">;
-
-def err_constructor_return_type : Error<
- "constructor cannot have a return type">;
-def err_constructor_redeclared : Error<"constructor cannot be redeclared">;
-def err_constructor_byvalue_arg : Error<
- "copy constructor must pass its first argument by reference">;
-def warn_no_constructor_for_refconst : Warning<
- "%select{struct|interface|union|class|enum}0 %1 does not declare any "
- "constructor to initialize its non-modifiable members">;
-def note_refconst_member_not_initialized : Note<
- "%select{const|reference}0 member %1 will never be initialized">;
-def ext_ms_explicit_constructor_call : ExtWarn<
- "explicit constructor calls are a Microsoft extension">,
- InGroup<MicrosoftExplicitConstructorCall>;
-
-// C++ destructors
-def err_destructor_not_member : Error<
- "destructor must be a non-static member function">;
-def err_destructor_cannot_be : Error<"destructor cannot be declared '%0'">;
-def err_invalid_qualified_destructor : Error<
- "'%0' qualifier is not allowed on a destructor">;
-def err_ref_qualifier_destructor : Error<
- "ref-qualifier '%select{&&|&}0' is not allowed on a destructor">;
-def err_destructor_return_type : Error<"destructor cannot have a return type">;
-def err_destructor_redeclared : Error<"destructor cannot be redeclared">;
-def err_destructor_with_params : Error<"destructor cannot have any parameters">;
-def err_destructor_variadic : Error<"destructor cannot be variadic">;
-def err_destructor_typedef_name : Error<
- "destructor cannot be declared using a %select{typedef|type alias}1 %0 of the class name">;
-def err_destructor_name : Error<
- "expected the class name after '~' to name the enclosing class">;
-def err_destructor_class_name : Error<
- "expected the class name after '~' to name a destructor">;
-def err_ident_in_dtor_not_a_type : Error<
- "identifier %0 in object destruction expression does not name a type">;
-def err_destructor_expr_type_mismatch : Error<
- "destructor type %0 in object destruction expression does not match the "
- "type %1 of the object being destroyed">;
-def note_destructor_type_here : Note<
- "type %0 is declared here">;
-
-def err_destructor_template : Error<
- "destructor cannot be declared as a template">;
-
-// C++ initialization
-def err_init_conversion_failed : Error<
- "cannot initialize %select{a variable|a parameter|return object|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 "
- "complex element|a lambda capture|a compound literal initializer|a "
- "related result|a parameter of CF audited function}0 "
- "%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"
- "with an %select{rvalue|lvalue}2 of incompatible type}1,3"
- "%select{|: different classes%diff{ ($ vs $)|}5,6"
- "|: different number of parameters (%5 vs %6)"
- "|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7"
- "|: different return type%diff{ ($ vs $)|}5,6"
- "|: different qualifiers ("
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}5 vs "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}6)}4">;
-
-def err_lvalue_to_rvalue_ref : Error<"rvalue reference %diff{to type $ cannot "
- "bind to lvalue of type $|cannot bind to incompatible lvalue}0,1">;
-def err_lvalue_reference_bind_to_initlist : Error<
- "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to an "
- "initializer list temporary">;
-def err_lvalue_reference_bind_to_temporary : Error<
- "%select{non-const|volatile}0 lvalue reference %diff{to type $ cannot bind "
- "to a temporary of type $|cannot bind to incompatible temporary}1,2">;
-def err_lvalue_reference_bind_to_unrelated : Error<
- "%select{non-const|volatile}0 lvalue reference "
- "%diff{to type $ cannot bind to a value of unrelated type $|"
- "cannot bind to a value of unrelated type}1,2">;
-def err_reference_bind_drops_quals : Error<
- "binding value %diff{of type $ to reference to type $|to reference}0,1 "
- "drops %select{<<ERROR>>|'const'|'restrict'|'const' and 'restrict'|"
- "'volatile'|'const' and 'volatile'|'restrict' and 'volatile'|"
- "'const', 'restrict', and 'volatile'}2 qualifier%plural{1:|2:|4:|:s}2">;
-def err_reference_bind_failed : Error<
- "reference %diff{to type $ could not bind to an %select{rvalue|lvalue}1 of "
- "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 "
- "bit-field%select{| %1}2">;
-def err_reference_bind_to_vector_element : Error<
- "%select{non-const|volatile}0 reference cannot bind to vector element">;
-def err_reference_var_requires_init : Error<
- "declaration of reference variable %0 requires an initializer">;
-def err_reference_without_init : Error<
- "reference to type %0 requires an initializer">;
-def note_value_initialization_here : Note<
- "in value-initialization of type %0 here">;
-def err_reference_has_multiple_inits : Error<
- "reference cannot be initialized with multiple values">;
-def err_init_non_aggr_init_list : Error<
- "initialization of non-aggregate type %0 with an initializer list">;
-def err_init_reference_member_uninitialized : Error<
- "reference member of type %0 uninitialized">;
-def note_uninit_reference_member : Note<
- "uninitialized reference member is here">;
-def warn_field_is_uninit : Warning<"field %0 is uninitialized when used here">,
- InGroup<Uninitialized>;
-def warn_base_class_is_uninit : Warning<
- "base class %0 is uninitialized when used here to access %q1">,
- InGroup<Uninitialized>;
-def warn_reference_field_is_uninit : Warning<
- "reference %0 is not yet bound to a value when used here">,
- InGroup<Uninitialized>;
-def note_uninit_in_this_constructor : Note<
- "during field initialization in %select{this|the implicit default}0 "
- "constructor">;
-def warn_static_self_reference_in_init : Warning<
- "static variable %0 is suspiciously used within its own initialization">,
- InGroup<UninitializedStaticSelfInit>;
-def warn_uninit_self_reference_in_init : Warning<
- "variable %0 is uninitialized when used within its own initialization">,
- InGroup<Uninitialized>;
-def warn_uninit_self_reference_in_reference_init : Warning<
- "reference %0 is not yet bound to a value when used within its own"
- " initialization">,
- InGroup<Uninitialized>;
-def warn_uninit_var : Warning<
- "variable %0 is uninitialized when %select{used here|captured by block}1">,
- InGroup<Uninitialized>, DefaultIgnore;
-def warn_sometimes_uninit_var : Warning<
- "variable %0 is %select{used|captured}1 uninitialized whenever "
- "%select{'%3' condition is %select{true|false}4|"
- "'%3' loop %select{is entered|exits because its condition is false}4|"
- "'%3' loop %select{condition is true|exits because its condition is false}4|"
- "switch %3 is taken|"
- "its declaration is reached|"
- "%3 is called}2">,
- InGroup<UninitializedSometimes>, DefaultIgnore;
-def warn_maybe_uninit_var : Warning<
- "variable %0 may be uninitialized when "
- "%select{used here|captured by block}1">,
- InGroup<UninitializedMaybe>, DefaultIgnore;
-def note_uninit_var_def : Note<"variable %0 is declared here">;
-def note_uninit_var_use : Note<
- "%select{uninitialized use occurs|variable is captured by block}0 here">;
-def warn_uninit_byref_blockvar_captured_by_block : Warning<
- "block pointer variable %0 is uninitialized when captured by block">,
- InGroup<Uninitialized>, DefaultIgnore;
-def note_block_var_fixit_add_initialization : Note<
- "did you mean to use __block %0?">;
-def note_in_omitted_aggregate_initializer : Note<
- "in implicit initialization of %select{array element %1|field %1}0 "
- "with omitted initializer">;
-def note_in_reference_temporary_list_initializer : Note<
- "in initialization of temporary of type %0 created to "
- "list-initialize this reference">;
-def note_var_fixit_add_initialization : Note<
- "initialize the variable %0 to silence this warning">;
-def note_uninit_fixit_remove_cond : Note<
- "remove the %select{'%1' if its condition|condition if it}0 "
- "is always %select{false|true}2">;
-def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
-
-def warn_unsequenced_mod_mod : Warning<
- "multiple unsequenced modifications to %0">, InGroup<Unsequenced>;
-def warn_unsequenced_mod_use : Warning<
- "unsequenced modification and access to %0">, InGroup<Unsequenced>;
-
-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">;
-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">,
- 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">;
-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">;
-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 "
- "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">,
- InGroup<CXX98CompatBindToTemporaryCopy>, DefaultIgnore;
-def err_selected_explicit_constructor : Error<
- "chosen constructor is explicit in copy-initialization">;
-def note_constructor_declared_here : Note<
- "constructor declared here">;
-
-// C++11 decltype
-def err_decltype_in_declarator : Error<
- "'decltype' cannot be used to name a declaration">;
-
-// C++11 auto
-def warn_cxx98_compat_auto_type_specifier : Warning<
- "'auto' type specifier is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_auto_variable_cannot_appear_in_own_initializer : Error<
- "variable %0 declared with %select{'auto'|'decltype(auto)'|'__auto_type'}1 "
- "type cannot appear in its own initializer">;
-def err_illegal_decl_array_of_auto : Error<
- "'%0' declared as array of %1">;
-def err_new_array_of_auto : Error<
- "cannot allocate array of 'auto'">;
-def err_auto_not_allowed : Error<
- "%select{'auto'|'decltype(auto)'|'__auto_type'}0 not allowed "
- "%select{in function prototype"
- "|in non-static struct member|in struct member"
- "|in non-static union member|in union member"
- "|in non-static class member|in interface member"
- "|in exception declaration|in template parameter|in block literal"
- "|in template argument|in typedef|in type alias|in function return type"
- "|in conversion function type|here|in lambda parameter"
- "|in type allocated by 'new'|in K&R-style function parameter}1">;
-def err_auto_not_allowed_var_inst : Error<
- "'auto' variable template instantiation is not allowed">;
-def err_auto_var_requires_init : Error<
- "declaration of variable %0 with type %1 requires an initializer">;
-def err_auto_new_requires_ctor_arg : Error<
- "new expression for type %0 requires a constructor argument">;
-def err_auto_new_list_init : Error<
- "new expression for type %0 cannot use list-initialization">;
-def err_auto_var_init_no_expression : Error<
- "initializer for variable %0 with type %1 is empty">;
-def err_auto_var_init_multiple_expressions : Error<
- "initializer for variable %0 with type %1 contains multiple expressions">;
-def err_auto_var_init_paren_braces : Error<
- "cannot deduce type for variable %1 with type %2 from "
- "%select{parenthesized|nested}0 initializer list">;
-def err_auto_new_ctor_multiple_expressions : Error<
- "new expression for type %0 contains multiple constructor arguments">;
-def err_auto_missing_trailing_return : Error<
- "'auto' return without trailing return type; deduced return types are a "
- "C++14 extension">;
-def err_deduced_return_type : Error<
- "deduced return types are a C++14 extension">;
-def err_trailing_return_without_auto : Error<
- "function with trailing return type must specify return type 'auto', not %0">;
-def err_trailing_return_in_parens : Error<
- "trailing return type may not be nested within parentheses">;
-def err_auto_var_deduction_failure : Error<
- "variable %0 with type %1 has incompatible initializer of type %2">;
-def err_auto_var_deduction_failure_from_init_list : Error<
- "cannot deduce actual type for variable %0 with type %1 from initializer list">;
-def err_auto_new_deduction_failure : Error<
- "new expression for type %0 has incompatible constructor argument of type %1">;
-def err_auto_different_deductions : Error<
- "'%select{auto|decltype(auto)|__auto_type}0' deduced as %1 in declaration "
- "of %2 and deduced as %3 in declaration of %4">;
-def err_implied_std_initializer_list_not_found : Error<
- "cannot deduce type of initializer list because std::initializer_list was "
- "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<
- "cannot pass bit-field as __auto_type initializer in C">;
-
-// C++1y decltype(auto) type
-def err_decltype_auto_cannot_be_combined : Error<
- "'decltype(auto)' cannot be combined with other type specifiers">;
-def err_decltype_auto_function_declarator_not_declaration : Error<
- "'decltype(auto)' can only be used as a return type "
- "in a function declaration">;
-def err_decltype_auto_compound_type : Error<
- "cannot form %select{pointer to|reference to|array of}0 'decltype(auto)'">;
-def err_decltype_auto_initializer_list : Error<
- "cannot deduce 'decltype(auto)' from initializer list">;
-
-// C++1y deduced return types
-def err_auto_fn_deduction_failure : Error<
- "cannot deduce return type %0 from returned value of type %1">;
-def err_auto_fn_different_deductions : Error<
- "'%select{auto|decltype(auto)}0' in return type deduced as %1 here but "
- "deduced as %2 in earlier return statement">;
-def err_auto_fn_used_before_defined : Error<
- "function %0 with deduced return type cannot be used before it is defined">;
-def err_auto_fn_no_return_but_not_auto : Error<
- "cannot deduce return type %0 for function with no return statements">;
-def err_auto_fn_return_void_but_not_auto : Error<
- "cannot deduce return type %0 from omitted return expression">;
-def err_auto_fn_return_init_list : Error<
- "cannot deduce return type from initializer list">;
-def err_auto_fn_virtual : Error<
- "function with deduced return type cannot be virtual">;
-
-// C++11 override control
-def override_keyword_only_allowed_on_virtual_member_functions : Error<
- "only virtual member functions can be marked '%0'">;
-def override_keyword_hides_virtual_member_function : Error<
- "non-virtual member function marked '%0' hides virtual member "
- "%select{function|functions}1">;
-def err_function_marked_override_not_overriding : Error<
- "%0 marked 'override' but does not override any member functions">;
-def warn_function_marked_not_override_overriding : Warning <
- "%0 overrides a member function but is not marked 'override'">,
- InGroup<CXX11WarnOverrideMethod>;
-def err_class_marked_final_used_as_base : Error<
- "base %0 is marked '%select{final|sealed}1'">;
-def warn_abstract_final_class : Warning<
- "abstract class is marked '%select{final|sealed}0'">, InGroup<AbstractFinalClass>;
-
-// C++11 attributes
-def err_repeat_attribute : Error<"%0 attribute cannot be repeated">;
-
-// C++11 final
-def err_final_function_overridden : Error<
- "declaration of %0 overrides a '%select{final|sealed}1' function">;
-
-// C++11 scoped enumerations
-def err_enum_invalid_underlying : Error<
- "non-integral type %0 is an invalid underlying type">;
-def err_enumerator_too_large : Error<
- "enumerator value is not representable in the underlying type %0">;
-def ext_enumerator_too_large : ExtWarn<
- "enumerator value is not representable in the underlying type %0">,
- InGroup<MicrosoftEnumValue>;
-def err_enumerator_wrapped : Error<
- "enumerator value %0 is not representable in the underlying type %1">;
-def err_enum_redeclare_type_mismatch : Error<
- "enumeration redeclared with different underlying type %0 (was %1)">;
-def err_enum_redeclare_fixed_mismatch : Error<
- "enumeration previously declared with %select{non|}0fixed underlying type">;
-def err_enum_redeclare_scoped_mismatch : Error<
- "enumeration previously declared as %select{un|}0scoped">;
-def err_enum_class_reference : Error<
- "reference to %select{|scoped }0enumeration must use 'enum' "
- "not 'enum class'">;
-def err_only_enums_have_underlying_types : Error<
- "only enumeration types have underlying types">;
-def err_underlying_type_of_incomplete_enum : Error<
- "cannot determine underlying type of incomplete enumeration type %0">;
-
-// C++11 delegating constructors
-def err_delegating_ctor : Error<
- "delegating constructors are permitted only in C++11">;
-def warn_cxx98_compat_delegating_ctor : Warning<
- "delegating constructors are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_delegating_initializer_alone : Error<
- "an initializer for a delegating constructor must appear alone">;
-def warn_delegating_ctor_cycle : Warning<
- "constructor for %0 creates a delegation cycle">, DefaultError,
- InGroup<DelegatingCtorCycles>;
-def note_it_delegates_to : Note<"it delegates to">;
-def note_which_delegates_to : Note<"which delegates to">;
-
-// C++11 range-based for loop
-def err_for_range_decl_must_be_var : Error<
- "for range declaration must declare a variable">;
-def err_for_range_storage_class : Error<
- "loop variable %0 may not be declared %select{'extern'|'static'|"
- "'__private_extern__'|'auto'|'register'|'constexpr'}1">;
-def err_type_defined_in_for_range : Error<
- "types may not be defined in a for range declaration">;
-def err_for_range_deduction_failure : Error<
- "cannot use type %0 as a range">;
-def err_for_range_incomplete_type : Error<
- "cannot use incomplete type %0 as a range">;
-def err_for_range_iter_deduction_failure : Error<
- "cannot use type %0 as an iterator">;
-def err_for_range_member_begin_end_mismatch : Error<
- "range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member">;
-def err_for_range_begin_end_types_differ : Error<
- "'begin' and 'end' must return the same type (got %0 and %1)">;
-def note_in_for_range: Note<
- "when looking up '%select{begin|end}0' function for range expression "
- "of type %1">;
-def err_for_range_invalid: Error<
- "invalid range expression of type %0; no viable '%select{begin|end}1' "
- "function available">;
-def err_range_on_array_parameter : Error<
- "cannot build range expression with array function parameter %0 since "
- "parameter with array type %1 is treated as pointer type %2">;
-def err_for_range_dereference : Error<
- "invalid range expression of type %0; did you mean to dereference it "
- "with '*'?">;
-def note_for_range_invalid_iterator : Note <
- "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1">;
-def note_for_range_begin_end : Note<
- "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">;
-
-// C++11 constexpr
-def warn_cxx98_compat_constexpr : Warning<
- "'constexpr' specifier is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-// FIXME: Maybe this should also go in -Wc++14-compat?
-def warn_cxx14_compat_constexpr_not_const : Warning<
- "'constexpr' non-static member function will not be implicitly 'const' "
- "in C++14; add 'const' to avoid a change in behavior">,
- InGroup<DiagGroup<"constexpr-not-const">>;
-def err_invalid_constexpr : Error<
- "%select{function parameter|typedef|non-static data member}0 "
- "cannot be constexpr">;
-def err_invalid_constexpr_member : Error<"non-static data member cannot be "
- "constexpr%select{; did you intend to make it %select{const|static}0?|}1">;
-def err_constexpr_tag : Error<
- "%select{class|struct|interface|union|enum}0 cannot be marked constexpr">;
-def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">;
-def err_constexpr_no_declarators : Error<
- "constexpr can only be used in variable and function declarations">;
-def err_invalid_constexpr_var_decl : Error<
- "constexpr variable declaration must be a definition">;
-def err_constexpr_static_mem_var_requires_init : Error<
- "declaration of constexpr static data member %0 requires an initializer">;
-def err_constexpr_var_non_literal : Error<
- "constexpr variable cannot have non-literal type %0">;
-def err_constexpr_var_requires_const_init : Error<
- "constexpr variable %0 must be initialized by a constant expression">;
-def err_constexpr_redecl_mismatch : Error<
- "%select{non-constexpr declaration of %0 follows constexpr declaration"
- "|constexpr declaration of %0 follows non-constexpr declaration}1">;
-def err_constexpr_virtual : Error<"virtual function cannot be constexpr">;
-def err_constexpr_virtual_base : Error<
- "constexpr %select{member function|constructor}0 not allowed in "
- "%select{struct|interface|class}1 with virtual base "
- "%plural{1:class|:classes}2">;
-def note_non_literal_incomplete : Note<
- "incomplete type %0 is not a literal type">;
-def note_non_literal_virtual_base : Note<"%select{struct|interface|class}0 "
- "with virtual base %plural{1:class|:classes}1 is not a literal type">;
-def note_constexpr_virtual_base_here : Note<"virtual base class declared here">;
-def err_constexpr_non_literal_return : Error<
- "constexpr function's return type %0 is not a literal type">;
-def err_constexpr_non_literal_param : Error<
- "constexpr %select{function|constructor}1's %ordinal0 parameter type %2 is "
- "not a literal type">;
-def err_constexpr_body_invalid_stmt : Error<
- "statement not allowed in constexpr %select{function|constructor}0">;
-def ext_constexpr_body_invalid_stmt : ExtWarn<
- "use of this statement in a constexpr %select{function|constructor}0 "
- "is a C++14 extension">, InGroup<CXX14>;
-def warn_cxx11_compat_constexpr_body_invalid_stmt : Warning<
- "use of this statement in a constexpr %select{function|constructor}0 "
- "is incompatible with C++ standards before C++14">,
- InGroup<CXXPre14Compat>, DefaultIgnore;
-def ext_constexpr_type_definition : ExtWarn<
- "type definition in a constexpr %select{function|constructor}0 "
- "is a C++14 extension">, InGroup<CXX14>;
-def warn_cxx11_compat_constexpr_type_definition : Warning<
- "type definition in a constexpr %select{function|constructor}0 "
- "is incompatible with C++ standards before C++14">,
- InGroup<CXXPre14Compat>, DefaultIgnore;
-def err_constexpr_vla : Error<
- "variably-modified type %0 cannot be used in a constexpr "
- "%select{function|constructor}1">;
-def ext_constexpr_local_var : ExtWarn<
- "variable declaration in a constexpr %select{function|constructor}0 "
- "is a C++14 extension">, InGroup<CXX14>;
-def warn_cxx11_compat_constexpr_local_var : Warning<
- "variable declaration in a constexpr %select{function|constructor}0 "
- "is incompatible with C++ standards before C++14">,
- InGroup<CXXPre14Compat>, DefaultIgnore;
-def err_constexpr_local_var_static : Error<
- "%select{static|thread_local}1 variable not permitted in a constexpr "
- "%select{function|constructor}0">;
-def err_constexpr_local_var_non_literal_type : Error<
- "variable of non-literal type %1 cannot be defined in a constexpr "
- "%select{function|constructor}0">;
-def err_constexpr_local_var_no_init : Error<
- "variables defined in a constexpr %select{function|constructor}0 must be "
- "initialized">;
-def ext_constexpr_function_never_constant_expr : ExtWarn<
- "constexpr %select{function|constructor}0 never produces a "
- "constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
-def err_enable_if_never_constant_expr : Error<
- "'enable_if' attribute expression never produces a constant expression">;
-def err_constexpr_body_no_return : Error<
- "no return statement in constexpr function">;
-def err_constexpr_return_missing_expr : Error<
- "non-void constexpr function %0 should return a value">;
-def warn_cxx11_compat_constexpr_body_no_return : Warning<
- "constexpr function with no return statements is incompatible with C++ "
- "standards before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
-def ext_constexpr_body_multiple_return : ExtWarn<
- "multiple return statements in constexpr function is a C++14 extension">,
- InGroup<CXX14>;
-def warn_cxx11_compat_constexpr_body_multiple_return : Warning<
- "multiple return statements in constexpr function "
- "is incompatible with C++ standards before C++14">,
- InGroup<CXXPre14Compat>, DefaultIgnore;
-def note_constexpr_body_previous_return : Note<
- "previous return statement is here">;
-def err_constexpr_function_try_block : Error<
- "function try block not allowed in constexpr %select{function|constructor}0">;
-def err_constexpr_union_ctor_no_init : Error<
- "constexpr union constructor does not initialize any member">;
-def err_constexpr_ctor_missing_init : Error<
- "constexpr constructor must initialize all members">;
-def note_constexpr_ctor_missing_init : Note<
- "member not initialized by constructor">;
-def note_non_literal_no_constexpr_ctors : Note<
- "%0 is not literal because it is not an aggregate and has no constexpr "
- "constructors other than copy or move constructors">;
-def note_non_literal_base_class : Note<
- "%0 is not literal because it has base class %1 of non-literal type">;
-def note_non_literal_field : Note<
- "%0 is not literal because it has data member %1 of "
- "%select{non-literal|volatile}3 type %2">;
-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 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>;
-def note_private_extern : Note<
- "use __attribute__((visibility(\"hidden\"))) attribute instead">;
-
-// C++ Concepts TS
-def err_concept_wrong_decl_kind : Error<
- "'concept' can only appear on the definition of a function template or variable template">;
-def err_concept_decls_may_only_appear_in_namespace_scope : Error<
- "concept declarations may only appear in namespace scope">;
-def err_function_concept_not_defined : Error<
- "function concept declaration must be a definition">;
-def err_var_concept_not_initialized : Error<
- "variable concept declaration must be initialized">;
-def err_function_concept_exception_spec : Error<
- "function concept cannot have exception specification">;
-def err_concept_decl_invalid_specifiers : Error<
- "%select{variable|function}0 concept cannot be declared "
- "'%select{thread_local|inline|friend|constexpr}1'">;
-def err_function_concept_with_params : Error<
- "function concept cannot have any parameters">;
-
-// C++11 char16_t/char32_t
-def warn_cxx98_compat_unicode_type : Warning<
- "'%0' type specifier is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-// __make_integer_seq
-def err_integer_sequence_negative_length : Error<
- "integer sequences must have non-negative sequence length">;
-def err_integer_sequence_integral_element_type : Error<
- "integer sequences must have integral element type">;
-
-// Objective-C++
-def err_objc_decls_may_only_appear_in_global_scope : Error<
- "Objective-C declarations may only appear in global scope">;
-def warn_auto_var_is_id : Warning<
- "'auto' deduced as 'id' in declaration of %0">,
- InGroup<DiagGroup<"auto-var-id">>;
-
-// Attributes
-def err_nsobject_attribute : Error<
- "'NSObject' attribute is for pointer types only">;
-def err_attributes_are_not_compatible : Error<
- "%0 and %1 attributes are not compatible">;
-def err_attribute_wrong_number_arguments : Error<
- "%0 attribute %plural{0:takes no arguments|1:takes one argument|"
- ":requires exactly %1 arguments}1">;
-def err_attribute_too_many_arguments : Error<
- "%0 attribute takes no more than %1 argument%s1">;
-def err_attribute_too_few_arguments : Error<
- "%0 attribute takes at least %1 argument%s1">;
-def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
-def err_attribute_bad_neon_vector_size : Error<
- "Neon vector size must be 64 or 128 bits">;
-def warn_unsupported_target_attribute
- : Warning<"Ignoring unsupported '%0' in the target attribute string">,
- InGroup<IgnoredAttributes>;
-def err_attribute_unsupported
- : Error<"%0 attribute is not supported for this target">;
-// The err_*_attribute_argument_not_int are seperate because they're used by
-// VerifyIntegerConstantExpression.
-def err_aligned_attribute_argument_not_int : Error<
- "'aligned' attribute requires integer constant">;
-def err_align_value_attribute_argument_not_int : Error<
- "'align_value' attribute requires integer constant">;
-def err_alignas_attribute_wrong_decl_type : Error<
- "%0 attribute cannot be applied to a %select{function parameter|"
- "variable with 'register' storage class|'catch' variable|bit-field}1">;
-def err_alignas_missing_on_definition : Error<
- "%0 must be specified on definition if it is specified on any declaration">;
-def note_alignas_on_declaration : Note<"declared with %0 attribute here">;
-def err_alignas_mismatch : Error<
- "redeclaration has different alignment requirement (%1 vs %0)">;
-def err_alignas_underaligned : Error<
- "requested alignment is less than minimum alignment of %1 for type %0">;
-def err_attribute_argument_n_type : Error<
- "%0 attribute requires parameter %1 to be %select{int or bool|an integer "
- "constant|a string|an identifier}2">;
-def err_attribute_argument_type : Error<
- "%0 attribute requires %select{int or bool|an integer "
- "constant|a string|an identifier}1">;
-def err_attribute_argument_outof_range : Error<
- "%0 attribute requires integer constant between %1 and %2 inclusive">;
-def err_init_priority_object_attr : Error<
- "can only use 'init_priority' attribute on file-scope definitions "
- "of objects of class type">;
-def err_attribute_argument_vec_type_hint : Error<
- "invalid attribute argument %0 - expecting a vector or vectorizable scalar type">;
-def err_attribute_argument_out_of_bounds : Error<
- "%0 attribute parameter %1 is out of bounds">;
-def err_attribute_only_once_per_parameter : Error<
- "%0 attribute can only be applied once per parameter">;
-def err_attribute_uuid_malformed_guid : Error<
- "uuid attribute contains a malformed GUID">;
-def warn_attribute_pointers_only : Warning<
- "%0 attribute only applies to%select{| constant}1 pointer arguments">,
- InGroup<IgnoredAttributes>;
-def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Text>;
-def warn_attribute_return_pointers_only : Warning<
- "%0 attribute only applies to return values that are pointers">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_return_pointers_refs_only : Warning<
- "%0 attribute only applies to return values that are pointers or references">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_pointer_or_reference_only : Warning<
- "%0 attribute only applies to a pointer or reference (%1 is invalid)">,
- InGroup<IgnoredAttributes>;
-def err_attribute_no_member_pointers : Error<
- "%0 attribute cannot be used with pointers to members">;
-def err_attribute_invalid_implicit_this_argument : Error<
- "%0 attribute is invalid for the implicit this argument">;
-def err_ownership_type : Error<
- "%0 attribute only applies to %select{pointer|integer}1 arguments">;
-def err_ownership_returns_index_mismatch : Error<
- "'ownership_returns' attribute index does not match; here it is %0">;
-def note_ownership_returns_index_mismatch : Note<
- "declared with index %0 here">;
-def err_format_strftime_third_parameter : Error<
- "strftime format attribute requires 3rd parameter to be 0">;
-def err_format_attribute_requires_variadic : Error<
- "format attribute requires variadic function">;
-def err_format_attribute_not : Error<"format argument not %0">;
-def err_format_attribute_result_not : Error<"function does not return %0">;
-def err_format_attribute_implicit_this_format_string : Error<
- "format attribute cannot specify the implicit this argument as the format "
- "string">;
-def err_init_method_bad_return_type : Error<
- "init methods must return an object pointer type, not %0">;
-def err_attribute_invalid_size : Error<
- "vector size not an integral multiple of component size">;
-def err_attribute_zero_size : Error<"zero vector size">;
-def err_attribute_size_too_large : Error<"vector size too large">;
-def err_typecheck_vector_not_convertable : Error<
- "cannot convert between vector values of different size (%0 and %1)">;
-def err_typecheck_vector_not_convertable_non_scalar : Error<
- "cannot convert between vector and non-scalar values (%0 and %1)">;
-def err_typecheck_vector_lengths_not_equal : Error<
- "vector operands do not have the same number of elements (%0 and %1)">;
-def err_ext_vector_component_exceeds_length : Error<
- "vector component access exceeds type %0">;
-def err_ext_vector_component_name_illegal : Error<
- "illegal vector component name '%0'">;
-def err_attribute_address_space_negative : Error<
- "address space is negative">;
-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 err_attribute_address_function_type : Error<
- "function type may not be qualified with an address space">;
-def err_as_qualified_auto_decl : Error<
- "automatic variable qualified with an address space">;
-def err_arg_with_address_space : Error<
- "parameter may not be qualified with an address space">;
-def err_field_with_address_space : Error<
- "field may not be qualified with an address space">;
-def err_attr_objc_ownership_redundant : Error<
- "the type %0 is already explicitly ownership-qualified">;
-def err_invalid_nsnumber_type : Error<
- "%0 is not a valid literal type for NSNumber">;
-def err_objc_illegal_boxed_expression_type : Error<
- "illegal type %0 used in a boxed expression">;
-def err_objc_non_trivially_copyable_boxed_expression_type : Error<
- "non-trivially copyable type %0 cannot be used in a boxed expression">;
-def err_objc_incomplete_boxed_expression_type : Error<
- "incomplete type %0 used in a boxed expression">;
-def err_undeclared_objc_literal_class : Error<
- "definition of class %0 must be available to use Objective-C "
- "%select{array literals|dictionary literals|numeric literals|boxed expressions|"
- "string literals}1">;
-def err_undeclared_boxing_method : Error<
- "declaration of %0 is missing in %1 class">;
-def err_objc_literal_method_sig : Error<
- "literal construction method %0 has incompatible signature">;
-def note_objc_literal_method_param : Note<
- "%select{first|second|third}0 parameter has unexpected type %1 "
- "(should be %2)">;
-def note_objc_literal_method_return : Note<
- "method returns unexpected type %0 (should be an object type)">;
-def err_invalid_collection_element : Error<
- "collection element of type %0 is not an Objective-C object">;
-def err_box_literal_collection : Error<
- "%select{string|character|boolean|numeric}0 literal must be prefixed by '@' "
- "in a collection">;
-def warn_objc_literal_comparison : Warning<
- "direct comparison of %select{an array literal|a dictionary literal|"
- "a numeric literal|a boxed expression|}0 has undefined behavior">,
- InGroup<ObjCLiteralComparison>;
-def err_missing_atsign_prefix : Error<
- "string literal must be prefixed by '@' ">;
-def warn_objc_string_literal_comparison : Warning<
- "direct comparison of a string literal has undefined behavior">,
- InGroup<ObjCStringComparison>;
-def warn_concatenated_nsarray_literal : Warning<
- "concatenated NSString literal for an NSArray expression - "
- "possibly missing a comma">,
- InGroup<ObjCStringConcatenation>;
-def note_objc_literal_comparison_isequal : Note<
- "use 'isEqual:' instead">;
-def warn_objc_collection_literal_element : Warning<
- "object of type %0 is not compatible with "
- "%select{array element type|dictionary key type|dictionary value type}1 %2">,
- InGroup<ObjCLiteralConversion>;
-
-def err_attribute_argument_is_zero : Error<
- "%0 attribute must be greater than 0">;
-def warn_attribute_argument_n_negative : Warning<
- "%0 attribute parameter %1 is negative and will be ignored">,
- InGroup<CudaCompat>;
-def err_property_function_in_objc_container : Error<
- "use of Objective-C property in function nested in Objective-C "
- "container not supported, move function outside its container">;
-
-let CategoryName = "Cocoa API Issue" in {
-def warn_objc_redundant_literal_use : Warning<
- "using %0 with a literal is redundant">, InGroup<ObjCRedundantLiteralUse>;
-}
-
-def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "
- "\"local-dynamic\", \"initial-exec\" or \"local-exec\"">;
-
-def err_tls_var_aligned_over_maximum : Error<
- "alignment (%0) of thread-local variable %1 is greater than the maximum supported "
- "alignment (%2) for a thread-local variable on this target">;
-
-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">;
-def warn_mismatched_section : Warning<
- "section does not match previous declaration">, InGroup<Section>;
-
-def err_anonymous_property: Error<
- "anonymous property is not supported">;
-def err_property_is_variably_modified : Error<
- "property %0 has a variably modified type">;
-def err_no_accessor_for_property : Error<
- "no %select{getter|setter}0 defined for property %1">;
-def error_cannot_find_suitable_accessor : Error<
- "cannot find suitable %select{getter|setter}0 for property %1">;
-
-def err_alignment_not_power_of_two : Error<
- "requested alignment is not a power of 2">;
-def err_alignment_dependent_typedef_name : Error<
- "requested alignment is dependent but declaration is not dependent">;
-
-def err_attribute_aligned_too_great : Error<
- "requested alignment must be %0 bytes or smaller">;
-def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
- "%q0 redeclared without %1 attribute: previous %1 ignored">,
- InGroup<DiagGroup<"inconsistent-dllimport">>;
-def warn_dllimport_dropped_from_inline_function : Warning<
- "%q0 redeclared inline; %1 attribute ignored">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_ignored : Warning<"%0 attribute ignored">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_ignored_on_inline :
- Warning<"%0 attribute ignored on inline function">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_after_definition_ignored : Warning<
- "attribute %0 after definition is ignored">,
- InGroup<IgnoredAttributes>;
-def warn_unknown_attribute_ignored : Warning<
- "unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
-def warn_cxx11_gnu_attribute_on_type : Warning<
- "attribute %0 ignored, because it cannot be applied to a type">,
- InGroup<IgnoredAttributes>;
-def warn_unhandled_ms_attribute_ignored : Warning<
- "__declspec attribute %0 is not supported">,
- InGroup<IgnoredAttributes>;
-def err_attribute_invalid_on_stmt : Error<
- "%0 attribute cannot be applied to a statement">;
-def warn_declspec_attribute_ignored : Warning<
- "attribute %0 is ignored, place it after "
- "\"%select{class|struct|interface|union|enum}1\" to apply attribute to "
- "type declaration">, InGroup<IgnoredAttributes>;
-def warn_attribute_precede_definition : Warning<
- "attribute declaration must precede definition">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_void_function_method : Warning<
- "attribute %0 cannot be applied to "
- "%select{functions|Objective-C method}1 without return value">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_weak_on_field : Warning<
- "__weak attribute cannot be specified on a field declaration">,
- InGroup<IgnoredAttributes>;
-def warn_gc_attribute_weak_on_local : Warning<
- "Objective-C GC does not allow weak variables on the stack">,
- InGroup<IgnoredAttributes>;
-def warn_nsobject_attribute : Warning<
- "'NSObject' attribute may be put on a typedef only; attribute is ignored">,
- InGroup<NSobjectAttribute>;
-def warn_independentclass_attribute : Warning<
- "'objc_independent_class' attribute may be put on a typedef only; "
- "attribute is ignored">,
- InGroup<IndependentClassAttribute>;
-def warn_ptr_independentclass_attribute : Warning<
- "'objc_independent_class' attribute may be put on Objective-C object "
- "pointer type only; attribute is ignored">,
- InGroup<IndependentClassAttribute>;
-def warn_attribute_weak_on_local : Warning<
- "__weak attribute cannot be specified on an automatic variable when ARC "
- "is not enabled">,
- InGroup<IgnoredAttributes>;
-def warn_weak_identifier_undeclared : Warning<
- "weak identifier %0 never declared">;
-def err_attribute_weak_static : Error<
- "weak declaration cannot have internal linkage">;
-def err_attribute_selectany_non_extern_data : Error<
- "'selectany' can only be applied to data items with external linkage">;
-def err_declspec_thread_on_thread_variable : Error<
- "'__declspec(thread)' applied to variable that already has a "
- "thread-local storage specifier">;
-def err_attribute_dll_not_extern : Error<
- "%q0 must have external linkage when declared %q1">;
-def err_attribute_dll_thread_local : Error<
- "%q0 cannot be thread local when declared %q1">;
-def err_attribute_dll_lambda : Error<
- "lambda cannot be declared %0">;
-def warn_attribute_invalid_on_definition : Warning<
- "'%0' attribute cannot be specified on a definition">,
- InGroup<IgnoredAttributes>;
-def err_attribute_dll_redeclaration : Error<
- "redeclaration of %q0 cannot add %q1 attribute">;
-def warn_attribute_dll_redeclaration : Warning<
- "redeclaration of %q0 should not add %q1 attribute">,
- InGroup<DiagGroup<"dll-attribute-on-redeclaration">>;
-def err_attribute_dllimport_function_definition : Error<
- "dllimport cannot be applied to non-inline function definition">;
-def err_attribute_dll_deleted : Error<
- "attribute %q0 cannot be applied to a deleted function">;
-def err_attribute_dllimport_data_definition : Error<
- "definition of dllimport data">;
-def err_attribute_dllimport_static_field_definition : Error<
- "definition of dllimport static field not allowed">;
-def warn_attribute_dllimport_static_field_definition : Warning<
- "definition of dllimport static field">,
- InGroup<DiagGroup<"dllimport-static-field-def">>;
-def warn_attribute_dllexport_explicit_instantiation_decl : Warning<
- "explicit instantiation declaration should not be 'dllexport'">,
- InGroup<DiagGroup<"dllexport-explicit-instantiation-decl">>;
-def warn_invalid_initializer_from_system_header : Warning<
- "invalid constructor form class in system header, should not be explicit">,
- InGroup<DiagGroup<"invalid-initializer-from-system-header">>;
-def note_used_in_initialization_here : Note<"used in initialization here">;
-def err_attribute_dll_member_of_dll_class : Error<
- "attribute %q0 cannot be applied to member of %q1 class">;
-def warn_attribute_dll_instantiated_base_class : Warning<
- "propagating dll attribute to %select{already instantiated|explicitly specialized}0 "
- "base class template without dll attribute is not supported">,
- InGroup<DiagGroup<"unsupported-dll-base-class-template">>, DefaultIgnore;
-def err_attribute_dll_ambiguous_default_ctor : Error<
- "'__declspec(dllexport)' cannot be applied to more than one default constructor in %0">;
-def err_attribute_weakref_not_static : Error<
- "weakref declaration must have internal linkage">;
-def err_attribute_weakref_not_global_context : Error<
- "weakref declaration of %0 must be in a global context">;
-def err_attribute_weakref_without_alias : Error<
- "weakref declaration of %0 must also have an alias attribute">;
-def err_alias_not_supported_on_darwin : Error <
- "only weak aliases are supported on darwin">;
-def err_alias_to_undefined : Error<
- "alias must point to a defined variable or function">;
-def warn_alias_to_weak_alias : Warning<
- "alias will always resolve to %0 even if weak definition of alias %1 is overridden">,
- InGroup<IgnoredAttributes>;
-def warn_alias_with_section : Warning<
- "alias will not be in section '%0' but in the same section as the aliasee">,
- InGroup<IgnoredAttributes>;
-def err_duplicate_mangled_name : Error<
- "definition with same mangled name as another definition">;
-def err_cyclic_alias : Error<
- "alias definition is part of a cycle">;
-def warn_attribute_wrong_decl_type : Warning<
- "%0 attribute only applies to %select{functions|unions|"
- "variables and functions|functions and methods|parameters|"
- "functions, methods and blocks|functions, methods, and classes|"
- "functions, methods, and parameters|classes|enums|variables|methods|"
- "variables, functions and labels|fields and global variables|structs|"
- "variables and typedefs|thread-local variables|"
- "variables and fields|variables, data members and tag types|"
- "types and namespaces|Objective-C interfaces|methods and properties|"
- "struct or union|struct, union or class|types|"
- "Objective-C instance methods|init methods of interface or class extension declarations|"
- "variables, functions and classes|Objective-C protocols|"
- "functions and global variables|structs, unions, and typedefs|structs and typedefs|"
- "interface or protocol declarations|kernel functions|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<
- "'%0' only applies to %select{function|pointer|"
- "Objective-C object or block pointer}1 types; type here is %2">,
- InGroup<IgnoredAttributes>;
-def warn_incomplete_encoded_type : Warning<
- "encoding of %0 type is incomplete because %1 component has unknown encoding">,
- InGroup<DiagGroup<"encode-type">>;
-def warn_attribute_requires_functions_or_static_globals : Warning<
- "%0 only applies to variables with static storage duration and functions">,
- InGroup<IgnoredAttributes>;
-def warn_gnu_inline_attribute_requires_inline : Warning<
- "'gnu_inline' attribute requires function to be marked 'inline',"
- " attribute ignored">,
- InGroup<IgnoredAttributes>;
-def err_attribute_vecreturn_only_vector_member : Error<
- "the vecreturn attribute can only be used on a class or structure with one member, which must be a vector">;
-def err_attribute_vecreturn_only_pod_record : Error<
- "the vecreturn attribute can only be used on a POD (plain old data) class or structure (i.e. no virtual functions)">;
-def err_cconv_change : Error<
- "function declared '%0' here was previously declared "
- "%select{'%2'|without calling convention}1">;
-def warn_cconv_ignored : Warning<
- "calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>;
-def err_cconv_knr : Error<
- "function with no prototype cannot use the %0 calling convention">;
-def warn_cconv_knr : Warning<
- err_cconv_knr.Text>,
- InGroup<DiagGroup<"missing-prototype-for-cc">>;
-def err_cconv_varargs : Error<
- "variadic function cannot use %0 calling convention">;
-def warn_cconv_varargs : Warning<
- "%0 calling convention ignored on variadic function">,
- InGroup<IgnoredAttributes>;
-def warn_cconv_structors : Warning<
- "%0 calling convention ignored on constructor/destructor">,
- InGroup<IgnoredAttributes>;
-def err_regparm_mismatch : Error<"function declared with regparm(%0) "
- "attribute was previously declared "
- "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
-def err_returns_retained_mismatch : Error<
- "function declared with the ns_returns_retained attribute "
- "was previously declared without the ns_returns_retained attribute">;
-def err_objc_precise_lifetime_bad_type : Error<
- "objc_precise_lifetime only applies to retainable types; type here is %0">;
-def warn_objc_precise_lifetime_meaningless : Error<
- "objc_precise_lifetime is not meaningful for "
- "%select{__unsafe_unretained|__autoreleasing}0 objects">;
-def err_invalid_pcs : Error<"invalid PCS type">;
-def warn_attribute_not_on_decl : Warning<
- "%0 attribute ignored when parsing type">, InGroup<IgnoredAttributes>;
-def err_base_specifier_attribute : Error<
- "%0 attribute cannot be applied to a base specifier">;
-def err_invalid_attribute_on_virtual_function : Error<
- "%0 attribute cannot be applied to virtual functions">;
-
-// Availability attribute
-def warn_availability_unknown_platform : Warning<
- "unknown platform %0 in availability macro">, InGroup<Availability>;
-def warn_availability_version_ordering : Warning<
- "feature cannot be %select{introduced|deprecated|obsoleted}0 in %1 version "
- "%2 before it was %select{introduced|deprecated|obsoleted}3 in version %4; "
- "attribute ignored">, InGroup<Availability>;
-def warn_mismatched_availability: Warning<
- "availability does not match previous declaration">, InGroup<Availability>;
-def warn_mismatched_availability_override : Warning<
- "%select{|overriding }4method %select{introduced after|"
- "deprecated before|obsoleted before}0 "
- "%select{the protocol method it implements|overridden method}4 "
- "on %1 (%2 vs. %3)">, InGroup<Availability>;
-def warn_mismatched_availability_override_unavail : Warning<
- "%select{|overriding }1method cannot be unavailable on %0 when "
- "%select{the protocol method it implements|its overridden method}1 is "
- "available">,
- InGroup<Availability>;
-def note_overridden_method : Note<
- "overridden method is here">;
-def note_protocol_method : Note<
- "protocol method is here">;
-
-// Thread Safety Attributes
-def warn_invalid_capability_name : Warning<
- "invalid capability name '%0'; capability name must be 'mutex' or 'role'">,
- InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_ignored : Warning<
- "ignoring %0 attribute because its argument is invalid">,
- InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_argument_not_lockable : Warning<
- "%0 attribute requires arguments whose type is annotated "
- "with 'capability' attribute; type here is %1">,
- InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_decl_not_lockable : Warning<
- "%0 attribute can only be applied in a context annotated "
- "with 'capability(\"mutex\")' attribute">,
- InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_decl_not_pointer : Warning<
- "%0 only applies to pointer types; type here is %1">,
- InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def err_attribute_argument_out_of_range : Error<
- "%0 attribute parameter %1 is out of bounds: "
- "%plural{0:no parameters to index into|"
- "1:can only be 1, since there is one parameter|"
- ":must be between 1 and %2}2">;
-
-// Thread Safety Analysis
-def warn_unlock_but_no_lock : Warning<"releasing %0 '%1' that was not held">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_unlock_kind_mismatch : Warning<
- "releasing %0 '%1' using %select{shared|exclusive}2 access, expected "
- "%select{shared|exclusive}3 access">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_double_lock : Warning<"acquiring %0 '%1' that is already held">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_no_unlock : Warning<
- "%0 '%1' is still held at the end of function">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_expecting_locked : Warning<
- "expecting %0 '%1' to be held at the end of function">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-// FIXME: improve the error message about locks not in scope
-def warn_lock_some_predecessors : Warning<
- "%0 '%1' is not held on every path through here">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_expecting_lock_held_on_loop : Warning<
- "expecting %0 '%1' to be held at start of each loop">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def note_locked_here : Note<"%0 acquired here">;
-def warn_lock_exclusive_and_shared : Warning<
- "%0 '%1' is acquired exclusively and shared in the same scope">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-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{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{any mutex|any mutex exclusively}1">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_fun_excludes_mutex : Warning<
- "cannot call function '%1' while %0 '%2' is held">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_cannot_resolve_lock : Warning<
- "cannot resolve lock expression">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_acquired_before : Warning<
- "%0 '%1' must be acquired before '%2'">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_acquired_before_after_cycle : Warning<
- "Cycle in acquired_before/after dependencies, starting with '%0'">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-
-
-// Thread safety warnings negative capabilities
-def warn_acquire_requires_negative_cap : Warning<
- "acquiring %0 '%1' requires negative capability '%2'">,
- InGroup<ThreadSafetyNegative>, DefaultIgnore;
-
-// Thread safety warnings on pass by reference
-def warn_guarded_pass_by_reference : Warning<
- "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 "
- "%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{'%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 "
- "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">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-
-// Precise thread safety warnings
-def warn_variable_requires_lock_precise :
- Warning<warn_variable_requires_lock.Text>,
- InGroup<ThreadSafetyPrecise>, DefaultIgnore;
-def warn_var_deref_requires_lock_precise :
- Warning<warn_var_deref_requires_lock.Text>,
- InGroup<ThreadSafetyPrecise>, DefaultIgnore;
-def warn_fun_requires_lock_precise :
- Warning<warn_fun_requires_lock.Text>,
- InGroup<ThreadSafetyPrecise>, DefaultIgnore;
-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_guarded_by_declared_here : Note<"Guarded_by declared here.">;
-
-// Dummy warning that will trigger "beta" warnings from the analysis if enabled.
-def warn_thread_safety_beta : Warning<"Thread safety beta warning.">,
- InGroup<ThreadSafetyBeta>, DefaultIgnore;
-
-// Consumed warnings
-def warn_use_in_invalid_state : Warning<
- "invalid invocation of method '%0' on object '%1' while it is in the '%2' "
- "state">, InGroup<Consumed>, DefaultIgnore;
-def warn_use_of_temp_in_invalid_state : Warning<
- "invalid invocation of method '%0' on a temporary object while it is in the "
- "'%1' state">, InGroup<Consumed>, DefaultIgnore;
-def warn_attr_on_unconsumable_class : Warning<
- "consumed analysis attribute is attached to member of class '%0' which isn't "
- "marked as consumable">, InGroup<Consumed>, DefaultIgnore;
-def warn_return_typestate_for_unconsumable_type : Warning<
- "return state set for an unconsumable type '%0'">, InGroup<Consumed>,
- DefaultIgnore;
-def warn_return_typestate_mismatch : Warning<
- "return value not in expected state; expected '%0', observed '%1'">,
- InGroup<Consumed>, DefaultIgnore;
-def warn_loop_state_mismatch : Warning<
- "state of variable '%0' must match at the entry and exit of loop">,
- InGroup<Consumed>, DefaultIgnore;
-def warn_param_return_typestate_mismatch : Warning<
- "parameter '%0' not in expected state when the function returns: expected "
- "'%1', observed '%2'">, InGroup<Consumed>, DefaultIgnore;
-def warn_param_typestate_mismatch : Warning<
- "argument not in expected state; expected '%0', observed '%1'">,
- InGroup<Consumed>, DefaultIgnore;
-
-// no_sanitize attribute
-def warn_unknown_sanitizer_ignored : Warning<
- "unknown sanitizer '%0' ignored">, InGroup<UnknownSanitizers>;
-
-def warn_impcast_vector_scalar : Warning<
- "implicit conversion turns vector to scalar: %0 to %1">,
- InGroup<Conversion>, DefaultIgnore;
-def warn_impcast_complex_scalar : Warning<
- "implicit conversion discards imaginary component: %0 to %1">,
- InGroup<Conversion>, DefaultIgnore;
-def warn_impcast_float_precision : Warning<
- "implicit conversion 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;
-def warn_impcast_float_integer : Warning<
- "implicit conversion turns floating-point number into integer: %0 to %1">,
- InGroup<FloatConversion>, DefaultIgnore;
-def warn_impcast_integer_sign : Warning<
- "implicit conversion changes signedness: %0 to %1">,
- InGroup<SignConversion>, DefaultIgnore;
-def warn_impcast_integer_sign_conditional : Warning<
- "operand of ? changes signedness: %0 to %1">,
- InGroup<SignConversion>, DefaultIgnore;
-def warn_impcast_integer_precision : Warning<
- "implicit conversion loses integer precision: %0 to %1">,
- InGroup<Conversion>, DefaultIgnore;
-def warn_impcast_integer_64_32 : Warning<
- "implicit conversion loses integer precision: %0 to %1">,
- InGroup<Shorten64To32>, DefaultIgnore;
-def warn_impcast_integer_precision_constant : Warning<
- "implicit conversion from %2 to %3 changes value from %0 to %1">,
- InGroup<ConstantConversion>;
-def warn_impcast_bitfield_precision_constant : Warning<
- "implicit truncation from %2 to bitfield changes value from %0 to %1">,
- InGroup<BitFieldConstantConversion>;
-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_string_literal_to_bool : Warning<
- "implicit conversion turns string literal into bool: %0 to %1">,
- InGroup<StringConversion>, DefaultIgnore;
-def warn_impcast_different_enum_types : Warning<
- "implicit conversion from enumeration type %0 to different enumeration type "
- "%1">, InGroup<EnumConversion>;
-def warn_impcast_bool_to_null_pointer : Warning<
- "initialization of pointer of type %0 to null from a constant boolean "
- "expression">, InGroup<BoolConversion>;
-def warn_non_literal_null_pointer : Warning<
- "expression which evaluates to zero treated as a null pointer constant of "
- "type %0">, InGroup<NonLiteralNullConversion>;
-def warn_impcast_null_pointer_to_integer : Warning<
- "implicit conversion of %select{NULL|nullptr}0 constant to %1">,
- InGroup<NullConversion>;
-def warn_impcast_floating_point_to_bool : Warning<
- "implicit conversion turns floating-point number into bool: %0 to %1">,
- InGroup<ImplicitConversionFloatingPointToBool>;
-def ext_ms_impcast_fn_obj : ExtWarn<
- "implicit conversion between pointer-to-function and pointer-to-object is a "
- "Microsoft extension">, InGroup<MicrosoftCast>;
-
-def warn_impcast_pointer_to_bool : Warning<
- "address of%select{| function| array}0 '%1' will always evaluate to "
- "'true'">,
- InGroup<PointerBoolConversion>;
-def warn_cast_nonnull_to_bool : Warning<
- "nonnull %select{function call|parameter}0 '%1' will evaluate to "
- "'true' on first encounter">,
- InGroup<PointerBoolConversion>;
-def warn_this_bool_conversion : Warning<
- "'this' pointer cannot be null in well-defined C++ code; pointer may be "
- "assumed to always convert to true">, InGroup<UndefinedBoolConversion>;
-def warn_address_of_reference_bool_conversion : Warning<
- "reference cannot be bound to dereferenced null pointer in well-defined C++ "
- "code; pointer may be assumed to always convert to true">,
- InGroup<UndefinedBoolConversion>;
-
-def warn_null_pointer_compare : Warning<
- "comparison of %select{address of|function|array}0 '%1' %select{not |}2"
- "equal to a null pointer is always %select{true|false}2">,
- InGroup<TautologicalPointerCompare>;
-def warn_nonnull_expr_compare : Warning<
- "comparison of nonnull %select{function call|parameter}0 '%1' "
- "%select{not |}2equal to a null pointer is '%select{true|false}2' on first "
- "encounter">,
- InGroup<TautologicalPointerCompare>;
-def warn_this_null_compare : Warning<
- "'this' pointer cannot be null in well-defined C++ code; comparison may be "
- "assumed to always evaluate to %select{true|false}0">,
- InGroup<TautologicalUndefinedCompare>;
-def warn_address_of_reference_null_compare : Warning<
- "reference cannot be bound to dereferenced null pointer in well-defined C++ "
- "code; comparison may be assumed to always evaluate to "
- "%select{true|false}0">,
- InGroup<TautologicalUndefinedCompare>;
-def note_reference_is_return_value : Note<"%0 returns a reference">;
-
-def note_function_warning_silence : Note<
- "prefix with the address-of operator to silence this warning">;
-def note_function_to_function_call : Note<
- "suffix with parentheses to turn this into a function call">;
-def warn_impcast_objective_c_literal_to_bool : Warning<
- "implicit boolean conversion of Objective-C object literal always "
- "evaluates to true">,
- InGroup<ObjCLiteralConversion>;
-
-def warn_cast_align : Warning<
- "cast from %0 to %1 increases required alignment from %2 to %3">,
- InGroup<CastAlign>, DefaultIgnore;
-def warn_old_style_cast : Warning<
- "use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore;
-
-// Separate between casts to void* and non-void* pointers.
-// Some APIs use (abuse) void* for something like a user context,
-// and often that value is an integer even if it isn't a pointer itself.
-// Having a separate warning flag allows users to control the warning
-// for their workflow.
-def warn_int_to_pointer_cast : Warning<
- "cast to %1 from smaller integer type %0">,
- InGroup<IntToPointerCast>;
-def warn_int_to_void_pointer_cast : Warning<
- "cast to %1 from smaller integer type %0">,
- InGroup<IntToVoidPointerCast>;
-
-def warn_attribute_packed_for_bitfield : Warning<
- "'packed' attribute was ignored on bit-fields with single-byte alignment "
- "in older versions of GCC and Clang">,
- InGroup<DiagGroup<"attribute-packed-for-bitfield">>;
-def warn_transparent_union_attribute_field_size_align : Warning<
- "%select{alignment|size}0 of field %1 (%2 bits) does not match the "
- "%select{alignment|size}0 of the first field in transparent union; "
- "transparent_union attribute ignored">,
- InGroup<IgnoredAttributes>;
-def note_transparent_union_first_field_size_align : Note<
- "%select{alignment|size}0 of first field is %1 bits">;
-def warn_transparent_union_attribute_not_definition : Warning<
- "transparent_union attribute can only be applied to a union definition; "
- "attribute ignored">,
- InGroup<IgnoredAttributes>;
-def warn_transparent_union_attribute_floating : Warning<
- "first field of a transparent union cannot have %select{floating point|"
- "vector}0 type %1; transparent_union attribute ignored">,
- InGroup<IgnoredAttributes>;
-def warn_transparent_union_attribute_zero_fields : Warning<
- "transparent union definition must contain at least one field; "
- "transparent_union attribute ignored">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_type_not_supported : Warning<
- "%0 attribute argument not supported: %1">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_unknown_visibility : Warning<"unknown visibility %0">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_protected_visibility :
- Warning<"target does not support 'protected' visibility; using 'default'">,
- InGroup<DiagGroup<"unsupported-visibility">>;
-def err_mismatched_visibility: Error<"visibility does not match previous declaration">;
-def note_previous_attribute : Note<"previous attribute is here">;
-def note_conflicting_attribute : Note<"conflicting attribute is here">;
-def note_attribute : Note<"attribute is here">;
-def err_mismatched_ms_inheritance : Error<
- "inheritance model does not match %select{definition|previous declaration}0">;
-def warn_ignored_ms_inheritance : Warning<
- "inheritance model ignored on %select{primary template|partial specialization}0">,
- InGroup<IgnoredAttributes>;
-def note_previous_ms_inheritance : Note<
- "previous inheritance model specified here">;
-def err_machine_mode : Error<"%select{unknown|unsupported}0 machine mode %1">;
-def err_mode_not_primitive : Error<
- "mode attribute only supported for integer and floating-point types">;
-def err_mode_wrong_type : Error<
- "type of machine mode does not match type of base type">;
-def warn_vector_mode_deprecated : Warning<
- "specifying vector types with the 'mode' attribute is deprecated; "
- "use the 'vector_size' attribute instead">,
- InGroup<DeprecatedAttributes>;
-def err_complex_mode_vector_type : Error<
- "type of machine mode does not support base vector types">;
-def err_attr_wrong_decl : Error<
- "%0 attribute invalid on this declaration, requires typedef or value">;
-def warn_attribute_nonnull_no_pointers : Warning<
- "'nonnull' attribute applied to function with no pointer arguments">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_nonnull_parm_no_args : Warning<
- "'nonnull' attribute when used on parameters takes no arguments">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_sentinel_named_arguments : Warning<
- "'sentinel' attribute requires named arguments">,
- InGroup<IgnoredAttributes>;
-def warn_attribute_sentinel_not_variadic : Warning<
- "'sentinel' attribute only supported for variadic %select{functions|blocks}0">,
- InGroup<IgnoredAttributes>;
-def err_attribute_sentinel_less_than_zero : Error<
- "'sentinel' parameter 1 less than zero">;
-def err_attribute_sentinel_not_zero_or_one : Error<
- "'sentinel' parameter 2 not 0 or 1">;
-def warn_cleanup_ext : Warning<
- "GCC does not allow the 'cleanup' attribute argument to be anything other "
- "than a simple identifier">,
- InGroup<GccCompat>;
-def err_attribute_cleanup_arg_not_function : Error<
- "'cleanup' argument %select{|%1 |%1 }0is not a %select{||single }0function">;
-def err_attribute_cleanup_func_must_take_one_arg : Error<
- "'cleanup' function %0 must take 1 parameter">;
-def err_attribute_cleanup_func_arg_incompatible_type : Error<
- "'cleanup' function %0 parameter has "
- "%diff{type $ which is incompatible with type $|incompatible type}1,2">;
-def err_attribute_regparm_wrong_platform : Error<
- "'regparm' is not valid on this platform">;
-def err_attribute_regparm_invalid_number : Error<
- "'regparm' parameter must be between 0 and %0 inclusive">;
-def err_attribute_not_supported_in_lang : Error<
- "%0 attribute is not supported in %select{C|C++|Objective-C}1">;
-
-
-// Clang-Specific Attributes
-def warn_attribute_iboutlet : Warning<
- "%0 attribute can only be applied to instance variables or properties">,
- InGroup<IgnoredAttributes>;
-def err_iboutletcollection_type : Error<
- "invalid type %0 as argument of iboutletcollection attribute">;
-def err_iboutletcollection_builtintype : Error<
- "type argument of iboutletcollection attribute cannot be a builtin type">;
-def warn_iboutlet_object_type : Warning<
- "%select{instance variable|property}2 with %0 attribute must "
- "be an object type (invalid %1)">, InGroup<ObjCInvalidIBOutletProperty>;
-def warn_iboutletcollection_property_assign : Warning<
- "IBOutletCollection properties should be copy/strong and not assign">,
- InGroup<ObjCInvalidIBOutletProperty>;
-
-def err_attribute_overloadable_missing : Error<
- "%select{overloaded function|redeclaration of}0 %1 must have the "
- "'overloadable' attribute">;
-def note_attribute_overloadable_prev_overload : Note<
- "previous overload of function is here">;
-def err_attribute_overloadable_no_prototype : Error<
- "'overloadable' function %0 must have a prototype">;
-def warn_ns_attribute_wrong_return_type : Warning<
- "%0 attribute only applies to %select{functions|methods|properties}1 that "
- "return %select{an Objective-C object|a pointer|a non-retainable pointer}2">,
- InGroup<IgnoredAttributes>;
-def warn_ns_attribute_wrong_parameter_type : Warning<
- "%0 attribute only applies to "
- "%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">,
- InGroup<IgnoredAttributes>;
-def warn_objc_requires_super_protocol : Warning<
- "%0 attribute cannot be applied to %select{methods in protocols|dealloc}1">,
- InGroup<DiagGroup<"requires-super-attribute">>;
-def note_protocol_decl : Note<
- "protocol is declared here">;
-def note_protocol_decl_undefined : Note<
- "protocol %0 has no definition">;
-
-// objc_designated_initializer attribute diagnostics.
-def warn_objc_designated_init_missing_super_call : Warning<
- "designated initializer missing a 'super' call to a designated initializer of the super class">,
- InGroup<ObjCDesignatedInit>;
-def note_objc_designated_init_marked_here : Note<
- "method marked as designated initializer of the class here">;
-def warn_objc_designated_init_non_super_designated_init_call : Warning<
- "designated initializer should only invoke a designated initializer on 'super'">,
- InGroup<ObjCDesignatedInit>;
-def warn_objc_designated_init_non_designated_init_call : Warning<
- "designated initializer invoked a non-designated initializer">,
- InGroup<ObjCDesignatedInit>;
-def warn_objc_secondary_init_super_init_call : Warning<
- "convenience initializer should not invoke an initializer on 'super'">,
- InGroup<ObjCDesignatedInit>;
-def warn_objc_secondary_init_missing_init_call : Warning<
- "convenience initializer missing a 'self' call to another initializer">,
- InGroup<ObjCDesignatedInit>;
-def warn_objc_implementation_missing_designated_init_override : Warning<
- "method override for the designated initializer of the superclass %objcinstance0 not found">,
- InGroup<ObjCDesignatedInit>;
-
-// objc_bridge attribute diagnostics.
-def err_objc_attr_not_id : Error<
- "parameter of %0 attribute must be a single name of an Objective-C %select{class|protocol}1">;
-def err_objc_attr_typedef_not_id : Error<
- "parameter of %0 attribute must be 'id' when used on a typedef">;
-def err_objc_attr_typedef_not_void_pointer : Error<
- "'objc_bridge(id)' is only allowed on structs and typedefs of void pointers">;
-def err_objc_cf_bridged_not_interface : Error<
- "CF object of type %0 is bridged to %1, which is not an Objective-C class">;
-def err_objc_ns_bridged_invalid_cfobject : Error<
- "ObjectiveC object of type %0 is bridged to %1, which is not valid CF object">;
-def warn_objc_invalid_bridge : Warning<
- "%0 bridges to %1, not %2">, InGroup<ObjCBridge>;
-def warn_objc_invalid_bridge_to_cf : Warning<
- "%0 cannot bridge to %1">, InGroup<ObjCBridge>;
-
-// objc_bridge_related attribute diagnostics.
-def err_objc_bridged_related_invalid_class : Error<
- "could not find Objective-C class %0 to convert %1 to %2">;
-def err_objc_bridged_related_invalid_class_name : Error<
- "%0 must be name of an Objective-C class to be able to convert %1 to %2">;
-def err_objc_bridged_related_known_method : Error<
- "%0 must be explicitly converted to %1; use %select{%objcclass2|%objcinstance2}3 "
- "method for this conversion">;
-
-def err_objc_attr_protocol_requires_definition : Error<
- "attribute %0 can only be applied to @protocol definitions, not forward declarations">;
-
-// Function Parameter Semantic Analysis.
-def err_param_with_void_type : Error<"argument may not have 'void' type">;
-def err_void_only_param : Error<
- "'void' must be the first and only parameter if specified">;
-def err_void_param_qualified : Error<
- "'void' as parameter must not have type qualifiers">;
-def err_ident_list_in_fn_declaration : Error<
- "a parameter list without types is only allowed in a function definition">;
-def ext_param_not_declared : Extension<
- "parameter %0 was not declared, defaulting to type 'int'">;
-def err_param_default_argument : Error<
- "C does not support default arguments">;
-def err_param_default_argument_redefinition : Error<
- "redefinition of default argument">;
-def ext_param_default_argument_redefinition : ExtWarn<
- err_param_default_argument_redefinition.Text>,
- InGroup<MicrosoftDefaultArgRedefinition>;
-def err_param_default_argument_missing : Error<
- "missing default argument on parameter">;
-def err_param_default_argument_missing_name : Error<
- "missing default argument on parameter %0">;
-def err_param_default_argument_references_param : Error<
- "default argument references parameter %0">;
-def err_param_default_argument_references_local : Error<
- "default argument references local variable %0 of enclosing function">;
-def err_param_default_argument_references_this : Error<
- "default argument references 'this'">;
-def err_param_default_argument_nonfunc : Error<
- "default arguments can only be specified for parameters in a function "
- "declaration">;
-def err_param_default_argument_template_redecl : Error<
- "default arguments cannot be added to a function template that has already "
- "been declared">;
-def err_param_default_argument_member_template_redecl : Error<
- "default arguments cannot be added to an out-of-line definition of a member "
- "of a %select{class template|class template partial specialization|nested "
- "class in a template}0">;
-def err_param_default_argument_on_parameter_pack : Error<
- "parameter pack cannot have a default argument">;
-def err_uninitialized_member_for_assign : Error<
- "cannot define the implicit copy assignment operator for %0, because "
- "non-static %select{reference|const}1 member %2 cannot use copy "
- "assignment operator">;
-def err_uninitialized_member_in_ctor : Error<
- "%select{|implicit default |inheriting }0constructor for %1 must explicitly "
- "initialize the %select{reference|const}2 member %3">;
-def err_default_arg_makes_ctor_special : Error<
- "addition of default argument on redeclaration makes this constructor a "
- "%select{default|copy|move}0 constructor">;
-
-def err_use_of_default_argument_to_function_declared_later : Error<
- "use of default argument to function %0 that is declared later in class %1">;
-def note_default_argument_declared_here : Note<
- "default argument declared here">;
-
-def ext_param_promoted_not_compatible_with_prototype : ExtWarn<
- "%diff{promoted type $ of K&R function parameter is not compatible with the "
- "parameter type $|promoted type of K&R function parameter is not compatible "
- "with parameter type}0,1 declared in a previous prototype">,
- InGroup<KNRPromotedParameter>;
-
-
-// C++ Overloading Semantic Analysis.
-def err_ovl_diff_return_type : Error<
- "functions that differ only in their return type cannot be overloaded">;
-def err_ovl_static_nonstatic_member : Error<
- "static and non-static member functions with the same parameter types "
- "cannot be overloaded">;
-
-def err_ovl_no_viable_function_in_call : Error<
- "no matching function for call to %0">;
-def err_ovl_no_viable_member_function_in_call : Error<
- "no matching member function for call to %0">;
-def err_ovl_ambiguous_call : Error<
- "call to %0 is ambiguous">;
-def err_ovl_deleted_call : Error<
- "call to %select{unavailable|deleted}0 function %1%2">;
-def err_ovl_ambiguous_member_call : Error<
- "call to member function %0 is ambiguous">;
-def err_ovl_deleted_member_call : Error<
- "call to %select{unavailable|deleted}0 member function %1%2">;
-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|"
- "is an inherited constructor}0%1"
- "%select{| has different class%diff{ (expected $ but has $)|}3,4"
- "| has different number of parameters (expected %3 but has %4)"
- "| has type mismatch at %ordinal3 parameter"
- "%diff{ (expected $ but has $)|}4,5"
- "| has different return type%diff{ ($ expected but has $)|}3,4"
- "| has different qualifiers (expected "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile"
- "|volatile and restrict|const, volatile, and restrict}3 but found "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile"
- "|volatile and restrict|const, volatile, and restrict}4)}2">;
-
-def note_ovl_candidate_inherited_constructor : Note<"inherited from here">;
-def note_ovl_candidate_illegal_constructor : Note<
- "candidate %select{constructor|template}0 ignored: "
- "instantiation %select{takes|would take}0 its own class type by value">;
-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_inconsistent_deduction : Note<
- "candidate template ignored: deduced conflicting %select{types|values|"
- "templates}0 for parameter %1%diff{ ($ vs. $)|}2,3">;
-def note_ovl_candidate_explicit_arg_mismatch_named : Note<
- "candidate template ignored: invalid explicitly-specified argument "
- "for template parameter %0">;
-def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
- "candidate template ignored: invalid explicitly-specified argument "
- "for %ordinal0 template parameter">;
-def note_ovl_candidate_instantiation_depth : Note<
- "candidate template ignored: substitution exceeded maximum template "
- "instantiation depth">;
-def note_ovl_candidate_underqualified : Note<
- "candidate template ignored: cannot deduce a type for %0 that would "
- "make %2 equal %1">;
-def note_ovl_candidate_substitution_failure : Note<
- "candidate template ignored: substitution failure%0%1">;
-def note_ovl_candidate_disabled_by_enable_if : Note<
- "candidate template ignored: disabled by %0%1">;
-def note_ovl_candidate_has_pass_object_size_params: Note<
- "candidate address cannot be taken because parameter %0 has "
- "pass_object_size attribute">;
-def note_ovl_candidate_disabled_by_enable_if_attr : Note<
- "candidate disabled: %0">;
-def err_addrof_function_disabled_by_enable_if_attr : Error<
- "cannot take address of function %0 becuase it has one or more "
- "non-tautological enable_if conditions">;
-def note_addrof_ovl_candidate_disabled_by_enable_if_attr : Note<
- "candidate function made ineligible by enable_if">;
-def note_ovl_candidate_failed_overload_resolution : Note<
- "candidate template ignored: couldn't resolve reference to overloaded "
- "function %0">;
-def note_ovl_candidate_deduced_mismatch : Note<
- "candidate template ignored: deduced type "
- "%diff{$ of %ordinal0 parameter does not match adjusted type $ of argument"
- "|of %ordinal0 parameter does not match adjusted type of argument}1,2%3">;
-def note_ovl_candidate_non_deduced_mismatch : Note<
- "candidate template ignored: could not match %diff{$ against $|types}0,1">;
-// This note is needed because the above note would sometimes print two
-// different types with the same name. Remove this note when the above note
-// can handle that case properly.
-def note_ovl_candidate_non_deduced_mismatch_qualified : Note<
- "candidate template ignored: could not match %q0 against %q1">;
-
-// 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)|"
- "constructor (inherited)}0 %select{|template }1"
- "not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 "
- "%plural{1:was|:were}4 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)|"
- "constructor (inherited)}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">;
-
-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)|"
- "constructor (inherited)}0%1 has been "
- "%select{explicitly made unavailable|explicitly deleted|"
- "implicitly deleted}2">;
-
-// 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)|"
- "constructor (inherited)}0%1 "
- "not viable: cannot convert argument of incomplete type "
- "%diff{$ to $|to parameter type}2,3">;
-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)|"
- "constructor (inherited)}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)|"
- "constructor (inherited)}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)|"
- "constructor (inherited)}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"
- "%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)|"
- "constructor (inherited)}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)|"
- "constructor (inherited)}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)|"
- "constructor (inherited)}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)|"
- "constructor (inherited)}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)|"
- "constructor (inherited)}0%1 not viable: "
- "%select{%ordinal6|'this'}5 argument (%2) has "
- "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 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 "
- "%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)|"
- "constructor (inherited)}0%1 not viable: "
- "%ordinal4 argument (%2) 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_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)|"
- "constructor (inherited)}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">;
-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)|"
- "constructor (inherited)}0 not viable: call to "
- "%select{__device__|__global__|__host__|__host__ __device__|invalid}1 function from"
- " %select{__device__|__global__|__host__|__host__ __device__|invalid}2 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 "
- "%select{__device__|__global__|__host__|__host__ __device__}1 and "
- "%select{__device__|__global__|__host__|__host__ __device__}2 members">;
-
-def note_ambiguous_type_conversion: Note<
- "because of ambiguity in conversion %diff{of $ to $|between types}0,1">;
-def note_ovl_builtin_binary_candidate : Note<
- "built-in candidate %0">;
-def note_ovl_builtin_unary_candidate : Note<
- "built-in candidate %0">;
-def err_ovl_no_viable_function_in_init : Error<
- "no matching constructor for initialization of %0">;
-def err_ovl_no_conversion_in_cast : Error<
- "cannot convert %1 to %2 without a conversion operator">;
-def err_ovl_no_viable_conversion_in_cast : Error<
- "no matching conversion for %select{|static_cast|reinterpret_cast|"
- "dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2">;
-def err_ovl_ambiguous_conversion_in_cast : Error<
- "ambiguous conversion for %select{|static_cast|reinterpret_cast|"
- "dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2">;
-def err_ovl_deleted_conversion_in_cast : Error<
- "%select{|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
- "functional-style cast}0 from %1 to %2 uses deleted function">;
-def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;
-def err_ref_init_ambiguous : Error<
- "reference initialization of type %0 with initializer of type %1 is ambiguous">;
-def err_ovl_deleted_init : Error<
- "call to %select{unavailable|deleted}0 constructor of %1">;
-def err_ovl_deleted_special_init : Error<
- "call to implicitly-deleted %select{default constructor|copy constructor|"
- "move constructor|copy assignment operator|move assignment operator|"
- "destructor|function}0 of %1">;
-def err_ovl_ambiguous_oper_unary : Error<
- "use of overloaded operator '%0' is ambiguous (operand type %1)">;
-def err_ovl_ambiguous_oper_binary : Error<
- "use of overloaded operator '%0' is ambiguous (with operand types %1 and %2)">;
-def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
-def note_assign_lhs_incomplete : Note<"type %0 is incomplete">;
-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">;
-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?">;
-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">;
-def note_possible_target_of_call : Note<"possible target for call">;
-
-def err_ovl_no_viable_object_call : Error<
- "no matching function for call to object of type %0">;
-def err_ovl_ambiguous_object_call : Error<
- "call to object of type %0 is ambiguous">;
-def err_ovl_deleted_object_call : Error<
- "call to %select{unavailable|deleted}0 function call operator in type %1%2">;
-def note_ovl_surrogate_cand : Note<"conversion candidate of type %0">;
-def err_member_call_without_object : Error<
- "call to non-static member function without an object argument">;
-
-// C++ Address of Overloaded Function
-def err_addr_ovl_no_viable : Error<
- "address of overloaded function %0 does not match required type %1">;
-def err_addr_ovl_ambiguous : Error<
- "address of overloaded function %0 is ambiguous">;
-def err_addr_ovl_not_func_ptrref : Error<
- "address of overloaded function %0 cannot be converted to type %1">;
-def err_addr_ovl_no_qualifier : Error<
- "cannot form member pointer of type %0 without '&' and class name">;
-
-// C++11 Literal Operators
-def err_ovl_no_viable_literal_operator : Error<
- "no matching literal operator for call to %0"
- "%select{| with argument of type %2| with arguments of types %2 and %3}1"
- "%select{| or 'const char *'}4"
- "%select{|, and no matching literal operator template}5">;
-
-// C++ Template Declarations
-def err_template_param_shadow : Error<
- "declaration of %0 shadows template parameter">;
-def note_template_param_here : Note<"template parameter is declared here">;
-def warn_template_export_unsupported : Warning<
- "exported templates are unsupported">;
-def err_template_outside_namespace_or_class_scope : Error<
- "templates can only be declared in namespace or class scope">;
-def err_template_inside_local_class : Error<
- "templates cannot be declared inside of a local class">;
-def err_template_linkage : Error<"templates must have C++ linkage">;
-def err_template_typedef : Error<"a typedef cannot be a template">;
-def err_template_unnamed_class : Error<
- "cannot declare a class template with no name">;
-def err_template_param_list_different_arity : Error<
- "%select{too few|too many}0 template parameters in template "
- "%select{|template parameter }1redeclaration">;
-def note_template_param_list_different_arity : Note<
- "%select{too few|too many}0 template parameters in template template "
- "argument">;
-def note_template_prev_declaration : Note<
- "previous template %select{declaration|template parameter}0 is here">;
-def err_template_param_different_kind : Error<
- "template parameter has a different kind in template "
- "%select{|template parameter }0redeclaration">;
-def note_template_param_different_kind : Note<
- "template parameter has a different kind in template argument">;
-
-def err_template_nontype_parm_different_type : Error<
- "template non-type parameter has a different type %0 in template "
- "%select{|template parameter }1redeclaration">;
-
-def note_template_nontype_parm_different_type : Note<
- "template non-type parameter has a different type %0 in template argument">;
-def note_template_nontype_parm_prev_declaration : Note<
- "previous non-type template parameter with type %0 is here">;
-def err_template_nontype_parm_bad_type : Error<
- "a non-type template parameter cannot have type %0">;
-def err_template_param_default_arg_redefinition : Error<
- "template parameter redefines default argument">;
-def note_template_param_prev_default_arg : Note<
- "previous default template argument defined here">;
-def err_template_param_default_arg_missing : Error<
- "template parameter missing a default argument">;
-def ext_template_parameter_default_in_function_template : ExtWarn<
- "default template arguments for a function template are a C++11 extension">,
- InGroup<CXX11>;
-def warn_cxx98_compat_template_parameter_default_in_function_template : Warning<
- "default template arguments for a function template are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_template_parameter_default_template_member : Error<
- "cannot add a default template argument to the definition of a member of a "
- "class template">;
-def err_template_parameter_default_friend_template : Error<
- "default template argument not permitted on a friend template">;
-def err_template_template_parm_no_parms : Error<
- "template template parameter must have its own template parameters">;
-
-def ext_variable_template : ExtWarn<"variable templates are a C++14 extension">,
- InGroup<CXX14>;
-def warn_cxx11_compat_variable_template : Warning<
- "variable templates are incompatible with C++ standards before C++14">,
- InGroup<CXXPre14Compat>, DefaultIgnore;
-def err_template_variable_noparams : Error<
- "extraneous 'template<>' in declaration of variable %0">;
-def err_template_member : Error<"member %0 declared as a template">;
-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<
- "use of class template %0 requires template arguments">;
-def err_template_arg_list_different_arity : Error<
- "%select{too few|too many}0 template arguments for "
- "%select{class template|function template|template template parameter"
- "|template}1 %2">;
-def note_template_decl_here : Note<"template is declared here">;
-def err_template_arg_must_be_type : Error<
- "template argument for template type parameter must be a type">;
-def err_template_arg_must_be_type_suggest : Error<
- "template argument for template type parameter must be a type; "
- "did you forget 'typename'?">;
-def ext_ms_template_type_arg_missing_typename : ExtWarn<
- "template argument for template type parameter must be a type; "
- "omitted 'typename' is a Microsoft extension">,
- InGroup<MicrosoftTemplate>;
-def err_template_arg_must_be_expr : Error<
- "template argument for non-type template parameter must be an expression">;
-def err_template_arg_nontype_ambig : Error<
- "template argument for non-type template parameter is treated as function type %0">;
-def err_template_arg_must_be_template : Error<
- "template argument for template template parameter must be a class template%select{| or type alias template}0">;
-def ext_template_arg_local_type : ExtWarn<
- "template argument uses local type %0">, InGroup<LocalTypeTemplateArgs>;
-def ext_template_arg_unnamed_type : ExtWarn<
- "template argument uses unnamed type">, InGroup<UnnamedTypeTemplateArgs>;
-def warn_cxx98_compat_template_arg_local_type : Warning<
- "local type %0 as template argument is incompatible with C++98">,
- InGroup<CXX98CompatLocalTypeTemplateArgs>, DefaultIgnore;
-def warn_cxx98_compat_template_arg_unnamed_type : Warning<
- "unnamed type as template argument is incompatible with C++98">,
- InGroup<CXX98CompatUnnamedTypeTemplateArgs>, DefaultIgnore;
-def note_template_unnamed_type_here : Note<
- "unnamed type used in template argument was declared here">;
-def err_template_arg_overload_type : Error<
- "template argument is the type of an unresolved overloaded function">;
-def err_template_arg_not_class_template : Error<
- "template argument does not refer to a class template or template "
- "template parameter">;
-def note_template_arg_refers_here_func : Note<
- "template argument refers to function template %0, here">;
-def err_template_arg_template_params_mismatch : Error<
- "template template argument has different template parameters than its "
- "corresponding template template parameter">;
-def err_template_arg_not_integral_or_enumeral : Error<
- "non-type template argument of type %0 must have an integral or enumeration"
- " type">;
-def err_template_arg_not_ice : Error<
- "non-type template argument of type %0 is not an integral constant "
- "expression">;
-def err_template_arg_not_address_constant : Error<
- "non-type template argument of type %0 is not a constant expression">;
-def warn_cxx98_compat_template_arg_null : Warning<
- "use of null pointer as non-type template argument is incompatible with "
- "C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def err_template_arg_untyped_null_constant : Error<
- "null non-type template argument must be cast to template parameter type %0">;
-def err_template_arg_wrongtype_null_constant : Error<
- "null non-type template argument of type %0 does not match template parameter "
- "of type %1">;
-def err_deduced_non_type_template_arg_type_mismatch : Error<
- "deduced non-type template argument does not have the same type as the "
- "its corresponding template parameter%diff{ ($ vs $)|}0,1">;
-def err_non_type_template_arg_subobject : Error<
- "non-type template argument refers to subobject '%0'">;
-def err_non_type_template_arg_addr_label_diff : Error<
- "template argument / label address difference / what did you expect?">;
-def err_template_arg_not_convertible : Error<
- "non-type template argument of type %0 cannot be converted to a value "
- "of type %1">;
-def warn_template_arg_negative : Warning<
- "non-type template argument with value '%0' converted to '%1' for unsigned "
- "template parameter of type %2">, InGroup<Conversion>, DefaultIgnore;
-def warn_template_arg_too_large : Warning<
- "non-type template argument value '%0' truncated to '%1' for "
- "template parameter of type %2">, InGroup<Conversion>, DefaultIgnore;
-def err_template_arg_no_ref_bind : Error<
- "non-type template parameter of reference type "
- "%diff{$ cannot bind to template argument of type $"
- "|cannot bind to template of incompatible argument type}0,1">;
-def err_template_arg_ref_bind_ignores_quals : Error<
- "reference binding of non-type template parameter "
- "%diff{of type $ to template argument of type $|to template argument}0,1 "
- "ignores qualifiers">;
-def err_template_arg_not_decl_ref : Error<
- "non-type template argument does not refer to any declaration">;
-def err_template_arg_not_address_of : Error<
- "non-type template argument for template parameter of pointer type %0 must "
- "have its address taken">;
-def err_template_arg_address_of_non_pointer : Error<
- "address taken in non-type template argument for template parameter of "
- "reference type %0">;
-def err_template_arg_reference_var : Error<
- "non-type template argument of reference type %0 is not an object">;
-def err_template_arg_field : Error<
- "non-type template argument refers to non-static data member %0">;
-def err_template_arg_method : Error<
- "non-type template argument refers to non-static member function %0">;
-def err_template_arg_object_no_linkage : Error<
- "non-type template argument refers to %select{function|object}0 %1 that "
- "does not have linkage">;
-def warn_cxx98_compat_template_arg_object_internal : Warning<
- "non-type template argument referring to %select{function|object}0 %1 with "
- "internal linkage is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_template_arg_object_internal : ExtWarn<
- "non-type template argument referring to %select{function|object}0 %1 with "
- "internal linkage is a C++11 extension">, InGroup<CXX11>;
-def err_template_arg_thread_local : Error<
- "non-type template argument refers to thread-local object">;
-def note_template_arg_internal_object : Note<
- "non-type template argument refers to %select{function|object}0 here">;
-def note_template_arg_refers_here : Note<
- "non-type template argument refers here">;
-def err_template_arg_not_object_or_func : Error<
- "non-type template argument does not refer to an object or function">;
-def err_template_arg_not_pointer_to_member_form : Error<
- "non-type template argument is not a pointer to member constant">;
-def err_template_arg_member_ptr_base_derived_not_supported : Error<
- "sorry, non-type template argument of pointer-to-member type %1 that refers "
- "to member %q0 of a different class is not supported yet">;
-def ext_template_arg_extra_parens : ExtWarn<
- "address non-type template argument cannot be surrounded by parentheses">;
-def warn_cxx98_compat_template_arg_extra_parens : Warning<
- "redundant parentheses surrounding address non-type template argument are "
- "incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def err_pointer_to_member_type : Error<
- "invalid use of pointer to member type after %select{.*|->*}0">;
-def err_pointer_to_member_call_drops_quals : Error<
- "call to pointer to member function of type %0 drops '%1' qualifier%s2">;
-def err_pointer_to_member_oper_value_classify: Error<
- "pointer-to-member function type %0 can only be called on an "
- "%select{rvalue|lvalue}1">;
-def ext_ms_deref_template_argument: ExtWarn<
- "non-type template argument containing a dereference operation is a "
- "Microsoft extension">, InGroup<MicrosoftTemplate>;
-def ext_ms_delayed_template_argument: ExtWarn<
- "using the undeclared type %0 as a default template argument is a "
- "Microsoft extension">, InGroup<MicrosoftTemplate>;
-
-// C++ template specialization
-def err_template_spec_unknown_kind : Error<
- "can only provide an explicit specialization for a class template, function "
- "template, variable template, or a member function, static data member, "
- "%select{or member class|member class, or member enumeration}0 of a "
- "class template">;
-def note_specialized_entity : Note<
- "explicitly specialized declaration is 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">;
-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 "
- "is a Microsoft extension">, InGroup<MicrosoftTemplate>;
-def err_template_spec_redecl_global_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 occur at global scope">;
-def err_spec_member_not_instantiated : Error<
- "specialization of member %q0 does not specialize an instantiated member">;
-def note_specialized_decl : Note<"attempt to specialize declaration here">;
-def err_specialization_after_instantiation : Error<
- "explicit specialization of %0 after instantiation">;
-def note_instantiation_required_here : Note<
- "%select{implicit|explicit}0 instantiation first required here">;
-def err_template_spec_friend : Error<
- "template specialization declaration cannot be a friend">;
-def err_template_spec_default_arg : Error<
- "default argument not permitted on an explicit "
- "%select{instantiation|specialization}0 of function %1">;
-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'">;
-
-// C++ class template specializations and out-of-line definitions
-def err_template_spec_needs_header : Error<
- "template specialization requires 'template<>'">;
-def err_template_spec_needs_template_parameters : Error<
- "template specialization or definition requires a template parameter list "
- "corresponding to the nested type %0">;
-def err_template_param_list_matches_nontemplate : Error<
- "template parameter list matching the non-templated nested type %0 should "
- "be empty ('template<>')">;
-def err_alias_template_extra_headers : Error<
- "extraneous template parameter list in alias template declaration">;
-def err_template_spec_extra_headers : Error<
- "extraneous template parameter list in template specialization or "
- "out-of-line template definition">;
-def warn_template_spec_extra_headers : Warning<
- "extraneous template parameter list in template specialization">;
-def note_explicit_template_spec_does_not_need_header : Note<
- "'template<>' header not required for explicitly-specialized class %0 "
- "declared here">;
-def err_template_qualified_declarator_no_match : Error<
- "nested name specifier '%0' for declaration does not refer into a class, "
- "class template or class template partial specialization">;
-def err_specialize_member_of_template : Error<
- "cannot specialize %select{|(with 'template<>') }0a member of an "
- "unspecialized template">;
-
-// C++ Class Template Partial Specialization
-def err_default_arg_in_partial_spec : Error<
- "default template argument in a class template partial specialization">;
-def err_dependent_non_type_arg_in_partial_spec : Error<
- "non-type template argument depends on a template parameter of the "
- "partial specialization">;
-def note_dependent_non_type_default_arg_in_partial_spec : Note<
- "template parameter is used in default argument declared here">;
-def err_dependent_typed_non_type_arg_in_partial_spec : Error<
- "non-type template argument specializes a template parameter with "
- "dependent type %0">;
-def err_partial_spec_args_match_primary_template : Error<
- "%select{class|variable}0 template partial specialization does not "
- "specialize any template argument; to %select{declare|define}1 the "
- "primary template, remove the template argument list">;
-def warn_partial_specs_not_deducible : Warning<
- "%select{class|variable}0 template partial specialization contains "
- "%select{a template parameter|template parameters}1 that cannot be "
- "deduced; this partial specialization will never be used">;
-def note_partial_spec_unused_parameter : Note<
- "non-deducible template parameter %0">;
-def err_partial_spec_ordering_ambiguous : Error<
- "ambiguous partial specializations of %0">;
-def note_partial_spec_match : Note<"partial specialization matches %0">;
-def err_partial_spec_redeclared : Error<
- "class template partial specialization %0 cannot be redeclared">;
-def note_prev_partial_spec_here : Note<
- "previous declaration of class template partial specialization %0 is here">;
-def err_partial_spec_fully_specialized : Error<
- "partial specialization of %0 does not use any of its template parameters">;
-
-// C++ Variable Template Partial Specialization
-def err_var_partial_spec_redeclared : Error<
- "variable template partial specialization %0 cannot be redefined">;
-def note_var_prev_partial_spec_here : Note<
- "previous declaration of variable template partial specialization is here">;
-def err_var_spec_no_template : Error<
- "no variable template matches%select{| partial}0 specialization">;
-def err_var_spec_no_template_but_method : Error<
- "no variable template matches specialization; "
- "did you mean to use %0 as function template instead?">;
-
-// C++ Function template specializations
-def err_function_template_spec_no_match : Error<
- "no function template matches function template specialization %0">;
-def err_function_template_spec_ambiguous : Error<
- "function template specialization %0 ambiguously refers to more than one "
- "function template; explicitly specify%select{| additional}1 template "
- "arguments to identify a particular function template">;
-def note_function_template_spec_matched : Note<
- "function template matches specialization %0">;
-def err_function_template_partial_spec : Error<
- "function template partial specialization is not allowed">;
-
-// C++ Template Instantiation
-def err_template_recursion_depth_exceeded : Error<
- "recursive template instantiation exceeded maximum depth of %0">,
- DefaultFatal, NoSFINAE;
-def note_template_recursion_depth : Note<
- "use -ftemplate-depth=N to increase recursive template instantiation depth">;
-
-def err_template_instantiate_within_definition : Error<
- "%select{implicit|explicit}0 instantiation of template %1 within its"
- " own definition">;
-def err_template_instantiate_undefined : Error<
- "%select{implicit|explicit}0 instantiation of undefined template %1">;
-def err_implicit_instantiate_member_undefined : Error<
- "implicit instantiation of undefined member %0">;
-def note_template_class_instantiation_was_here : Note<
- "class template %0 was instantiated here">;
-def note_template_class_explicit_specialization_was_here : Note<
- "class template %0 was explicitly specialized here">;
-def note_template_class_instantiation_here : Note<
- "in instantiation of template class %0 requested here">;
-def note_template_member_class_here : Note<
- "in instantiation of member class %0 requested here">;
-def note_template_member_function_here : Note<
- "in instantiation of member function %q0 requested here">;
-def note_function_template_spec_here : Note<
- "in instantiation of function template specialization %q0 requested here">;
-def note_template_static_data_member_def_here : Note<
- "in instantiation of static data member %q0 requested here">;
-def note_template_variable_def_here : Note<
- "in instantiation of variable template specialization %q0 requested here">;
-def note_template_enum_def_here : Note<
- "in instantiation of enumeration %q0 requested here">;
-def note_template_nsdmi_here : Note<
- "in instantiation of default member initializer %q0 requested here">;
-def note_template_type_alias_instantiation_here : Note<
- "in instantiation of template type alias %0 requested here">;
-def note_template_exception_spec_instantiation_here : Note<
- "in instantiation of exception specification for %0 requested here">;
-
-def note_default_arg_instantiation_here : Note<
- "in instantiation of default argument for '%0' required here">;
-def note_default_function_arg_instantiation_here : Note<
- "in instantiation of default function argument expression "
- "for '%0' required here">;
-def note_explicit_template_arg_substitution_here : Note<
- "while substituting explicitly-specified template arguments into function "
- "template %0 %1">;
-def note_function_template_deduction_instantiation_here : Note<
- "while substituting deduced template arguments into function template %0 "
- "%1">;
-def note_partial_spec_deduct_instantiation_here : Note<
- "during template argument deduction for class template partial "
- "specialization %0 %1">;
-def note_prior_template_arg_substitution : Note<
- "while substituting prior template arguments into %select{non-type|template}0"
- " template parameter%1 %2">;
-def note_template_default_arg_checking : Note<
- "while checking a default template argument used here">;
-def note_instantiation_contexts_suppressed : Note<
- "(skipping %0 context%s0 in backtrace; use -ftemplate-backtrace-limit=0 to "
- "see all)">;
-
-def err_field_instantiates_to_function : Error<
- "data member instantiated with function type %0">;
-def err_variable_instantiates_to_function : Error<
- "%select{variable|static data member}0 instantiated with function type %1">;
-def err_nested_name_spec_non_tag : Error<
- "type %0 cannot be used prior to '::' because it has no members">;
-
-// C++ Explicit Instantiation
-def err_explicit_instantiation_duplicate : Error<
- "duplicate explicit instantiation of %0">;
-def ext_explicit_instantiation_duplicate : ExtWarn<
- "duplicate explicit instantiation of %0 ignored as a Microsoft extension">,
- InGroup<MicrosoftTemplate>;
-def note_previous_explicit_instantiation : Note<
- "previous explicit instantiation is here">;
-def ext_explicit_instantiation_after_specialization : Extension<
- "explicit instantiation of %0 that occurs after an explicit "
- "specialization will be ignored (C++11 extension)">,
- InGroup<CXX11>;
-def warn_cxx98_compat_explicit_instantiation_after_specialization : Warning<
- "explicit instantiation of %0 that occurs after an explicit "
- "specialization is incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def note_previous_template_specialization : Note<
- "previous template specialization is here">;
-def err_explicit_instantiation_nontemplate_type : Error<
- "explicit instantiation of non-templated type %0">;
-def note_nontemplate_decl_here : Note<
- "non-templated declaration is here">;
-def err_explicit_instantiation_in_class : Error<
- "explicit instantiation of %0 in class scope">;
-def err_explicit_instantiation_out_of_scope : Error<
- "explicit instantiation of %0 not in a namespace enclosing %1">;
-def err_explicit_instantiation_must_be_global : Error<
- "explicit instantiation of %0 must occur at global scope">;
-def warn_explicit_instantiation_out_of_scope_0x : Warning<
- "explicit instantiation of %0 not in a namespace enclosing %1">,
- InGroup<CXX11Compat>, DefaultIgnore;
-def warn_explicit_instantiation_must_be_global_0x : Warning<
- "explicit instantiation of %0 must occur at global scope">,
- InGroup<CXX11Compat>, DefaultIgnore;
-
-def err_explicit_instantiation_requires_name : Error<
- "explicit instantiation declaration requires a name">;
-def err_explicit_instantiation_of_typedef : Error<
- "explicit instantiation of typedef %0">;
-def err_explicit_instantiation_storage_class : Error<
- "explicit instantiation cannot have a storage class">;
-def err_explicit_instantiation_not_known : Error<
- "explicit instantiation of %0 does not refer to a function template, "
- "variable template, member function, member class, or static data member">;
-def note_explicit_instantiation_here : Note<
- "explicit instantiation refers here">;
-def err_explicit_instantiation_data_member_not_instantiated : Error<
- "explicit instantiation refers to static data member %q0 that is not an "
- "instantiation">;
-def err_explicit_instantiation_member_function_not_instantiated : Error<
- "explicit instantiation refers to member function %q0 that is not an "
- "instantiation">;
-def err_explicit_instantiation_ambiguous : Error<
- "partial ordering for explicit instantiation of %0 is ambiguous">;
-def note_explicit_instantiation_candidate : Note<
- "explicit instantiation candidate function template here %0">;
-def err_explicit_instantiation_inline : Error<
- "explicit instantiation cannot be 'inline'">;
-def warn_explicit_instantiation_inline_0x : Warning<
- "explicit instantiation cannot be 'inline'">, InGroup<CXX11Compat>,
- DefaultIgnore;
-def err_explicit_instantiation_constexpr : Error<
- "explicit instantiation cannot be 'constexpr'">;
-def ext_explicit_instantiation_without_qualified_id : Extension<
- "qualifier in explicit instantiation of %q0 requires a template-id "
- "(a typedef is not permitted)">;
-def err_explicit_instantiation_without_template_id : Error<
- "explicit instantiation of %q0 must specify a template argument list">;
-def err_explicit_instantiation_unqualified_wrong_namespace : Error<
- "explicit instantiation of %q0 must occur in namespace %1">;
-def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning<
- "explicit instantiation of %q0 must occur in namespace %1">,
- InGroup<CXX11Compat>, DefaultIgnore;
-def err_explicit_instantiation_undefined_member : Error<
- "explicit instantiation of undefined %select{member class|member function|"
- "static data member}0 %1 of class template %2">;
-def err_explicit_instantiation_undefined_func_template : Error<
- "explicit instantiation of undefined function template %0">;
-def err_explicit_instantiation_undefined_var_template : Error<
- "explicit instantiation of undefined variable template %q0">;
-def err_explicit_instantiation_declaration_after_definition : Error<
- "explicit instantiation declaration (with 'extern') follows explicit "
- "instantiation definition (without 'extern')">;
-def note_explicit_instantiation_definition_here : Note<
- "explicit instantiation definition is here">;
-def err_invalid_var_template_spec_type : Error<"type %2 "
- "of %select{explicit instantiation|explicit specialization|"
- "partial specialization|redeclaration}0 of %1 does not match"
- " expected type %3">;
-def err_mismatched_exception_spec_explicit_instantiation : Error<
- "exception specification in explicit instantiation does not match "
- "instantiated one">;
-def ext_mismatched_exception_spec_explicit_instantiation : ExtWarn<
- err_mismatched_exception_spec_explicit_instantiation.Text>,
- InGroup<MicrosoftExceptionSpec>;
-
-// C++ typename-specifiers
-def err_typename_nested_not_found : Error<"no type named %0 in %1">;
-def err_typename_nested_not_found_enable_if : Error<
- "no type named 'type' in %0; 'enable_if' cannot be used to disable "
- "this declaration">;
-def err_typename_nested_not_type : Error<
- "typename specifier refers to non-type member %0 in %1">;
-def note_typename_refers_here : Note<
- "referenced member %0 is declared here">;
-def err_typename_missing : Error<
- "missing 'typename' prior to dependent type name '%0%1'">;
-def ext_typename_missing : ExtWarn<
- "missing 'typename' prior to dependent type name '%0%1'">,
- InGroup<DiagGroup<"typename-missing">>;
-def ext_typename_outside_of_template : ExtWarn<
- "'typename' occurs outside of a template">, InGroup<CXX11>;
-def warn_cxx98_compat_typename_outside_of_template : Warning<
- "use of 'typename' outside of a template is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_typename_refers_to_using_value_decl : Error<
- "typename specifier refers to a dependent using declaration for a value "
- "%0 in %1">;
-def note_using_value_decl_missing_typename : Note<
- "add 'typename' to treat this using declaration as a type">;
-
-def err_template_kw_refers_to_non_template : Error<
- "%0 following the 'template' keyword does not refer to a template">;
-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 : Error<
- "class template declared here">;
-def err_template_kw_missing : Error<
- "missing 'template' keyword prior to dependent template name '%0%1'">;
-def ext_template_outside_of_template : ExtWarn<
- "'template' keyword outside of a template">, InGroup<CXX11>;
-def warn_cxx98_compat_template_outside_of_template : Warning<
- "use of 'template' keyword outside of a template is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-def err_non_type_template_in_nested_name_specifier : Error<
- "qualified name refers into a specialization of %select{function|variable}0 "
- "template %1">;
-def err_template_id_not_a_type : Error<
- "template name refers to non-type template %0">;
-def note_template_declared_here : Note<
- "%select{function template|class template|variable template"
- "|type alias template|template template parameter}0 "
- "%1 declared here">;
-def err_alias_template_expansion_into_fixed_list : Error<
- "pack expansion used as argument for non-pack parameter of alias template">;
-def note_parameter_type : Note<
- "parameter of type %0 is declared here">;
-
-// C++11 Variadic Templates
-def err_template_param_pack_default_arg : Error<
- "template parameter pack cannot have a default argument">;
-def err_template_param_pack_must_be_last_template_parameter : Error<
- "template parameter pack must be the last template parameter">;
-
-def err_template_parameter_pack_non_pack : Error<
- "%select{template type|non-type template|template template}0 parameter"
- "%select{| pack}1 conflicts with previous %select{template type|"
- "non-type template|template template}0 parameter%select{ pack|}1">;
-def note_template_parameter_pack_non_pack : Note<
- "%select{template type|non-type template|template template}0 parameter"
- "%select{| pack}1 does not match %select{template type|non-type template"
- "|template template}0 parameter%select{ pack|}1 in template argument">;
-def note_template_parameter_pack_here : Note<
- "previous %select{template type|non-type template|template template}0 "
- "parameter%select{| pack}1 declared here">;
-
-def err_unexpanded_parameter_pack : Error<
- "%select{expression|base type|declaration type|data member type|bit-field "
- "size|static assertion|fixed underlying type|enumerator value|"
- "using declaration|friend declaration|qualifier|initializer|default argument|"
- "non-type template parameter type|exception type|partial specialization|"
- "__if_exists name|__if_not_exists name|lambda|block}0 contains"
- "%plural{0: an|:}1 unexpanded parameter pack"
- "%plural{0:|1: %2|2:s %2 and %3|:s %2, %3, ...}1">;
-
-def err_pack_expansion_without_parameter_packs : Error<
- "pack expansion does not contain any unexpanded parameter packs">;
-def err_pack_expansion_length_conflict : Error<
- "pack expansion contains parameter packs %0 and %1 that have different "
- "lengths (%2 vs. %3)">;
-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_member_init : Error<
- "pack expansion for initialization of member %0">;
-
-def err_function_parameter_pack_without_parameter_packs : Error<
- "type %0 of function parameter pack does not contain any unexpanded "
- "parameter packs">;
-def err_ellipsis_in_declarator_not_parameter : Error<
- "only function and template parameters can be parameter packs">;
-
-def err_sizeof_pack_no_pack_name : Error<
- "%0 does not refer to the name of a parameter pack">;
-
-def err_fold_expression_packs_both_sides : Error<
- "binary fold expression has unexpanded parameter packs in both operands">;
-def err_fold_expression_empty : Error<
- "unary fold expression has empty expansion for operator '%0' "
- "with no fallback value">;
-def err_fold_expression_bad_operand : Error<
- "expression not permitted as operand of fold expression">;
-
-def err_unexpected_typedef : Error<
- "unexpected type name %0: expected expression">;
-def err_unexpected_namespace : Error<
- "unexpected namespace name %0: expected expression">;
-def err_undeclared_var_use : Error<"use of undeclared identifier %0">;
-def ext_undeclared_unqual_id_with_dependent_base : ExtWarn<
- "use of undeclared identifier %0; "
- "unqualified lookup into dependent bases of class template %1 is a Microsoft extension">,
- InGroup<MicrosoftTemplate>;
-def ext_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 "
- "found via unqualified lookup into dependent bases of class templates is a "
- "Microsoft extension">, InGroup<MicrosoftTemplate>;
-def note_dependent_var_use : Note<"must qualify identifier to find this "
- "declaration in dependent base class">;
-def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither "
- "visible in the template definition nor found by argument-dependent lookup">;
-def note_not_found_by_two_phase_lookup : Note<"%0 should be declared prior to the "
- "call site%select{| or in %2| or in an associated namespace of one of its arguments}1">;
-def err_undeclared_use : Error<"use of undeclared %0">;
-def warn_partial_availability : Warning<"%0 is only available conditionally">,
- InGroup<PartialAvailability>, DefaultIgnore;
-def note_partial_availability_silence : Note<
- "explicitly redeclare %0 to silence this warning">;
-def warn_partial_message : Warning<"%0 is partial: %1">,
- InGroup<PartialAvailability>, DefaultIgnore;
-def warn_partial_fwdclass_message : Warning<
- "%0 may be partial because the receiver type is unknown">,
- InGroup<PartialAvailability>, DefaultIgnore;
-def warn_deprecated : Warning<"%0 is deprecated">,
- InGroup<DeprecatedDeclarations>;
-def warn_property_method_deprecated :
- Warning<"property access is using %0 method which is deprecated">,
- InGroup<DeprecatedDeclarations>;
-def warn_deprecated_message : Warning<"%0 is deprecated: %1">,
- InGroup<DeprecatedDeclarations>;
-def warn_deprecated_anonymous_namespace : Warning<
- "'deprecated' attribute on anonymous namespace ignored">,
- InGroup<IgnoredAttributes>;
-def warn_deprecated_fwdclass_message : Warning<
- "%0 may be deprecated because the receiver type is unknown">,
- InGroup<DeprecatedDeclarations>;
-def warn_deprecated_def : Warning<
- "Implementing deprecated %select{method|class|category}0">,
- InGroup<DeprecatedImplementations>, DefaultIgnore;
-def err_unavailable : Error<"%0 is unavailable">;
-def err_property_method_unavailable :
- Error<"property access is using %0 method which is unavailable">;
-def err_unavailable_message : Error<"%0 is unavailable: %1">;
-def warn_unavailable_fwdclass_message : Warning<
- "%0 may be unavailable because the receiver type is unknown">,
- InGroup<UnavailableDeclarations>;
-def note_availability_specified_here : Note<
- "%0 has been explicitly marked "
- "%select{unavailable|deleted|deprecated|partial}1 here">;
-def note_implicitly_deleted : Note<
- "explicitly defaulted function was implicitly deleted here">;
-def note_inherited_deleted_here : Note<
- "deleted constructor was inherited here">;
-def note_cannot_inherit : Note<
- "constructor cannot be inherited">;
-def warn_not_enough_argument : Warning<
- "not enough variable arguments in %0 declaration to fit a sentinel">,
- InGroup<Sentinel>;
-def warn_missing_sentinel : Warning <
- "missing sentinel in %select{function call|method dispatch|block call}0">,
- InGroup<Sentinel>;
-def note_sentinel_here : Note<
- "%select{function|method|block}0 has been explicitly marked sentinel here">;
-def warn_missing_prototype : Warning<
- "no previous prototype for function %0">,
- InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
-def note_declaration_not_a_prototype : Note<
- "this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function">;
-def warn_missing_variable_declarations : Warning<
- "no previous extern declaration for non-static variable %0">,
- InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
-def err_static_data_member_reinitialization :
- Error<"static data member %0 already has an initializer">;
-def err_redefinition : Error<"redefinition of %0">;
-def err_alias_after_tentative :
- Error<"alias definition of %0 after tentative definition">;
-def err_alias_is_definition :
- Error<"definition %0 cannot also be an alias">;
-def err_definition_of_implicitly_declared_member : Error<
- "definition of implicitly declared %select{default constructor|copy "
- "constructor|move constructor|copy assignment operator|move assignment "
- "operator|destructor|function}1">;
-def err_definition_of_explicitly_defaulted_member : Error<
- "definition of explicitly defaulted %select{default constructor|copy "
- "constructor|move constructor|copy assignment operator|move assignment "
- "operator|destructor}0">;
-def err_redefinition_extern_inline : Error<
- "redefinition of a 'extern inline' function %0 is not supported in "
- "%select{C99 mode|C++}1">;
-
-def note_deleted_dtor_no_operator_delete : Note<
- "virtual destructor requires an unambiguous, accessible 'operator delete'">;
-def note_deleted_special_member_class_subobject : Note<
- "%select{default constructor|copy constructor|move constructor|"
- "copy assignment operator|move assignment operator|destructor}0 of "
- "%1 is implicitly deleted because "
- "%select{base class %3|%select{||||variant }4field %3}2 has "
- "%select{no|a deleted|multiple|an inaccessible|a non-trivial}4 "
- "%select{%select{default constructor|copy constructor|move constructor|copy "
- "assignment operator|move assignment operator|destructor}0|destructor}5"
- "%select{||s||}4">;
-def note_deleted_default_ctor_uninit_field : Note<
- "default constructor of %0 is implicitly deleted because field %1 of "
- "%select{reference|const-qualified}3 type %2 would not be initialized">;
-def note_deleted_default_ctor_all_const : Note<
- "default constructor of %0 is implicitly deleted because all "
- "%select{data members|data members of an anonymous union member}1"
- " are const-qualified">;
-def note_deleted_copy_ctor_rvalue_reference : Note<
- "copy constructor of %0 is implicitly deleted because field %1 is of "
- "rvalue reference type %2">;
-def note_deleted_copy_user_declared_move : Note<
- "copy %select{constructor|assignment operator}0 is implicitly deleted because"
- " %1 has a user-declared move %select{constructor|assignment operator}2">;
-def note_deleted_assign_field : Note<
- "%select{copy|move}0 assignment operator of %1 is implicitly deleted "
- "because field %2 is of %select{reference|const-qualified}4 type %3">;
-
-// These should be errors.
-def warn_undefined_internal : Warning<
- "%select{function|variable}0 %q1 has internal linkage but is not defined">,
- InGroup<DiagGroup<"undefined-internal">>;
-def warn_undefined_inline : Warning<"inline function %q0 is not defined">,
- InGroup<DiagGroup<"undefined-inline">>;
-def note_used_here : Note<"used here">;
-
-def err_internal_linkage_redeclaration : Error<
- "'internal_linkage' attribute does not appear on the first declaration of %0">;
-def warn_internal_linkage_local_storage : Warning<
- "'internal_linkage' attribute on a non-static local variable is ignored">,
- InGroup<IgnoredAttributes>;
-
-def ext_internal_in_extern_inline : ExtWarn<
- "static %select{function|variable}0 %1 is used in an inline function with "
- "external linkage">, InGroup<StaticInInline>;
-def ext_internal_in_extern_inline_quiet : Extension<
- "static %select{function|variable}0 %1 is used in an inline function with "
- "external linkage">, InGroup<StaticInInline>;
-def warn_static_local_in_extern_inline : Warning<
- "non-constant static local variable in inline function may be different "
- "in different files">, InGroup<StaticLocalInInline>;
-def note_convert_inline_to_static : Note<
- "use 'static' to give inline function %0 internal linkage">;
-
-def ext_redefinition_of_typedef : ExtWarn<
- "redefinition of typedef %0 is a C11 feature">,
- InGroup<DiagGroup<"typedef-redefinition"> >;
-def err_redefinition_variably_modified_typedef : Error<
- "redefinition of %select{typedef|type alias}0 for variably-modified type %1">;
-
-def err_inline_decl_follows_def : Error<
- "inline declaration of %0 follows non-inline definition">;
-def err_inline_declaration_block_scope : Error<
- "inline declaration of %0 not allowed in block scope">;
-def err_static_non_static : Error<
- "static declaration of %0 follows non-static declaration">;
-def err_different_language_linkage : Error<
- "declaration of %0 has a different language linkage">;
-def ext_retained_language_linkage : Extension<
- "friend function %0 retaining previous language linkage is an extension">,
- InGroup<DiagGroup<"retained-language-linkage">>;
-def err_extern_c_global_conflict : Error<
- "declaration of %1 %select{with C language linkage|in global scope}0 "
- "conflicts with declaration %select{in global scope|with C language linkage}0">;
-def note_extern_c_global_conflict : Note<
- "declared %select{in global scope|with C language linkage}0 here">;
-def warn_weak_import : Warning <
- "an already-declared variable is made a weak_import declaration %0">;
-def ext_static_non_static : Extension<
- "redeclaring non-static %0 as static is a Microsoft extension">,
- InGroup<MicrosoftRedeclareStatic>;
-def err_non_static_static : Error<
- "non-static declaration of %0 follows static declaration">;
-def err_extern_non_extern : Error<
- "extern declaration of %0 follows non-extern declaration">;
-def err_non_extern_extern : Error<
- "non-extern declaration of %0 follows extern declaration">;
-def err_non_thread_thread : Error<
- "non-thread-local declaration of %0 follows thread-local declaration">;
-def err_thread_non_thread : Error<
- "thread-local declaration of %0 follows non-thread-local declaration">;
-def err_thread_thread_different_kind : Error<
- "thread-local declaration of %0 with %select{static|dynamic}1 initialization "
- "follows declaration with %select{dynamic|static}1 initialization">;
-def err_redefinition_different_type : Error<
- "redefinition of %0 with a different type%diff{: $ vs $|}1,2">;
-def err_redefinition_different_kind : Error<
- "redefinition of %0 as different kind of symbol">;
-def err_redefinition_different_namespace_alias : Error<
- "redefinition of %0 as an alias for a different namespace">;
-def note_previous_namespace_alias : Note<
- "previously defined as an alias for %0">;
-def warn_forward_class_redefinition : Warning<
- "redefinition of forward class %0 of a typedef name of an object type is ignored">,
- InGroup<DiagGroup<"objc-forward-class-redefinition">>;
-def err_redefinition_different_typedef : Error<
- "%select{typedef|type alias|type alias template}0 "
- "redefinition with different types%diff{ ($ vs $)|}1,2">;
-def err_tag_reference_non_tag : Error<
- "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template}0">;
-def err_tag_reference_conflict : Error<
- "implicit declaration introduced by elaborated type conflicts with "
- "%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
-def err_dependent_tag_decl : Error<
- "%select{declaration|definition}0 of "
- "%select{struct|interface|union|class|enum}1 in a dependent scope">;
-def err_tag_definition_of_typedef : Error<
- "definition of type %0 conflicts with %select{typedef|type alias}1 of the same name">;
-def err_conflicting_types : Error<"conflicting types for %0">;
-def err_different_pass_object_size_params : Error<
- "conflicting pass_object_size attributes on parameters">;
-def err_late_asm_label_name : Error<
- "cannot apply asm label to %select{variable|function}0 after its first use">;
-def err_different_asm_label : Error<"conflicting asm label">;
-def err_nested_redefinition : Error<"nested redefinition of %0">;
-def err_use_with_wrong_tag : Error<
- "use of %0 with tag type that does not match previous declaration">;
-def warn_struct_class_tag_mismatch : Warning<
- "%select{struct|interface|class}0%select{| template}1 %2 was previously "
- "declared as a %select{struct|interface|class}3%select{| template}1">,
- InGroup<MismatchedTags>, DefaultIgnore;
-def warn_struct_class_previous_tag_mismatch : Warning<
- "%2 defined as %select{a struct|an interface|a class}0%select{| template}1 "
- "here but previously declared as "
- "%select{a struct|an interface|a class}3%select{| template}1">,
- InGroup<MismatchedTags>, DefaultIgnore;
-def note_struct_class_suggestion : Note<
- "did you mean %select{struct|interface|class}0 here?">;
-def ext_forward_ref_enum : Extension<
- "ISO C forbids forward references to 'enum' types">;
-def err_forward_ref_enum : Error<
- "ISO C++ forbids forward references to 'enum' types">;
-def ext_ms_forward_ref_enum : Extension<
- "forward references to 'enum' types are a Microsoft extension">,
- InGroup<MicrosoftEnumForwardReference>;
-def ext_forward_ref_enum_def : Extension<
- "redeclaration of already-defined enum %0 is a GNU extension">,
- InGroup<GNURedeclaredEnum>;
-
-def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
-def err_duplicate_member : Error<"duplicate member %0">;
-def err_misplaced_ivar : Error<
- "instance variables may not be placed in %select{categories|class extension}0">;
-def warn_ivars_in_interface : Warning<
- "declaration of instance variables in the interface is deprecated">,
- InGroup<DiagGroup<"objc-interface-ivars">>, DefaultIgnore;
-def ext_enum_value_not_int : Extension<
- "ISO C restricts enumerator values to range of 'int' (%0 is too "
- "%select{small|large}1)">;
-def ext_enum_too_large : ExtWarn<
- "enumeration values exceed range of largest integer">, InGroup<EnumTooLarge>;
-def ext_enumerator_increment_too_large : ExtWarn<
- "incremented enumerator value %0 is not representable in the "
- "largest integer type">, InGroup<EnumTooLarge>;
-def warn_flag_enum_constant_out_of_range : Warning<
- "enumeration value %0 is out of range of flags in enumeration type %1">,
- InGroup<FlagEnum>;
-
-def warn_illegal_constant_array_size : Extension<
- "size of static array must be an integer constant expression">;
-def err_vm_decl_in_file_scope : Error<
- "variably modified type declaration not allowed at file scope">;
-def err_vm_decl_has_extern_linkage : Error<
- "variably modified type declaration cannot have 'extern' linkage">;
-def err_typecheck_field_variable_size : Error<
- "fields must have a constant size: 'variable length array in structure' "
- "extension will never be supported">;
-def err_vm_func_decl : Error<
- "function declaration cannot have variably modified type">;
-def err_array_too_large : Error<
- "array is too large (%0 elements)">;
-def warn_array_new_too_large : Warning<"array is too large (%0 elements)">,
- // FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
- InGroup<BadArrayNewLength>;
-
-// -Wpadded, -Wpacked
-def warn_padded_struct_field : Warning<
- "padding %select{struct|interface|class}0 %1 with %2 "
- "%select{byte|bit}3%s2 to align %4">,
- InGroup<Padded>, DefaultIgnore;
-def warn_padded_struct_anon_field : Warning<
- "padding %select{struct|interface|class}0 %1 with %2 "
- "%select{byte|bit}3%s2 to align anonymous bit-field">,
- InGroup<Padded>, DefaultIgnore;
-def warn_padded_struct_size : Warning<
- "padding size of %0 with %1 %select{byte|bit}2%s1 to alignment boundary">,
- InGroup<Padded>, DefaultIgnore;
-def warn_unnecessary_packed : Warning<
- "packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
-
-def err_typecheck_negative_array_size : Error<"array size is negative">;
-def warn_typecheck_negative_array_new_size : Warning<"array size is negative">,
- // FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
- InGroup<BadArrayNewLength>;
-def warn_typecheck_function_qualifiers_ignored : Warning<
- "'%0' qualifier on function type %1 has no effect">,
- InGroup<IgnoredQualifiers>;
-def warn_typecheck_function_qualifiers_unspecified : Warning<
- "'%0' qualifier on function type %1 has unspecified behavior">;
-def warn_typecheck_reference_qualifiers : Warning<
- "'%0' qualifier on reference type %1 has no effect">,
- InGroup<IgnoredQualifiers>;
-def err_typecheck_invalid_restrict_not_pointer : Error<
- "restrict requires a pointer or reference (%0 is invalid)">;
-def err_typecheck_invalid_restrict_not_pointer_noarg : Error<
- "restrict requires a pointer or reference">;
-def err_typecheck_invalid_restrict_invalid_pointee : Error<
- "pointer to function type %0 may not be 'restrict' qualified">;
-def ext_typecheck_zero_array_size : Extension<
- "zero size arrays are an extension">, InGroup<ZeroLengthArray>;
-def err_typecheck_zero_array_size : Error<
- "zero-length arrays are not permitted in C++">;
-def warn_typecheck_zero_static_array_size : Warning<
- "'static' has no effect on zero-length arrays">,
- InGroup<ArrayBounds>;
-def err_array_size_non_int : Error<"size of array has non-integer type %0">;
-def err_init_element_not_constant : Error<
- "initializer element is not a compile-time constant">;
-def ext_aggregate_init_not_constant : Extension<
- "initializer for aggregate is not a compile-time constant">, InGroup<C99>;
-def err_local_cant_init : Error<
- "'__local' variable cannot have an initializer">;
-def err_block_extern_cant_init : Error<
- "'extern' variable cannot have an initializer">;
-def warn_extern_init : Warning<"'extern' variable has an initializer">,
- InGroup<DiagGroup<"extern-initializer">>;
-def err_variable_object_no_init : Error<
- "variable-sized object may not be initialized">;
-def err_excess_initializers : Error<
- "excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
-def ext_excess_initializers : ExtWarn<
- "excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
-def err_excess_initializers_in_char_array_initializer : Error<
- "excess elements in char array initializer">;
-def ext_excess_initializers_in_char_array_initializer : ExtWarn<
- "excess elements in char array initializer">;
-def err_initializer_string_for_char_array_too_long : Error<
- "initializer-string for char array is too long">;
-def ext_initializer_string_for_char_array_too_long : ExtWarn<
- "initializer-string for char array is too long">;
-def warn_missing_field_initializers : Warning<
- "missing field %0 initializer">,
- InGroup<MissingFieldInitializers>, DefaultIgnore;
-def warn_braces_around_scalar_init : Warning<
- "braces around scalar initializer">, InGroup<DiagGroup<"braced-scalar-init">>;
-def ext_many_braces_around_scalar_init : ExtWarn<
- "too many braces around scalar initializer">,
- InGroup<DiagGroup<"many-braces-around-scalar-init">>;
-def ext_complex_component_init : Extension<
- "complex initialization specifying real and imaginary components "
- "is an extension">, InGroup<DiagGroup<"complex-component-init">>;
-def err_empty_scalar_initializer : Error<"scalar initializer cannot be empty">;
-def warn_cxx98_compat_empty_scalar_initializer : Warning<
- "scalar initialized from empty initializer list is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx98_compat_reference_list_init : Warning<
- "reference initialized from initializer list is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx98_compat_initializer_list_init : Warning<
- "initialization of initializer_list object is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx98_compat_ctor_list_init : Warning<
- "constructor call from initializer list is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_illegal_initializer : Error<
- "illegal initializer (only variables can be initialized)">;
-def err_illegal_initializer_type : Error<"illegal initializer type %0">;
-def ext_init_list_type_narrowing : ExtWarn<
- "type %0 cannot be narrowed to %1 in initializer list">,
- InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
-def ext_init_list_variable_narrowing : ExtWarn<
- "non-constant-expression cannot be narrowed from type %0 to %1 in "
- "initializer list">, InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
-def ext_init_list_constant_narrowing : ExtWarn<
- "constant expression evaluates to %0 which cannot be narrowed to type %1">,
- InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
-def warn_init_list_type_narrowing : Warning<
- "type %0 cannot be narrowed to %1 in initializer list in C++11">,
- InGroup<CXX11Narrowing>, DefaultIgnore;
-def warn_init_list_variable_narrowing : Warning<
- "non-constant-expression cannot be narrowed from type %0 to %1 in "
- "initializer list in C++11">,
- InGroup<CXX11Narrowing>, DefaultIgnore;
-def warn_init_list_constant_narrowing : Warning<
- "constant expression evaluates to %0 which cannot be narrowed to type %1 in "
- "C++11">,
- InGroup<CXX11Narrowing>, DefaultIgnore;
-def note_init_list_narrowing_silence : Note<
- "insert an explicit cast to silence this issue">;
-def err_init_objc_class : Error<
- "cannot initialize Objective-C class type %0">;
-def err_implicit_empty_initializer : Error<
- "initializer for aggregate with no elements requires explicit braces">;
-def err_bitfield_has_negative_width : Error<
- "bit-field %0 has negative width (%1)">;
-def err_anon_bitfield_has_negative_width : Error<
- "anonymous bit-field has negative width (%0)">;
-def err_bitfield_has_zero_width : Error<"named bit-field %0 has zero width">;
-def err_bitfield_width_exceeds_type_width : Error<
- "width of bit-field %0 (%1 bits) exceeds %select{width|size}2 "
- "of its type (%3 bit%s3)">;
-def err_anon_bitfield_width_exceeds_type_width : Error<
- "width of anonymous bit-field (%0 bits) exceeds %select{width|size}1 "
- "of its type (%2 bit%s2)">;
-def err_incorrect_number_of_vector_initializers : Error<
- "number of elements must be either one or match the size of the vector">;
-
-// Used by C++ which allows bit-fields that are wider than the type.
-def warn_bitfield_width_exceeds_type_width: Warning<
- "width of bit-field %0 (%1 bits) exceeds the width of its type; value will "
- "be truncated to %2 bit%s2">, InGroup<BitFieldWidth>;
-def warn_anon_bitfield_width_exceeds_type_width : Warning<
- "width of anonymous bit-field (%0 bits) exceeds width of its type; value "
- "will be truncated to %1 bit%s1">, InGroup<BitFieldWidth>;
-
-def warn_missing_braces : Warning<
- "suggest braces around initialization of subobject">,
- InGroup<MissingBraces>, DefaultIgnore;
-
-def err_redefinition_of_label : Error<"redefinition of label %0">;
-def err_undeclared_label_use : Error<"use of undeclared label %0">;
-def err_goto_ms_asm_label : Error<
- "cannot jump from this goto statement to label %0 inside an inline assembly block">;
-def note_goto_ms_asm_label : Note<
- "inline assembly label %0 declared here">;
-def warn_unused_label : Warning<"unused label %0">,
- InGroup<UnusedLabel>, DefaultIgnore;
-
-def err_goto_into_protected_scope : Error<
- "cannot jump from this goto statement to its label">;
-def ext_goto_into_protected_scope : ExtWarn<
- "jump from this goto statement to its label is a Microsoft extension">,
- InGroup<MicrosoftGoto>;
-def warn_cxx98_compat_goto_into_protected_scope : Warning<
- "jump from this goto statement to its label is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_switch_into_protected_scope : Error<
- "cannot jump from switch statement to this case label">;
-def warn_cxx98_compat_switch_into_protected_scope : Warning<
- "jump from switch statement to this case label is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def err_indirect_goto_without_addrlabel : Error<
- "indirect goto in function with no address-of-label expressions">;
-def err_indirect_goto_in_protected_scope : Error<
- "cannot jump from this indirect goto statement to one of its possible targets">;
-def warn_cxx98_compat_indirect_goto_in_protected_scope : Warning<
- "jump from this indirect goto statement to one of its possible targets "
- "is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def note_indirect_goto_target : Note<
- "possible target of indirect goto statement">;
-def note_protected_by_variable_init : Note<
- "jump bypasses variable initialization">;
-def note_protected_by_variable_nontriv_destructor : Note<
- "jump bypasses variable with a non-trivial destructor">;
-def note_protected_by_variable_non_pod : Note<
- "jump bypasses initialization of non-POD variable">;
-def note_protected_by_cleanup : Note<
- "jump bypasses initialization of variable with __attribute__((cleanup))">;
-def note_protected_by_vla_typedef : Note<
- "jump bypasses initialization of VLA typedef">;
-def note_protected_by_vla_type_alias : Note<
- "jump bypasses initialization of VLA type alias">;
-def note_protected_by_vla : Note<
- "jump bypasses initialization of variable length array">;
-def note_protected_by_objc_try : Note<
- "jump bypasses initialization of @try block">;
-def note_protected_by_objc_catch : Note<
- "jump bypasses initialization of @catch block">;
-def note_protected_by_objc_finally : Note<
- "jump bypasses initialization of @finally block">;
-def note_protected_by_objc_synchronized : Note<
- "jump bypasses initialization of @synchronized block">;
-def note_protected_by_objc_autoreleasepool : Note<
- "jump bypasses auto release push of @autoreleasepool block">;
-def note_protected_by_cxx_try : Note<
- "jump bypasses initialization of try block">;
-def note_protected_by_cxx_catch : Note<
- "jump bypasses initialization of catch block">;
-def note_protected_by_seh_try : Note<
- "jump bypasses initialization of __try block">;
-def note_protected_by_seh_except : Note<
- "jump bypasses initialization of __except block">;
-def note_protected_by_seh_finally : Note<
- "jump bypasses initialization of __finally block">;
-def note_protected_by___block : Note<
- "jump bypasses setup of __block variable">;
-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_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_exits_cleanup : Note<
- "jump exits scope of variable with __attribute__((cleanup))">;
-def note_exits_dtor : Note<
- "jump exits scope of variable with non-trivial destructor">;
-def note_exits_temporary_dtor : Note<
- "jump exits scope of lifetime-extended temporary with non-trivial "
- "destructor">;
-def note_exits___block : Note<
- "jump exits scope of __block variable">;
-def note_exits_objc_try : Note<
- "jump exits @try block">;
-def note_exits_objc_catch : Note<
- "jump exits @catch block">;
-def note_exits_objc_finally : Note<
- "jump exits @finally block">;
-def note_exits_objc_synchronized : Note<
- "jump exits @synchronized block">;
-def note_exits_cxx_try : Note<
- "jump exits try block">;
-def note_exits_cxx_catch : Note<
- "jump exits catch block">;
-def note_exits_seh_try : Note<
- "jump exits __try block">;
-def note_exits_seh_except : Note<
- "jump exits __except block">;
-def note_exits_seh_finally : Note<
- "jump exits __finally block">;
-def note_exits_objc_autoreleasepool : Note<
- "jump exits autoreleasepool block">;
-def note_exits_objc_strong : Note<
- "jump exits scope of __strong variable">;
-def note_exits_objc_weak : Note<
- "jump exits scope of __weak variable">;
-def note_exits_block_captures_cxx_obj : Note<
- "jump exits lifetime of block which captures a destructible C++ object">;
-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 err_func_returning_qualified_void : ExtWarn<
- "function cannot return qualified void type %0">,
- InGroup<DiagGroup<"qualified-void-return-type">>;
-def err_func_returning_array_function : Error<
- "function cannot return %select{array|function}0 type %1">;
-def err_field_declared_as_function : Error<"field %0 declared as a function">;
-def err_field_incomplete : Error<"field has incomplete type %0">;
-def ext_variable_sized_type_in_struct : ExtWarn<
- "field %0 with variable sized type %1 not at the end of a struct or class is"
- " a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>;
-
-def ext_c99_flexible_array_member : Extension<
- "flexible array members are a C99 feature">, InGroup<C99>;
-def err_flexible_array_virtual_base : Error<
- "flexible array member %0 not allowed in "
- "%select{struct|interface|union|class|enum}1 which has a virtual base class">;
-def err_flexible_array_empty_aggregate : Error<
- "flexible array member %0 not allowed in otherwise empty "
- "%select{struct|interface|union|class|enum}1">;
-def err_flexible_array_has_nontrivial_dtor : Error<
- "flexible array member %0 of type %1 with non-trivial destruction">;
-def ext_flexible_array_in_struct : Extension<
- "%0 may not be nested in a struct due to flexible array member">,
- InGroup<FlexibleArrayExtensions>;
-def ext_flexible_array_in_array : Extension<
- "%0 may not be used as an array element due to flexible array member">,
- InGroup<FlexibleArrayExtensions>;
-def err_flexible_array_init : Error<
- "initialization of flexible array member is not allowed">;
-def ext_flexible_array_empty_aggregate_ms : Extension<
- "flexible array member %0 in otherwise empty "
- "%select{struct|interface|union|class|enum}1 is a Microsoft extension">,
- InGroup<MicrosoftFlexibleArray>;
-def err_flexible_array_union : Error<
- "flexible array member %0 in a union is not allowed">;
-def ext_flexible_array_union_ms : Extension<
- "flexible array member %0 in a union is a Microsoft extension">,
- InGroup<MicrosoftFlexibleArray>;
-def ext_flexible_array_empty_aggregate_gnu : Extension<
- "flexible array member %0 in otherwise empty "
- "%select{struct|interface|union|class|enum}1 is a GNU extension">,
- InGroup<GNUEmptyStruct>;
-def ext_flexible_array_union_gnu : Extension<
- "flexible array member %0 in a union is a GNU extension">, InGroup<GNUFlexibleArrayUnionMember>;
-
-let CategoryName = "ARC Semantic Issue" in {
-
-// ARC-mode diagnostics.
-
-let CategoryName = "ARC Weak References" in {
-
-def err_arc_weak_no_runtime : Error<
- "cannot create __weak reference because the current deployment target "
- "does not support weak references">;
-def err_arc_weak_disabled : Error<
- "cannot create __weak reference in file using manual reference counting">;
-def err_synthesizing_arc_weak_property_disabled : Error<
- "cannot synthesize weak property in file using manual reference counting">;
-def err_synthesizing_arc_weak_property_no_runtime : Error<
- "cannot synthesize weak property because the current deployment target "
- "does not support weak references">;
-def err_arc_unsupported_weak_class : Error<
- "class is incompatible with __weak references">;
-def err_arc_weak_unavailable_assign : Error<
- "assignment of a weak-unavailable object to a __weak object">;
-def err_arc_weak_unavailable_property : Error<
- "synthesizing __weak instance variable of type %0, which does not "
- "support weak references">;
-def note_implemented_by_class : Note<
- "when implemented by class %0">;
-def err_arc_convesion_of_weak_unavailable : Error<
- "%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to"
- " a __weak object of type %2">;
-
-} // end "ARC Weak References" category
-
-let CategoryName = "ARC Restrictions" in {
-
-def err_unavailable_in_arc : Error<
- "%0 is unavailable in ARC">;
-def note_arc_forbidden_type : Note<
- "declaration uses type that is ill-formed in ARC">;
-def note_performs_forbidden_arc_conversion : Note<
- "inline function performs a conversion which is forbidden in ARC">;
-def note_arc_init_returns_unrelated : Note<
- "init method must return a type related to its receiver type">;
-def note_arc_weak_disabled : Note<
- "declaration uses __weak, but ARC is disabled">;
-def note_arc_weak_no_runtime : Note<"declaration uses __weak, which "
- "the current deployment target does not support">;
-def note_arc_field_with_ownership : Note<
- "field has non-trivial ownership qualification">;
-
-def err_arc_illegal_explicit_message : Error<
- "ARC forbids explicit message send of %0">;
-def err_arc_unused_init_message : Error<
- "the result of a delegate init call must be immediately returned "
- "or assigned to 'self'">;
-def err_arc_mismatched_cast : Error<
- "%select{implicit conversion|cast}0 of "
- "%select{%2|a non-Objective-C pointer type %2|a block pointer|"
- "an Objective-C pointer|an indirect pointer to an Objective-C pointer}1"
- " to %3 is disallowed with ARC">;
-def err_arc_nolifetime_behavior : Error<
- "explicit ownership qualifier on cast result has no effect">;
-def err_arc_objc_object_in_tag : Error<
- "ARC forbids %select{Objective-C objects|blocks}0 in "
- "%select{struct|interface|union|<<ERROR>>|enum}1">;
-def err_arc_objc_property_default_assign_on_object : Error<
- "ARC forbids synthesizing a property of an Objective-C object "
- "with unspecified ownership or storage attribute">;
-def err_arc_illegal_selector : Error<
- "ARC forbids use of %0 in a @selector">;
-def err_arc_illegal_method_def : Error<
- "ARC forbids %select{implementation|synthesis}0 of %1">;
-def warn_arc_strong_pointer_objc_pointer : Warning<
- "method parameter of type %0 with no explicit ownership">,
- InGroup<DiagGroup<"explicit-ownership-type">>, DefaultIgnore;
-
-} // end "ARC Restrictions" category
-
-def err_arc_lost_method_convention : Error<
- "method was declared as %select{an 'alloc'|a 'copy'|an 'init'|a 'new'}0 "
- "method, but its implementation doesn't match because %select{"
- "its result type is not an object pointer|"
- "its result type is unrelated to its receiver type}1">;
-def note_arc_lost_method_convention : Note<"declaration in interface">;
-def err_arc_gained_method_convention : Error<
- "method implementation does not match its declaration">;
-def note_arc_gained_method_convention : Note<
- "declaration in interface is not in the '%select{alloc|copy|init|new}0' "
- "family because %select{its result type is not an object pointer|"
- "its result type is unrelated to its receiver type}1">;
-def err_typecheck_arc_assign_self : Error<
- "cannot assign to 'self' outside of a method in the init family">;
-def err_typecheck_arc_assign_self_class_method : Error<
- "cannot assign to 'self' in a class method">;
-def err_typecheck_arr_assign_enumeration : Error<
- "fast enumeration variables cannot be modified in ARC by default; "
- "declare the variable __strong to allow this">;
-def warn_arc_retained_assign : Warning<
- "assigning retained object to %select{weak|unsafe_unretained}0 "
- "%select{property|variable}1"
- "; object will be released after assignment">,
- InGroup<ARCUnsafeRetainedAssign>;
-def warn_arc_retained_property_assign : Warning<
- "assigning retained object to unsafe property"
- "; object will be released after assignment">,
- InGroup<ARCUnsafeRetainedAssign>;
-def warn_arc_literal_assign : Warning<
- "assigning %select{array literal|dictionary literal|numeric literal|boxed expression|<should not happen>|block literal}0"
- " to a weak %select{property|variable}1"
- "; object will be released after assignment">,
- InGroup<ARCUnsafeRetainedAssign>;
-def err_arc_new_array_without_ownership : Error<
- "'new' cannot allocate an array of %0 with no explicit ownership">;
-def err_arc_autoreleasing_var : Error<
- "%select{__block variables|global variables|fields|instance variables}0 cannot have "
- "__autoreleasing ownership">;
-def err_arc_autoreleasing_capture : Error<
- "cannot capture __autoreleasing variable in a "
- "%select{block|lambda by copy}0">;
-def err_arc_thread_ownership : Error<
- "thread-local variable has non-trivial ownership: type is %0">;
-def err_arc_indirect_no_ownership : Error<
- "%select{pointer|reference}1 to non-const type %0 with no explicit ownership">;
-def err_arc_array_param_no_ownership : Error<
- "must explicitly describe intended ownership of an object array parameter">;
-def err_arc_pseudo_dtor_inconstant_quals : Error<
- "pseudo-destructor destroys object of type %0 with inconsistently-qualified "
- "type %1">;
-def err_arc_init_method_unrelated_result_type : Error<
- "init methods must return a type related to the receiver type">;
-def err_arc_nonlocal_writeback : Error<
- "passing address of %select{non-local|non-scalar}0 object to "
- "__autoreleasing parameter for write-back">;
-def err_arc_method_not_found : Error<
- "no known %select{instance|class}1 method for selector %0">;
-def err_arc_receiver_forward_class : Error<
- "receiver %0 for class message is a forward declaration">;
-def err_arc_may_not_respond : Error<
- "no visible @interface for %0 declares the selector %1">;
-def err_arc_receiver_forward_instance : Error<
- "receiver type %0 for instance message is a forward declaration">;
-def warn_receiver_forward_instance : Warning<
- "receiver type %0 for instance message is a forward declaration">,
- InGroup<ForwardClassReceiver>, DefaultIgnore;
-def err_arc_collection_forward : Error<
- "collection expression type %0 is a forward declaration">;
-def err_arc_multiple_method_decl : Error<
- "multiple methods named %0 found with mismatched result, "
- "parameter type or attributes">;
-def warn_arc_lifetime_result_type : Warning<
- "ARC %select{unused|__unsafe_unretained|__strong|__weak|__autoreleasing}0 "
- "lifetime qualifier on return type is ignored">,
- InGroup<IgnoredQualifiers>;
-
-let CategoryName = "ARC Retain Cycle" in {
-
-def warn_arc_retain_cycle : Warning<
- "capturing %0 strongly in this block is likely to lead to a retain cycle">,
- InGroup<ARCRetainCycles>;
-def note_arc_retain_cycle_owner : Note<
- "block will be retained by %select{the captured object|an object strongly "
- "retained by the captured object}0">;
-
-} // end "ARC Retain Cycle" category
-
-def warn_arc_object_memaccess : Warning<
- "%select{destination for|source of}0 this %1 call is a pointer to "
- "ownership-qualified type %2">, InGroup<ARCNonPodMemAccess>;
-
-let CategoryName = "ARC and @properties" in {
-
-def err_arc_strong_property_ownership : Error<
- "existing instance variable %1 for strong property %0 may not be "
- "%select{|__unsafe_unretained||__weak}2">;
-def err_arc_assign_property_ownership : Error<
- "existing instance variable %1 for property %0 with %select{unsafe_unretained|assign}2 "
- "attribute must be __unsafe_unretained">;
-def err_arc_inconsistent_property_ownership : Error<
- "%select{|unsafe_unretained|strong|weak}1 property %0 may not also be "
- "declared %select{|__unsafe_unretained|__strong|__weak|__autoreleasing}2">;
-
-} // end "ARC and @properties" category
-
-def err_arc_atomic_ownership : Error<
- "cannot perform atomic operation on a pointer to type %0: type has "
- "non-trivial ownership">;
-
-let CategoryName = "ARC Casting Rules" in {
-
-def err_arc_bridge_cast_incompatible : Error<
- "incompatible types casting %0 to %1 with a %select{__bridge|"
- "__bridge_transfer|__bridge_retained}2 cast">;
-def err_arc_bridge_cast_wrong_kind : Error<
- "cast of %select{Objective-C|block|C}0 pointer type %1 to "
- "%select{Objective-C|block|C}2 pointer type %3 cannot use %select{__bridge|"
- "__bridge_transfer|__bridge_retained}4">;
-def err_arc_cast_requires_bridge : Error<
- "%select{cast|implicit conversion}0 of %select{Objective-C|block|C}1 "
- "pointer type %2 to %select{Objective-C|block|C}3 pointer type %4 "
- "requires a bridged cast">;
-def note_arc_bridge : Note<
- "use __bridge to convert directly (no change in ownership)">;
-def note_arc_cstyle_bridge : Note<
- "use __bridge with C-style cast to convert directly (no change in ownership)">;
-def note_arc_bridge_transfer : Note<
- "use %select{__bridge_transfer|CFBridgingRelease call}1 to transfer "
- "ownership of a +1 %0 into ARC">;
-def note_arc_cstyle_bridge_transfer : Note<
- "use __bridge_transfer with C-style cast to transfer "
- "ownership of a +1 %0 into ARC">;
-def note_arc_bridge_retained : Note<
- "use %select{__bridge_retained|CFBridgingRetain call}1 to make an "
- "ARC object available as a +1 %0">;
-def note_arc_cstyle_bridge_retained : Note<
- "use __bridge_retained with C-style cast to make an "
- "ARC object available as a +1 %0">;
-
-} // ARC Casting category
-
-} // ARC category name
-
-def err_flexible_array_init_needs_braces : Error<
- "flexible array requires brace-enclosed initializer">;
-def err_illegal_decl_array_of_functions : Error<
- "'%0' declared as array of functions of type %1">;
-def err_illegal_decl_array_incomplete_type : Error<
- "array has incomplete element type %0">;
-def err_illegal_message_expr_incomplete_type : Error<
- "Objective-C message has incomplete result type %0">;
-def err_illegal_decl_array_of_references : Error<
- "'%0' declared as array of references of type %1">;
-def err_decl_negative_array_size : Error<
- "'%0' declared as an array with a negative size">;
-def err_array_static_outside_prototype : Error<
- "%0 used in array declarator outside of function prototype">;
-def err_array_static_not_outermost : Error<
- "%0 used in non-outermost array type derivation">;
-def err_array_star_outside_prototype : Error<
- "star modifier used outside of function prototype">;
-def err_illegal_decl_pointer_to_reference : Error<
- "'%0' declared as a pointer to a reference of type %1">;
-def err_illegal_decl_mempointer_to_reference : Error<
- "'%0' declared as a member pointer to a reference of type %1">;
-def err_illegal_decl_mempointer_to_void : Error<
- "'%0' declared as a member pointer to void">;
-def err_illegal_decl_mempointer_in_nonclass : Error<
- "'%0' does not point into a class">;
-def err_mempointer_in_nonclass_type : Error<
- "member pointer refers into non-class type %0">;
-def err_reference_to_void : Error<"cannot form a reference to 'void'">;
-def err_nonfunction_block_type : Error<
- "block pointer to non-function type is invalid">;
-def err_return_block_has_expr : Error<"void block should not return a value">;
-def err_block_return_missing_expr : Error<
- "non-void block should return a value">;
-def err_func_def_incomplete_result : Error<
- "incomplete result type %0 in function definition">;
-def err_atomic_specifier_bad_type : Error<
- "_Atomic cannot be applied to "
- "%select{incomplete |array |function |reference |atomic |qualified |}0type "
- "%1 %select{||||||which is not trivially copyable}0">;
-
-// Expressions.
-def ext_sizeof_alignof_function_type : Extension<
- "invalid application of '%select{sizeof|alignof|vec_step}0' to a "
- "function type">, InGroup<PointerArith>;
-def ext_sizeof_alignof_void_type : Extension<
- "invalid application of '%select{sizeof|alignof|vec_step}0' to a void "
- "type">, InGroup<PointerArith>;
-def err_opencl_sizeof_alignof_type : Error<
- "invalid application of '%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align}0' to a void type">;
-def err_sizeof_alignof_incomplete_type : Error<
- "invalid application of '%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align}0' to an "
- "incomplete type %1">;
-def err_sizeof_alignof_function_type : Error<
- "invalid application of '%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align}0' to a "
- "function type">;
-def err_openmp_default_simd_align_expr : Error<
- "invalid application of '__builtin_omp_required_simd_align' to an expression, only type is allowed">;
-def err_sizeof_alignof_typeof_bitfield : Error<
- "invalid application of '%select{sizeof|alignof|typeof}0' to bit-field">;
-def err_alignof_member_of_incomplete_type : Error<
- "invalid application of 'alignof' to a field of a class still being defined">;
-def err_vecstep_non_scalar_vector_type : Error<
- "'vec_step' requires built-in scalar or vector type, %0 invalid">;
-def err_offsetof_incomplete_type : Error<
- "offsetof of incomplete type %0">;
-def err_offsetof_record_type : Error<
- "offsetof requires struct, union, or class type, %0 invalid">;
-def err_offsetof_array_type : Error<"offsetof requires array type, %0 invalid">;
-def ext_offsetof_extended_field_designator : Extension<
- "using extended field designator is an extension">,
- InGroup<DiagGroup<"extended-offsetof">>;
-def ext_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
- InGroup<InvalidOffsetof>;
-def ext_offsetof_non_standardlayout_type : ExtWarn<
- "offset of on non-standard-layout type %0">, InGroup<InvalidOffsetof>;
-def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
-def err_offsetof_field_of_virtual_base : Error<
- "invalid application of 'offsetof' to a field of a virtual base">;
-def warn_sub_ptr_zero_size_types : Warning<
- "subtraction of pointers to type %0 of zero size has undefined behavior">,
- InGroup<PointerArith>;
-
-def warn_floatingpoint_eq : Warning<
- "comparing floating point with == or != is unsafe">,
- InGroup<DiagGroup<"float-equal">>, DefaultIgnore;
-
-def warn_remainder_division_by_zero : Warning<
- "%select{remainder|division}0 by zero is undefined">,
- InGroup<DivZero>;
-def warn_shift_lhs_negative : Warning<"shifting a negative signed value is undefined">,
- InGroup<DiagGroup<"shift-negative-value">>;
-def warn_shift_negative : Warning<"shift count is negative">,
- InGroup<DiagGroup<"shift-count-negative">>;
-def warn_shift_gt_typewidth : Warning<"shift count >= width of type">,
- InGroup<DiagGroup<"shift-count-overflow">>;
-def warn_shift_result_gt_typewidth : Warning<
- "signed shift result (%0) requires %1 bits to represent, but %2 only has "
- "%3 bits">, InGroup<DiagGroup<"shift-overflow">>;
-def warn_shift_result_sets_sign_bit : Warning<
- "signed shift result (%0) sets the sign bit of the shift expression's "
- "type (%1) and becomes negative">,
- InGroup<DiagGroup<"shift-sign-overflow">>, DefaultIgnore;
-
-def warn_precedence_bitwise_rel : Warning<
- "%0 has lower precedence than %1; %1 will be evaluated first">,
- InGroup<Parentheses>;
-def note_precedence_bitwise_first : Note<
- "place parentheses around the %0 expression to evaluate it first">;
-def note_precedence_silence : Note<
- "place parentheses around the '%0' expression to silence this warning">;
-
-def warn_precedence_conditional : Warning<
- "operator '?:' has lower precedence than '%0'; '%0' will be evaluated first">,
- InGroup<Parentheses>;
-def note_precedence_conditional_first : Note<
- "place parentheses around the '?:' expression to evaluate it first">;
-
-def warn_logical_instead_of_bitwise : Warning<
- "use of logical '%0' with constant operand">,
- InGroup<DiagGroup<"constant-logical-operand">>;
-def note_logical_instead_of_bitwise_change_operator : Note<
- "use '%0' for a bitwise operation">;
-def note_logical_instead_of_bitwise_remove_constant : Note<
- "remove constant to silence this warning">;
-
-def warn_bitwise_op_in_bitwise_op : Warning<
- "'%0' within '%1'">, InGroup<BitwiseOpParentheses>;
-
-def warn_logical_and_in_logical_or : Warning<
- "'&&' within '||'">, InGroup<LogicalOpParentheses>;
-
-def warn_overloaded_shift_in_comparison :Warning<
- "overloaded operator %select{>>|<<}0 has higher precedence than "
- "comparison operator">,
- InGroup<OverloadedShiftOpParentheses>;
-def note_evaluate_comparison_first :Note<
- "place parentheses around comparison expression to evaluate it first">;
-
-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<
- "explicitly assigning value of variable of type %0 to itself">,
- InGroup<SelfAssignment>, DefaultIgnore;
-def warn_self_move : Warning<
- "explicitly moving variable of type %0 to itself">,
- InGroup<SelfMove>, DefaultIgnore;
-
-def warn_redundant_move_on_return : Warning<
- "redundant move in return statement">,
- InGroup<RedundantMove>, DefaultIgnore;
-def warn_pessimizing_move_on_return : Warning<
- "moving a local object in a return statement prevents copy elision">,
- InGroup<PessimizingMove>, DefaultIgnore;
-def warn_pessimizing_move_on_initialization : Warning<
- "moving a temporary object prevents copy elision">,
- InGroup<PessimizingMove>, DefaultIgnore;
-def note_remove_move : Note<"remove std::move call here">;
-
-def warn_string_plus_int : Warning<
- "adding %0 to a string does not append to the string">,
- InGroup<StringPlusInt>;
-def warn_string_plus_char : Warning<
- "adding %0 to a string pointer does not append to the string">,
- InGroup<StringPlusChar>;
-def note_string_plus_scalar_silence : Note<
- "use array indexing to silence this warning">;
-
-def warn_sizeof_array_param : Warning<
- "sizeof on array function parameter will return size of %0 instead of %1">,
- InGroup<SizeofArrayArgument>;
-
-def warn_sizeof_array_decay : Warning<
- "sizeof on pointer operation will return size of %0 instead of %1">,
- InGroup<SizeofArrayDecay>;
-
-def err_sizeof_nonfragile_interface : Error<
- "application of '%select{alignof|sizeof}1' to interface %0 is "
- "not supported on this architecture and platform">;
-def err_atdef_nonfragile_interface : Error<
- "use of @defs is not supported on this architecture and platform">;
-def err_subscript_nonfragile_interface : Error<
- "subscript requires size of interface %0, which is not constant for "
- "this architecture and platform">;
-
-def err_arithmetic_nonfragile_interface : Error<
- "arithmetic on pointer to interface %0, which is not a constant size for "
- "this architecture and platform">;
-
-
-def ext_subscript_non_lvalue : Extension<
- "ISO C90 does not allow subscripting non-lvalue array">;
-def err_typecheck_subscript_value : Error<
- "subscripted value is not an array, pointer, or vector">;
-def err_typecheck_subscript_not_integer : Error<
- "array subscript is not an integer">;
-def err_subscript_function_type : Error<
- "subscript of pointer to function type %0">;
-def err_subscript_incomplete_type : Error<
- "subscript of pointer to incomplete type %0">;
-def err_dereference_incomplete_type : Error<
- "dereference of pointer to incomplete type %0">;
-def ext_gnu_subscript_void_type : Extension<
- "subscript of a pointer to void is a GNU extension">, InGroup<PointerArith>;
-def err_typecheck_member_reference_struct_union : Error<
- "member reference base type %0 is not a structure or union">;
-def err_typecheck_member_reference_ivar : Error<
- "%0 does not have a member named %1">;
-def error_arc_weak_ivar_access : Error<
- "dereferencing a __weak pointer is not allowed due to possible "
- "null value caused by race condition, assign it to strong variable first">;
-def err_typecheck_member_reference_arrow : Error<
- "member reference type %0 is not a pointer">;
-def err_typecheck_member_reference_suggestion : Error<
- "member reference type %0 is %select{a|not a}1 pointer; did you mean to use '%select{->|.}1'?">;
-def note_typecheck_member_reference_suggestion : Note<
- "did you mean to use '.' instead?">;
-def note_member_reference_arrow_from_operator_arrow : Note<
- "'->' applied to return value of the operator->() declared here">;
-def err_typecheck_member_reference_type : Error<
- "cannot refer to type member %0 in %1 with '%select{.|->}2'">;
-def err_typecheck_member_reference_unknown : Error<
- "cannot refer to member %0 in %1 with '%select{.|->}2'">;
-def err_member_reference_needs_call : Error<
- "base of member reference is a function; perhaps you meant to call "
- "it%select{| with no arguments}0?">;
-def warn_subscript_is_char : Warning<"array subscript is of type 'char'">,
- InGroup<CharSubscript>, DefaultIgnore;
-
-def err_typecheck_incomplete_tag : Error<"incomplete definition of type %0">;
-def err_no_member : Error<"no member named %0 in %1">;
-def err_no_member_overloaded_arrow : Error<
- "no member named %0 in %1; did you mean to use '->' instead of '.'?">;
-
-def err_member_not_yet_instantiated : Error<
- "no member %0 in %1; it has not yet been instantiated">;
-def note_non_instantiated_member_here : Note<
- "not-yet-instantiated member is declared here">;
-
-def err_enumerator_does_not_exist : Error<
- "enumerator %0 does not exist in instantiation of %1">;
-def note_enum_specialized_here : Note<
- "enum %0 was explicitly specialized here">;
-
-def err_member_redeclared : Error<"class member cannot be redeclared">;
-def ext_member_redeclared : ExtWarn<"class member cannot be redeclared">,
- InGroup<RedeclaredClassMember>;
-def err_member_redeclared_in_instantiation : Error<
- "multiple overloads of %0 instantiate to the same signature %1">;
-def err_member_name_of_class : Error<"member %0 has the same name as its class">;
-def err_member_def_undefined_record : Error<
- "out-of-line definition of %0 from class %1 without definition">;
-def err_member_decl_does_not_match : Error<
- "out-of-line %select{declaration|definition}2 of %0 "
- "does not match any declaration in %1">;
-def err_friend_decl_with_def_arg_must_be_def : Error<
- "friend declaration specifying a default argument must be a definition">;
-def err_friend_decl_with_def_arg_redeclared : Error<
- "friend declaration specifying a default argument must be the only declaration">;
-def err_friend_decl_does_not_match : Error<
- "friend declaration of %0 does not match any declaration in %1">;
-def err_member_decl_does_not_match_suggest : Error<
- "out-of-line %select{declaration|definition}2 of %0 "
- "does not match any declaration in %1; did you mean %3?">;
-def err_member_def_does_not_match_ret_type : Error<
- "return type of out-of-line definition of %q0 differs from "
- "that in the declaration">;
-def err_nonstatic_member_out_of_line : Error<
- "non-static data member defined out-of-line">;
-def err_qualified_typedef_declarator : Error<
- "typedef declarator cannot be qualified">;
-def err_qualified_param_declarator : Error<
- "parameter declarator cannot be qualified">;
-def ext_out_of_line_declaration : ExtWarn<
- "out-of-line declaration of a member must be a definition">,
- InGroup<OutOfLineDeclaration>, DefaultError;
-def err_member_extra_qualification : Error<
- "extra qualification on member %0">;
-def warn_member_extra_qualification : Warning<
- err_member_extra_qualification.Text>, InGroup<MicrosoftExtraQualification>;
-def warn_namespace_member_extra_qualification : Warning<
- "extra qualification on member %0">,
- InGroup<DiagGroup<"extra-qualification">>;
-def err_member_qualification : Error<
- "non-friend class member %0 cannot have a qualified name">;
-def note_member_def_close_match : Note<"member declaration nearly matches">;
-def note_member_def_close_const_match : Note<
- "member declaration does not match because "
- "it %select{is|is not}0 const qualified">;
-def note_member_def_close_param_match : Note<
- "type of %ordinal0 parameter of member declaration does not match definition"
- "%diff{ ($ vs $)|}1,2">;
-def note_local_decl_close_match : Note<"local declaration nearly matches">;
-def note_local_decl_close_param_match : Note<
- "type of %ordinal0 parameter of local declaration does not match definition"
- "%diff{ ($ vs $)|}1,2">;
-def err_typecheck_ivar_variable_size : Error<
- "instance variables must have a constant size">;
-def err_ivar_reference_type : Error<
- "instance variables cannot be of reference type">;
-def err_typecheck_illegal_increment_decrement : Error<
- "cannot %select{decrement|increment}1 value of type %0">;
-def err_typecheck_expect_int : Error<
- "used type %0 where integer is required">;
-def err_typecheck_arithmetic_incomplete_type : Error<
- "arithmetic on a pointer to an incomplete type %0">;
-def err_typecheck_pointer_arith_function_type : Error<
- "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 "
- "function type%select{|s}2 %1%select{| and %3}2">;
-def err_typecheck_pointer_arith_void_type : Error<
- "arithmetic on%select{ a|}0 pointer%select{|s}0 to void">;
-def err_typecheck_decl_incomplete_type : Error<
- "variable has incomplete type %0">;
-def err_typecheck_decl_incomplete_type___float128 : Error<
- "support for type '__float128' is not yet implemented">;
-def ext_typecheck_decl_incomplete_type : ExtWarn<
- "tentative definition of variable with internal linkage has incomplete non-array type %0">,
- InGroup<DiagGroup<"tentative-definition-incomplete-type">>;
-def err_tentative_def_incomplete_type : Error<
- "tentative definition has type %0 that is never completed">;
-def warn_tentative_incomplete_array : Warning<
- "tentative array definition assumed to have one element">;
-def err_typecheck_incomplete_array_needs_initializer : Error<
- "definition of variable with array type needs an explicit size "
- "or an initializer">;
-def err_array_init_not_init_list : Error<
- "array initializer must be an initializer "
- "list%select{| or string literal| or wide string literal}0">;
-def err_array_init_narrow_string_into_wchar : Error<
- "initializing wide char array with non-wide string literal">;
-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_different_type : Error<
- "cannot initialize array %diff{of type $ with array of type $|"
- "with different type of array}0,1">;
-def err_array_init_non_constant_array : Error<
- "cannot initialize array %diff{of type $ with non-constant array of type $|"
- "with different type of array}0,1">;
-def ext_array_init_copy : Extension<
- "initialization of an array "
- "%diff{of type $ from a compound literal of type $|"
- "from a compound literal}0,1 is a GNU extension">, InGroup<GNUCompoundLiteralInitializer>;
-// This is intentionally not disabled by -Wno-gnu.
-def ext_array_init_parens : ExtWarn<
- "parenthesized initialization of a member array is a GNU extension">,
- InGroup<DiagGroup<"gnu-array-member-paren-init">>, DefaultError;
-def warn_deprecated_string_literal_conversion : Warning<
- "conversion from string literal to %0 is deprecated">,
- InGroup<CXX11CompatDeprecatedWritableStr>;
-def ext_deprecated_string_literal_conversion : ExtWarn<
- "ISO C++11 does not allow conversion from string literal to %0">,
- InGroup<WritableStrings>, SFINAEFailure;
-def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
-def err_typecheck_sclass_fscope : Error<
- "illegal storage class on file-scoped variable">;
-def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">,
- InGroup<MissingDeclarations>;
-def ext_standalone_specifier : ExtWarn<"'%0' is not permitted on a declaration "
- "of a type">, InGroup<MissingDeclarations>;
-def err_standalone_class_nested_name_specifier : Error<
- "forward declaration of %select{class|struct|interface|union|enum}0 cannot "
- "have a nested name specifier">;
-def err_typecheck_sclass_func : Error<"illegal storage class on function">;
-def err_static_block_func : Error<
- "function declared in block scope cannot have 'static' storage class">;
-def err_typecheck_address_of : Error<"address of %select{bit-field"
- "|vector element|property expression|register variable}0 requested">;
-def ext_typecheck_addrof_void : Extension<
- "ISO C forbids taking the address of an expression of type 'void'">;
-def err_unqualified_pointer_member_function : Error<
- "must explicitly qualify name of member function when taking its address">;
-def err_invalid_form_pointer_member_function : Error<
- "cannot create a non-constant pointer to member function">;
-def err_address_of_function_with_pass_object_size_params: Error<
- "cannot take address of function %0 because parameter %1 has "
- "pass_object_size attribute">;
-def err_parens_pointer_member_function : Error<
- "cannot parenthesize the name of a method when forming a member pointer">;
-def err_typecheck_invalid_lvalue_addrof_addrof_function : Error<
- "extra '&' taking address of overloaded function">;
-def err_typecheck_invalid_lvalue_addrof : Error<
- "cannot take the address of an rvalue of type %0">;
-def ext_typecheck_addrof_temporary : ExtWarn<
- "taking the address of a temporary object of type %0">,
- InGroup<DiagGroup<"address-of-temporary">>, DefaultError;
-def err_typecheck_addrof_temporary : Error<
- "taking the address of a temporary object of type %0">;
-def err_typecheck_addrof_dtor : Error<
- "taking the address of a destructor">;
-def err_typecheck_unary_expr : Error<
- "invalid argument type %0 to unary expression">;
-def err_typecheck_indirection_requires_pointer : Error<
- "indirection requires pointer operand (%0 invalid)">;
-def ext_typecheck_indirection_through_void_pointer : ExtWarn<
- "ISO C++ does not allow indirection on operand of type %0">,
- InGroup<DiagGroup<"void-ptr-dereference">>;
-def warn_indirection_through_null : Warning<
- "indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>;
-def note_indirection_through_null : Note<
- "consider using __builtin_trap() or qualifying pointer with 'volatile'">;
-def warn_pointer_indirection_from_incompatible_type : Warning<
- "dereference of type %1 that was reinterpret_cast from type %0 has undefined "
- "behavior">,
- InGroup<UndefinedReinterpretCast>, DefaultIgnore;
-
-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 err_typecheck_sub_ptr_compatible : Error<
- "%diff{$ and $ are not pointers to compatible types|"
- "pointers to incompatible types}0,1">;
-def ext_typecheck_ordered_comparison_of_pointer_integer : ExtWarn<
- "ordered comparison between pointer and integer (%0 and %1)">;
-def ext_typecheck_ordered_comparison_of_pointer_and_zero : Extension<
- "ordered comparison between pointer and zero (%0 and %1) is an extension">;
-def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
- "ordered comparison of function pointers (%0 and %1)">;
-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<
- "equality comparison between function pointer and void pointer (%0 and %1)">;
-def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
- "comparison between pointer and integer (%0 and %1)">;
-def err_typecheck_comparison_of_pointer_integer : Error<
- "comparison between pointer and integer (%0 and %1)">;
-def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
- "comparison of distinct pointer types%diff{ ($ and $)|}0,1">,
- InGroup<CompareDistinctPointerType>;
-def ext_typecheck_cond_incompatible_operands : ExtWarn<
- "incompatible operand types (%0 and %1)">;
-def err_cond_voidptr_arc : Error <
- "operands to conditional of types%diff{ $ and $|}0,1 are incompatible "
- "in ARC mode">;
-def err_typecheck_comparison_of_distinct_pointers : Error<
- "comparison of distinct pointer types%diff{ ($ and $)|}0,1">;
-def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn<
- "comparison of distinct pointer types (%0 and %1) uses non-standard "
- "composite pointer type %2">, InGroup<CompareDistinctPointerType>;
-def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error<
- "%select{comparison between %diff{ ($ and $)|}0,1"
- "|arithmetic operation with operands of type %diff{ ($ and $)|}0,1}2"
- " which are pointers to non-overlapping address spaces">;
-
-def err_typecheck_assign_const : Error<
- "%select{"
- "cannot assign to return value because function %1 returns a const value|"
- "cannot assign to variable %1 with const-qualified type %2|"
- "cannot assign to %select{non-|}1static data member %2 "
- "with const-qualified type %3|"
- "cannot assign to non-static data member within const member function %1|"
- "read-only variable is not assignable}0">;
-
-def note_typecheck_assign_const : Note<
- "%select{"
- "function %1 which returns const-qualified type %2 declared here|"
- "variable %1 declared const here|"
- "%select{non-|}1static data member %2 declared const here|"
- "member function %q1 is declared const here}0">;
-
-def warn_mixed_sign_comparison : Warning<
- "comparison of integers of different signs: %0 and %1">,
- InGroup<SignCompare>, DefaultIgnore;
-def warn_lunsigned_always_true_comparison : Warning<
- "comparison of unsigned%select{| enum}2 expression %0 is always %1">,
- InGroup<TautologicalCompare>;
-def warn_out_of_range_compare : Warning<
- "comparison of %select{constant %0|true|false}1 with "
- "%select{expression of type %2|boolean expression}3 is always "
- "%select{false|true}4">, InGroup<TautologicalOutOfRangeCompare>;
-def warn_runsigned_always_true_comparison : Warning<
- "comparison of %0 unsigned%select{| enum}2 expression is always %1">,
- InGroup<TautologicalCompare>;
-def warn_comparison_of_mixed_enum_types : Warning<
- "comparison of two values with different enumeration types"
- "%diff{ ($ and $)|}0,1">,
- InGroup<DiagGroup<"enum-compare">>;
-def warn_null_in_arithmetic_operation : Warning<
- "use of NULL in arithmetic operation">,
- InGroup<NullArithmetic>;
-def warn_null_in_comparison_operation : Warning<
- "comparison between NULL and non-pointer "
- "%select{(%1 and NULL)|(NULL and %1)}0">,
- InGroup<NullArithmetic>;
-def err_shift_rhs_only_vector : Error<
- "requested shift is a vector of type %0 but the first operand is not a "
- "vector (%1)">;
-
-def warn_logical_not_on_lhs_of_comparison : Warning<
- "logical not is only applied to the left hand side of this comparison">,
- InGroup<LogicalNotParentheses>;
-def note_logical_not_fix : Note<
- "add parentheses after the '!' to evaluate the comparison first">;
-def note_logical_not_silence_with_parens : Note<
- "add parentheses around left hand side expression to silence this warning">;
-
-def err_invalid_this_use : Error<
- "invalid use of 'this' outside of a non-static member function">;
-def err_this_static_member_func : Error<
- "'this' cannot be%select{| implicitly}0 used in a static member function "
- "declaration">;
-def err_invalid_member_use_in_static_method : Error<
- "invalid use of member %0 in static member function">;
-def err_invalid_qualified_function_type : Error<
- "%select{static |non-}0member function %select{of type %2 |}1"
- "cannot have '%3' qualifier">;
-def err_compound_qualified_function_type : Error<
- "%select{block pointer|pointer|reference}0 to function type %select{%2 |}1"
- "cannot have '%3' qualifier">;
-
-def err_ref_qualifier_overload : Error<
- "cannot overload a member function %select{without a ref-qualifier|with "
- "ref-qualifier '&'|with ref-qualifier '&&'}0 with a member function %select{"
- "without a ref-qualifier|with ref-qualifier '&'|with ref-qualifier '&&'}1">;
-
-def err_invalid_non_static_member_use : Error<
- "invalid use of non-static data member %0">;
-def err_nested_non_static_member_use : Error<
- "%select{call to non-static member function|use of non-static data member}0 "
- "%2 of %1 from nested type %3">;
-def warn_cxx98_compat_non_static_member_use : Warning<
- "use of non-static data member %0 in an unevaluated context is "
- "incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def err_invalid_incomplete_type_use : Error<
- "invalid use of incomplete type %0">;
-def err_builtin_func_cast_more_than_one_arg : Error<
- "function-style cast to a builtin type can only take one argument">;
-def err_value_init_for_array_type : Error<
- "array types cannot be value-initialized">;
-def err_value_init_for_function_type : Error<
- "function types cannot be value-initialized">;
-def warn_format_nonliteral_noargs : Warning<
- "format string is not a string literal (potentially insecure)">,
- InGroup<FormatSecurity>;
-def warn_format_nonliteral : Warning<
- "format string is not a string literal">,
- InGroup<FormatNonLiteral>, DefaultIgnore;
-
-def err_unexpected_interface : Error<
- "unexpected interface name %0: expected expression">;
-def err_ref_non_value : Error<"%0 does not refer to a value">;
-def err_ref_vm_type : Error<
- "cannot refer to declaration with a variably modified type inside block">;
-def err_ref_flexarray_type : Error<
- "cannot refer to declaration of structure variable with flexible array member "
- "inside block">;
-def err_ref_array_type : Error<
- "cannot refer to declaration with an array type inside block">;
-def err_property_not_found : Error<
- "property %0 not found on object of type %1">;
-def err_invalid_property_name : Error<
- "%0 is not a valid property name (accessing an object of type %1)">;
-def err_getter_not_found : Error<
- "no getter method for read from property">;
-def err_objc_subscript_method_not_found : Error<
- "expected method to %select{read|write}1 %select{dictionary|array}2 element not "
- "found on object of type %0">;
-def err_objc_subscript_index_type : Error<
- "method index parameter type %0 is not integral type">;
-def err_objc_subscript_key_type : Error<
- "method key parameter type %0 is not object type">;
-def err_objc_subscript_dic_object_type : Error<
- "method object parameter type %0 is not object type">;
-def err_objc_subscript_object_type : Error<
- "cannot assign to this %select{dictionary|array}1 because assigning method's "
- "2nd parameter of type %0 is not an Objective-C pointer type">;
-def err_objc_subscript_base_type : Error<
- "%select{dictionary|array}1 subscript base type %0 is not an Objective-C object">;
-def err_objc_multiple_subscript_type_conversion : Error<
- "indexing expression is invalid because subscript type %0 has "
- "multiple type conversion functions">;
-def err_objc_subscript_type_conversion : Error<
- "indexing expression is invalid because subscript type %0 is not an integral"
- " or Objective-C pointer type">;
-def err_objc_subscript_pointer : Error<
- "indexing expression is invalid because subscript type %0 is not an"
- " Objective-C pointer">;
-def err_objc_indexing_method_result_type : Error<
- "method for accessing %select{dictionary|array}1 element must have Objective-C"
- " object return type instead of %0">;
-def err_objc_index_incomplete_class_type : Error<
- "Objective-C index expression has incomplete class type %0">;
-def err_illegal_container_subscripting_op : Error<
- "illegal operation on Objective-C container subscripting">;
-def err_property_not_found_forward_class : Error<
- "property %0 cannot be found in forward class object %1">;
-def err_property_not_as_forward_class : Error<
- "property %0 refers to an incomplete Objective-C class %1 "
- "(with no @interface available)">;
-def note_forward_class : Note<
- "forward declaration of class here">;
-def err_duplicate_property : Error<
- "property has a previous declaration">;
-def ext_gnu_void_ptr : Extension<
- "arithmetic on%select{ a|}0 pointer%select{|s}0 to void is a GNU extension">,
- InGroup<PointerArith>;
-def ext_gnu_ptr_func_arith : Extension<
- "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function "
- "type%select{|s}2 %1%select{| and %3}2 is a GNU extension">,
- InGroup<PointerArith>;
-def error_readonly_message_assignment : Error<
- "assigning to 'readonly' return result of an Objective-C message not allowed">;
-def ext_integer_increment_complex : Extension<
- "ISO C does not support '++'/'--' on complex integer type %0">;
-def ext_integer_complement_complex : Extension<
- "ISO C does not support '~' for complex conjugation of %0">;
-def err_nosetter_property_assignment : Error<
- "%select{assignment to readonly property|"
- "no setter method %1 for assignment to property}0">;
-def err_nosetter_property_incdec : Error<
- "%select{%select{increment|decrement}1 of readonly property|"
- "no setter method %2 for %select{increment|decrement}1 of property}0">;
-def err_nogetter_property_compound_assignment : Error<
- "a getter method is needed to perform a compound assignment on a property">;
-def err_nogetter_property_incdec : Error<
- "no getter method %1 for %select{increment|decrement}0 of property">;
-def error_no_subobject_property_setting : Error<
- "expression is not assignable">;
-def err_qualified_objc_access : Error<
- "%select{property|instance variable}0 access cannot be qualified with '%1'">;
-
-def ext_freestanding_complex : Extension<
- "complex numbers are an extension in a freestanding C99 implementation">;
-
-// FIXME: Remove when we support imaginary.
-def err_imaginary_not_supported : Error<"imaginary types are not supported">;
-
-// Obj-c expressions
-def warn_root_inst_method_not_found : Warning<
- "instance method %0 is being used on 'Class' which is not in the root class">,
- InGroup<MethodAccess>;
-def warn_class_method_not_found : Warning<
- "class method %objcclass0 not found (return type defaults to 'id')">,
- InGroup<MethodAccess>;
-def warn_instance_method_on_class_found : Warning<
- "instance method %0 found instead of class method %1">,
- InGroup<MethodAccess>;
-def warn_inst_method_not_found : Warning<
- "instance method %objcinstance0 not found (return type defaults to 'id')">,
- InGroup<MethodAccess>;
-def warn_instance_method_not_found_with_typo : Warning<
- "instance method %objcinstance0 not found (return type defaults to 'id')"
- "; did you mean %objcinstance2?">, InGroup<MethodAccess>;
-def warn_class_method_not_found_with_typo : Warning<
- "class method %objcclass0 not found (return type defaults to 'id')"
- "; did you mean %objcclass2?">, InGroup<MethodAccess>;
-def error_method_not_found_with_typo : Error<
- "%select{instance|class}1 method %0 not found "
- "; did you mean %2?">;
-def error_no_super_class_message : Error<
- "no @interface declaration found in class messaging of %0">;
-def error_root_class_cannot_use_super : Error<
- "%0 cannot use 'super' because it is a root class">;
-def err_invalid_receiver_to_message_super : Error<
- "'super' is only valid in a method body">;
-def err_invalid_receiver_class_message : Error<
- "receiver type %0 is not an Objective-C class">;
-def err_missing_open_square_message_send : Error<
- "missing '[' at start of message send expression">;
-def warn_bad_receiver_type : Warning<
- "receiver type %0 is not 'id' or interface pointer, consider "
- "casting it to 'id'">,InGroup<ObjCReceiver>;
-def err_bad_receiver_type : Error<"bad receiver type %0">;
-def err_incomplete_receiver_type : Error<"incomplete receiver type %0">;
-def err_unknown_receiver_suggest : Error<
- "unknown receiver %0; did you mean %1?">;
-def error_objc_throw_expects_object : Error<
- "@throw requires an Objective-C object type (%0 invalid)">;
-def error_objc_synchronized_expects_object : Error<
- "@synchronized requires an Objective-C object type (%0 invalid)">;
-def error_rethrow_used_outside_catch : Error<
- "@throw (rethrow) used outside of a @catch block">;
-def err_attribute_multiple_objc_gc : Error<
- "multiple garbage collection attributes specified for type">;
-def err_catch_param_not_objc_type : Error<
- "@catch parameter is not a pointer to an interface type">;
-def err_illegal_qualifiers_on_catch_parm : Error<
- "illegal qualifiers on @catch parameter">;
-def err_storage_spec_on_catch_parm : Error<
- "@catch parameter cannot have storage specifier '%0'">;
-def warn_register_objc_catch_parm : Warning<
- "'register' storage specifier on @catch parameter will be ignored">;
-def err_qualified_objc_catch_parm : Error<
- "@catch parameter declarator cannot be qualified">;
-def warn_objc_pointer_cxx_catch_fragile : Warning<
- "cannot catch an exception thrown with @throw in C++ in the non-unified "
- "exception model">, InGroup<ObjCNonUnifiedException>;
-def err_objc_object_catch : Error<
- "cannot catch an Objective-C object by value">;
-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">,
- InGroup<DiagGroup<"objc-circular-container">>;
-def note_objc_circular_container_declared_here : Note<"'%0' declared here">;
-
-def warn_setter_getter_impl_required : Warning<
- "property %0 requires method %1 to be defined - "
- "use @synthesize, @dynamic or provide a method implementation "
- "in this class implementation">,
- InGroup<ObjCPropertyImpl>;
-def warn_setter_getter_impl_required_in_category : Warning<
- "property %0 requires method %1 to be defined - "
- "use @dynamic or provide a method implementation in this category">,
- InGroup<ObjCPropertyImpl>;
-def note_parameter_named_here : Note<
- "passing argument to parameter %0 here">;
-def note_parameter_here : Note<
- "passing argument to parameter here">;
-def note_method_return_type_change : Note<
- "compiler has implicitly changed method %0 return type">;
-
-// C++ casts
-// These messages adhere to the TryCast pattern: %0 is an int specifying the
-// cast type, %1 is the source type, %2 is the destination type.
-def err_bad_reinterpret_cast_overload : Error<
- "reinterpret_cast cannot resolve overloaded function %0 to type %1">;
-
-def warn_reinterpret_different_from_static : Warning<
- "'reinterpret_cast' %select{from|to}3 class %0 %select{to|from}3 its "
- "%select{virtual base|base at non-zero offset}2 %1 behaves differently from "
- "'static_cast'">, InGroup<ReinterpretBaseClass>;
-def note_reinterpret_updowncast_use_static: Note<
- "use 'static_cast' to adjust the pointer correctly while "
- "%select{upcasting|downcasting}0">;
-
-def err_bad_static_cast_overload : Error<
- "address of overloaded function %0 cannot be static_cast to type %1">;
-
-def err_bad_cstyle_cast_overload : Error<
- "address of overloaded function %0 cannot be cast to type %1">;
-
-
-def err_bad_cxx_cast_generic : Error<
- "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
- "functional-style cast}0 from %1 to %2 is not allowed">;
-def err_bad_cxx_cast_unrelated_class : Error<
- "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
- "functional-style cast}0 from %1 to %2, which are not related by "
- "inheritance, is not allowed">;
-def note_type_incomplete : Note<"%0 is incomplete">;
-def err_bad_cxx_cast_rvalue : Error<
- "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
- "functional-style cast}0 from rvalue to reference type %2">;
-def err_bad_cxx_cast_bitfield : Error<
- "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
- "functional-style cast}0 from bit-field lvalue to reference type %2">;
-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 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">;
-def ext_cast_fn_obj : Extension<
- "cast between pointer-to-function and pointer-to-object is an extension">;
-def ext_ms_cast_fn_obj : ExtWarn<
- "static_cast between pointer-to-function and pointer-to-object is a "
- "Microsoft extension">, InGroup<MicrosoftCast>;
-def warn_cxx98_compat_cast_fn_obj : Warning<
- "cast between pointer-to-function and pointer-to-object is incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def err_bad_reinterpret_cast_small_int : Error<
- "cast from pointer to smaller type %2 loses information">;
-def err_bad_cxx_cast_vector_to_scalar_different_size : Error<
- "%select{||reinterpret_cast||C-style cast|}0 from vector %1 "
- "to scalar %2 of different size">;
-def err_bad_cxx_cast_scalar_to_vector_different_size : Error<
- "%select{||reinterpret_cast||C-style cast|}0 from scalar %1 "
- "to vector %2 of different size">;
-def err_bad_cxx_cast_vector_to_vector_different_size : Error<
- "%select{||reinterpret_cast||C-style cast|}0 from vector %1 "
- "to vector %2 of different size">;
-def err_bad_lvalue_to_rvalue_cast : Error<
- "cannot cast from lvalue of type %1 to rvalue reference type %2; types are "
- "not compatible">;
-def err_bad_static_cast_pointer_nonpointer : Error<
- "cannot cast from type %1 to pointer type %2">;
-def err_bad_static_cast_member_pointer_nonmp : Error<
- "cannot cast from type %1 to member pointer type %2">;
-def err_bad_cxx_cast_member_pointer_size : Error<
- "cannot %select{||reinterpret_cast||C-style cast|}0 from member pointer "
- "type %1 to member pointer type %2 of different size">;
-def err_bad_reinterpret_cast_reference : Error<
- "reinterpret_cast of a %0 to %1 needs its address, which is not allowed">;
-def warn_undefined_reinterpret_cast : Warning<
- "reinterpret_cast from %0 to %1 has undefined behavior">,
- InGroup<UndefinedReinterpretCast>, DefaultIgnore;
-
-// These messages don't adhere to the pattern.
-// FIXME: Display the path somehow better.
-def err_ambiguous_base_to_derived_cast : Error<
- "ambiguous cast from base %0 to derived %1:%2">;
-def err_static_downcast_via_virtual : Error<
- "cannot cast %0 to %1 via virtual base %2">;
-def err_downcast_from_inaccessible_base : Error<
- "cannot cast %select{private|protected}2 base class %1 to %0">;
-def err_upcast_to_inaccessible_base : Error<
- "cannot cast %0 to its %select{private|protected}2 base class %1">;
-def err_bad_dynamic_cast_not_ref_or_ptr : Error<
- "%0 is not a reference or pointer">;
-def err_bad_dynamic_cast_not_class : Error<"%0 is not a class">;
-def err_bad_dynamic_cast_incomplete : Error<"%0 is an incomplete type">;
-def err_bad_dynamic_cast_not_ptr : Error<"%0 is not a pointer">;
-def err_bad_dynamic_cast_not_polymorphic : Error<"%0 is not polymorphic">;
-
-// Other C++ expressions
-def err_need_header_before_typeid : Error<
- "you need to include <typeinfo> before using the 'typeid' operator">;
-def err_need_header_before_ms_uuidof : Error<
- "you need to include <guiddef.h> before using the '__uuidof' operator">;
-def err_ms___leave_not_in___try : Error<
- "'__leave' statement not in __try block">;
-def err_uuidof_without_guid : Error<
- "cannot call operator __uuidof on a type with no GUID">;
-def err_uuidof_with_multiple_guids : Error<
- "cannot call operator __uuidof on a type with multiple GUIDs">;
-def err_incomplete_typeid : Error<"'typeid' of incomplete type %0">;
-def err_variably_modified_typeid : Error<"'typeid' of variably modified type %0">;
-def err_static_illegal_in_new : Error<
- "the 'static' modifier for the array size is not legal in new expressions">;
-def err_array_new_needs_size : Error<
- "array size must be specified in new expressions">;
-def err_bad_new_type : Error<
- "cannot allocate %select{function|reference}1 type %0 with new">;
-def err_new_incomplete_type : Error<
- "allocation of incomplete type %0">;
-def err_new_array_nonconst : Error<
- "only the first dimension of an allocated array may have dynamic size">;
-def err_new_array_init_args : Error<
- "array 'new' cannot have initialization arguments">;
-def ext_new_paren_array_nonconst : ExtWarn<
- "when type is in parentheses, array cannot have dynamic size">;
-def err_placement_new_non_placement_delete : Error<
- "'new' expression with placement arguments refers to non-placement "
- "'operator delete'">;
-def err_array_size_not_integral : Error<
- "array size expression must have integral or %select{|unscoped }0"
- "enumeration type, not %1">;
-def err_array_size_incomplete_type : Error<
- "array size expression has incomplete class type %0">;
-def err_array_size_explicit_conversion : Error<
- "array size expression of type %0 requires explicit conversion to type %1">;
-def note_array_size_conversion : Note<
- "conversion to %select{integral|enumeration}0 type %1 declared here">;
-def err_array_size_ambiguous_conversion : Error<
- "ambiguous conversion of array size expression of type %0 to an integral or "
- "enumeration type">;
-def ext_array_size_conversion : Extension<
- "implicit conversion from array size expression of type %0 to "
- "%select{integral|enumeration}1 type %2 is a C++11 extension">,
- InGroup<CXX11>;
-def warn_cxx98_compat_array_size_conversion : Warning<
- "implicit conversion from array size expression of type %0 to "
- "%select{integral|enumeration}1 type %2 is incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def err_address_space_qualified_new : Error<
- "'new' cannot allocate objects of type %0 in address space '%1'">;
-def err_address_space_qualified_delete : Error<
- "'delete' cannot delete objects of type %0 in address space '%1'">;
-
-def err_default_init_const : Error<
- "default initialization of an object of const type %0"
- "%select{| without a user-provided default constructor}1">;
-def ext_default_init_const : ExtWarn<
- "default initialization of an object of const type %0"
- "%select{| without a user-provided default constructor}1 "
- "is a Microsoft extension">,
- InGroup<MicrosoftConstInit>;
-def err_delete_operand : Error<"cannot delete expression of type %0">;
-def ext_delete_void_ptr_operand : ExtWarn<
- "cannot delete expression with pointer-to-'void' type %0">,
- InGroup<DeleteIncomplete>;
-def err_ambiguous_delete_operand : Error<
- "ambiguous conversion of delete expression of type %0 to a pointer">;
-def warn_delete_incomplete : Warning<
- "deleting pointer to incomplete type %0 may cause undefined behavior">,
- InGroup<DeleteIncomplete>;
-def err_delete_incomplete_class_type : Error<
- "deleting incomplete class type %0; no conversions to pointer type">;
-def err_delete_explicit_conversion : Error<
- "converting delete expression from type %0 to type %1 invokes an explicit "
- "conversion function">;
-def note_delete_conversion : Note<"conversion to pointer type %0">;
-def warn_delete_array_type : Warning<
- "'delete' applied to a pointer-to-array type %0 treated as 'delete[]'">;
-def warn_mismatched_delete_new : Warning<
- "'delete%select{|[]}0' applied to a pointer that was allocated with "
- "'new%select{[]|}0'; did you mean 'delete%select{[]|}0'?">,
- InGroup<DiagGroup<"mismatched-new-delete">>;
-def note_allocated_here : Note<"allocated with 'new%select{[]|}0' here">;
-def err_no_suitable_delete_member_function_found : Error<
- "no suitable member %0 in %1">;
-def err_ambiguous_suitable_delete_member_function_found : Error<
- "multiple suitable %0 functions in %1">;
-def note_member_declared_here : Note<
- "member %0 declared here">;
-def err_decrement_bool : Error<"cannot decrement expression of type bool">;
-def warn_increment_bool : Warning<
- "incrementing expression of type bool is deprecated and "
- "incompatible with C++1z">, InGroup<DeprecatedIncrementBool>;
-def ext_increment_bool : ExtWarn<
- "ISO C++1z does not allow incrementing expression of type bool">,
- DefaultError, InGroup<IncrementBool>;
-def err_increment_decrement_enum : Error<
- "cannot %select{decrement|increment}0 expression of enum type %1">;
-def err_catch_incomplete_ptr : Error<
- "cannot catch pointer to incomplete type %0">;
-def err_catch_incomplete_ref : Error<
- "cannot catch reference to incomplete type %0">;
-def err_catch_incomplete : Error<"cannot catch incomplete type %0">;
-def err_catch_rvalue_ref : Error<"cannot catch exceptions by rvalue reference">;
-def err_qualified_catch_declarator : Error<
- "exception declarator cannot be qualified">;
-def err_early_catch_all : Error<"catch-all handler must come last">;
-def err_bad_memptr_rhs : Error<
- "right hand operand to %0 has non-pointer-to-member type %1">;
-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 warn_exception_caught_by_earlier_handler : Warning<
- "exception of type %0 will be caught by earlier handler">,
- InGroup<Exceptions>;
-def note_previous_exception_handler : Note<"for type %0">;
-def err_exceptions_disabled : Error<
- "cannot use '%0' with exceptions disabled">;
-def err_objc_exceptions_disabled : Error<
- "cannot use '%0' with Objective-C exceptions disabled">;
-def err_seh_try_outside_functions : Error<
- "cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls">;
-def err_mixing_cxx_try_seh_try : Error<
- "cannot use C++ 'try' in the same function as SEH '__try'">;
-def err_seh_try_unsupported : Error<
- "SEH '__try' is not supported on this target">;
-def note_conflicting_try_here : Note<
- "conflicting %0 here">;
-def warn_jump_out_of_seh_finally : Warning<
- "jump out of __finally block has undefined behavior">,
- InGroup<DiagGroup<"jump-seh-finally">>;
-def warn_non_virtual_dtor : Warning<
- "%0 has virtual functions but non-virtual destructor">,
- InGroup<NonVirtualDtor>, DefaultIgnore;
-def warn_delete_non_virtual_dtor : Warning<
- "delete called on non-final %0 that has virtual functions "
- "but non-virtual destructor">,
- InGroup<DeleteNonVirtualDtor>, DefaultIgnore;
-def warn_delete_abstract_non_virtual_dtor : Warning<
- "delete called on %0 that is abstract but has non-virtual destructor">,
- InGroup<DeleteNonVirtualDtor>;
-def warn_overloaded_virtual : Warning<
- "%q0 hides overloaded virtual %select{function|functions}1">,
- InGroup<OverloadedVirtual>, DefaultIgnore;
-def note_hidden_overloaded_virtual_declared_here : Note<
- "hidden overloaded virtual function %q0 declared here"
- "%select{|: different classes%diff{ ($ vs $)|}2,3"
- "|: different number of parameters (%2 vs %3)"
- "|: type mismatch at %ordinal2 parameter%diff{ ($ vs $)|}3,4"
- "|: different return type%diff{ ($ vs $)|}2,3"
- "|: different qualifiers ("
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}2 vs "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}3)}1">;
-def warn_using_directive_in_header : Warning<
- "using namespace directive in global context in header">,
- InGroup<HeaderHygiene>, DefaultIgnore;
-def warn_overaligned_type : Warning<
- "type %0 requires %1 bytes of alignment and the default allocator only "
- "guarantees %2 bytes">,
- InGroup<OveralignedType>, DefaultIgnore;
-
-def err_conditional_void_nonvoid : Error<
- "%select{left|right}1 operand to ? is void, but %select{right|left}1 operand "
- "is of type %0">;
-def err_conditional_ambiguous : Error<
- "conditional expression is ambiguous; "
- "%diff{$ can be converted to $ and vice versa|"
- "types can be convert to each other}0,1">;
-def err_conditional_ambiguous_ovl : Error<
- "conditional expression is ambiguous; %diff{$ and $|types}0,1 "
- "can be converted to several common types">;
-def err_conditional_vector_size : Error<
- "vector condition type %0 and result type %1 do not have the same number "
- "of elements">;
-def err_conditional_vector_element_size : Error<
- "vector condition type %0 and result type %1 do not have elements of the "
- "same size">;
-
-def err_throw_incomplete : Error<
- "cannot throw object of incomplete type %0">;
-def err_throw_incomplete_ptr : Error<
- "cannot throw pointer to object of incomplete type %0">;
-def err_return_in_constructor_handler : Error<
- "return in the catch of a function try block of a constructor is illegal">;
-def warn_cdtor_function_try_handler_mem_expr : Warning<
- "cannot refer to a non-static member from the handler of a "
- "%select{constructor|destructor}0 function try block">, InGroup<Exceptions>;
-
-let CategoryName = "Lambda Issue" in {
- def err_capture_more_than_once : Error<
- "%0 can appear only once in a capture list">;
- def err_reference_capture_with_reference_default : Error<
- "'&' cannot precede a capture when the capture default is '&'">;
- def err_this_capture_with_copy_default : Error<
- "'this' cannot be explicitly captured when the capture default is '='">;
- def err_copy_capture_with_copy_default : Error<
- "'&' must precede a capture when the capture default is '='">;
- def err_capture_does_not_name_variable : Error<
- "%0 in capture list does not name a variable">;
- def err_capture_non_automatic_variable : Error<
- "%0 cannot be captured because it does not have automatic storage "
- "duration">;
- def err_this_capture : Error<
- "'this' cannot be %select{implicitly |}0captured in this context">;
- def err_lambda_capture_anonymous_var : Error<
- "unnamed variable cannot be implicitly captured in a lambda expression">;
- def err_lambda_capture_flexarray_type : Error<
- "variable %0 with flexible array member cannot be captured in "
- "a lambda expression">;
- def err_lambda_impcap : Error<
- "variable %0 cannot be implicitly captured in a lambda with no "
- "capture-default specified">;
- def note_lambda_decl : Note<"lambda expression begins here">;
- def err_lambda_unevaluated_operand : Error<
- "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_return_init_list : Error<
- "cannot deduce lambda return type from initializer list">;
- def err_lambda_capture_default_arg : Error<
- "lambda expression in default argument cannot capture any entity">;
- def err_lambda_incomplete_result : Error<
- "incomplete result type %0 in lambda expression">;
- def err_noreturn_lambda_has_return_expr : Error<
- "lambda declared 'noreturn' should not return">;
- def warn_maybe_falloff_nonvoid_lambda : Warning<
- "control may reach end of non-void lambda">,
- InGroup<ReturnType>;
- def warn_falloff_nonvoid_lambda : Warning<
- "control reaches end of non-void lambda">,
- InGroup<ReturnType>;
- def err_access_lambda_capture : Error<
- // The ERRORs represent other special members that aren't constructors, in
- // hopes that someone will bother noticing and reporting if they appear
- "capture of variable '%0' as type %1 calls %select{private|protected}3 "
- "%select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}2constructor">,
- AccessControl;
- def note_lambda_to_block_conv : Note<
- "implicit capture of lambda object due to conversion to block pointer "
- "here">;
-
- // C++14 lambda init-captures.
- def warn_cxx11_compat_init_capture : Warning<
- "initialized lambda captures are incompatible with C++ standards "
- "before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
- def ext_init_capture : ExtWarn<
- "initialized lambda captures are a C++14 extension">, InGroup<CXX14>;
- def err_init_capture_no_expression : Error<
- "initializer missing for lambda capture %0">;
- def err_init_capture_multiple_expressions : Error<
- "initializer for lambda capture %0 contains multiple expressions">;
- def err_init_capture_paren_braces : Error<
- "cannot deduce type for lambda capture %1 from "
- "%select{parenthesized|nested}0 initializer list">;
- def err_init_capture_deduction_failure : Error<
- "cannot deduce type for lambda capture %0 from initializer of type %2">;
- def err_init_capture_deduction_failure_from_init_list : Error<
- "cannot deduce type for lambda capture %0 from initializer list">;
-}
-
-def err_return_in_captured_stmt : Error<
- "cannot return from %0">;
-def err_capture_block_variable : Error<
- "__block variable %0 cannot be captured in a "
- "%select{lambda expression|captured statement}1">;
-
-def err_operator_arrow_circular : Error<
- "circular pointer delegation detected">;
-def err_operator_arrow_depth_exceeded : Error<
- "use of 'operator->' on type %0 would invoke a sequence of more than %1 "
- "'operator->' calls">;
-def note_operator_arrow_here : Note<
- "'operator->' declared here produces an object of type %0">;
-def note_operator_arrows_suppressed : Note<
- "(skipping %0 'operator->'%s0 in backtrace)">;
-def note_operator_arrow_depth : Note<
- "use -foperator-arrow-depth=N to increase 'operator->' limit">;
-
-def err_pseudo_dtor_base_not_scalar : Error<
- "object expression of non-scalar type %0 cannot be used in a "
- "pseudo-destructor expression">;
-def ext_pseudo_dtor_on_void : ExtWarn<
- "pseudo-destructors on type void are a Microsoft extension">,
- InGroup<MicrosoftVoidPseudoDtor>;
-def err_pseudo_dtor_type_mismatch : Error<
- "the type of object expression "
- "%diff{($) does not match the type being destroyed ($)|"
- "does not match the type being destroyed}0,1 "
- "in pseudo-destructor expression">;
-def err_pseudo_dtor_call_with_args : Error<
- "call to pseudo-destructor cannot have any arguments">;
-def err_dtor_expr_without_call : Error<
- "reference to %select{destructor|pseudo-destructor}0 must be called"
- "%select{|; did you mean to call it with no arguments?}1">;
-def err_pseudo_dtor_destructor_non_type : Error<
- "%0 does not refer to a type name in pseudo-destructor expression; expected "
- "the name of type %1">;
-def err_invalid_use_of_function_type : Error<
- "a function type is not allowed here">;
-def err_invalid_use_of_array_type : Error<"an array type is not allowed here">;
-def err_typecheck_bool_condition : Error<
- "value of type %0 is not contextually convertible to 'bool'">;
-def err_typecheck_ambiguous_condition : Error<
- "conversion %diff{from $ to $|between types}0,1 is ambiguous">;
-def err_typecheck_nonviable_condition : Error<
- "no viable conversion%select{%diff{ from $ to $|}1,2|"
- "%diff{ from returned value of type $ to function return type $|}1,2}0">;
-def err_typecheck_nonviable_condition_incomplete : Error<
- "no viable conversion%diff{ from $ to incomplete type $|}0,1">;
-def err_typecheck_deleted_function : Error<
- "conversion function %diff{from $ to $|between types}0,1 "
- "invokes a deleted function">;
-
-def err_expected_class_or_namespace : Error<"%0 is not a class"
- "%select{ or namespace|, namespace, or enumeration}1">;
-def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here "
- "because namespace %1 does not enclose namespace %2">;
-def err_invalid_declarator_global_scope : Error<
- "definition or redeclaration of %0 cannot name the global scope">;
-def err_invalid_declarator_in_function : Error<
- "definition or redeclaration of %0 not allowed inside a function">;
-def err_invalid_declarator_in_block : Error<
- "definition or redeclaration of %0 not allowed inside a block">;
-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">;
-def err_no_dynamic_cast_with_fno_rtti : Error<
- "cannot use dynamic_cast with -fno-rtti">;
-
-def err_cannot_form_pointer_to_member_of_reference_type : Error<
- "cannot form a pointer-to-member to member %0 of reference type %1">;
-def err_incomplete_object_call : Error<
- "incomplete type in call to object of type %0">;
-
-def warn_condition_is_assignment : Warning<"using the result of an "
- "assignment as a condition without parentheses">,
- InGroup<Parentheses>;
-// Completely identical except off by default.
-def warn_condition_is_idiomatic_assignment : Warning<"using the result "
- "of an assignment as a condition without parentheses">,
- InGroup<DiagGroup<"idiomatic-parentheses">>, DefaultIgnore;
-def note_condition_assign_to_comparison : Note<
- "use '==' to turn this assignment into an equality comparison">;
-def note_condition_or_assign_to_comparison : Note<
- "use '!=' to turn this compound assignment into an inequality comparison">;
-def note_condition_assign_silence : Note<
- "place parentheses around the assignment to silence this warning">;
-
-def warn_equality_with_extra_parens : Warning<"equality comparison with "
- "extraneous parentheses">, InGroup<ParenthesesOnEquality>;
-def note_equality_comparison_to_assign : Note<
- "use '=' to turn this equality comparison into an assignment">;
-def note_equality_comparison_silence : Note<
- "remove extraneous parentheses around the comparison to silence this warning">;
-
-// assignment related diagnostics (also for argument passing, returning, etc).
-// In most of these diagnostics the %2 is a value from the
-// Sema::AssignmentAction enumeration
-def err_typecheck_convert_incompatible : Error<
- "%select{%diff{assigning to $ from incompatible type $|"
- "assigning to type from incompatible type}0,1"
- "|%diff{passing $ to parameter of incompatible type $|"
- "passing type to parameter of incompatible type}0,1"
- "|%diff{returning $ from a function with incompatible result type $|"
- "returning type from a function with incompatible result type}0,1"
- "|%diff{converting $ to incompatible type $|"
- "converting type to incompatible type}0,1"
- "|%diff{initializing $ with an expression of incompatible type $|"
- "initializing type with an expression of incompatible type}0,1"
- "|%diff{sending $ to parameter of incompatible type $|"
- "sending type to parameter of incompatible type}0,1"
- "|%diff{casting $ to incompatible type $|"
- "casting type to incompatible type}0,1}2"
- "%select{|; dereference with *|"
- "; take the address with &|"
- "; remove *|"
- "; remove &}3"
- "%select{|: different classes%diff{ ($ vs $)|}5,6"
- "|: different number of parameters (%5 vs %6)"
- "|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7"
- "|: different return type%diff{ ($ vs $)|}5,6"
- "|: different qualifiers ("
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}5 vs "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}6)}4">;
-def err_typecheck_missing_return_type_incompatible : Error<
- "%diff{return type $ must match previous return type $|"
- "return type must match previous return type}0,1 when %select{block "
- "literal|lambda expression}2 has unspecified explicit return type">;
-
-def not_incomplete_class_and_qualified_id : Note<
- "conformance of forward class %0 to protocol %1 can not be confirmed">;
-def warn_incompatible_qualified_id : Warning<
- "%select{%diff{assigning to $ from incompatible type $|"
- "assigning to type from incompatible type}0,1"
- "|%diff{passing $ to parameter of incompatible type $|"
- "passing type to parameter of incompatible type}0,1"
- "|%diff{returning $ from a function with incompatible result type $|"
- "returning type from a function with incompatible result type}0,1"
- "|%diff{converting $ to incompatible type $|"
- "converting type to incompatible type}0,1"
- "|%diff{initializing $ with an expression of incompatible type $|"
- "initializing type with an expression of incompatible type}0,1"
- "|%diff{sending $ to parameter of incompatible type $|"
- "sending type to parameter of incompatible type}0,1"
- "|%diff{casting $ to incompatible type $|"
- "casting type to incompatible type}0,1}2">;
-def ext_typecheck_convert_pointer_int : ExtWarn<
- "incompatible pointer to integer conversion "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- "%select{|; dereference with *|"
- "; take the address with &|"
- "; remove *|"
- "; remove &}3">,
- InGroup<IntConversion>;
-def ext_typecheck_convert_int_pointer : ExtWarn<
- "incompatible integer to pointer conversion "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- "%select{|; dereference with *|"
- "; take the address with &|"
- "; remove *|"
- "; remove &}3">,
- InGroup<IntConversion>;
-def ext_typecheck_convert_pointer_void_func : Extension<
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- " converts between void pointer and function pointer">;
-def ext_typecheck_convert_incompatible_pointer_sign : ExtWarn<
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- " converts between pointers to integer types with different sign">,
- InGroup<DiagGroup<"pointer-sign">>;
-def ext_typecheck_convert_incompatible_pointer : ExtWarn<
- "incompatible pointer types "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- "%select{|; dereference with *|"
- "; take the address with &|"
- "; remove *|"
- "; remove &}3">,
- InGroup<IncompatiblePointerTypes>;
-def ext_typecheck_convert_discards_qualifiers : ExtWarn<
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- " discards qualifiers">,
- InGroup<IncompatiblePointerTypesDiscardsQualifiers>;
-def ext_nested_pointer_qualifier_mismatch : ExtWarn<
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- " discards qualifiers in nested pointer types">,
- InGroup<IncompatiblePointerTypesDiscardsQualifiers>;
-def warn_incompatible_vectors : Warning<
- "incompatible vector types "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2">,
- InGroup<VectorConversion>, DefaultIgnore;
-def err_int_to_block_pointer : Error<
- "invalid block pointer conversion "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2">;
-def err_typecheck_convert_incompatible_block_pointer : Error<
- "incompatible block pointer types "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2">;
-def err_typecheck_incompatible_address_space : Error<
- "%select{%diff{assigning $ to $|assigning to different types}1,0"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- " changes address space of pointer">;
-def err_typecheck_incompatible_ownership : Error<
- "%select{%diff{assigning $ to $|assigning to different types}1,0"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- " changes retain/release properties of pointer">;
-def err_typecheck_comparison_of_distinct_blocks : Error<
- "comparison of distinct block types%diff{ ($ and $)|}0,1">;
-
-def err_typecheck_array_not_modifiable_lvalue : Error<
- "array type %0 is not assignable">;
-def err_typecheck_non_object_not_modifiable_lvalue : Error<
- "non-object type %0 is not assignable">;
-def err_typecheck_expression_not_modifiable_lvalue : Error<
- "expression is not assignable">;
-def err_typecheck_incomplete_type_not_modifiable_lvalue : Error<
- "incomplete type %0 is not assignable">;
-def err_typecheck_lvalue_casts_not_supported : Error<
- "assignment to cast is illegal, lvalue casts are not supported">;
-
-def err_typecheck_duplicate_vector_components_not_mlvalue : Error<
- "vector is not assignable (contains duplicate components)">;
-def err_block_decl_ref_not_modifiable_lvalue : Error<
- "variable is not assignable (missing __block type specifier)">;
-def err_lambda_decl_ref_not_modifiable_lvalue : Error<
- "cannot assign to a variable captured by copy in a non-mutable lambda">;
-def err_typecheck_call_not_function : Error<
- "called object type %0 is not a function or function pointer">;
-def err_call_incomplete_return : Error<
- "calling function with incomplete return type %0">;
-def err_call_function_incomplete_return : Error<
- "calling %0 with incomplete return type %1">;
-def err_call_incomplete_argument : Error<
- "argument type %0 is incomplete">;
-def err_typecheck_call_too_few_args : Error<
- "too few %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected %1, have %2">;
-def err_typecheck_call_too_few_args_one : Error<
- "too few %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "single argument %1 was not specified">;
-def err_typecheck_call_too_few_args_at_least : Error<
- "too few %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected at least %1, have %2">;
-def err_typecheck_call_too_few_args_at_least_one : Error<
- "too few %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "at least argument %1 must be specified">;
-def err_typecheck_call_too_few_args_suggest : Error<
- "too few %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected %1, have %2; did you mean %3?">;
-def err_typecheck_call_too_few_args_at_least_suggest : Error<
- "too few %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected at least %1, have %2; did you mean %3?">;
-def err_typecheck_call_too_many_args : Error<
- "too many %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected %1, have %2">;
-def err_typecheck_call_too_many_args_one : Error<
- "too many %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected single argument %1, have %2 arguments">;
-def err_typecheck_call_too_many_args_at_most : Error<
- "too many %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected at most %1, have %2">;
-def err_typecheck_call_too_many_args_at_most_one : Error<
- "too many %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected at most single argument %1, have %2 arguments">;
-def err_typecheck_call_too_many_args_suggest : Error<
- "too many %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected %1, have %2; did you mean %3?">;
-def err_typecheck_call_too_many_args_at_most_suggest : Error<
- "too many %select{|||execution configuration }0arguments to "
- "%select{function|block|method|kernel function}0 call, "
- "expected at most %1, have %2; did you mean %3?">;
-
-def err_arc_typecheck_convert_incompatible_pointer : Error<
- "incompatible pointer types passing retainable parameter of type %0"
- "to a CF function expecting %1 type">;
-
-def err_builtin_fn_use : Error<"builtin functions must be directly called">;
-
-def warn_call_wrong_number_of_arguments : Warning<
- "too %select{few|many}0 arguments in call to %1">;
-def err_atomic_builtin_must_be_pointer : Error<
- "address argument to atomic builtin must be a pointer (%0 invalid)">;
-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_must_be_pointer_intfltptr : Error<
- "address argument to atomic builtin must be a pointer to integer,"
- " floating-point or pointer (%0 invalid)">;
-def err_atomic_builtin_pointer_size : Error<
- "address argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte "
- "type (%0 invalid)">;
-def err_atomic_exclusive_builtin_pointer_size : Error<
- "address argument to load or store exclusive builtin must be a pointer to"
- " 1,2,4 or 8 byte type (%0 invalid)">;
-def err_atomic_op_needs_atomic : Error<
- "address argument to atomic operation must be a pointer to _Atomic "
- "type (%0 invalid)">;
-def err_atomic_op_needs_non_const_atomic : Error<
- "address argument to atomic operation must be a pointer to non-const _Atomic "
- "type (%0 invalid)">;
-def err_atomic_op_needs_non_const_pointer : Error<
- "address argument to atomic operation must be a pointer to non-const "
- "type (%0 invalid)">;
-def err_atomic_op_needs_trivial_copy : Error<
- "address argument to atomic operation must be a pointer to a "
- "trivially-copyable type (%0 invalid)">;
-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_bitwise_needs_atomic_int : Error<
- "address argument to bitwise atomic operation must be a pointer to "
- "%select{|atomic }0integer (%1 invalid)">;
-def warn_atomic_op_has_invalid_memory_order : Warning<
- "memory order argument to atomic operation is invalid">,
- InGroup<DiagGroup<"atomic-memory-ordering">>;
-
-def err_overflow_builtin_must_be_int : Error<
- "operand argument to overflow builtin must be an integer (%0 invalid)">;
-def err_overflow_builtin_must_be_ptr_int : Error<
- "result argument to overflow builtin must be a pointer "
- "to a non-const integer (%0 invalid)">;
-
-def err_atomic_load_store_uses_lib : Error<
- "atomic %select{load|store}0 requires runtime support that is not "
- "available for this target">;
-
-def err_nontemporal_builtin_must_be_pointer : Error<
- "address argument to nontemporal builtin must be a pointer (%0 invalid)">;
-def err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector : Error<
- "address argument to nontemporal builtin must be a pointer to integer, float, "
- "pointer, or a vector of such types (%0 invalid)">;
-
-def err_deleted_function_use : Error<"attempt to use a deleted function">;
-
-def err_kern_type_not_void_return : Error<
- "kernel function type %0 must have void return type">;
-def err_config_scalar_return : Error<
- "CUDA special function 'cudaConfigureCall' must have scalar return type">;
-def err_kern_call_not_global_function : Error<
- "kernel call to non-global function %0">;
-def err_global_call_not_config : Error<
- "call to global function %0 not configured">;
-def err_ref_bad_target : Error<
- "reference to %select{__device__|__global__|__host__|__host__ __device__}0 "
- "function %1 in %select{__device__|__global__|__host__|__host__ __device__}2 function">;
-def warn_host_calls_from_host_device : Warning<
- "calling __host__ function %0 from __host__ __device__ function %1 can lead to runtime errors">,
- InGroup<CudaCompat>;
-
-def warn_non_pod_vararg_with_format_string : Warning<
- "cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic "
- "%select{function|block|method|constructor}2; expected type from format "
- "string was %3">, InGroup<NonPODVarargs>, DefaultError;
-// The arguments to this diagnostic should match the warning above.
-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_objc_interface_to_vararg : Error<
- "cannot pass object with interface type %0 by value through variadic "
- "%select{function|block|method|constructor}1">;
-def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
- "cannot pass object of %select{non-POD|non-trivial}0 type %1 through variadic"
- " %select{function|block|method|constructor}2; call will abort at runtime">,
- InGroup<NonPODVarargs>, DefaultError;
-def warn_cxx98_compat_pass_non_pod_arg_to_vararg : Warning<
- "passing object of trivial but non-POD type %0 through variadic"
- " %select{function|block|method|constructor}1 is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_pass_class_arg_to_vararg : Warning<
- "passing object of class type %0 through variadic "
- "%select{function|block|method|constructor}1"
- "%select{|; did you mean to call '%3'?}2">,
- InGroup<ClassVarargs>, DefaultIgnore;
-def err_cannot_pass_to_vararg : Error<
- "cannot pass %select{expression of type %1|initializer list}0 to variadic "
- "%select{function|block|method|constructor}2">;
-def err_cannot_pass_to_vararg_format : Error<
- "cannot pass %select{expression of type %1|initializer list}0 to variadic "
- "%select{function|block|method|constructor}2; expected type from format "
- "string was %3">;
-
-def err_typecheck_call_invalid_ordered_compare : Error<
- "ordered compare requires two args of floating point type"
- "%diff{ ($ and $)|}0,1">;
-def err_typecheck_call_invalid_unary_fp : Error<
- "floating point classification requires argument of floating point type "
- "(passed in %0)">;
-def err_typecheck_cond_expect_int_float : Error<
- "used type %0 where integer or floating point type is required">;
-def err_typecheck_cond_expect_scalar : Error<
- "used type %0 where arithmetic or pointer type is required">;
-def err_typecheck_cond_expect_nonfloat : Error<
- "used type %0 where floating point type is not allowed">;
-def ext_typecheck_cond_one_void : Extension<
- "C99 forbids conditional expressions with only one void side">;
-def err_typecheck_cast_to_incomplete : Error<
- "cast to incomplete type %0">;
-def ext_typecheck_cast_nonscalar : Extension<
- "C99 forbids casting nonscalar type %0 to the same type">;
-def ext_typecheck_cast_to_union : Extension<
- "cast to union type is a GNU extension">,
- InGroup<GNUUnionCast>;
-def err_typecheck_cast_to_union_no_type : Error<
- "cast to union type from type %0 not present in union">;
-def err_cast_pointer_from_non_pointer_int : Error<
- "operand of type %0 cannot be cast to a pointer type">;
-def warn_cast_pointer_from_sel : Warning<
- "cast of type %0 to %1 is deprecated; use sel_getName instead">,
- InGroup<SelTypeCast>;
-def warn_function_def_in_objc_container : Warning<
- "function definition inside an Objective-C container is deprecated">,
- InGroup<FunctionDefInObjCContainer>;
-
-def warn_bad_function_cast : Warning<
- "cast from function call of type %0 to non-matching type %1">,
- InGroup<BadFunctionCast>, DefaultIgnore;
-def err_cast_pointer_to_non_pointer_int : Error<
- "pointer cannot be cast to type %0">;
-def err_typecheck_expect_scalar_operand : Error<
- "operand of type %0 where arithmetic or pointer type is required">;
-def err_typecheck_cond_incompatible_operands : Error<
- "incompatible operand types%diff{ ($ and $)|}0,1">;
-def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn<
- "incompatible operand types%diff{ ($ and $)|}0,1 use non-standard composite "
- "pointer type %2">;
-def err_cast_selector_expr : Error<
- "cannot type cast @selector expression">;
-def ext_typecheck_cond_incompatible_pointers : ExtWarn<
- "pointer type mismatch%diff{ ($ and $)|}0,1">,
- InGroup<DiagGroup<"pointer-type-mismatch">>;
-def ext_typecheck_cond_pointer_integer_mismatch : ExtWarn<
- "pointer/integer type mismatch in conditional expression"
- "%diff{ ($ and $)|}0,1">,
- InGroup<DiagGroup<"conditional-type-mismatch">>;
-def err_typecheck_choose_expr_requires_constant : Error<
- "'__builtin_choose_expr' requires a constant expression">;
-def warn_unused_expr : Warning<"expression result unused">,
- InGroup<UnusedValue>;
-def warn_unused_voidptr : Warning<
- "expression result unused; should this cast be to 'void'?">,
- InGroup<UnusedValue>;
-def warn_unused_property_expr : Warning<
- "property access result unused - getters should not be used for side effects">,
- InGroup<UnusedGetterReturnValue>;
-def warn_unused_container_subscript_expr : Warning<
- "container access result unused - container access should not be used for side effects">,
- InGroup<UnusedValue>;
-def warn_unused_call : Warning<
- "ignoring return value of function declared with %0 attribute">,
- InGroup<UnusedValue>;
-def warn_side_effects_unevaluated_context : Warning<
- "expression with side effects has no effect in an unevaluated context">,
- InGroup<UnevaluatedExpression>;
-def warn_side_effects_typeid : Warning<
- "expression with side effects will be evaluated despite being used as an "
- "operand to 'typeid'">, InGroup<PotentiallyEvaluatedExpression>;
-def warn_unused_result : Warning<
- "ignoring return value of function declared with warn_unused_result "
- "attribute">, InGroup<DiagGroup<"unused-result">>;
-def warn_unused_volatile : Warning<
- "expression result unused; assign into a variable to force a volatile load">,
- InGroup<DiagGroup<"unused-volatile-lvalue">>;
-
-def warn_unused_comparison : Warning<
- "%select{%select{|in}1equality|relational}0 comparison result unused">,
- InGroup<UnusedComparison>;
-def note_inequality_comparison_to_or_assign : Note<
- "use '|=' to turn this inequality comparison into an or-assignment">;
-
-def err_incomplete_type_used_in_type_trait_expr : Error<
- "incomplete type %0 used in type trait expression">;
-
-def err_dimension_expr_not_constant_integer : Error<
- "dimension expression does not evaluate to a constant unsigned int">;
-
-def err_typecheck_cond_incompatible_operands_null : Error<
- "non-pointer operand type %0 incompatible with %select{NULL|nullptr}1">;
-def ext_empty_struct_union : Extension<
- "empty %select{struct|union}0 is a GNU extension">, InGroup<GNUEmptyStruct>;
-def ext_no_named_members_in_struct_union : Extension<
- "%select{struct|union}0 without named members is a GNU extension">, InGroup<GNUEmptyStruct>;
-def warn_zero_size_struct_union_compat : Warning<"%select{|empty }0"
- "%select{struct|union}1 has size 0 in C, %select{size 1|non-zero size}2 in C++">,
- InGroup<CXXCompat>, DefaultIgnore;
-def warn_zero_size_struct_union_in_extern_c : Warning<"%select{|empty }0"
- "%select{struct|union}1 has size 0 in C, %select{size 1|non-zero size}2 in C++">,
- InGroup<ExternCCompat>;
-def warn_cast_qual : Warning<"cast from %0 to %1 drops %select{const and "
- "volatile qualifiers|const qualifier|volatile qualifier}2">,
- InGroup<CastQual>, DefaultIgnore;
-def warn_cast_qual2 : Warning<"cast from %0 to %1 must have all intermediate "
- "pointers const qualified to be safe">, InGroup<CastQual>, DefaultIgnore;
-def warn_redefine_extname_not_applied : Warning<
- "#pragma redefine_extname is applicable to external C declarations only; "
- "not applied to %select{function|variable}0 %1">,
- InGroup<Pragmas>;
-} // End of general sema category.
-
-// inline asm.
-let CategoryName = "Inline Assembly Issue" in {
- def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">;
- def err_asm_invalid_output_constraint : Error<
- "invalid output constraint '%0' in asm">;
- def err_asm_invalid_lvalue_in_input : Error<
- "invalid lvalue in asm input for constraint '%0'">;
- def err_asm_invalid_input_constraint : Error<
- "invalid input constraint '%0' in asm">;
- def err_asm_immediate_expected : Error<"constraint '%0' expects "
- "an integer constant expression">;
- def err_asm_invalid_type_in_input : Error<
- "invalid type %0 in asm input for constraint '%1'">;
- def err_asm_tying_incompatible_types : Error<
- "unsupported inline asm: input with type "
- "%diff{$ matching output with type $|}0,1">;
- def err_asm_unexpected_constraint_alternatives : Error<
- "asm constraint has an unexpected number of alternatives: %0 vs %1">;
- def err_asm_incomplete_type : Error<"asm operand has incomplete type %0">;
- def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
- def err_asm_invalid_global_var_reg : Error<"register '%0' unsuitable for "
- "global register variables on this target">;
- def err_asm_register_size_mismatch : Error<"size of register '%0' does not "
- "match variable size">;
- def err_asm_bad_register_type : Error<"bad type for named register variable">;
- def err_asm_invalid_input_size : Error<
- "invalid input size for constraint '%0'">;
- def err_asm_invalid_output_size : Error<
- "invalid output size for constraint '%0'">;
- def err_invalid_asm_cast_lvalue : Error<
- "invalid use of a cast in a inline asm context requiring an l-value: "
- "remove the cast or build with -fheinous-gnu-extensions">;
- def err_invalid_asm_value_for_constraint
- : Error <"value '%0' out of range for constraint '%1'">;
- def err_asm_non_addr_value_in_memory_constraint : Error <
- "reference to a %select{bit-field|vector element|global register variable}0"
- " in asm %select{input|output}1 with a memory constraint '%2'">;
- def err_asm_input_duplicate_match : Error<
- "more than one input constraint matches the same output '%0'">;
-
- def warn_asm_label_on_auto_decl : Warning<
- "ignored asm label '%0' on automatic variable">;
- def warn_invalid_asm_cast_lvalue : Warning<
- "invalid use of a cast in an inline asm context requiring an l-value: "
- "accepted due to -fheinous-gnu-extensions, but clang may remove support "
- "for this in the future">;
- def warn_asm_mismatched_size_modifier : Warning<
- "value size does not match register size specified by the constraint "
- "and modifier">,
- InGroup<ASMOperandWidths>;
-
- def note_asm_missing_constraint_modifier : Note<
- "use constraint modifier \"%0\"">;
- def note_asm_input_duplicate_first : Note<
- "constraint '%0' is already present here">;
-}
-
-let CategoryName = "Semantic Issue" in {
-
-def err_invalid_conversion_between_vectors : Error<
- "invalid conversion between vector type%diff{ $ and $|}0,1 of different "
- "size">;
-def err_invalid_conversion_between_vector_and_integer : Error<
- "invalid conversion between vector type %0 and integer type %1 "
- "of different size">;
-
-def err_opencl_function_pointer_variable : Error<
- "pointers to functions are not allowed">;
-
-def err_opencl_taking_function_address : Error<
- "taking address of function is not allowed">;
-
-def err_invalid_conversion_between_vector_and_scalar : Error<
- "invalid conversion between vector type %0 and scalar type %1">;
-
-// C++ member initializers.
-def err_only_constructors_take_base_inits : Error<
- "only constructors take base initializers">;
-
-def err_multiple_mem_initialization : Error <
- "multiple initializations given for non-static member %0">;
-def err_multiple_mem_union_initialization : Error <
- "initializing multiple members of union">;
-def err_multiple_base_initialization : Error <
- "multiple initializations given for base %0">;
-
-def err_mem_init_not_member_or_class : Error<
- "member initializer %0 does not name a non-static data member or base "
- "class">;
-
-def warn_initializer_out_of_order : Warning<
- "%select{field|base class}0 %1 will be initialized after "
- "%select{field|base}2 %3">,
- InGroup<Reorder>, DefaultIgnore;
-def warn_abstract_vbase_init_ignored : Warning<
- "initializer for virtual base class %0 of abstract class %1 "
- "will never be used">,
- InGroup<DiagGroup<"abstract-vbase-init">>, DefaultIgnore;
-
-def err_base_init_does_not_name_class : Error<
- "constructor initializer %0 does not name a class">;
-def err_base_init_direct_and_virtual : Error<
- "base class initializer %0 names both a direct base class and an "
- "inherited virtual base class">;
-def err_not_direct_base_or_virtual : Error<
- "type %0 is not a direct or virtual base of %1">;
-
-def err_in_class_initializer_non_const : Error<
- "non-const static data member must be initialized out of line">;
-def err_in_class_initializer_volatile : Error<
- "static const volatile data member must be initialized out of line">;
-def err_in_class_initializer_bad_type : Error<
- "static data member of type %0 must be initialized out of line">;
-def ext_in_class_initializer_float_type : ExtWarn<
- "in-class initializer for static data member of type %0 is a GNU extension">,
- InGroup<GNUStaticFloatInit>;
-def ext_in_class_initializer_float_type_cxx11 : ExtWarn<
- "in-class initializer for static data member of type %0 requires "
- "'constexpr' specifier">, InGroup<StaticFloatInit>, DefaultError;
-def note_in_class_initializer_float_type_cxx11 : Note<"add 'constexpr'">;
-def err_in_class_initializer_literal_type : Error<
- "in-class initializer for static data member of type %0 requires "
- "'constexpr' specifier">;
-def err_in_class_initializer_non_constant : Error<
- "in-class initializer for static data member is not a constant expression">;
-def err_in_class_initializer_not_yet_parsed
- : Error<"cannot use defaulted default constructor of %0 within the class "
- "outside of member functions because %1 has an initializer">;
-def err_in_class_initializer_not_yet_parsed_outer_class
- : Error<"cannot use defaulted default constructor of %0 within "
- "%1 outside of member functions because %2 has an initializer">;
-
-def ext_in_class_initializer_non_constant : Extension<
- "in-class initializer for static data member is not a constant expression; "
- "folding it to a constant is a GNU extension">, InGroup<GNUFoldingConstant>;
-
-def err_thread_dynamic_init : Error<
- "initializer for thread-local variable must be a constant expression">;
-def err_thread_nontrivial_dtor : Error<
- "type of thread-local variable has non-trivial destruction">;
-def note_use_thread_local : Note<
- "use 'thread_local' to allow this">;
-
-// C++ anonymous unions and GNU anonymous structs/unions
-def ext_anonymous_union : Extension<
- "anonymous unions are a C11 extension">, InGroup<C11>;
-def ext_gnu_anonymous_struct : Extension<
- "anonymous structs are a GNU extension">, InGroup<GNUAnonymousStruct>;
-def ext_c11_anonymous_struct : Extension<
- "anonymous structs are a C11 extension">, InGroup<C11>;
-def err_anonymous_union_not_static : Error<
- "anonymous unions at namespace or global scope must be declared 'static'">;
-def err_anonymous_union_with_storage_spec : Error<
- "anonymous union at class scope must not have a storage specifier">;
-def err_anonymous_struct_not_member : Error<
- "anonymous %select{structs|structs and classes}0 must be "
- "%select{struct or union|class}0 members">;
-def err_anonymous_record_member_redecl : Error<
- "member of anonymous %select{struct|union}0 redeclares %1">;
-def err_anonymous_record_with_type : Error<
- "types cannot be declared in an anonymous %select{struct|union}0">;
-def ext_anonymous_record_with_type : Extension<
- "types declared in an anonymous %select{struct|union}0 are a Microsoft "
- "extension">, InGroup<MicrosoftAnonTag>;
-def ext_anonymous_record_with_anonymous_type : Extension<
- "anonymous types declared in an anonymous %select{struct|union}0 "
- "are an extension">, InGroup<DiagGroup<"nested-anon-types">>;
-def err_anonymous_record_with_function : Error<
- "functions cannot be declared in an anonymous %select{struct|union}0">;
-def err_anonymous_record_with_static : Error<
- "static members cannot be declared in an anonymous %select{struct|union}0">;
-def err_anonymous_record_bad_member : Error<
- "anonymous %select{struct|union}0 can only contain non-static data members">;
-def err_anonymous_record_nonpublic_member : Error<
- "anonymous %select{struct|union}0 cannot contain a "
- "%select{private|protected}1 data member">;
-def ext_ms_anonymous_record : ExtWarn<
- "anonymous %select{structs|unions}0 are a Microsoft extension">,
- InGroup<MicrosoftAnonTag>;
-
-// C++ local classes
-def err_reference_to_local_var_in_enclosing_function : Error<
- "reference to local variable %0 declared in enclosing function %1">;
-def err_reference_to_local_var_in_enclosing_block : Error<
- "reference to local variable %0 declared in enclosing block literal">;
-def err_reference_to_local_var_in_enclosing_lambda : Error<
- "reference to local variable %0 declared in enclosing lambda expression">;
-def err_reference_to_local_var_in_enclosing_context : Error<
- "reference to local variable %0 declared in enclosing context">;
-
-def err_static_data_member_not_allowed_in_local_class : Error<
- "static data member %0 not allowed in local class %1">;
-
-// C++ derived classes
-def err_base_clause_on_union : Error<"unions cannot have base classes">;
-def err_base_must_be_class : Error<"base specifier must name a class">;
-def err_union_as_base_class : Error<"unions cannot be base classes">;
-def err_circular_inheritance : Error<
- "circular inheritance between %0 and %1">;
-def err_base_class_has_flexible_array_member : Error<
- "base class %0 has a flexible array member">;
-def err_incomplete_base_class : Error<"base class has incomplete type">;
-def err_duplicate_base_class : Error<
- "base class %0 specified more than once as a direct base class">;
-def warn_inaccessible_base_class : Warning<
- "direct base %0 is inaccessible due to ambiguity:%1">,
- InGroup<DiagGroup<"inaccessible-base">>;
-// FIXME: better way to display derivation? Pass entire thing into diagclient?
-def err_ambiguous_derived_to_base_conv : Error<
- "ambiguous conversion from derived class %0 to base class %1:%2">;
-def err_ambiguous_memptr_conv : Error<
- "ambiguous conversion from pointer to member of %select{base|derived}0 "
- "class %1 to pointer to member of %select{derived|base}0 class %2:%3">;
-
-def err_memptr_conv_via_virtual : Error<
- "conversion from pointer to member of class %0 to pointer to member "
- "of class %1 via virtual base %2 is not allowed">;
-
-// C++ member name lookup
-def err_ambiguous_member_multiple_subobjects : Error<
- "non-static member %0 found in multiple base-class subobjects of type %1:%2">;
-def err_ambiguous_member_multiple_subobject_types : Error<
- "member %0 found in multiple base classes of different types">;
-def note_ambiguous_member_found : Note<"member found by ambiguous name lookup">;
-def err_ambiguous_reference : Error<"reference to %0 is ambiguous">;
-def note_ambiguous_candidate : Note<"candidate found by name lookup is %q0">;
-def err_ambiguous_tag_hiding : Error<"a type named %0 is hidden by a "
- "declaration in a different namespace">;
-def note_hidden_tag : Note<"type declaration hidden">;
-def note_hiding_object : Note<"declaration hides type">;
-
-// C++ operator overloading
-def err_operator_overload_needs_class_or_enum : Error<
- "overloaded %0 must have at least one parameter of class "
- "or enumeration type">;
-
-def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
-def err_operator_overload_static : Error<
- "overloaded %0 cannot be a static member function">;
-def err_operator_overload_default_arg : Error<
- "parameter of overloaded %0 cannot have a default argument">;
-def err_operator_overload_must_be : Error<
- "overloaded %0 must be a %select{unary|binary|unary or binary}2 operator "
- "(has %1 parameter%s1)">;
-
-def err_operator_overload_must_be_member : Error<
- "overloaded %0 must be a non-static member function">;
-def err_operator_overload_post_incdec_must_be_int : Error<
- "parameter of overloaded post-%select{increment|decrement}1 operator must "
- "have type 'int' (not %0)">;
-
-// C++ allocation and deallocation functions.
-def err_operator_new_delete_declared_in_namespace : Error<
- "%0 cannot be declared inside a namespace">;
-def err_operator_new_delete_declared_static : Error<
- "%0 cannot be declared static in global scope">;
-def ext_operator_new_delete_declared_inline : ExtWarn<
- "replacement function %0 cannot be declared 'inline'">,
- InGroup<DiagGroup<"inline-new-delete">>;
-def err_operator_new_delete_invalid_result_type : Error<
- "%0 must return type %1">;
-def err_operator_new_delete_dependent_result_type : Error<
- "%0 cannot have a dependent return type; use %1 instead">;
-def err_operator_new_delete_too_few_parameters : Error<
- "%0 must have at least one parameter">;
-def err_operator_new_delete_template_too_few_parameters : Error<
- "%0 template must have at least two parameters">;
-def warn_operator_new_returns_null : Warning<
- "%0 should not return a null pointer unless it is declared 'throw()'"
- "%select{| or 'noexcept'}1">, InGroup<OperatorNewReturnsNull>;
-
-def err_operator_new_dependent_param_type : Error<
- "%0 cannot take a dependent type as first parameter; "
- "use size_t (%1) instead">;
-def err_operator_new_param_type : Error<
- "%0 takes type size_t (%1) as first parameter">;
-def err_operator_new_default_arg: Error<
- "parameter of %0 cannot have a default argument">;
-def err_operator_delete_dependent_param_type : Error<
- "%0 cannot take a dependent type as first parameter; use %1 instead">;
-def err_operator_delete_param_type : Error<
- "first parameter of %0 must have type %1">;
-
-// C++ literal operators
-def err_literal_operator_outside_namespace : Error<
- "literal operator %0 must be in a namespace or global scope">;
-def err_literal_operator_id_outside_namespace : Error<
- "non-namespace scope '%0' cannot have a literal operator member">;
-def err_literal_operator_default_argument : Error<
- "literal operator cannot have a default argument">;
-// FIXME: This diagnostic sucks
-def err_literal_operator_params : Error<
- "parameter declaration for literal operator %0 is not valid">;
-def err_literal_operator_extern_c : Error<
- "literal operator must have C++ linkage">;
-def ext_string_literal_operator_template : ExtWarn<
- "string literal operator templates are a GNU extension">,
- InGroup<GNUStringLiteralOperatorTemplate>;
-def warn_user_literal_reserved : Warning<
- "user-defined literal suffixes not starting with '_' are reserved"
- "%select{; no literal will invoke this operator|}0">,
- InGroup<UserDefinedLiterals>;
-
-// C++ conversion functions
-def err_conv_function_not_member : Error<
- "conversion function must be a non-static member function">;
-def err_conv_function_return_type : Error<
- "conversion function cannot have a return type">;
-def err_conv_function_with_params : Error<
- "conversion function cannot have any parameters">;
-def err_conv_function_variadic : Error<
- "conversion function cannot be variadic">;
-def err_conv_function_to_array : Error<
- "conversion function cannot convert to an array type">;
-def err_conv_function_to_function : Error<
- "conversion function cannot convert to a function type">;
-def err_conv_function_with_complex_decl : Error<
- "cannot specify any part of a return type in the "
- "declaration of a conversion function"
- "%select{"
- "; put the complete type after 'operator'|"
- "; use a typedef to declare a conversion to %1|"
- "; use an alias template to declare a conversion to %1|"
- "}0">;
-def err_conv_function_redeclared : Error<
- "conversion function cannot be redeclared">;
-def warn_conv_to_self_not_used : Warning<
- "conversion function converting %0 to itself will never be used">;
-def warn_conv_to_base_not_used : Warning<
- "conversion function converting %0 to its base class %1 will never be used">;
-def warn_conv_to_void_not_used : Warning<
- "conversion function converting %0 to %1 will never be used">;
-
-def warn_not_compound_assign : Warning<
- "use of unary operator that may be intended as compound assignment (%0=)">;
-
-// C++11 explicit conversion operators
-def ext_explicit_conversion_functions : ExtWarn<
- "explicit conversion functions are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_explicit_conversion_functions : Warning<
- "explicit conversion functions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-// C++11 defaulted functions
-def err_defaulted_special_member_params : Error<
- "an explicitly-defaulted %select{|copy |move }0constructor cannot "
- "have default arguments">;
-def err_defaulted_special_member_variadic : Error<
- "an explicitly-defaulted %select{|copy |move }0constructor cannot "
- "be variadic">;
-def err_defaulted_special_member_return_type : Error<
- "explicitly-defaulted %select{copy|move}0 assignment operator must "
- "return %1">;
-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">;
-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">;
-def err_defaulted_special_member_copy_const_param : Error<
- "the parameter for this explicitly-defaulted copy "
- "%select{constructor|assignment operator}0 is const, but a member or base "
- "requires it to be non-const">;
-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">;
-def err_incorrect_defaulted_constexpr : Error<
- "defaulted definition of %select{default constructor|copy constructor|"
- "move constructor|copy assignment operator|move assignment operator}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 "
- "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 "
- "class %1 multiple times">, InGroup<DiagGroup<"multiple-move-vbase">>;
-def note_vbase_moved_here : Note<
- "%select{%1 is a virtual base class of base class %2 declared here|"
- "virtual base class %1 declared here}0">;
-
-def ext_implicit_exception_spec_mismatch : ExtWarn<
- "function previously declared with an %select{explicit|implicit}0 exception "
- "specification redeclared with an %select{implicit|explicit}0 exception "
- "specification">, InGroup<DiagGroup<"implicit-exception-spec-mismatch">>;
-
-def warn_ptr_arith_precedes_bounds : Warning<
- "the pointer decremented by %0 refers before the beginning of the array">,
- InGroup<ArrayBoundsPointerArithmetic>, DefaultIgnore;
-def warn_ptr_arith_exceeds_bounds : Warning<
- "the pointer incremented by %0 refers past the end of the array (that "
- "contains %1 element%s2)">,
- InGroup<ArrayBoundsPointerArithmetic>, DefaultIgnore;
-def warn_array_index_precedes_bounds : Warning<
- "array index %0 is before the beginning of the array">,
- InGroup<ArrayBounds>;
-def warn_array_index_exceeds_bounds : Warning<
- "array index %0 is past the end of the array (which contains %1 "
- "element%s2)">, InGroup<ArrayBounds>;
-def note_array_index_out_of_bounds : Note<
- "array %0 declared here">;
-
-def warn_printf_insufficient_data_args : Warning<
- "more '%%' conversions than data arguments">, InGroup<Format>;
-def warn_printf_data_arg_not_used : Warning<
- "data argument not used by format string">, InGroup<FormatExtraArgs>;
-def warn_format_invalid_conversion : Warning<
- "invalid conversion specifier '%0'">, InGroup<FormatInvalidSpecifier>;
-def warn_printf_incomplete_specifier : Warning<
- "incomplete format specifier">, InGroup<Format>;
-def warn_missing_format_string : Warning<
- "format string missing">, InGroup<Format>;
-def warn_scanf_nonzero_width : Warning<
- "zero field width in scanf format string is unused">,
- InGroup<Format>;
-def warn_format_conversion_argument_type_mismatch : Warning<
- "format specifies type %0 but the argument has "
- "%select{type|underlying type}2 %1">,
- InGroup<Format>;
-def warn_format_conversion_argument_type_mismatch_pedantic : Extension<
- "format specifies type %0 but the argument has "
- "%select{type|underlying type}2 %1">,
- InGroup<FormatPedantic>;
-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_printf_positional_arg_exceeds_data_args : Warning <
- "data argument position '%0' exceeds the number of data arguments (%1)">,
- InGroup<Format>;
-def warn_format_zero_positional_specifier : Warning<
- "position arguments in format strings start counting at 1 (not 0)">,
- InGroup<Format>;
-def warn_format_invalid_positional_specifier : Warning<
- "invalid position specified for %select{field width|field precision}0">,
- InGroup<Format>;
-def warn_format_mix_positional_nonpositional_args : Warning<
- "cannot mix positional and non-positional arguments in format string">,
- InGroup<Format>;
-def warn_static_array_too_small : Warning<
- "array argument is too small; contains %0 elements, callee requires at least %1">,
- InGroup<ArrayBounds>;
-def note_callee_static_array : Note<
- "callee declares array parameter as static here">;
-def warn_empty_format_string : Warning<
- "format string is empty">, InGroup<FormatZeroLength>;
-def warn_format_string_is_wide_literal : Warning<
- "format string should not be a wide string">, InGroup<Format>;
-def warn_printf_format_string_contains_null_char : Warning<
- "format string contains '\\0' within the string body">, InGroup<Format>;
-def warn_printf_format_string_not_null_terminated : Warning<
- "format string is not null-terminated">, InGroup<Format>;
-def warn_printf_asterisk_missing_arg : Warning<
- "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">,
- InGroup<Format>;
-def warn_printf_asterisk_wrong_type : Warning<
- "field %select{width|precision}0 should have type %1, but argument has type %2">,
- InGroup<Format>;
-def warn_printf_nonsensical_optional_amount: Warning<
- "%select{field width|precision}0 used with '%1' conversion specifier, resulting in undefined behavior">,
- InGroup<Format>;
-def warn_printf_nonsensical_flag: Warning<
- "flag '%0' results in undefined behavior with '%1' conversion specifier">,
- InGroup<Format>;
-def warn_format_nonsensical_length: Warning<
- "length modifier '%0' results in undefined behavior or no effect with '%1' conversion specifier">,
- InGroup<Format>;
-def warn_format_non_standard_positional_arg: Warning<
- "positional arguments are not supported by ISO C">, InGroup<FormatNonStandard>, DefaultIgnore;
-def warn_format_non_standard: Warning<
- "'%0' %select{length modifier|conversion specifier}1 is not supported by ISO C">,
- InGroup<FormatNonStandard>, DefaultIgnore;
-def warn_format_non_standard_conversion_spec: Warning<
- "using length modifier '%0' with conversion specifier '%1' is not supported by ISO C">,
- InGroup<FormatNonStandard>, DefaultIgnore;
-def warn_printf_ignored_flag: Warning<
- "flag '%0' is ignored when flag '%1' is present">,
- InGroup<Format>;
-def warn_printf_empty_objc_flag: Warning<
- "missing object format flag">,
- InGroup<Format>;
-def warn_printf_ObjCflags_without_ObjCConversion: Warning<
- "object format flags cannot be used with '%0' conversion specifier">,
- InGroup<Format>;
-def warn_printf_invalid_objc_flag: Warning<
- "'%0' is not a valid object format flag">,
- InGroup<Format>;
-def warn_scanf_scanlist_incomplete : Warning<
- "no closing ']' for '%%[' in scanf format string">,
- InGroup<Format>;
-def note_format_string_defined : Note<"format string is defined here">;
-def note_format_fix_specifier : Note<"did you mean to use '%0'?">;
-def note_printf_c_str: Note<"did you mean to call the %0 method?">;
-
-def warn_null_arg : Warning<
- "null passed to a callee that requires a non-null argument">,
- InGroup<NonNull>;
-def warn_null_ret : Warning<
- "null returned from %select{function|method}0 that requires a non-null return value">,
- InGroup<NonNull>;
-
-// 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">,
- InGroup<ReturnStackAddress>;
-def warn_ret_local_temp_addr_ref : Warning<
- "returning %select{address of|reference to}0 local temporary object">,
- InGroup<ReturnStackAddress>;
-def warn_ret_addr_label : Warning<
- "returning address of label, which is local">,
- 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">;
-
-// 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>;
-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>;
-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">;
-
-// 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">,
- InGroup<TautologicalCompare>;
-def warn_comparison_bitwise_always : Warning<
- "bitwise comparison always evaluates to %select{false|true}0">,
- InGroup<TautologicalCompare>;
-def warn_tautological_overlap_comparison : Warning<
- "overlapping comparisons always evaluate to %select{false|true}0">,
- InGroup<TautologicalOverlapCompare>, DefaultIgnore;
-
-def warn_stringcompare : Warning<
- "result of comparison against %select{a string literal|@encode}0 is "
- "unspecified (use strncmp instead)">,
- InGroup<StringCompare>;
-
-def warn_identity_field_assign : Warning<
- "assigning %select{field|instance variable}0 to itself">,
- InGroup<SelfAssignmentField>;
-
-// Type safety attributes
-def err_type_tag_for_datatype_not_ice : Error<
- "'type_tag_for_datatype' attribute requires the initializer to be "
- "an %select{integer|integral}0 constant expression">;
-def err_type_tag_for_datatype_too_large : Error<
- "'type_tag_for_datatype' attribute requires the initializer to be "
- "an %select{integer|integral}0 constant expression "
- "that can be represented by a 64 bit integer">;
-def warn_type_tag_for_datatype_wrong_kind : Warning<
- "this type tag was not designed to be used with this function">,
- InGroup<TypeSafety>;
-def warn_type_safety_type_mismatch : Warning<
- "argument type %0 doesn't match specified %1 type tag "
- "%select{that requires %3|}2">, InGroup<TypeSafety>;
-def warn_type_safety_null_pointer_required : Warning<
- "specified %0 type tag requires a null pointer">, InGroup<TypeSafety>;
-
-// Generic selections.
-def err_assoc_type_incomplete : Error<
- "type %0 in generic association incomplete">;
-def err_assoc_type_nonobject : Error<
- "type %0 in generic association not an object type">;
-def err_assoc_type_variably_modified : Error<
- "type %0 in generic association is a variably modified type">;
-def err_assoc_compatible_types : Error<
- "type %0 in generic association compatible with previously specified type %1">;
-def note_compat_assoc : Note<
- "compatible type %0 specified here">;
-def err_generic_sel_no_match : Error<
- "controlling expression type %0 not compatible with any generic association type">;
-def err_generic_sel_multi_match : Error<
- "controlling expression type %0 compatible with %1 generic association types">;
-
-
-// Blocks
-def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks"
- " or pick a deployment target that supports them">;
-def err_block_returning_array_function : Error<
- "block cannot return %select{array|function}0 type %1">;
-
-// Builtin annotation
-def err_builtin_annotation_first_arg : Error<
- "first argument to __builtin_annotation must be an integer">;
-def err_builtin_annotation_second_arg : Error<
- "second argument to __builtin_annotation must be a non-wide string constant">;
-
-// CFString checking
-def err_cfstring_literal_not_string_constant : Error<
- "CFString literal is not a string constant">;
-def warn_cfstring_truncated : Warning<
- "input conversion stopped due to an input byte that does not "
- "belong to the input codeset UTF-8">,
- InGroup<DiagGroup<"CFString-literal">>;
-
-// Statements.
-def err_continue_not_in_loop : Error<
- "'continue' statement not in loop statement">;
-def err_break_not_in_loop_or_switch : Error<
- "'break' statement not in loop or switch statement">;
-def warn_loop_ctrl_binds_to_inner : Warning<
- "'%0' is bound to current loop, GCC binds it to the enclosing loop">,
- InGroup<GccCompat>;
-def warn_break_binds_to_switch : Warning<
- "'break' is bound to loop, GCC binds it to switch">,
- InGroup<GccCompat>;
-def err_default_not_in_switch : Error<
- "'default' statement not in switch statement">;
-def err_case_not_in_switch : Error<"'case' statement not in switch statement">;
-def warn_bool_switch_condition : Warning<
- "switch condition has boolean value">, InGroup<SwitchBool>;
-def warn_case_value_overflow : Warning<
- "overflow converting case value to switch condition type (%0 to %1)">,
- InGroup<Switch>;
-def err_duplicate_case : Error<"duplicate case value '%0'">;
-def err_duplicate_case_differing_expr : Error<
- "duplicate case value: '%0' and '%1' both equal '%2'">;
-def warn_case_empty_range : Warning<"empty case range specified">;
-def warn_missing_case_for_condition :
- Warning<"no case matching constant switch condition '%0'">;
-
-def warn_def_missing_case : Warning<"%plural{"
- "1:enumeration value %1 not explicitly handled in switch|"
- "2:enumeration values %1 and %2 not explicitly handled in switch|"
- "3:enumeration values %1, %2, and %3 not explicitly handled in switch|"
- ":%0 enumeration values not explicitly handled in switch: %1, %2, %3...}0">,
- InGroup<SwitchEnum>, DefaultIgnore;
-
-def warn_missing_case : Warning<"%plural{"
- "1:enumeration value %1 not handled in switch|"
- "2:enumeration values %1 and %2 not handled in switch|"
- "3:enumeration values %1, %2, and %3 not handled in switch|"
- ":%0 enumeration values not handled in switch: %1, %2, %3...}0">,
- InGroup<Switch>;
-
-def warn_unannotated_fallthrough : Warning<
- "unannotated fall-through between switch labels">,
- InGroup<ImplicitFallthrough>, DefaultIgnore;
-def warn_unannotated_fallthrough_per_function : Warning<
- "unannotated fall-through between switch labels in partly-annotated "
- "function">, InGroup<ImplicitFallthroughPerFunction>, DefaultIgnore;
-def note_insert_fallthrough_fixit : Note<
- "insert '%0;' to silence this warning">;
-def note_insert_break_fixit : Note<
- "insert 'break;' to avoid fall-through">;
-def err_fallthrough_attr_wrong_target : Error<
- "clang::fallthrough attribute is only allowed on empty statements">;
-def note_fallthrough_insert_semi_fixit : Note<"did you forget ';'?">;
-def err_fallthrough_attr_outside_switch : Error<
- "fallthrough annotation is outside switch statement">;
-def warn_fallthrough_attr_invalid_placement : Warning<
- "fallthrough annotation does not directly precede switch label">,
- InGroup<ImplicitFallthrough>;
-def warn_fallthrough_attr_unreachable : Warning<
- "fallthrough annotation in unreachable code">,
- InGroup<ImplicitFallthrough>;
-
-def warn_unreachable_default : Warning<
- "default label in switch which covers all enumeration values">,
- InGroup<CoveredSwitchDefault>, DefaultIgnore;
-def warn_not_in_enum : Warning<"case value not in enumerated type %0">,
- InGroup<Switch>;
-def warn_not_in_enum_assignment : Warning<"integer constant not in range "
- "of enumerated type %0">, InGroup<DiagGroup<"assign-enum">>, DefaultIgnore;
-def err_typecheck_statement_requires_scalar : Error<
- "statement requires expression of scalar type (%0 invalid)">;
-def err_typecheck_statement_requires_integer : Error<
- "statement requires expression of integer type (%0 invalid)">;
-def err_multiple_default_labels_defined : Error<
- "multiple default labels in one switch">;
-def err_switch_multiple_conversions : Error<
- "multiple conversions from switch condition type %0 to an integral or "
- "enumeration type">;
-def note_switch_conversion : Note<
- "conversion to %select{integral|enumeration}0 type %1">;
-def err_switch_explicit_conversion : Error<
- "switch condition type %0 requires explicit conversion to %1">;
-def err_switch_incomplete_class_type : Error<
- "switch condition has incomplete class type %0">;
-
-def warn_empty_if_body : Warning<
- "if statement has empty body">, InGroup<EmptyBody>;
-def warn_empty_for_body : Warning<
- "for loop has empty body">, InGroup<EmptyBody>;
-def warn_empty_range_based_for_body : Warning<
- "range-based for loop has empty body">, InGroup<EmptyBody>;
-def warn_empty_while_body : Warning<
- "while loop has empty body">, InGroup<EmptyBody>;
-def warn_empty_switch_body : Warning<
- "switch statement has empty body">, InGroup<EmptyBody>;
-def note_empty_body_on_separate_line : Note<
- "put the semicolon on a separate line to silence this warning">;
-
-def err_va_start_used_in_non_variadic_function : Error<
- "'va_start' used in function with fixed args">;
-def err_va_start_used_in_wrong_abi_function : Error<
- "'va_start' used in %select{System V|Win64}0 ABI function">;
-def err_ms_va_start_used_in_sysv_function : Error<
- "'__builtin_ms_va_start' used in System V ABI function">;
-def warn_second_parameter_of_va_start_not_last_named_argument : Warning<
- "second parameter of 'va_start' not last named argument">, InGroup<Varargs>;
-def warn_va_start_of_reference_type_is_undefined : Warning<
- "'va_start' has undefined behavior with reference types">, InGroup<Varargs>;
-def err_first_argument_to_va_arg_not_of_type_va_list : Error<
- "first argument to 'va_arg' is of type %0 and not 'va_list'">;
-def err_second_parameter_to_va_arg_incomplete: Error<
- "second argument to 'va_arg' is of incomplete type %0">;
-def err_second_parameter_to_va_arg_abstract: Error<
- "second argument to 'va_arg' is of abstract type %0">;
-def warn_second_parameter_to_va_arg_not_pod : Warning<
- "second argument to 'va_arg' is of non-POD type %0">,
- InGroup<NonPODVarargs>, DefaultError;
-def warn_second_parameter_to_va_arg_ownership_qualified : Warning<
- "second argument to 'va_arg' is of ARC ownership-qualified type %0">,
- InGroup<NonPODVarargs>, DefaultError;
-def warn_second_parameter_to_va_arg_never_compatible : Warning<
- "second argument to 'va_arg' is of promotable type %0; this va_arg has "
- "undefined behavior because arguments will be promoted to %1">, InGroup<Varargs>;
-
-def warn_return_missing_expr : Warning<
- "non-void %select{function|method}1 %0 should return a value">, DefaultError,
- InGroup<ReturnType>;
-def ext_return_missing_expr : ExtWarn<
- "non-void %select{function|method}1 %0 should return a value">, DefaultError,
- InGroup<ReturnType>;
-def ext_return_has_expr : ExtWarn<
- "%select{void function|void method|constructor|destructor}1 %0 "
- "should not return a value">,
- DefaultError, InGroup<ReturnType>;
-def ext_return_has_void_expr : Extension<
- "void %select{function|method|block}1 %0 should not return void expression">;
-def err_return_init_list : Error<
- "%select{void function|void method|constructor|destructor}1 %0 "
- "must not return a value">;
-def err_ctor_dtor_returns_void : Error<
- "%select{constructor|destructor}1 %0 must not return void expression">;
-def warn_noreturn_function_has_return_expr : Warning<
- "function %0 declared 'noreturn' should not return">,
- InGroup<InvalidNoreturn>;
-def warn_falloff_noreturn_function : Warning<
- "function declared 'noreturn' should not return">,
- InGroup<InvalidNoreturn>;
-def err_noreturn_block_has_return_expr : Error<
- "block declared 'noreturn' should not return">;
-def err_noreturn_missing_on_first_decl : Error<
- "function declared '[[noreturn]]' after its first declaration">;
-def note_noreturn_missing_first_decl : Note<
- "declaration missing '[[noreturn]]' attribute is here">;
-def err_carries_dependency_missing_on_first_decl : Error<
- "%select{function|parameter}0 declared '[[carries_dependency]]' "
- "after its first declaration">;
-def note_carries_dependency_missing_first_decl : Note<
- "declaration missing '[[carries_dependency]]' attribute is here">;
-def err_carries_dependency_param_not_function_decl : Error<
- "'[[carries_dependency]]' attribute only allowed on parameter in a function "
- "declaration or lambda">;
-def err_block_on_nonlocal : Error<
- "__block attribute not allowed, only allowed on local variables">;
-def err_block_on_vm : Error<
- "__block attribute not allowed on declaration with a variably modified type">;
-
-def err_shufflevector_non_vector : Error<
- "first two arguments to __builtin_shufflevector must be vectors">;
-def err_shufflevector_incompatible_vector : Error<
- "first two arguments to __builtin_shufflevector must have the same type">;
-def err_shufflevector_nonconstant_argument : Error<
- "index for __builtin_shufflevector must be a constant integer">;
-def err_shufflevector_argument_too_large : Error<
- "index for __builtin_shufflevector must be less than the total number "
- "of vector elements">;
-
-def err_convertvector_non_vector : Error<
- "first argument to __builtin_convertvector must be a vector">;
-def err_convertvector_non_vector_type : Error<
- "second argument to __builtin_convertvector must be a vector type">;
-def err_convertvector_incompatible_vector : Error<
- "first two arguments to __builtin_convertvector must have the same number of elements">;
-
-def err_first_argument_to_cwsc_not_call : Error<
- "first argument to __builtin_call_with_static_chain must be a non-member call expression">;
-def err_first_argument_to_cwsc_block_call : Error<
- "first argument to __builtin_call_with_static_chain must not be a block call">;
-def err_first_argument_to_cwsc_builtin_call : Error<
- "first argument to __builtin_call_with_static_chain must not be a builtin call">;
-def err_first_argument_to_cwsc_pdtor_call : Error<
- "first argument to __builtin_call_with_static_chain must not be a pseudo-destructor call">;
-def err_second_argument_to_cwsc_not_pointer : Error<
- "second argument to __builtin_call_with_static_chain must be of pointer type">;
-
-def err_vector_incorrect_num_initializers : Error<
- "%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)">;
-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">;
-def warn_neon_vector_initializer_non_portable : Warning<
- "vector initializers are not compatible with NEON intrinsics in big endian "
- "mode">, InGroup<DiagGroup<"nonportable-vector-initialization">>;
-def note_neon_vector_initializer_non_portable : Note<
- "consider using vld1_%0%1() to initialize a vector from memory, or "
- "vcreate_%0%1() to initialize from an integer constant">;
-def note_neon_vector_initializer_non_portable_q : Note<
- "consider using vld1q_%0%1() to initialize a vector from memory, or "
- "vcombine_%0%1(vcreate_%0%1(), vcreate_%0%1()) to initialize from integer "
- "constants">;
-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_ppc_builtin_only_on_pwr7 : Error<
- "this builtin is only valid on POWER7 or later CPUs">;
-def err_x86_builtin_32_bit_tgt : Error<
- "this builtin is only available on x86-64 targets">;
-
-def err_builtin_longjmp_unsupported : Error<
- "__builtin_longjmp is not supported for the current target">;
-def err_builtin_setjmp_unsupported : Error<
- "__builtin_setjmp is not supported for the current target">;
-
-def err_builtin_longjmp_invalid_val : Error<
- "argument to __builtin_longjmp must be a constant 1">;
-def err_builtin_requires_language : Error<"'%0' is only available in %1">;
-
-def err_constant_integer_arg_type : Error<
- "argument to %0 must be a constant integer">;
-
-def ext_mixed_decls_code : Extension<
- "ISO C90 forbids mixing declarations and code">,
- InGroup<DiagGroup<"declaration-after-statement">>;
-
-def err_non_local_variable_decl_in_for : Error<
- "declaration of non-local variable in 'for' loop">;
-def err_non_variable_decl_in_for : Error<
- "non-variable declaration in 'for' loop">;
-def err_toomany_element_decls : Error<
- "only one element declaration is allowed">;
-def err_selector_element_not_lvalue : Error<
- "selector element is not a valid lvalue">;
-def err_selector_element_type : Error<
- "selector element type %0 is not a valid object">;
-def err_selector_element_const_type : Error<
- "selector element of type %0 cannot be a constant l-value expression">;
-def err_collection_expr_type : Error<
- "the type %0 is not a pointer to a fast-enumerable object">;
-def warn_collection_expr_type : Warning<
- "collection expression type %0 may not respond to %1">;
-
-def err_invalid_conversion_between_ext_vectors : Error<
- "invalid conversion between ext-vector type %0 and %1">;
-
-def warn_duplicate_attribute_exact : Warning<
- "attribute %0 is already applied">, InGroup<IgnoredAttributes>;
-
-def warn_duplicate_attribute : Warning<
- "attribute %0 is already applied with different parameters">,
- InGroup<IgnoredAttributes>;
-
-def warn_sync_fetch_and_nand_semantics_change : Warning<
- "the semantics of this intrinsic changed with GCC "
- "version 4.4 - the newer semantics are provided here">,
- InGroup<DiagGroup<"sync-fetch-and-nand-semantics-changed">>;
-
-// Type
-def ext_invalid_sign_spec : Extension<"'%0' cannot be signed or unsigned">;
-def warn_receiver_forward_class : Warning<
- "receiver %0 is a forward class and corresponding @interface may not exist">,
- InGroup<ForwardClassReceiver>;
-def note_method_sent_forward_class : Note<"method %0 is used for the forward class">;
-def ext_missing_declspec : ExtWarn<
- "declaration specifier missing, defaulting to 'int'">;
-def ext_missing_type_specifier : ExtWarn<
- "type specifier missing, defaults to 'int'">,
- InGroup<ImplicitInt>;
-def err_decimal_unsupported : Error<
- "GNU decimal type extension not supported">;
-def err_missing_type_specifier : Error<
- "C++ requires a type specifier for all declarations">;
-def err_objc_array_of_interfaces : Error<
- "array of interface %0 is invalid (probably should be an array of pointers)">;
-def ext_c99_array_usage : Extension<
- "%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 "
- "feature">, InGroup<C99>;
-def err_c99_array_usage_cxx : Error<
- "%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 "
- "feature, not permitted in C++">;
- def err_type_requires_extension : Error<
- "use of type %0 requires %1 extension to be enabled">;
-def err_int128_unsupported : Error<
- "__int128 is not supported on this target">;
-def err_nsconsumed_attribute_mismatch : Error<
- "overriding method has mismatched ns_consumed attribute on its"
- " parameter">;
-def err_nsreturns_retained_attribute_mismatch : Error<
- "overriding method has mismatched ns_returns_%select{not_retained|retained}0"
- " attributes">;
-
-def note_getter_unavailable : Note<
- "or because setter is declared here, but no getter method %0 is found">;
-def err_invalid_protocol_qualifiers : Error<
- "invalid protocol qualifiers on non-ObjC type">;
-def warn_ivar_use_hidden : Warning<
- "local declaration of %0 hides instance variable">,
- InGroup<DiagGroup<"shadow-ivar">>;
-def warn_direct_initialize_call : Warning<
- "explicit call to +initialize results in duplicate call to +initialize">,
- InGroup<ExplicitInitializeCall>;
-def warn_direct_super_initialize_call : Warning<
- "explicit call to [super initialize] should only be in implementation "
- "of +initialize">,
- InGroup<ExplicitInitializeCall>;
-def error_ivar_use_in_class_method : Error<
- "instance variable %0 accessed in class method">;
-def error_implicit_ivar_access : Error<
- "instance variable %0 cannot be accessed because 'self' has been redeclared">;
-def error_private_ivar_access : Error<"instance variable %0 is private">,
- AccessControl;
-def error_protected_ivar_access : Error<"instance variable %0 is protected">,
- AccessControl;
-def warn_maynot_respond : Warning<"%0 may not respond to %1">;
-def ext_typecheck_base_super : Warning<
- "method parameter type "
- "%diff{$ does not match super class method parameter type $|"
- "does not match super class method parameter type}0,1">,
- InGroup<SuperSubClassMismatch>, DefaultIgnore;
-def warn_missing_method_return_type : Warning<
- "method has no return type specified; defaults to 'id'">,
- InGroup<MissingMethodReturnType>, DefaultIgnore;
-def warn_direct_ivar_access : Warning<"instance variable %0 is being "
- "directly accessed">, InGroup<DiagGroup<"direct-ivar-access">>, DefaultIgnore;
-
-// Spell-checking diagnostics
-def err_unknown_typename : Error<
- "unknown type name %0">;
-def err_unknown_type_or_class_name_suggest : Error<
- "unknown %select{type|class}1 name %0; did you mean %2?">;
-def err_unknown_typename_suggest : Error<
- "unknown type name %0; did you mean %1?">;
-def err_unknown_nested_typename_suggest : Error<
- "no type named %0 in %1; did you mean %select{|simply }2%3?">;
-def err_no_member_suggest : Error<"no member named %0 in %1; did you mean %select{|simply }2%3?">;
-def err_undeclared_use_suggest : Error<
- "use of undeclared %0; did you mean %1?">;
-def err_undeclared_var_use_suggest : Error<
- "use of undeclared identifier %0; did you mean %1?">;
-def err_no_template_suggest : Error<"no template named %0; did you mean %1?">;
-def err_no_member_template_suggest : Error<
- "no template named %0 in %1; did you mean %select{|simply }2%3?">;
-def err_mem_init_not_member_or_class_suggest : Error<
- "initializer %0 does not name a non-static data member or base "
- "class; did you mean the %select{base class|member}1 %2?">;
-def err_field_designator_unknown_suggest : Error<
- "field designator %0 does not refer to any field in type %1; did you mean "
- "%2?">;
-def err_typecheck_member_reference_ivar_suggest : Error<
- "%0 does not have a member named %1; did you mean %2?">;
-def err_property_not_found_suggest : Error<
- "property %0 not found on object of type %1; did you mean %2?">;
-def err_ivar_access_using_property_syntax_suggest : Error<
- "property %0 not found on object of type %1; did you mean to access instance variable %2?">;
-def warn_property_access_suggest : Warning<
-"property %0 not found on object of type %1; did you mean to access property %2?">,
-InGroup<PropertyAccessDotSyntax>;
-def err_property_found_suggest : Error<
- "property %0 found on object of type %1; did you mean to access "
- "it with the \".\" operator?">;
-def err_undef_interface_suggest : Error<
- "cannot find interface declaration for %0; did you mean %1?">;
-def warn_undef_interface_suggest : Warning<
- "cannot find interface declaration for %0; did you mean %1?">;
-def err_undef_superclass_suggest : Error<
- "cannot find interface declaration for %0, superclass of %1; did you mean "
- "%2?">;
-def err_undeclared_protocol_suggest : Error<
- "cannot find protocol declaration for %0; did you mean %1?">;
-def note_base_class_specified_here : Note<
- "base class %0 specified here">;
-def err_using_directive_suggest : Error<
- "no namespace named %0; did you mean %1?">;
-def err_using_directive_member_suggest : Error<
- "no namespace named %0 in %1; did you mean %select{|simply }2%3?">;
-def note_namespace_defined_here : Note<"namespace %0 defined here">;
-def err_sizeof_pack_no_pack_name_suggest : Error<
- "%0 does not refer to the name of a parameter pack; did you mean %1?">;
-def note_parameter_pack_here : Note<"parameter pack %0 declared here">;
-
-def err_uncasted_use_of_unknown_any : Error<
- "%0 has unknown type; cast it to its declared type to use it">;
-def err_uncasted_call_of_unknown_any : Error<
- "%0 has unknown return type; cast the call to its declared return type">;
-def err_uncasted_send_to_unknown_any_method : Error<
- "no known method %select{%objcinstance1|%objcclass1}0; cast the "
- "message send to the method's return type">;
-def err_unsupported_unknown_any_decl : Error<
- "%0 has unknown type, which is not supported for this kind of declaration">;
-def err_unsupported_unknown_any_expr : Error<
- "unsupported expression with unknown type">;
-def err_unsupported_unknown_any_call : Error<
- "call to unsupported expression with unknown type">;
-def err_unknown_any_addrof : Error<
- "the address of a declaration with unknown type "
- "can only be cast to a pointer type">;
-def err_unknown_any_var_function_type : Error<
- "variable %0 with unknown type cannot be given a function type">;
-def err_unknown_any_function : Error<
- "function %0 with unknown type must be given a function type">;
-
-def err_filter_expression_integral : Error<
- "filter expression type should be an integral value not %0">;
-
-def err_non_asm_stmt_in_naked_function : Error<
- "non-ASM statement in naked function is not supported">;
-def err_asm_naked_this_ref : Error<
- "'this' pointer references not allowed in naked functions">;
-def err_asm_naked_parm_ref : Error<
- "parameter references not allowed in naked functions">;
-
-def ext_deprecated_attr_is_a_cxx14_extension : ExtWarn<
- "use of the 'deprecated' attribute is a C++14 extension">, InGroup<CXX14>;
-
-// OpenCL warnings and errors.
-def err_invalid_astype_of_different_size : Error<
- "invalid reinterpretation: sizes of %0 and %1 must match">;
-def err_static_kernel : Error<
- "kernel functions cannot be declared static">;
-def err_opencl_ptrptr_kernel_param : Error<
- "kernel parameter cannot be declared as a pointer to a pointer">;
-def err_opencl_private_ptr_kernel_param : Error<
- "kernel parameter cannot be declared as a pointer to the __private address space">;
-def err_opencl_non_kernel_variable : Error<
- "non-kernel function variable cannot be declared in %0 address space">;
-def err_static_function_scope : Error<
- "variables in function scope cannot be declared static">;
-def err_opencl_bitfields : Error<
- "bitfields are not supported in OpenCL">;
-def err_opencl_vla : Error<
- "variable length arrays are not supported in OpenCL">;
-def err_bad_kernel_param_type : Error<
- "%0 cannot be used as the type of a kernel parameter">;
-def err_record_with_pointers_kernel_param : Error<
- "%select{struct|union}0 kernel parameters may not contain pointers">;
-def note_within_field_of_type : Note<
- "within field of type %0 declared here">;
-def note_illegal_field_declared_here : Note<
- "field of illegal %select{type|pointer type}0 %1 declared here">;
-def err_event_t_global_var : Error<
- "the event_t type cannot be used to declare a program scope variable">;
-def err_event_t_struct_field : Error<
- "the event_t type cannot be used to declare a structure or union field">;
-def err_event_t_addr_space_qual : Error<
- "the event_t type can only be used with __private address space qualifier">;
-def err_expected_kernel_void_return_type : Error<
- "kernel must have void return type">;
-def err_sampler_argument_required : Error<
- "sampler_t variable required - got %0">;
-def err_wrong_sampler_addressspace: Error<
- "sampler type cannot be used with the __local and __global address space qualifiers">;
-def err_opencl_global_invalid_addr_space : Error<
- "program scope variable must reside in %0 address space">;
-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">;
-def err_opencl_return_value_with_address_space : Error<
- "return value cannot be qualified with address space">;
-def err_opencl_constant_no_init : Error<
- "variable in constant address space must be initialized">;
-def err_atomic_init_constant : Error<
- "atomic variable can only be assigned to a compile time constant"
- " in the declaration statement in the program scope">;
-def err_opencl_implicit_vector_conversion : Error<
- "implicit conversions between vector types (%0 and %1) are not permitted">;
-
-// OpenCL Section 6.8.g
-def err_opencl_unknown_type_specifier : Error<
- "OpenCL does not support the '%0' %select{type qualifier|storage class specifier}1">;
-
-} // end of sema category
-
-let CategoryName = "OpenMP Issue" in {
-// OpenMP support.
-def err_omp_expected_var_arg : Error<
- "%0 is not a global variable, static local variable or static data member">;
-def err_omp_expected_var_arg_suggest : Error<
- "%0 is not a global variable, static local variable or static data member; "
- "did you mean %1">;
-def err_omp_global_var_arg : Error<
- "arguments of '#pragma omp %0' must have %select{global storage|static storage duration}1">;
-def err_omp_ref_type_arg : Error<
- "arguments of '#pragma omp %0' cannot be of reference type %1">;
-def err_omp_var_scope : Error<
- "'#pragma omp %0' must appear in the scope of the %q1 variable declaration">;
-def err_omp_var_used : Error<
- "'#pragma omp %0' must precede all references to variable %q1">;
-def err_omp_var_thread_local : Error<
- "variable %0 cannot be threadprivate because it is %select{thread-local|a global named register variable}1">;
-def err_omp_private_incomplete_type : Error<
- "a private variable with incomplete type %0">;
-def err_omp_firstprivate_incomplete_type : Error<
- "a firstprivate variable with incomplete type %0">;
-def err_omp_lastprivate_incomplete_type : Error<
- "a lastprivate variable with incomplete type %0">;
-def err_omp_reduction_incomplete_type : Error<
- "a reduction list item with incomplete type %0">;
-def err_omp_unexpected_clause_value : Error<
- "expected %0 in OpenMP clause '%1'">;
-def err_omp_expected_var_name : Error<
- "expected variable name">;
-def err_omp_expected_var_name_or_array_item : Error<
- "expected variable name, array element or array section">;
-def note_omp_task_predetermined_firstprivate_here : Note<
- "predetermined as a firstprivate in a task construct here">;
-def err_omp_threadprivate_incomplete_type : Error<
- "threadprivate variable with incomplete type %0">;
-def err_omp_no_dsa_for_variable : Error<
- "variable %0 must have explicitly specified data sharing attributes">;
-def err_omp_wrong_dsa : Error<
- "%0 variable cannot be %1">;
-def err_omp_variably_modified_type_not_supported : Error<
- "arguments of OpenMP clause '%0' in '#pragma omp %2' directive cannot be of variably-modified type %1">;
-def note_omp_explicit_dsa : Note<
- "defined as %0">;
-def note_omp_predetermined_dsa : Note<
- "%select{static data member is predetermined as shared|"
- "variable with static storage duration is predetermined as shared|"
- "loop iteration variable is predetermined as private|"
- "loop iteration variable is predetermined as linear|"
- "loop iteration variable is predetermined as lastprivate|"
- "constant variable is predetermined as shared|"
- "global variable is predetermined as shared|"
- "non-shared variable in a task construct is predetermined as firstprivate|"
- "variable with automatic storage duration is predetermined as private}0"
- "%select{|; perhaps you forget to enclose 'omp %2' directive into a parallel or another task region?}1">;
-def note_omp_implicit_dsa : Note<
- "implicitly determined as %0">;
-def err_omp_loop_var_dsa : Error<
- "loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2">;
-def err_omp_not_for : Error<
- "%select{statement after '#pragma omp %1' must be a for loop|"
- "expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">;
-def note_omp_collapse_ordered_expr : Note<
- "as specified in %select{'collapse'|'ordered'|'collapse' and 'ordered'}0 clause%select{||s}0">;
-def err_omp_negative_expression_in_clause : Error<
- "argument to '%0' clause must be a %select{non-negative|strictly positive}1 integer value">;
-def err_omp_not_integral : Error<
- "expression must have integral or unscoped enumeration "
- "type, not %0">;
-def err_omp_incomplete_type : Error<
- "expression has incomplete class type %0">;
-def err_omp_explicit_conversion : Error<
- "expression requires explicit conversion from %0 to %1">;
-def note_omp_conversion_here : Note<
- "conversion to %select{integral|enumeration}0 type %1 declared here">;
-def err_omp_ambiguous_conversion : Error<
- "ambiguous conversion from type %0 to an integral or unscoped "
- "enumeration type">;
-def err_omp_required_access : Error<
- "%0 variable must be %1">;
-def err_omp_const_variable : Error<
- "const-qualified variable cannot be %0">;
-def err_omp_const_reduction_list_item : Error<
- "const-qualified list item cannot be reduction">;
-def err_omp_linear_incomplete_type : Error<
- "a linear variable with incomplete type %0">;
-def err_omp_linear_expected_int_or_ptr : Error<
- "argument of a linear clause should be of integral or pointer "
- "type, not %0">;
-def warn_omp_linear_step_zero : Warning<
- "zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
- InGroup<OpenMPClauses>;
-def warn_omp_alignment_not_power_of_two : Warning<
- "aligned clause will be ignored because the requested alignment is not a power of 2">,
- InGroup<OpenMPClauses>;
-def err_omp_aligned_expected_array_or_ptr : Error<
- "argument of aligned clause should be array"
- "%select{ or pointer|, pointer, reference to array or reference to pointer}1"
- ", not %0">;
-def err_omp_aligned_twice : Error<
- "a variable cannot appear in more than one aligned clause">;
-def err_omp_local_var_in_threadprivate_init : Error<
- "variable with local storage in initial value of threadprivate variable">;
-def err_omp_loop_not_canonical_init : Error<
- "initialization clause of OpenMP for loop is not in canonical form "
- "('var = init' or 'T var = init')">;
-def ext_omp_loop_not_canonical_init : ExtWarn<
- "initialization clause of OpenMP for loop is not in canonical form "
- "('var = init' or 'T var = init')">, InGroup<OpenMPLoopForm>;
-def err_omp_loop_not_canonical_cond : Error<
- "condition of OpenMP for loop must be a relational comparison "
- "('<', '<=', '>', or '>=') of loop variable %0">;
-def err_omp_loop_not_canonical_incr : Error<
- "increment clause of OpenMP for loop must perform simple addition "
- "or subtraction on loop variable %0">;
-def err_omp_loop_variable_type : Error<
- "variable must be of integer or %select{pointer|random access iterator}0 type">;
-def err_omp_loop_incr_not_compatible : Error<
- "increment expression must cause %0 to %select{decrease|increase}1 "
- "on each iteration of OpenMP for loop">;
-def note_omp_loop_cond_requres_compatible_incr : Note<
- "loop step is expected to be %select{negative|positive}0 due to this condition">;
-def err_omp_loop_diff_cxx : Error<
- "could not calculate number of iterations calling 'operator-' with "
- "upper and lower loop bounds">;
-def err_omp_loop_cannot_use_stmt : Error<
- "'%0' statement cannot be used in OpenMP for loop">;
-def err_omp_simd_region_cannot_use_stmt : Error<
- "'%0' statement cannot be used in OpenMP simd region">;
-def warn_omp_loop_64_bit_var : Warning<
- "OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed">,
- InGroup<OpenMPLoopForm>;
-def err_omp_unknown_reduction_identifier : Error<
- "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">;
-def err_omp_reduction_type_array : Error<
- "a reduction list item with array type %0">;
-def err_omp_reduction_ref_type_arg : Error<
- "argument of OpenMP clause 'reduction' must reference the same object in all threads">;
-def err_omp_clause_not_arithmetic_type_arg : Error<
- "arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of %select{scalar|arithmetic}0 type">;
-def err_omp_clause_floating_type_arg : Error<
- "arguments of OpenMP clause 'reduction' with bitwise operators cannot be of floating type">;
-def err_omp_once_referenced : Error<
- "variable can appear only once in OpenMP '%0' clause">;
-def note_omp_referenced : Note<
- "previously referenced here">;
-def err_omp_reduction_in_task : Error<
- "reduction variables may not be accessed in an explicit task">;
-def err_omp_reduction_id_not_compatible : Error<
- "list item of type %0 is not valid for specified reduction operation: unable to provide default initialization value">;
-def err_omp_prohibited_region : Error<
- "region cannot be%select{| closely}0 nested inside '%1' region"
- "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?|"
- "; perhaps you forget to enclose 'omp %3' directive into a for or a parallel for region with 'ordered' clause?|"
- "; perhaps you forget to enclose 'omp %3' directive into a target region?|"
- "; perhaps you forget to enclose 'omp %3' directive into a teams region?}2">;
-def err_omp_prohibited_region_simd : Error<
- "OpenMP constructs may not be nested inside a simd region">;
-def err_omp_prohibited_region_atomic : Error<
- "OpenMP constructs may not be nested inside an atomic region">;
-def err_omp_prohibited_region_critical_same_name : Error<
- "cannot nest 'critical' regions having the same name %0">;
-def note_omp_previous_critical_region : Note<
- "previous 'critical' region starts here">;
-def err_omp_sections_not_compound_stmt : Error<
- "the statement for '#pragma omp sections' must be a compound statement">;
-def err_omp_parallel_sections_not_compound_stmt : Error<
- "the statement for '#pragma omp parallel sections' must be a compound statement">;
-def err_omp_orphaned_section_directive : Error<
- "%select{orphaned 'omp section' directives are prohibited, it|'omp section' directive}0"
- " must be closely nested to a sections region%select{|, not a %1 region}0">;
-def err_omp_sections_substmt_not_section : Error<
- "statement in 'omp sections' directive must be enclosed into a section region">;
-def err_omp_parallel_sections_substmt_not_section : Error<
- "statement in 'omp parallel sections' directive must be enclosed into a section region">;
-def err_omp_parallel_reduction_in_task_firstprivate : Error<
- "argument of a reduction clause of a %0 construct must not appear in a firstprivate clause on a task construct">;
-def err_omp_atomic_read_not_expression_statement : Error<
- "the statement for 'atomic read' must be an expression statement of form 'v = x;',"
- " where v and x are both lvalue expressions with scalar type">;
-def note_omp_atomic_read_write: Note<
- "%select{expected an expression statement|expected built-in assignment operator|expected expression of scalar type|expected lvalue expression}0">;
-def err_omp_atomic_write_not_expression_statement : Error<
- "the statement for 'atomic write' must be an expression statement of form 'x = expr;',"
- " where x is a lvalue expression with scalar type">;
-def err_omp_atomic_update_not_expression_statement : Error<
- "the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x',"
- " where x is an l-value expression with scalar type">;
-def err_omp_atomic_not_expression_statement : Error<
- "the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x',"
- " where x is an l-value expression with scalar type">;
-def note_omp_atomic_update: Note<
- "%select{expected an expression statement|expected built-in binary or unary operator|expected unary decrement/increment operation|"
- "expected expression of scalar type|expected assignment expression|expected built-in binary operator|"
- "expected one of '+', '*', '-', '/', '&', '^', '%|', '<<', or '>>' built-in operations|expected in right hand side of expression}0">;
-def err_omp_atomic_capture_not_expression_statement : Error<
- "the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x',"
- " where x and v are both l-value expressions with scalar type">;
-def err_omp_atomic_capture_not_compound_statement : Error<
- "the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}',"
- " '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}',"
- " '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}'"
- " where x is an l-value expression with scalar type">;
-def note_omp_atomic_capture: Note<
- "%select{expected assignment expression|expected compound statement|expected exactly two expression statements|expected in right hand side of the first expression}0">;
-def err_omp_atomic_several_clauses : Error<
- "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">;
-def note_omp_atomic_previous_clause : Note<
- "'%0' clause used here">;
-def err_omp_target_contains_not_only_teams : Error<
- "target construct with nested teams region contains statements outside of the teams construct">;
-def note_omp_nested_teams_construct_here : Note<
- "nested teams construct here">;
-def note_omp_nested_statement_here : Note<
- "%select{statement|directive}0 outside teams construct here">;
-def err_omp_single_copyprivate_with_nowait : Error<
- "the 'copyprivate' clause must not be used with the 'nowait' clause">;
-def note_omp_nowait_clause_here : Note<
- "'nowait' clause is here">;
-def err_omp_wrong_cancel_region : Error<
- "one of 'for', 'parallel', 'sections' or 'taskgroup' is expected">;
-def err_omp_parent_cancel_region_nowait : Error<
- "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be nowait">;
-def err_omp_parent_cancel_region_ordered : Error<
- "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be ordered">;
-def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">;
-def err_omp_typecheck_section_value : Error<
- "subscripted value is not an array or pointer">;
-def err_omp_typecheck_section_not_integer : Error<
- "array section %select{lower bound|length}0 is not an integer">;
-def err_omp_section_function_type : Error<
- "section of pointer to function type %0">;
-def warn_omp_section_is_char : Warning<"array section %select{lower bound|length}0 is of type 'char'">,
- InGroup<CharSubscript>, DefaultIgnore;
-def err_omp_section_incomplete_type : Error<
- "section of pointer to incomplete type %0">;
-def err_omp_section_negative : Error<
- "section %select{lower bound|length}0 is evaluated to a negative value %1">;
-def err_omp_section_length_undefined : Error<
- "section length is unspecified and cannot be inferred because subscripted value is %select{not an array|an array of unknown bound}0">;
-def err_omp_wrong_linear_modifier : Error<
- "expected %select{'val' modifier|one of 'ref', val' or 'uval' modifiers}0">;
-def err_omp_wrong_linear_modifier_non_reference : Error<
- "variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">;
-def err_omp_wrong_simdlen_safelen_values : Error<
- "the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter">;
-def err_omp_wrong_if_directive_name_modifier : Error<
- "directive name modifier '%0' is not allowed for '#pragma omp %1'">;
-def err_omp_no_more_if_clause : Error<
- "no more 'if' clause is allowed">;
-def err_omp_unnamed_if_clause : Error<
- "expected %select{|one of}0 %1 directive name modifier%select{|s}0">;
-def note_omp_previous_named_if_clause : Note<
- "previous clause with directive name modifier specified here">;
-def err_omp_ordered_directive_with_param : Error<
- "'ordered' directive %select{without any clauses|with 'threads' clause}0 cannot be closely nested inside ordered region with specified parameter">;
-def err_omp_ordered_directive_without_param : Error<
- "'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter">;
-def note_omp_ordered_param : Note<
- "'ordered' clause with specified parameter">;
-def err_omp_expected_base_var_name : Error<
- "expected variable name as a base of the array %select{subscript|section}0">;
-def err_omp_map_shared_storage : Error<
- "variable already marked as mapped in current construct">;
-def err_omp_not_mappable_type : Error<
- "type %0 is not mappable to target">;
-def note_omp_polymorphic_in_target : Note<
- "mappable type cannot be polymorphic">;
-def note_omp_static_member_in_target : Note<
- "mappable type cannot contain static members">;
-def err_omp_threadprivate_in_map : Error<
- "threadprivate variables are not allowed in map clause">;
-def err_omp_wrong_ordered_loop_count : Error<
- "the parameter of the 'ordered' clause must be greater than or equal to the parameter of the 'collapse' clause">;
-def note_collapse_loop_count : Note<
- "parameter of the 'collapse' clause">;
-def err_omp_grainsize_num_tasks_mutually_exclusive : Error<
- "'%0' and '%1' clause are mutually exclusive and may not appear on the same directive">;
-def note_omp_previous_grainsize_num_tasks : Note<
- "'%0' clause is specified here">;
-def err_omp_hint_clause_no_name : Error<
- "the name of the construct must be specified in presence of 'hint' clause">;
-def err_omp_critical_with_hint : Error<
- "constructs with the same name must have a 'hint' clause with the same value">;
-def note_omp_critical_hint_here : Note<
- "%select{|previous }0'hint' clause with value '%1'">;
-def note_omp_critical_no_hint : Note<
- "%select{|previous }0directive with no 'hint' clause specified">;
-def err_omp_firstprivate_distribute_private_teams : Error<
- "private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">;
-def err_omp_firstprivate_and_lastprivate_in_distribute : Error<
- "lastprivate variable cannot be firstprivate in '#pragma omp distribute'">;
-def err_omp_firstprivate_distribute_in_teams_reduction : Error<
- "reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">;
-def err_omp_depend_clause_thread_simd : Error<
- "'depend' clauses cannot be mixed with '%0' clause">;
-def err_omp_depend_sink_wrong_expr : Error<
- "expected expression form x[+-d], where x is the loop iteration variable and d is a constant non-negative integer">;
-def err_omp_depend_sink_expected_loop_iteration : Error<
- "expected %0 loop iteration variable">;
-def err_omp_depend_sink_unexpected_expr : Error<
- "unexpected expression: number of expressions is larger than the number of associated loops">;
-def err_omp_depend_sink_expected_plus_minus : Error<
- "expected '+' or '-' operation">;
-def err_omp_depend_sink_source_not_allowed : Error<
- "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">;
-def err_omp_linear_ordered : Error<
- "'linear' clause cannot be specified along with 'ordered' clause with a parameter">;
-def err_omp_unexpected_schedule_modifier : Error<
- "modifier '%0' cannot be used along with modifier '%1'">;
-def err_omp_schedule_nonmonotonic_static : Error<
- "'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind">;
-def err_omp_schedule_nonmonotonic_ordered : Error<
- "'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified">;
-def err_omp_ordered_simd : Error<
- "'ordered' clause with a parameter can not be specified in '#pragma omp %0' directive">;
-} // end of OpenMP category
-
-let CategoryName = "Related Result Type Issue" in {
-// Objective-C related result type compatibility
-def warn_related_result_type_compatibility_class : Warning<
- "method is expected to return an instance of its class type "
- "%diff{$, but is declared to return $|"
- ", but is declared to return different type}0,1">;
-def warn_related_result_type_compatibility_protocol : Warning<
- "protocol method is expected to return an instance of the implementing "
- "class, but is declared to return %0">;
-def note_related_result_type_family : Note<
- "%select{overridden|current}0 method is part of the '%select{|alloc|copy|init|"
- "mutableCopy|new|autorelease|dealloc|finalize|release|retain|retainCount|"
- "self}1' method family%select{| and is expected to return an instance of its "
- "class type}0">;
-def note_related_result_type_overridden : Note<
- "overridden method returns an instance of its class type">;
-def note_related_result_type_inferred : Note<
- "%select{class|instance}0 method %1 is assumed to return an instance of "
- "its receiver type (%2)">;
-def note_related_result_type_explicit : Note<
- "%select{overridden|current}0 method is explicitly declared 'instancetype'"
- "%select{| and is expected to return an instance of its class type}0">;
-
-}
-
-let CategoryName = "Modules Issue" in {
-def err_module_private_specialization : Error<
- "%select{template|partial|member}0 specialization cannot be "
- "declared __module_private__">;
-def err_module_private_local : Error<
- "%select{local variable|parameter|typedef}0 %1 cannot be declared "
- "__module_private__">;
-def err_module_private_local_class : Error<
- "local %select{struct|interface|union|class|enum}0 cannot be declared "
- "__module_private__">;
-def err_module_unimported_use : Error<
- "%select{declaration|definition|default argument}0 of %1 must be imported "
- "from module '%2' before it is required">;
-def err_module_unimported_use_multiple : Error<
- "%select{declaration|definition|default argument}0 of %1 must be imported "
- "from one of the following modules before it is required:%2">;
-def ext_module_import_in_extern_c : ExtWarn<
- "import of C++ module '%0' appears within extern \"C\" language linkage "
- "specification">, DefaultError,
- InGroup<DiagGroup<"module-import-in-extern-c">>;
-def note_module_import_in_extern_c : Note<
- "extern \"C\" language linkage specification begins here">;
-def err_module_import_not_at_top_level_fatal : Error<
- "import of module '%0' appears within %1">, DefaultFatal;
-def ext_module_import_not_at_top_level_noop : ExtWarn<
- "redundant #include of module '%0' appears within %1">, DefaultError,
- InGroup<DiagGroup<"modules-import-nested-redundant">>;
-def note_module_import_not_at_top_level : Note<"%0 begins here">;
-def err_module_self_import : Error<
- "import of module '%0' appears within same top-level module '%1'">;
-def err_module_import_in_implementation : Error<
- "@import of module '%0' in implementation of '%1'; use #import">;
-
-def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
- "ambiguous use of internal linkage declaration %0 defined in multiple modules">,
- InGroup<DiagGroup<"modules-ambiguous-internal-linkage">>;
-def note_equivalent_internal_linkage_decl : Note<
- "declared here%select{ in module '%1'|}0">;
-}
-
-let CategoryName = "Coroutines Issue" in {
-def err_return_in_coroutine : Error<
- "return statement not allowed in coroutine; did you mean 'co_return'?">;
-def note_declared_coroutine_here : Note<
- "function is a coroutine due to use of "
- "'%select{co_await|co_yield|co_return}0' here">;
-def err_coroutine_objc_method : Error<
- "Objective-C methods as coroutines are not yet supported">;
-def err_coroutine_unevaluated_context : Error<
- "'%0' cannot be used in an unevaluated context">;
-def err_coroutine_outside_function : Error<
- "'%0' cannot be used outside a function">;
-def err_coroutine_ctor_dtor : Error<
- "'%1' cannot be used in a %select{constructor|destructor}0">;
-def err_coroutine_constexpr : Error<
- "'%0' cannot be used in a constexpr function">;
-def err_coroutine_varargs : Error<
- "'%0' cannot be used in a varargs function">;
-def ext_coroutine_without_co_await_co_yield : ExtWarn<
- "'co_return' used in a function "
- "that uses neither 'co_await' nor 'co_yield'">,
- InGroup<DiagGroup<"coreturn-without-coawait">>;
-def err_implied_std_coroutine_traits_not_found : Error<
- "you need to include <coroutine> before defining a coroutine">;
-def err_malformed_std_coroutine_traits : Error<
- "'std::coroutine_traits' must be a class template">;
-def err_implied_std_coroutine_traits_promise_type_not_found : Error<
- "this function cannot be a coroutine: %q0 has no member named 'promise_type'">;
-def err_implied_std_coroutine_traits_promise_type_not_class : Error<
- "this function cannot be a coroutine: %0 is not a class">;
-def err_coroutine_traits_missing_specialization : Error<
- "this function cannot be a coroutine: missing definition of "
- "specialization %q0">;
-}
-
-let CategoryName = "Documentation Issue" in {
-def warn_not_a_doxygen_trailing_member_comment : Warning<
- "not a Doxygen trailing comment">, InGroup<Documentation>, DefaultIgnore;
-} // end of documentation issue category
-
-let CategoryName = "Instrumentation Issue" in {
-def warn_profile_data_out_of_date : Warning<
- "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1"
- " no data and %2 %plural{1:has|:have}2 mismatched data that will be ignored">,
- InGroup<ProfileInstrOutOfDate>;
-def warn_profile_data_unprofiled : Warning<
- "no profile data available for file \"%0\"">,
- InGroup<ProfileInstrUnprofiled>;
-
-} // end of instrumentation issue category
-
-let CategoryName = "Nullability Issue" in {
-
-def warn_mismatched_nullability_attr : Warning<
- "nullability specifier %0 conflicts with existing specifier %1">,
- InGroup<Nullability>;
-
-def warn_nullability_declspec : Warning<
- "nullability specifier %0 cannot be applied "
- "to non-pointer type %1; did you mean to apply the specifier to the "
- "%select{pointer|block pointer|member pointer|function pointer|"
- "member function pointer}2?">,
- InGroup<NullabilityDeclSpec>,
- DefaultError;
-
-def note_nullability_here : Note<"%0 specified here">;
-
-def err_nullability_nonpointer : Error<
- "nullability specifier %0 cannot be applied to non-pointer type %1">;
-
-def warn_nullability_lost : Warning<
- "implicit conversion from nullable pointer %0 to non-nullable pointer "
- "type %1">,
- InGroup<NullableToNonNullConversion>, DefaultIgnore;
-
-def err_nullability_cs_multilevel : Error<
- "nullability keyword %0 cannot be applied to multi-level pointer type %1">;
-def note_nullability_type_specifier : Note<
- "use nullability type specifier %0 to affect the innermost "
- "pointer type of %1">;
-
-def warn_null_resettable_setter : Warning<
- "synthesized setter %0 for null_resettable property %1 does not handle nil">,
- InGroup<Nullability>;
-
-def warn_nullability_missing : Warning<
- "%select{pointer|block pointer|member pointer}0 is missing a nullability "
- "type specifier (_Nonnull, _Nullable, or _Null_unspecified)">,
- InGroup<NullabilityCompleteness>;
-
-def err_objc_type_arg_explicit_nullability : Error<
- "type argument %0 cannot explicitly specify nullability">;
-
-def err_objc_type_param_bound_explicit_nullability : Error<
- "type parameter %0 bound %1 cannot explicitly specify nullability">;
-
-}
-
-let CategoryName = "Generics Issue" in {
-
-def err_objc_type_param_bound_nonobject : Error<
- "type bound %0 for type parameter %1 is not an Objective-C pointer type">;
-
-def err_objc_type_param_bound_missing_pointer : Error<
- "missing '*' in type bound %0 for type parameter %1">;
-def err_objc_type_param_bound_qualified : Error<
- "type bound %1 for type parameter %0 cannot be qualified with '%2'">;
-
-def err_objc_type_param_redecl : Error<
- "redeclaration of type parameter %0">;
-
-def err_objc_type_param_arity_mismatch : Error<
- "%select{forward class declaration|class definition|category|extension}0 has "
- "too %select{few|many}1 type parameters (expected %2, have %3)">;
-
-def err_objc_type_param_bound_conflict : Error<
- "type bound %0 for type parameter %1 conflicts with "
- "%select{implicit|previous}2 bound %3%select{for type parameter %5|}4">;
-
-def err_objc_type_param_variance_conflict : Error<
- "%select{in|co|contra}0variant type parameter %1 conflicts with previous "
- "%select{in|co|contra}2variant type parameter %3">;
-
-def note_objc_type_param_here : Note<"type parameter %0 declared here">;
-
-def err_objc_type_param_bound_missing : Error<
- "missing type bound %0 for type parameter %1 in %select{@interface|@class}2">;
-
-def err_objc_parameterized_category_nonclass : Error<
- "%select{extension|category}0 of non-parameterized class %1 cannot have type "
- "parameters">;
-
-def err_objc_parameterized_forward_class : Error<
- "forward declaration of non-parameterized class %0 cannot have type "
- "parameters">;
-
-def err_objc_parameterized_forward_class_first : Error<
- "class %0 previously declared with type parameters">;
-
-def err_objc_type_arg_missing_star : Error<
- "type argument %0 must be a pointer (requires a '*')">;
-def err_objc_type_arg_qualified : Error<
- "type argument %0 cannot be qualified with '%1'">;
-
-def err_objc_type_arg_missing : Error<
- "no type or protocol named %0">;
-
-def err_objc_type_args_and_protocols : Error<
- "angle brackets contain both a %select{type|protocol}0 (%1) and a "
- "%select{protocol|type}0 (%2)">;
-
-def err_objc_type_args_non_class : Error<
- "type arguments cannot be applied to non-class type %0">;
-
-def err_objc_type_args_non_parameterized_class : Error<
- "type arguments cannot be applied to non-parameterized class %0">;
-
-def err_objc_type_args_specialized_class : Error<
- "type arguments cannot be applied to already-specialized class type %0">;
-
-def err_objc_type_args_wrong_arity : Error<
- "too %select{many|few}0 type arguments for class %1 (have %2, expected %3)">;
-}
-
-def err_objc_type_arg_not_id_compatible : Error<
- "type argument %0 is neither an Objective-C object nor a block type">;
-
-def err_objc_type_arg_does_not_match_bound : Error<
- "type argument %0 does not satisfy the bound (%1) of type parameter %2">;
-
-def warn_objc_redundant_qualified_class_type : Warning<
- "parameterized class %0 already conforms to the protocols listed; did you "
- "forget a '*'?">, InGroup<ObjCProtocolQualifiers>;
-
-} // end of sema component.
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
deleted file mode 100644
index 16c7743..0000000
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ /dev/null
@@ -1,124 +0,0 @@
-//==--- DiagnosticSerializationKinds.td - serialization diagnostics -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-let Component = "Serialization" in {
-let CategoryName = "AST Deserialization Issue" in {
-
-def err_fe_unable_to_read_pch_file : Error<
- "unable to read PCH file %0: '%1'">;
-def err_fe_not_a_pch_file : Error<
- "input is not a PCH file: '%0'">;
-def err_fe_pch_malformed : Error<
- "malformed or corrupted AST file: '%0'">, DefaultFatal;
-def err_fe_pch_malformed_block : Error<
- "malformed block record in PCH file: '%0'">, DefaultFatal;
-def err_fe_pch_file_modified : Error<
- "file '%0' has been modified since the precompiled header '%1' was built">,
- DefaultFatal;
-def err_fe_pch_file_overridden : Error<
- "file '%0' from the precompiled header has been overridden">;
-def note_pch_required_by : Note<"'%0' required by '%1'">;
-def note_pch_rebuild_required : Note<"please rebuild precompiled header '%0'">;
-def note_module_cache_path : Note<
- "after modifying system headers, please delete the module cache at '%0'">;
-
-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 "
- "not">;
-def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in "
- "PCH file but is currently %select{disabled|enabled}2">;
-def err_pch_langopt_value_mismatch : Error<
- "%0 differs in PCH file vs. current file">;
-def err_pch_diagopt_mismatch : Error<"%0 is currently enabled, but was not in "
- "the PCH file">;
-def err_pch_modulecache_mismatch : Error<"PCH was compiled with module cache "
- "path '%0', but the path is currently '%1'">;
-
-def err_pch_version_too_old : Error<
- "PCH file uses an older PCH format that is no longer supported">;
-def err_pch_version_too_new : Error<
- "PCH file uses a newer PCH format that cannot be read">;
-def err_pch_different_branch : Error<
- "PCH file built from a different branch (%0) than the compiler (%1)">;
-def err_pch_with_compiler_errors : Error<
- "PCH file contains compiler errors">;
-
-def err_module_file_conflict : Error<
- "module '%0' is defined in both '%1' and '%2'">, DefaultFatal;
-def err_module_file_not_found : Error<
- "%select{PCH|module|AST}0 file '%1' not found%select{|: %3}2">, DefaultFatal;
-def err_module_file_out_of_date : Error<
- "%select{PCH|module|AST}0 file '%1' is out of date and "
- "needs to be rebuilt%select{|: %3}2">, DefaultFatal;
-def err_module_file_invalid : Error<
- "file '%1' is not a valid precompiled %select{PCH|module|AST}0 file">, DefaultFatal;
-def note_module_file_imported_by : Note<
- "imported by %select{|module '%2' in }1'%0'">;
-def err_module_file_not_module : Error<
- "AST file '%0' was not built as a module">, DefaultFatal;
-
-def err_imported_module_not_found : Error<
- "module '%0' in AST file '%1' (imported by AST file '%2') "
- "is not defined in any loaded module map file; "
- "maybe you need to load '%3'?">, DefaultFatal;
-def err_imported_module_modmap_changed : Error<
- "module '%0' imported by AST file '%1' found in a different module map file"
- " (%2) than when the importing AST file was built (%3)">, DefaultFatal;
-def err_imported_module_relocated : Error<
- "module '%0' was built in directory '%1' but now resides in "
- "directory '%2'">, DefaultFatal;
-def err_module_different_modmap : Error<
- "module '%0' %select{uses|does not use}1 additional module map '%2'"
- "%select{| not}1 used when the module was built">;
-
-def err_pch_macro_def_undef : Error<
- "macro '%0' was %select{defined|undef'd}1 in the precompiled header but "
- "%select{undef'd|defined}1 on the command line">;
-def err_pch_macro_def_conflict : Error<
- "definition of macro '%0' differs between the precompiled header ('%1') "
- "and the command line ('%2')">;
-def err_pch_undef : Error<
- "%select{command line contains|precompiled header was built with}0 "
- "'-undef' but %select{precompiled header was not built with it|"
- "it is not present on the command line}0">;
-def err_pch_pp_detailed_record : Error<
- "%select{command line contains|precompiled header was built with}0 "
- "'-detailed-preprocessing-record' but %select{precompiled header was not "
- "built with it|it is not present on the command line}0">;
-
-def err_module_odr_violation_missing_decl : Error<
- "%q0 from module '%1' is not present in definition of %q2"
- "%select{ in module '%4'| provided earlier}3">, NoSFINAE;
-def note_module_odr_violation_no_possible_decls : Note<
- "definition has no member %0">;
-def note_module_odr_violation_possible_decl : Note<
- "declaration of %0 does not match">;
-def err_module_odr_violation_different_definitions : Error<
- "%q0 has different definitions in different modules; "
- "%select{definition in module '%2' is here|defined here}1">;
-def note_module_odr_violation_different_definitions : Note<
- "definition in module '%0' is here">;
-def err_module_odr_violation_different_instantiations : Error<
- "instantiation of %q0 is different in different modules">;
-
-def warn_module_uses_date_time : Warning<
- "%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
- InGroup<DiagGroup<"pch-date-time">>;
-
-def warn_duplicate_module_file_extension : Warning<
- "duplicate module file extension block name '%0'">,
- InGroup<ModuleFileExtension>;
-
-} // let CategoryName
-} // let Component
-
diff --git a/include/clang/Basic/ExceptionSpecificationType.h b/include/clang/Basic/ExceptionSpecificationType.h
deleted file mode 100644
index 132b5ba..0000000
--- a/include/clang/Basic/ExceptionSpecificationType.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//===--- ExceptionSpecificationType.h ---------------------------*- 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 ExceptionSpecificationType enumeration and various
-/// utility functions.
-///
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
-#define LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
-
-namespace clang {
-
-/// \brief 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_Unevaluated, ///< not evaluated yet, for special member function
- EST_Uninstantiated, ///< not instantiated yet
- EST_Unparsed ///< not parsed yet
-};
-
-inline bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType) {
- return ESpecType >= EST_DynamicNone && ESpecType <= EST_MSAny;
-}
-
-inline bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType) {
- return ESpecType == EST_BasicNoexcept || ESpecType == EST_ComputedNoexcept;
-}
-
-inline bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType) {
- return ESpecType == EST_Unevaluated || ESpecType == EST_Uninstantiated;
-}
-
-/// \brief Possible results from evaluation of a noexcept expression.
-enum CanThrowResult {
- CT_Cannot,
- CT_Dependent,
- CT_Can
-};
-
-inline CanThrowResult mergeCanThrow(CanThrowResult CT1, CanThrowResult CT2) {
- // CanThrowResult constants are ordered so that the maximum is the correct
- // merge result.
- return CT1 > CT2 ? CT1 : CT2;
-}
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
diff --git a/include/clang/Basic/ExpressionTraits.h b/include/clang/Basic/ExpressionTraits.h
deleted file mode 100644
index 0363a1d..0000000
--- a/include/clang/Basic/ExpressionTraits.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//===- ExpressionTraits.h - C++ Expression Traits Support Enums -*- 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 enumerations for expression traits intrinsics.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H
-#define LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H
-
-namespace clang {
-
- enum ExpressionTrait {
- ET_IsLValueExpr,
- ET_IsRValueExpr
- };
-}
-
-#endif
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
deleted file mode 100644
index 17758ec..0000000
--- a/include/clang/Basic/FileManager.h
+++ /dev/null
@@ -1,288 +0,0 @@
-//===--- FileManager.h - File System Probing and Caching --------*- 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::FileManager interface and associated types.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_FILEMANAGER_H
-#define LLVM_CLANG_BASIC_FILEMANAGER_H
-
-#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/VirtualFileSystem.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-#include <memory>
-#include <map>
-
-namespace llvm {
-class MemoryBuffer;
-}
-
-namespace clang {
-class FileManager;
-class FileSystemStatCache;
-
-/// \brief Cached information about one directory (either on disk or in
-/// the virtual file system).
-class DirectoryEntry {
- const char *Name; // Name of the directory.
- friend class FileManager;
-public:
- DirectoryEntry() : Name(nullptr) {}
- const char *getName() const { return Name; }
-};
-
-/// \brief 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
-/// descriptor for the file.
-class FileEntry {
- const char *Name; // Name of the file.
- off_t Size; // File size in bytes.
- time_t ModTime; // Modification time of file.
- const DirectoryEntry *Dir; // Directory file lives in.
- unsigned UID; // A unique (small) ID for the file.
- llvm::sys::fs::UniqueID UniqueID;
- bool IsNamedPipe;
- bool InPCH;
- bool IsValid; // Is this \c FileEntry initialized and valid?
-
- /// \brief The open file, if it is owned by the \p FileEntry.
- mutable std::unique_ptr<vfs::File> File;
- friend class FileManager;
-
- void operator=(const FileEntry &) = delete;
-
-public:
- FileEntry()
- : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
- {}
-
- // FIXME: this is here to allow putting FileEntry in std::map. Once we have
- // emplace, we shouldn't need a copy constructor anymore.
- /// Intentionally does not copy fields that are not set in an uninitialized
- /// \c FileEntry.
- FileEntry(const FileEntry &FE) : UniqueID(FE.UniqueID),
- IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid) {
- assert(!isValid() && "Cannot copy an initialized FileEntry");
- }
-
- const char *getName() const { return Name; }
- bool isValid() const { return IsValid; }
- off_t getSize() const { return Size; }
- unsigned getUID() const { return UID; }
- const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
- bool isInPCH() const { return InPCH; }
- time_t getModificationTime() const { return ModTime; }
-
- /// \brief 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
- /// the native FileManager methods).
- bool isNamedPipe() const { return IsNamedPipe; }
-
- void closeFile() const {
- File.reset(); // rely on destructor to close File
- }
-};
-
-struct FileData;
-
-/// \brief Implements support for file system lookup, file system caching,
-/// and directory search management.
-///
-/// This also handles more advanced properties, such as uniquing files based
-/// on "inode", so that a file with two names (e.g. symlinked) will be treated
-/// as a single file.
-///
-class FileManager : public RefCountedBase<FileManager> {
- IntrusiveRefCntPtr<vfs::FileSystem> FS;
- FileSystemOptions FileSystemOpts;
-
- /// \brief Cache for existing real directories.
- std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueRealDirs;
-
- /// \brief Cache for existing real files.
- std::map<llvm::sys::fs::UniqueID, FileEntry> UniqueRealFiles;
-
- /// \brief 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.
- SmallVector<std::unique_ptr<FileEntry>, 4> VirtualFileEntries;
-
- /// \brief A cache that maps paths to directory entries (either real or
- /// virtual) we have looked up
- ///
- /// The actual Entries for real directories/files are
- /// owned by UniqueRealDirs/UniqueRealFiles above, while the Entries
- /// for virtual directories/files are owned by
- /// VirtualDirectoryEntries/VirtualFileEntries above.
- ///
- llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> SeenDirEntries;
-
- /// \brief 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.
- llvm::DenseMap<const DirectoryEntry *, llvm::StringRef> CanonicalDirNames;
-
- /// \brief Storage for canonical names that we have computed.
- llvm::BumpPtrAllocator CanonicalNameStorage;
-
- /// \brief Each FileEntry we create is assigned a unique ID #.
- ///
- unsigned NextFileUID;
-
- // Statistics.
- unsigned NumDirLookups, NumFileLookups;
- unsigned NumDirCacheMisses, NumFileCacheMisses;
-
- // Caching.
- std::unique_ptr<FileSystemStatCache> StatCache;
-
- bool getStatValue(const char *Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F);
-
- /// Add all ancestors of the given path (pointing to either a file
- /// or a directory) as virtual directories.
- void addAncestorsAsVirtualDirs(StringRef Path);
-
-public:
- FileManager(const FileSystemOptions &FileSystemOpts,
- IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
- ~FileManager();
-
- /// \brief Installs the provided FileSystemStatCache object within
- /// the FileManager.
- ///
- /// Ownership of this object is transferred to the FileManager.
- ///
- /// \param statCache the new stat cache to install. Ownership of this
- /// object is transferred to the FileManager.
- ///
- /// \param AtBeginning whether this new stat cache must be installed at the
- /// beginning of the chain of stat caches. Otherwise, it will be added to
- /// the end of the chain.
- void addStatCache(std::unique_ptr<FileSystemStatCache> statCache,
- bool AtBeginning = false);
-
- /// \brief Removes the specified FileSystemStatCache object from the manager.
- void removeStatCache(FileSystemStatCache *statCache);
-
- /// \brief Removes all FileSystemStatCache objects from the manager.
- void clearStatCaches();
-
- /// \brief Lookup, cache, and verify the specified directory (real or
- /// virtual).
- ///
- /// This returns NULL if the directory doesn't exist.
- ///
- /// \param CacheFailure If true and the file does not exist, we'll cache
- /// the failure to find this file.
- const DirectoryEntry *getDirectory(StringRef DirName,
- bool CacheFailure = true);
-
- /// \brief Lookup, cache, and verify the specified file (real or
- /// virtual).
- ///
- /// This returns NULL if the file doesn't exist.
- ///
- /// \param OpenFile if true and the file exists, it will be opened.
- ///
- /// \param CacheFailure If true and the file does not exist, we'll cache
- /// the failure to find this file.
- const FileEntry *getFile(StringRef Filename, bool OpenFile = false,
- bool CacheFailure = true);
-
- /// \brief Returns the current file system options
- FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
- const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
-
- IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystem() const {
- return FS;
- }
-
- /// \brief 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
- /// 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);
-
- /// \brief 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.
- ///
- /// \returns false on success, true on error.
- bool getNoncachedStatValue(StringRef Path,
- vfs::Status &Result);
-
- /// \brief 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
- /// directory, the path is modified to be relative to the given
- /// working directory.
- /// \returns true if \c path changed.
- bool FixupRelativePath(SmallVectorImpl<char> &path) const;
-
- /// Makes \c Path absolute taking into account FileSystemOptions and the
- /// working directory option.
- /// \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
- /// file to the corresponding FileEntry pointer.
- void GetUniqueIDMapping(
- SmallVectorImpl<const FileEntry *> &UIDToFiles) const;
-
- /// \brief 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.
- ///
- /// 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
- /// required, which is (almost) never.
- StringRef getCanonicalName(const DirectoryEntry *Dir);
-
- void PrintStats() const;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/FileSystemOptions.h b/include/clang/Basic/FileSystemOptions.h
deleted file mode 100644
index 38f1346..0000000
--- a/include/clang/Basic/FileSystemOptions.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===--- FileSystemOptions.h - File System Options --------------*- 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::FileSystemOptions interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_FILESYSTEMOPTIONS_H
-#define LLVM_CLANG_BASIC_FILESYSTEMOPTIONS_H
-
-#include <string>
-
-namespace clang {
-
-/// \brief 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
- /// set to the value of WorkingDir.
- std::string WorkingDir;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
deleted file mode 100644
index cad9189..0000000
--- a/include/clang/Basic/FileSystemStatCache.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//===--- FileSystemStatCache.h - Caching for 'stat' calls -------*- 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 FileSystemStatCache interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
-#define LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/FileSystem.h"
-#include <memory>
-
-namespace clang {
-
-namespace vfs {
-class File;
-class FileSystem;
-}
-
-// FIXME: should probably replace this with vfs::Status
-struct FileData {
- std::string Name;
- uint64_t Size;
- time_t ModTime;
- 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) {}
-};
-
-/// \brief 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() {}
-
- enum LookupResult {
- CacheExists, ///< We know the file exists and its cached stat data.
- CacheMissing ///< We know that the file doesn't exist.
- };
-
- /// \brief 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.
- ///
- /// If isFile is true, then this lookup should only return success for files
- /// (not directories). If it is false this lookup should only return
- /// success for directories (not files). On a successful file lookup, the
- /// implementation can optionally fill in \p F with a valid \p File object and
- /// the client guarantees that it will close it.
- static bool get(const char *Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
- vfs::FileSystem &FS);
-
- /// \brief 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.
- FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
-
- /// \brief 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() {
- return std::move(NextStatCache);
- }
-
-protected:
- // FIXME: The pointer here is a non-owning/optional reference to the
- // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
- // Optional needs some work to support references so this isn't possible yet.
- virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F,
- vfs::FileSystem &FS) = 0;
-
- LookupResult statChained(const char *Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
- if (FileSystemStatCache *Next = getNextStatCache())
- return Next->getStat(Path, Data, isFile, F, FS);
-
- // If we hit the end of the list of stat caches to try, just compute and
- // return it without a cache.
- return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
- }
-};
-
-/// \brief 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.
- llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
-
- typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator
- iterator;
-
- iterator begin() const { return StatCalls.begin(); }
- iterator end() const { return StatCalls.end(); }
-
- LookupResult getStat(const char *Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F,
- vfs::FileSystem &FS) override;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
deleted file mode 100644
index d672314..0000000
--- a/include/clang/Basic/IdentifierTable.h
+++ /dev/null
@@ -1,876 +0,0 @@
-//===--- IdentifierTable.h - Hash table for identifier lookup ---*- 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::IdentifierInfo, clang::IdentifierTable, and
-/// clang::Selector interfaces.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
-#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/TokenKinds.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <cassert>
-#include <string>
-
-namespace llvm {
- template <typename T> struct DenseMapInfo;
-}
-
-namespace clang {
- class LangOptions;
- class IdentifierInfo;
- class IdentifierTable;
- class SourceLocation;
- class MultiKeywordSelector; // private class used by Selector
- class DeclarationName; // AST class that stores declaration names
-
- /// \brief A simple pair of identifier info and location.
- typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
-
-
-/// One of these records is kept for each identifier that
-/// is lexed. This contains information about whether the token was \#define'd,
-/// is a language keyword, or if it is a front-end token of some sort (e.g. a
-/// variable or function name). The preprocessor keeps this information in a
-/// set, and all tok::identifier tokens have a pointer to one of these.
-class IdentifierInfo {
- unsigned TokenID : 9; // Front-end token ID or tok::identifier.
- // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
- // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
- // are for builtins.
- unsigned ObjCOrBuiltinID :13;
- bool HasMacro : 1; // True if there is a #define for this.
- bool HadMacro : 1; // True if there was a #define for this.
- bool IsExtension : 1; // True if identifier is a lang extension.
- bool IsFutureCompatKeyword : 1; // True if identifier is a keyword in a
- // newer Standard or proposed Standard.
- bool IsPoisoned : 1; // True if identifier is poisoned.
- bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
- bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier".
- bool IsFromAST : 1; // True if identifier was loaded (at least
- // partially) from an AST file.
- bool ChangedAfterLoad : 1; // True if identifier has changed from the
- // definition loaded from an AST file.
- bool RevertedTokenID : 1; // True if revertTokenIDToIdentifier was
- // called.
- bool OutOfDate : 1; // True if there may be additional
- // information about this identifier
- // stored externally.
- bool IsModulesImport : 1; // True if this is the 'import' contextual
- // keyword.
- // 30 bit left in 64-bit word.
-
- void *FETokenInfo; // Managed by the language front-end.
- llvm::StringMapEntry<IdentifierInfo*> *Entry;
-
- IdentifierInfo(const IdentifierInfo&) = delete;
- void operator=(const IdentifierInfo&) = delete;
-
- friend class IdentifierTable;
-
-public:
- IdentifierInfo();
-
-
- /// \brief 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>
- bool isStr(const char (&Str)[StrLen]) const {
- return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
- }
-
- /// \brief Return the beginning of the actual null-terminated string for this
- /// identifier.
- ///
- const char *getNameStart() const {
- if (Entry) return Entry->getKeyData();
- // FIXME: This is gross. It would be best not to embed specific details
- // of the PTH file format here.
- // The 'this' pointer really points to a
- // std::pair<IdentifierInfo, const char*>, where internal pointer
- // points to the external string data.
- typedef std::pair<IdentifierInfo, const char*> actualtype;
- return ((const actualtype*) this)->second;
- }
-
- /// \brief 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
- // of the PTH file format here.
- // The 'this' pointer really points to a
- // std::pair<IdentifierInfo, const char*>, where internal pointer
- // points to the external string data.
- typedef std::pair<IdentifierInfo, const char*> actualtype;
- const char* p = ((const actualtype*) this)->second - 2;
- return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
- }
-
- /// \brief Return the actual identifier string.
- StringRef getName() const {
- return StringRef(getNameStart(), getLength());
- }
-
- /// \brief 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;
- }
- void setHasMacroDefinition(bool Val) {
- if (HasMacro == Val) return;
-
- HasMacro = Val;
- if (Val) {
- NeedsHandleIdentifier = 1;
- HadMacro = true;
- } else {
- RecomputeNeedsHandleIdentifier();
- }
- }
- /// \brief 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 {
- return HadMacro;
- }
-
- /// If this is a source-language token (e.g. 'for'), this API
- /// can be used to cause the lexer to map identifiers to source-language
- /// tokens.
- tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
-
- /// \brief True if revertTokenIDToIdentifier() was called.
- bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; }
-
- /// \brief 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
- /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens
- /// using this method so we can inform serialization about it.
- void revertTokenIDToIdentifier() {
- assert(TokenID != tok::identifier && "Already at tok::identifier");
- TokenID = tok::identifier;
- RevertedTokenID = true;
- }
- void revertIdentifierToTokenID(tok::TokenKind TK) {
- assert(TokenID == tok::identifier && "Should be at tok::identifier");
- TokenID = TK;
- RevertedTokenID = false;
- }
-
- /// \brief 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.
- ///
- /// For example, 'class' will return tok::objc_class if ObjC is enabled.
- tok::ObjCKeywordKind getObjCKeywordID() const {
- if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
- return tok::ObjCKeywordKind(ObjCOrBuiltinID);
- else
- return tok::objc_not_keyword;
- }
- void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
-
- /// \brief 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
- /// 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.
- ///
- /// 0 is not-built-in. 1 is builtin-for-some-nonprimary-target.
- /// 2+ are specific builtin functions.
- unsigned getBuiltinID() const {
- if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
- return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
- else
- return 0;
- }
- void setBuiltinID(unsigned ID) {
- ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
- assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
- && "ID too large for field!");
- }
-
- unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
- void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; }
-
- /// get/setExtension - Initialize information about whether or not this
- /// language token is an extension. This controls extension warnings, and is
- /// only valid if a custom token ID is set.
- bool isExtensionToken() const { return IsExtension; }
- void setIsExtensionToken(bool Val) {
- IsExtension = Val;
- if (Val)
- NeedsHandleIdentifier = 1;
- else
- RecomputeNeedsHandleIdentifier();
- }
-
- /// is/setIsFutureCompatKeyword - Initialize information about whether or not
- /// this language token is a keyword in a newer or proposed Standard. This
- /// controls compatibility warnings, and is only true when not parsing the
- /// corresponding Standard. Once a compatibility problem has been diagnosed
- /// with this keyword, the flag will be cleared.
- bool isFutureCompatKeyword() const { return IsFutureCompatKeyword; }
- void setIsFutureCompatKeyword(bool Val) {
- IsFutureCompatKeyword = Val;
- if (Val)
- NeedsHandleIdentifier = 1;
- else
- RecomputeNeedsHandleIdentifier();
- }
-
- /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the
- /// Preprocessor will emit an error every time this token is used.
- void setIsPoisoned(bool Value = true) {
- IsPoisoned = Value;
- if (Value)
- NeedsHandleIdentifier = 1;
- else
- RecomputeNeedsHandleIdentifier();
- }
-
- /// \brief Return true if this token has been poisoned.
- bool isPoisoned() const { return IsPoisoned; }
-
- /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
- /// this identifier is a C++ alternate representation of an operator.
- void setIsCPlusPlusOperatorKeyword(bool Val = true) {
- IsCPPOperatorKeyword = Val;
- if (Val)
- NeedsHandleIdentifier = 1;
- else
- RecomputeNeedsHandleIdentifier();
- }
- bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
-
- /// \brief Return true if this token is a keyword in the specified language.
- bool isKeyword(const LangOptions &LangOpts);
-
- /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
- /// associate arbitrary metadata with this token.
- template<typename T>
- T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
- void setFETokenInfo(void *T) { FETokenInfo = T; }
-
- /// \brief 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
- /// from an AST file.
- bool isFromAST() const { return IsFromAST; }
-
- void setIsFromAST() { IsFromAST = true; }
-
- /// \brief 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
- /// an AST file.
- void setChangedSinceDeserialization() {
- ChangedAfterLoad = true;
- }
-
- /// \brief 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
- /// date with respect to the external source.
- void setOutOfDate(bool OOD) {
- OutOfDate = OOD;
- if (OOD)
- NeedsHandleIdentifier = true;
- else
- RecomputeNeedsHandleIdentifier();
- }
-
- /// \brief 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.
- void setModulesImport(bool I) {
- IsModulesImport = I;
- if (I)
- NeedsHandleIdentifier = true;
- else
- RecomputeNeedsHandleIdentifier();
- }
-
- /// \brief Provide less than operator for lexicographical sorting.
- bool operator<(const IdentifierInfo &RHS) const {
- return getName() < RHS.getName();
- }
-
-private:
- /// The Preprocessor::HandleIdentifier does several special (but rare)
- /// things to identifiers of various sorts. For example, it changes the
- /// \c for keyword token from tok::identifier to tok::for.
- ///
- /// This method is very tied to the definition of HandleIdentifier. Any
- /// change to it should be reflected here.
- void RecomputeNeedsHandleIdentifier() {
- NeedsHandleIdentifier =
- (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
- isExtensionToken() | isFutureCompatKeyword() || isOutOfDate() ||
- isModulesImport());
- }
-};
-
-/// \brief 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.
-class PoisonIdentifierRAIIObject {
- IdentifierInfo *const II;
- const bool OldValue;
-public:
- PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
- : II(II), OldValue(II ? II->isPoisoned() : false) {
- if(II)
- II->setIsPoisoned(NewValue);
- }
-
- ~PoisonIdentifierRAIIObject() {
- if(II)
- II->setIsPoisoned(OldValue);
- }
-};
-
-/// \brief An iterator that walks over all of the known identifiers
-/// in the lookup table.
-///
-/// Since this iterator uses an abstract interface via virtual
-/// functions, it uses an object-oriented interface rather than the
-/// more standard C++ STL iterator interface. In this OO-style
-/// iteration, the single function \c Next() provides dereference,
-/// advance, and end-of-sequence checking in a single
-/// operation. Subclasses of this iterator type will provide the
-/// actual functionality.
-class IdentifierIterator {
-private:
- IdentifierIterator(const IdentifierIterator &) = delete;
- void operator=(const IdentifierIterator &) = delete;
-
-protected:
- IdentifierIterator() { }
-
-public:
- virtual ~IdentifierIterator();
-
- /// \brief 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
- /// no such string, returns an empty \c StringRef.
- virtual StringRef Next() = 0;
-};
-
-/// \brief Provides lookups to, and iteration over, IdentiferInfo objects.
-class IdentifierInfoLookup {
-public:
- virtual ~IdentifierInfoLookup();
-
- /// \brief 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
- /// known to this identifier lookup source.
- ///
- /// This routine provides access to all of the identifiers known to
- /// the identifier lookup, allowing access to the contents of the
- /// identifiers without introducing the overhead of constructing
- /// IdentifierInfo objects for each.
- ///
- /// \returns A new iterator into the set of known identifiers. The
- /// caller is responsible for deleting this iterator.
- virtual IdentifierIterator *getIdentifiers();
-};
-
-/// \brief 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
-/// here when lexed.
-class IdentifierTable {
- // Shark shows that using MallocAllocator is *much* slower than using this
- // BumpPtrAllocator!
- typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
- HashTableTy HashTable;
-
- IdentifierInfoLookup* ExternalLookup;
-
-public:
- /// \brief 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);
-
- /// \brief Set the external identifier lookup mechanism.
- void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
- ExternalLookup = IILookup;
- }
-
- /// \brief Retrieve the external identifier lookup object, if any.
- IdentifierInfoLookup *getExternalIdentifierLookup() const {
- return ExternalLookup;
- }
-
- llvm::BumpPtrAllocator& getAllocator() {
- return HashTable.getAllocator();
- }
-
- /// \brief Return the identifier token info for the specified named
- /// identifier.
- IdentifierInfo &get(StringRef Name) {
- auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
-
- IdentifierInfo *&II = Entry.second;
- if (II) return *II;
-
- // No entry; if we have an external lookup, look there first.
- if (ExternalLookup) {
- II = ExternalLookup->get(Name);
- if (II)
- return *II;
- }
-
- // Lookups failed, make a new IdentifierInfo.
- void *Mem = getAllocator().Allocate<IdentifierInfo>();
- II = new (Mem) IdentifierInfo();
-
- // Make sure getName() knows how to find the IdentifierInfo
- // contents.
- II->Entry = &Entry;
-
- return *II;
- }
-
- IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) {
- IdentifierInfo &II = get(Name);
- II.TokenID = TokenCode;
- assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large");
- return II;
- }
-
- /// \brief Gets an IdentifierInfo for the given name without consulting
- /// external sources.
- ///
- /// This is a version of get() meant for external sources that want to
- /// introduce or modify an identifier. If they called get(), they would
- /// likely end up in a recursion.
- IdentifierInfo &getOwn(StringRef Name) {
- auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
-
- IdentifierInfo *&II = Entry.second;
- if (II)
- return *II;
-
- // Lookups failed, make a new IdentifierInfo.
- void *Mem = getAllocator().Allocate<IdentifierInfo>();
- II = new (Mem) IdentifierInfo();
-
- // Make sure getName() knows how to find the IdentifierInfo
- // contents.
- II->Entry = &Entry;
-
- // If this is the 'import' contextual keyword, mark it as such.
- if (Name.equals("import"))
- II->setModulesImport(true);
-
- return *II;
- }
-
- typedef HashTableTy::const_iterator iterator;
- typedef HashTableTy::const_iterator const_iterator;
-
- iterator begin() const { return HashTable.begin(); }
- iterator end() const { return HashTable.end(); }
- unsigned size() const { return HashTable.size(); }
-
- /// \brief Print some statistics to stderr that indicate how well the
- /// hashing is doing.
- void PrintStats() const;
-
- void AddKeywords(const LangOptions &LangOpts);
-};
-
-/// \brief 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
-/// merit direct AST support. While, in theory, arbitrary methods can
-/// be considered to form families, we focus here on the methods
-/// involving allocation and retain-count management, as these are the
-/// most "core" and the most likely to be useful to diverse clients
-/// without extra information.
-///
-/// Both selectors and actual method declarations may be classified
-/// into families. Method families may impose additional restrictions
-/// beyond their selector name; for example, a method called '_init'
-/// that returns void is not considered to be in the 'init' family
-/// (but would be if it returned 'id'). It is also possible to
-/// 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.
- OMF_None,
-
- // Selectors in these families may have arbitrary arity, may be
- // written with arbitrary leading underscores, and may have
- // additional CamelCase "words" in their first selector chunk
- // following the family name.
- OMF_alloc,
- OMF_copy,
- OMF_init,
- OMF_mutableCopy,
- OMF_new,
-
- // These families are singletons consisting only of the nullary
- // selector with the given name.
- OMF_autorelease,
- OMF_dealloc,
- OMF_finalize,
- OMF_release,
- OMF_retain,
- OMF_retainCount,
- OMF_self,
- OMF_initialize,
-
- // performSelector families
- OMF_performSelector
-};
-
-/// Enough bits to store any enumerator in ObjCMethodFamily or
-/// InvalidObjCMethodFamily.
-enum { ObjCMethodFamilyBitWidth = 4 };
-
-/// \brief An invalid value of ObjCMethodFamily.
-enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 };
-
-/// \brief 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'.
-enum ObjCInstanceTypeFamily {
- OIT_None,
- OIT_Array,
- OIT_Dictionary,
- OIT_Singleton,
- OIT_Init,
- OIT_ReturnsSelf
-};
-
-enum ObjCStringFormatFamily {
- SFF_None,
- SFF_NSString,
- SFF_CFString
-};
-
-/// \brief Smart pointer class that efficiently represents Objective-C method
-/// names.
-///
-/// This class will either point to an IdentifierInfo or a
-/// MultiKeywordSelector (which is private). This enables us to optimize
-/// selectors that take no arguments and selectors that take 1 argument, which
-/// accounts for 78% of all selectors in Cocoa.h.
-class Selector {
- friend class Diagnostic;
-
- enum IdentifierInfoFlag {
- // Empty selector = 0.
- ZeroArg = 0x1,
- OneArg = 0x2,
- MultiArg = 0x3,
- ArgFlags = ZeroArg|OneArg
- };
- uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
-
- Selector(IdentifierInfo *II, unsigned nArgs) {
- InfoPtr = reinterpret_cast<uintptr_t>(II);
- assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
- assert(nArgs < 2 && "nArgs not equal to 0/1");
- InfoPtr |= nArgs+1;
- }
- Selector(MultiKeywordSelector *SI) {
- InfoPtr = reinterpret_cast<uintptr_t>(SI);
- assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
- InfoPtr |= MultiArg;
- }
-
- IdentifierInfo *getAsIdentifierInfo() const {
- if (getIdentifierInfoFlag() < MultiArg)
- return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
- return nullptr;
- }
- MultiKeywordSelector *getMultiKeywordSelector() const {
- return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
- }
-
- unsigned getIdentifierInfoFlag() const {
- return InfoPtr & ArgFlags;
- }
-
- static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
-
- static ObjCStringFormatFamily getStringFormatFamilyImpl(Selector sel);
-
-public:
- friend class SelectorTable; // only the SelectorTable can create these
- friend class DeclarationName; // and the AST's DeclarationName.
-
- /// The default ctor should only be used when creating data structures that
- /// will contain selectors.
- Selector() : InfoPtr(0) {}
- Selector(uintptr_t V) : InfoPtr(V) {}
-
- /// operator==/!= - Indicate whether the specified selectors are identical.
- bool operator==(Selector RHS) const {
- return InfoPtr == RHS.InfoPtr;
- }
- bool operator!=(Selector RHS) const {
- return InfoPtr != RHS.InfoPtr;
- }
- void *getAsOpaquePtr() const {
- return reinterpret_cast<void*>(InfoPtr);
- }
-
- /// \brief Determine whether this is the empty selector.
- bool isNull() const { return InfoPtr == 0; }
-
- // Predicates to identify the selector type.
- bool isKeywordSelector() const {
- return getIdentifierInfoFlag() != ZeroArg;
- }
- bool isUnarySelector() const {
- return getIdentifierInfoFlag() == ZeroArg;
- }
- unsigned getNumArgs() const;
-
-
- /// \brief 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,
- /// uniqued identifier pointer, should use \c getNameForSlot(), which returns
- /// an empty string when the identifier pointer would be NULL.
- ///
- /// \param argIndex The index for which we want to retrieve the identifier.
- /// This index shall be less than \c getNumArgs() unless this is a keyword
- /// selector, in which case 0 is the only permissible value.
- ///
- /// \returns the uniqued identifier for this slot, or NULL if this slot has
- /// no corresponding identifier.
- IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
-
- /// \brief 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
- /// selector, in which case 0 is the only permissible value.
- ///
- /// \returns the name for this slot, which may be the empty string if no
- /// name was supplied.
- StringRef getNameForSlot(unsigned argIndex) const;
-
- /// \brief 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:").
- void print(llvm::raw_ostream &OS) const;
-
- /// \brief Derive the conventional family of this method.
- ObjCMethodFamily getMethodFamily() const {
- return getMethodFamilyImpl(*this);
- }
-
- ObjCStringFormatFamily getStringFormatFamily() const {
- return getStringFormatFamilyImpl(*this);
- }
-
- static Selector getEmptyMarker() {
- return Selector(uintptr_t(-1));
- }
- static Selector getTombstoneMarker() {
- return Selector(uintptr_t(-2));
- }
-
- static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel);
-};
-
-/// \brief This table allows us to fully hide how we implement
-/// multi-keyword caching.
-class SelectorTable {
- void *Impl; // Actually a SelectorTableImpl
- SelectorTable(const SelectorTable &) = delete;
- void operator=(const SelectorTable &) = delete;
-public:
- SelectorTable();
- ~SelectorTable();
-
- /// \brief 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:".
- Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
-
- Selector getUnarySelector(IdentifierInfo *ID) {
- return Selector(ID, 1);
- }
- Selector getNullarySelector(IdentifierInfo *ID) {
- return Selector(ID, 0);
- }
-
- /// \brief Return the total amount of memory allocated for managing selectors.
- size_t getTotalMemory() const;
-
- /// \brief 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.
- ///
- /// 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);
-};
-
-/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
-/// CXXSpecialName, and CXXOperatorIdName classes, all of which are
-/// private classes that describe different kinds of names.
-class DeclarationNameExtra {
-public:
- /// ExtraKind - The kind of "extra" information stored in the
- /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
- /// how these enumerator values are used.
- enum ExtraKind {
- CXXConstructor = 0,
- CXXDestructor,
- CXXConversionFunction,
-#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
- CXXOperator##Name,
-#include "clang/Basic/OperatorKinds.def"
- CXXLiteralOperator,
- CXXUsingDirective,
- NUM_EXTRA_KINDS
- };
-
- /// ExtraKindOrNumArgs - Either the kind of C++ special name or
- /// operator-id (if the value is one of the CXX* enumerators of
- /// ExtraKind), in which case the DeclarationNameExtra is also a
- /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
- /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
- /// it may be also name common to C++ using-directives (CXXUsingDirective),
- /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
- /// arguments in the Objective-C selector, in which case the
- /// DeclarationNameExtra is also a MultiKeywordSelector.
- unsigned ExtraKindOrNumArgs;
-};
-
-} // end namespace clang
-
-namespace llvm {
-/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
-/// DenseSets.
-template <>
-struct DenseMapInfo<clang::Selector> {
- static inline clang::Selector getEmptyKey() {
- return clang::Selector::getEmptyMarker();
- }
- static inline clang::Selector getTombstoneKey() {
- return clang::Selector::getTombstoneMarker();
- }
-
- static unsigned getHashValue(clang::Selector S);
-
- static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
- return LHS == RHS;
- }
-};
-
-template <>
-struct isPodLike<clang::Selector> { static const bool value = true; };
-
-template <typename T> class PointerLikeTypeTraits;
-
-template<>
-class PointerLikeTypeTraits<clang::Selector> {
-public:
- static inline const void *getAsVoidPointer(clang::Selector P) {
- return P.getAsOpaquePtr();
- }
- static inline clang::Selector getFromVoidPointer(const void *P) {
- return clang::Selector(reinterpret_cast<uintptr_t>(P));
- }
- enum { NumLowBitsAvailable = 0 };
-};
-
-// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
-// are not guaranteed to be 8-byte aligned.
-template<>
-class PointerLikeTypeTraits<clang::IdentifierInfo*> {
-public:
- static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
- return P;
- }
- static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
- return static_cast<clang::IdentifierInfo*>(P);
- }
- enum { NumLowBitsAvailable = 1 };
-};
-
-template<>
-class PointerLikeTypeTraits<const clang::IdentifierInfo*> {
-public:
- static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
- return P;
- }
- static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
- return static_cast<const clang::IdentifierInfo*>(P);
- }
- enum { NumLowBitsAvailable = 1 };
-};
-
-} // end namespace llvm
-#endif
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
deleted file mode 100644
index 0e6ff92..0000000
--- a/include/clang/Basic/LLVM.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// \brief Forward-declares and imports various common LLVM datatypes that
-/// clang wants to use unqualified.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_LLVM_H
-#define LLVM_CLANG_BASIC_LLVM_H
-
-// Do not proliferate #includes here, require clients to #include their
-// dependencies.
-// Casting.h has complex templates that cannot be easily forward declared.
-#include "llvm/Support/Casting.h"
-// None.h includes an enumerator that is desired & cannot be forward declared
-// without a definition of NoneType.
-#include "llvm/ADT/None.h"
-
-namespace llvm {
- // ADT's.
- class StringRef;
- class Twine;
- template<typename T> class ArrayRef;
- template<typename T> class MutableArrayRef;
- template<unsigned InternalLen> class SmallString;
- template<typename T, unsigned N> class SmallVector;
- template<typename T> class SmallVectorImpl;
- template<typename T> class Optional;
-
- template<typename T>
- struct SaveAndRestore;
-
- // Reference counting.
- template <typename T> class IntrusiveRefCntPtr;
- template <typename T> struct IntrusiveRefCntPtrInfo;
- template <class Derived> class RefCountedBase;
- class RefCountedBaseVPTR;
-
- class raw_ostream;
- class raw_pwrite_stream;
- // TODO: DenseMap, ...
-}
-
-
-namespace clang {
- // Casting operators.
- using llvm::isa;
- using llvm::cast;
- using llvm::dyn_cast;
- using llvm::dyn_cast_or_null;
- 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::SmallString;
- using llvm::SmallVector;
- using llvm::SmallVectorImpl;
- using llvm::SaveAndRestore;
-
- // Reference counting.
- using llvm::IntrusiveRefCntPtr;
- using llvm::IntrusiveRefCntPtrInfo;
- using llvm::RefCountedBase;
- using llvm::RefCountedBaseVPTR;
-
- using llvm::raw_ostream;
- using llvm::raw_pwrite_stream;
-} // end namespace clang.
-
-#endif
diff --git a/include/clang/Basic/Lambda.h b/include/clang/Basic/Lambda.h
deleted file mode 100644
index e676e72..0000000
--- a/include/clang/Basic/Lambda.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===--- Lambda.h - Types for C++ Lambdas -----------------------*- 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 several types used to describe C++ lambda expressions
-/// that are shared between the parser and AST.
-///
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_BASIC_LAMBDA_H
-#define LLVM_CLANG_BASIC_LAMBDA_H
-
-namespace clang {
-
-/// \brief 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
-///
-/// 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
-/// is an expression.
-enum LambdaCaptureKind {
- LCK_This, ///< Capturing the \c this pointer
- LCK_ByCopy, ///< Capturing by copy (a.k.a., by value)
- LCK_ByRef, ///< Capturing by reference
- LCK_VLAType ///< Capturing variable-length array type
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_BASIC_LAMBDA_H
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
deleted file mode 100644
index cc70d62..0000000
--- a/include/clang/Basic/LangOptions.def
+++ /dev/null
@@ -1,246 +0,0 @@
-//===--- LangOptions.def - Language option 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 the language options. Users of this file must
-// define the LANGOPT macro to make use of this information.
-//
-// Optionally, the user may also define:
-//
-// BENIGN_LANGOPT: for options that don't affect the construction of the AST in
-// any way (that is, the value can be different between an implicit module
-// and the user of that module).
-//
-// COMPATIBLE_LANGOPT: for options that affect the construction of the AST in
-// a way that doesn't prevent interoperability (that is, the value can be
-// different between an explicit module and the user of that module).
-//
-// ENUM_LANGOPT: for options that have enumeration, rather than unsigned, type.
-//
-// VALUE_LANGOPT: for options that describe a value rather than a flag.
-//
-// BENIGN_ENUM_LANGOPT, COMPATIBLE_ENUM_LANGOPT: combinations of the above.
-//
-// FIXME: Clients should be able to more easily select whether they want
-// different levels of compatibility versus how to handle different kinds
-// of option.
-//===----------------------------------------------------------------------===//
-
-#ifndef LANGOPT
-# error Define the LANGOPT macro to handle language options
-#endif
-
-#ifndef COMPATIBLE_LANGOPT
-# define COMPATIBLE_LANGOPT(Name, Bits, Default, Description) \
- LANGOPT(Name, Bits, Default, Description)
-#endif
-
-#ifndef BENIGN_LANGOPT
-# define BENIGN_LANGOPT(Name, Bits, Default, Description) \
- COMPATIBLE_LANGOPT(Name, Bits, Default, Description)
-#endif
-
-#ifndef ENUM_LANGOPT
-# define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- LANGOPT(Name, Bits, Default, Description)
-#endif
-
-#ifndef COMPATIBLE_ENUM_LANGOPT
-# define COMPATIBLE_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- ENUM_LANGOPT(Name, Type, Bits, Default, Description)
-#endif
-
-#ifndef BENIGN_ENUM_LANGOPT
-# define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- COMPATIBLE_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
-#endif
-
-#ifndef VALUE_LANGOPT
-# define VALUE_LANGOPT(Name, Bits, Default, Description) \
- LANGOPT(Name, Bits, Default, Description)
-#endif
-
-// FIXME: A lot of the BENIGN_ options should be COMPATIBLE_ instead.
-LANGOPT(C99 , 1, 0, "C99")
-LANGOPT(C11 , 1, 0, "C11")
-LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
-LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions")
-LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
-LANGOPT(Borland , 1, 0, "Borland extensions")
-LANGOPT(CPlusPlus , 1, 0, "C++")
-LANGOPT(CPlusPlus11 , 1, 0, "C++11")
-LANGOPT(CPlusPlus14 , 1, 0, "C++14")
-LANGOPT(CPlusPlus1z , 1, 0, "C++1z")
-LANGOPT(ObjC1 , 1, 0, "Objective-C 1")
-LANGOPT(ObjC2 , 1, 0, "Objective-C 2")
-BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
- "Objective-C auto-synthesized properties")
-BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0,
- "Encoding extended block type signature")
-BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1,
- "Objective-C related result type inference")
-LANGOPT(AppExt , 1, 0, "Objective-C App Extension")
-LANGOPT(Trigraphs , 1, 0,"trigraphs")
-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(DeclSpecKeyword , 1, 0, "__declspec keyword")
-BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers")
-BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
-BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions")
-LANGOPT(GNUKeywords , 1, 1, "GNU keywords")
-BENIGN_LANGOPT(ImplicitInt, 1, !C99 && !CPlusPlus, "C89 implicit 'int'")
-LANGOPT(Digraphs , 1, 0, "digraphs")
-BENIGN_LANGOPT(HexFloats , 1, C99, "C99 hexadecimal float constants")
-LANGOPT(CXXOperatorNames , 1, 0, "C++ operator name keywords")
-LANGOPT(AppleKext , 1, 0, "Apple kext support")
-BENIGN_LANGOPT(PascalStrings, 1, 0, "Pascal string support")
-LANGOPT(WritableStrings , 1, 0, "writable string support")
-LANGOPT(ConstStrings , 1, 0, "const-qualified string support")
-LANGOPT(LaxVectorConversions , 1, 1, "lax vector conversions")
-LANGOPT(AltiVec , 1, 0, "AltiVec-style vector initializers")
-LANGOPT(ZVector , 1, 0, "System z vector extensions")
-LANGOPT(Exceptions , 1, 0, "exception handling")
-LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions")
-LANGOPT(CXXExceptions , 1, 0, "C++ exceptions")
-LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling")
-LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation")
-LANGOPT(RTTI , 1, 1, "run-time type information")
-LANGOPT(RTTIData , 1, 1, "emit run-time type information data")
-LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout")
-LANGOPT(Freestanding, 1, 0, "freestanding implementation")
-LANGOPT(NoBuiltin , 1, 0, "disable builtin functions")
-LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
-LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
-LANGOPT(Coroutines , 1, 0, "C++ coroutines")
-
-BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers")
-LANGOPT(POSIXThreads , 1, 0, "POSIX thread support")
-LANGOPT(Blocks , 1, 0, "blocks extension to C")
-BENIGN_LANGOPT(EmitAllDecls , 1, 0, "support for emitting all declarations")
-LANGOPT(MathErrno , 1, 1, "errno support for math functions")
-BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time")
-LANGOPT(Modules , 1, 0, "modules extension to C")
-COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
-LANGOPT(ModulesSearchAll , 1, 1, "search even non-imported modules to find unresolved references")
-COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules")
-BENIGN_LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery")
-BENIGN_LANGOPT(ImplicitModules, 1, 1, "build modules that are not specified via -fmodule-file")
-COMPATIBLE_LANGOPT(ModulesLocalVisibility, 1, 0, "local submodule visibility")
-COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro")
-COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
-LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
-VALUE_LANGOPT(PackStruct , 32, 0,
- "default struct packing maximum alignment")
-VALUE_LANGOPT(MaxTypeAlign , 32, 0,
- "default maximum alignment for types")
-VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
-VALUE_LANGOPT(PIELevel , 2, 0, "__PIE__ level")
-LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
-COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
-COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
-LANGOPT(FastMath , 1, 0, "__FAST_MATH__ predefined macro")
-LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
-LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math")
-
-BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
-
-BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control")
-LANGOPT(CharIsSigned , 1, 1, "signed char")
-LANGOPT(ShortWChar , 1, 0, "unsigned short wchar_t")
-ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method")
-
-LANGOPT(ShortEnums , 1, 0, "short enum types")
-
-LANGOPT(OpenCL , 1, 0, "OpenCL")
-LANGOPT(OpenCLVersion , 32, 0, "OpenCL version")
-LANGOPT(NativeHalfType , 1, 0, "Native half type support")
-LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns")
-LANGOPT(CUDA , 1, 0, "CUDA")
-LANGOPT(OpenMP , 1, 0, "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(CUDAIsDevice , 1, 0, "Compiling for CUDA device")
-LANGOPT(CUDAAllowHostCallsFromHostDevice, 1, 0, "Allow host device functions to call host functions")
-LANGOPT(CUDADisableTargetCallChecks, 1, 0, "Disable checks for call targets (host, device, etc.)")
-LANGOPT(CUDATargetOverloads, 1, 0, "Enable function overloads based on CUDA target attributes")
-
-LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators")
-LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions")
-LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts")
-BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
-BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
-BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")
-BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables")
-LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings")
-BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden default visibility for inline C++ methods")
-BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
-BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
-BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
-BENIGN_LANGOPT(DebuggerObjCLiteral , 1, 0, "debugger Objective-C literals and subscripting support")
-
-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")
-LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT")
-LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
-LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
-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(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map")
-ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode")
-
-LANGOPT(MRTD , 1, 0, "-mrtd calling convention")
-BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing")
-LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime")
-
-ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode")
-ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility,
- "value symbol visibility")
-ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
- "type symbol visibility")
-ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
- "stack protector mode")
-ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
- "signed integer overflow handling")
-
-BENIGN_LANGOPT(ArrowDepth, 32, 256,
- "maximum number of operator->s to follow")
-BENIGN_LANGOPT(InstantiationDepth, 32, 256,
- "maximum template instantiation depth")
-BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
- "maximum constexpr call depth")
-BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576,
- "maximum constexpr evaluation steps")
-BENIGN_LANGOPT(BracketDepth, 32, 256,
- "maximum bracket nesting depth")
-BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
- "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
-VALUE_LANGOPT(MSCompatibilityVersion, 32, 0, "Microsoft Visual C/C++ Version")
-VALUE_LANGOPT(VtorDispMode, 2, 1, "How many vtordisps to insert")
-
-LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
-
-LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
-
-LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
- "field padding (0: none, 1:least "
- "aggressive, 2: more aggressive)")
-
-#undef LANGOPT
-#undef COMPATIBLE_LANGOPT
-#undef BENIGN_LANGOPT
-#undef ENUM_LANGOPT
-#undef COMPATIBLE_ENUM_LANGOPT
-#undef BENIGN_ENUM_LANGOPT
-#undef VALUE_LANGOPT
-
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
deleted file mode 100644
index 736d4e0..0000000
--- a/include/clang/Basic/LangOptions.h
+++ /dev/null
@@ -1,190 +0,0 @@
-//===--- LangOptions.h - C Language Family Language Options -----*- 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::LangOptions interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H
-#define LLVM_CLANG_BASIC_LANGOPTIONS_H
-
-#include "clang/Basic/CommentOptions.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/ObjCRuntime.h"
-#include "clang/Basic/Sanitizers.h"
-#include "clang/Basic/Visibility.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-
-/// Bitfields of LangOptions, split out from LangOptions in order to ensure that
-/// this large collection of bitfields is a trivial class type.
-class LangOptionsBase {
-public:
- // Define simple language options (with no accessors).
-#define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits;
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
-#include "clang/Basic/LangOptions.def"
-
-protected:
- // Define language options of enumeration type. These are private, and will
- // have accessors (below).
-#define LANGOPT(Name, Bits, Default, Description)
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- unsigned Name : Bits;
-#include "clang/Basic/LangOptions.def"
-};
-
-/// \brief 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;
-
- 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
- };
-
- enum PragmaMSPointersToMembersKind {
- PPTMK_BestCase,
- PPTMK_FullGeneralitySingleInheritance,
- PPTMK_FullGeneralityMultipleInheritance,
- PPTMK_FullGeneralityVirtualInheritance
- };
-
- enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
-
- enum MSVCMajorVersion {
- MSVC2010 = 16,
- MSVC2012 = 17,
- MSVC2013 = 18,
- MSVC2015 = 19
- };
-
-public:
- /// \brief Set of enabled sanitizers.
- SanitizerSet Sanitize;
-
- /// \brief Paths to blacklist files specifying which objects
- /// (files, functions, variables) should not be instrumented.
- std::vector<std::string> SanitizerBlacklistFiles;
-
- clang::ObjCRuntime ObjCRuntime;
-
- std::string ObjCConstantStringClass;
-
- /// \brief 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.
- std::string CurrentModule;
-
- /// \brief The name of the module that the translation unit is an
- /// implementation of. Prevents semantic imports, but does not otherwise
- /// treat this as the CurrentModule.
- std::string ImplementationOfModule;
-
- /// \brief 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.
- CommentOptions CommentOpts;
-
- /// \brief 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
- /// 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
- /// host code generation.
- std::string OMPHostIRFile;
-
- LangOptions();
-
- // Define accessors/mutators for language options of enumeration type.
-#define LANGOPT(Name, Bits, Default, Description)
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- Type get##Name() const { return static_cast<Type>(Name); } \
- void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
-#include "clang/Basic/LangOptions.def"
-
- bool isSignedOverflowDefined() const {
- return getSignedOverflowBehavior() == SOB_Defined;
- }
-
- bool isSubscriptPointerArithmetic() const {
- return ObjCRuntime.isSubscriptPointerArithmetic() &&
- !ObjCSubscriptingLegacyRuntime;
- }
-
- bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
- return MSCompatibilityVersion >= MajorVersion * 10000000U;
- }
-
- /// \brief 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
- /// builtin because a -fno-builtin-* option has been specified?
- bool isNoBuiltinFunc(const char *Name) const;
-};
-
-/// \brief Floating point control options
-class FPOptions {
-public:
- unsigned fp_contract : 1;
-
- FPOptions() : fp_contract(0) {}
-
- FPOptions(const LangOptions &LangOpts) :
- fp_contract(LangOpts.DefaultFPContract) {}
-};
-
-/// \brief OpenCL volatile options
-class OpenCLOptions {
-public:
-#define OPENCLEXT(nm) unsigned nm : 1;
-#include "clang/Basic/OpenCLExtensions.def"
-
- OpenCLOptions() {
-#define OPENCLEXT(nm) nm = 0;
-#include "clang/Basic/OpenCLExtensions.def"
- }
-};
-
-/// \brief Describes the kind of translation unit being processed.
-enum TranslationUnitKind {
- /// \brief The translation unit is a complete translation unit.
- TU_Complete,
- /// \brief The translation unit is a prefix to a translation unit, and is
- /// not complete.
- TU_Prefix,
- /// \brief The translation unit is a module.
- TU_Module
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
deleted file mode 100644
index 8b15c8e..0000000
--- a/include/clang/Basic/Linkage.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===--- Linkage.h - Linkage enumeration and utilities ----------*- 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 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
-/// (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
- /// can only be referred to from within its scope.
- NoLinkage = 0,
-
- /// \brief 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.
- ///
- /// From the language perspective, these entities have external
- /// linkage. However, since they reside in an anonymous namespace,
- /// their names are unique to this translation unit, which is
- /// equivalent to having internal linkage from the code-generation
- /// point of view.
- UniqueExternalLinkage,
-
- /// \brief No linkage according to the standard, but is visible from other
- /// translation units because of types defined in a inline function.
- VisibleNoLinkage,
-
- /// \brief External linkage, which indicates that the entity can
- /// be referred to from other translation units.
- ExternalLinkage
-};
-
-/// \brief Describes the different kinds of language linkage
-/// (C++ [dcl.link]) that an entity may have.
-enum LanguageLinkage {
- CLanguageLinkage,
- CXXLanguageLinkage,
- NoLanguageLinkage
-};
-
-/// \brief A more specific kind of linkage than enum Linkage.
-///
-/// This is relevant to CodeGen and AST file reading.
-enum GVALinkage {
- GVA_Internal,
- GVA_AvailableExternally,
- GVA_DiscardableODR,
- GVA_StrongExternal,
- GVA_StrongODR
-};
-
-inline bool isExternallyVisible(Linkage L) {
- return L == ExternalLinkage || L == VisibleNoLinkage;
-}
-
-inline Linkage getFormalLinkage(Linkage L) {
- if (L == UniqueExternalLinkage)
- return ExternalLinkage;
- if (L == VisibleNoLinkage)
- return NoLinkage;
- return L;
-}
-
-inline bool isExternalFormalLinkage(Linkage L) {
- return getFormalLinkage(L) == ExternalLinkage;
-}
-
-/// \brief 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
-/// isExternallyVisible return. We want the minimum of both components. The
-/// Linkage enum is defined in an order that makes this simple, we just need
-/// special cases for when VisibleNoLinkage would lose the visible bit and
-/// become NoLinkage.
-inline Linkage minLinkage(Linkage L1, Linkage L2) {
- if (L2 == VisibleNoLinkage)
- std::swap(L1, L2);
- if (L1 == VisibleNoLinkage) {
- if (L2 == InternalLinkage)
- return NoLinkage;
- if (L2 == UniqueExternalLinkage)
- return NoLinkage;
- }
- return L1 < L2 ? L1 : L2;
-}
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_BASIC_LINKAGE_H
diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h
deleted file mode 100644
index 9a9eaa2..0000000
--- a/include/clang/Basic/MacroBuilder.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===--- MacroBuilder.h - CPP Macro building utility ------------*- 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::MacroBuilder utility class.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_MACROBUILDER_H
-#define LLVM_CLANG_BASIC_MACROBUILDER_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-
-class MacroBuilder {
- raw_ostream &Out;
-public:
- MacroBuilder(raw_ostream &Output) : Out(Output) {}
-
- /// Append a \#define line for macro of the form "\#define Name Value\n".
- void defineMacro(const Twine &Name, const Twine &Value = "1") {
- Out << "#define " << Name << ' ' << Value << '\n';
- }
-
- /// Append a \#undef line for Name. Name should be of the form XXX
- /// and we emit "\#undef XXX".
- void undefineMacro(const Twine &Name) {
- Out << "#undef " << Name << '\n';
- }
-
- /// Directly append Str and a newline to the underlying buffer.
- void append(const Twine &Str) {
- Out << Str << '\n';
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
deleted file mode 100644
index 5579a99..0000000
--- a/include/clang/Basic/Makefile
+++ /dev/null
@@ -1,70 +0,0 @@
-CLANG_LEVEL := ../../..
-BUILT_SOURCES = \
- DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \
- DiagnosticCommentKinds.inc \
- DiagnosticCommonKinds.inc DiagnosticDriverKinds.inc \
- DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
- DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
- DiagnosticSerializationKinds.inc \
- AttrHasAttributeImpl.inc \
- DiagnosticIndexName.inc DiagnosticGroups.inc AttrList.inc arm_neon.inc \
- Version.inc
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td)
-
-# Compute the Clang version from the LLVM version, unless specified explicitly.
-ifndef CLANG_VERSION
-CLANG_VERSION := $(subst svn,,$(LLVMVersion))
-CLANG_VERSION := $(subst rc,,$(CLANG_VERSION))
-endif
-
-CLANG_VERSION_COMPONENTS := $(subst ., ,$(CLANG_VERSION))
-CLANG_VERSION_MAJOR := $(word 1,$(CLANG_VERSION_COMPONENTS))
-CLANG_VERSION_MINOR := $(word 2,$(CLANG_VERSION_COMPONENTS))
-CLANG_VERSION_PATCHLEVEL := $(word 3,$(CLANG_VERSION_COMPONENTS))
-ifeq ($(CLANG_VERSION_PATCHLEVEL),)
-CLANG_HAS_VERSION_PATCHLEVEL := 0
-else
-CLANG_HAS_VERSION_PATCHLEVEL := 1
-endif
-
-$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/DiagnosticIndexName.inc.tmp : Diagnostic.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang diagnostic name index with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-diags-index-name -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang diagnostic groups with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/AttrList.inc.tmp : Attr.td $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang attribute list with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../.. $<
-
-$(ObjDir)/AttrHasAttributeImpl.inc.tmp : Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang __has_attribute implementation with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-has-attribute-impl -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang arm_neon.inc with tblgen"
- $(Verb) $(ClangTableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../.. $<
-
-$(ObjDir)/Version.inc.tmp : Version.inc.in Makefile $(LLVM_OBJ_ROOT)/Makefile.config $(ObjDir)/.dir
- $(Echo) "Updating Clang version info."
- $(Verb)sed -e "s#@CLANG_VERSION@#$(CLANG_VERSION)#g" \
- -e "s#@CLANG_VERSION_MAJOR@#$(CLANG_VERSION_MAJOR)#g" \
- -e "s#@CLANG_VERSION_MINOR@#$(CLANG_VERSION_MINOR)#g" \
- -e "s#@CLANG_VERSION_PATCHLEVEL@#$(CLANG_VERSION_PATCHLEVEL)#g" \
- -e "s#@CLANG_HAS_VERSION_PATCHLEVEL@#$(CLANG_HAS_VERSION_PATCHLEVEL)#g" \
- $< > $@
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
deleted file mode 100644
index 1702fb1..0000000
--- a/include/clang/Basic/Module.h
+++ /dev/null
@@ -1,569 +0,0 @@
-//===--- Module.h - Describe a module ---------------------------*- 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::Module class, which describes a module in the
-/// source code.
-///
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_MODULE_H
-#define LLVM_CLANG_BASIC_MODULE_H
-
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace llvm {
- class raw_ostream;
-}
-
-namespace clang {
-
-class LangOptions;
-class TargetInfo;
-class IdentifierInfo;
-
-/// \brief Describes the name of a module.
-typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
-
-/// \brief Describes a module or submodule.
-class Module {
-public:
- /// \brief The name of this module.
- std::string Name;
-
- /// \brief The location of the module definition.
- SourceLocation DefinitionLoc;
-
- /// \brief 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
- /// which the module is notionally built, and relative to which its headers
- /// are found.
- const DirectoryEntry *Directory;
-
- /// \brief The umbrella header or directory.
- llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
-
- /// \brief The module signature.
- uint64_t Signature;
-
- /// \brief The name of the umbrella entry, as written in the module map.
- std::string UmbrellaAsWritten;
-
-private:
- /// \brief The submodules of this module, indexed by name.
- std::vector<Module *> SubModules;
-
- /// \brief 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
- /// corresponding serialized AST file, or null otherwise.
- const FileEntry *ASTFile;
-
- /// \brief 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.
- std::vector<std::string> TopHeaderNames;
-
- /// \brief 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.
- unsigned VisibilityID;
-
-public:
- enum HeaderKind {
- HK_Normal,
- HK_Textual,
- HK_Private,
- HK_PrivateTextual,
- HK_Excluded
- };
- static const int NumHeaderKinds = HK_Excluded + 1;
-
- /// \brief Information about a header directive as found in the module map
- /// file.
- struct Header {
- std::string NameAsWritten;
- const FileEntry *Entry;
-
- explicit operator bool() { return Entry; }
- };
-
- /// \brief Information about a directory name as found in the module map
- /// file.
- struct DirectoryName {
- std::string NameAsWritten;
- const DirectoryEntry *Entry;
-
- explicit operator bool() { return Entry; }
- };
-
- /// \brief 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
- /// module map file but has not been resolved to a file.
- struct UnresolvedHeaderDirective {
- SourceLocation FileNameLoc;
- std::string FileName;
- bool IsUmbrella;
- };
-
- /// \brief 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
- /// the required state of that feature.
- typedef std::pair<std::string, bool> Requirement;
-
- /// \brief 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.
- unsigned IsMissingRequirement : 1;
-
- /// \brief 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.
- ///
- /// 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.
- unsigned IsFromModuleFile : 1;
-
- /// \brief Whether this is a framework module.
- unsigned IsFramework : 1;
-
- /// \brief Whether this is an explicit submodule.
- unsigned IsExplicit : 1;
-
- /// \brief 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
- /// 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 * { ... }).
- unsigned IsInferred : 1;
-
- /// \brief 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
- /// should be explicit.
- unsigned InferExplicitSubmodules : 1;
-
- /// \brief 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.
- ///
- /// 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 Describes the visibility of the various names within a
- /// particular module.
- enum NameVisibilityKind {
- /// \brief All of the names in this module are hidden.
- Hidden,
- /// \brief All of the names in this module are visible.
- AllVisible
- };
-
- /// \brief The visibility of names within this particular module.
- NameVisibilityKind NameVisibility;
-
- /// \brief The location of the inferred submodule.
- SourceLocation InferredSubmoduleLoc;
-
- /// \brief The set of modules imported by this module, and on which this
- /// module depends.
- llvm::SmallSetVector<Module *, 2> Imports;
-
- /// \brief 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.
- typedef llvm::PointerIntPair<Module *, 1, bool> ExportDecl;
-
- /// \brief The set of export declarations.
- SmallVector<ExportDecl, 2> Exports;
-
- /// \brief 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.
- SourceLocation ExportLoc;
-
- /// \brief The name of the module.
- ModuleId Id;
-
- /// \brief 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.
- SmallVector<UnresolvedExportDecl, 2> UnresolvedExports;
-
- /// \brief The directly used modules.
- SmallVector<Module *, 2> DirectUses;
-
- /// \brief 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
- /// module is used.
- struct LinkLibrary {
- LinkLibrary() : IsFramework(false) { }
- LinkLibrary(const std::string &Library, bool IsFramework)
- : Library(Library), IsFramework(IsFramework) { }
-
- /// \brief 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.
- bool IsFramework;
- };
-
- /// \brief 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
- /// (intentionally) change how this module is built.
- std::vector<std::string> ConfigMacros;
-
- /// \brief An unresolved conflict with another module.
- struct UnresolvedConflict {
- /// \brief The (unresolved) module id.
- ModuleId Id;
-
- /// \brief 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
- /// resolved.
- std::vector<UnresolvedConflict> UnresolvedConflicts;
-
- /// \brief A conflict between two modules.
- struct Conflict {
- /// \brief The module that this module conflicts with.
- Module *Other;
-
- /// \brief The message provided to the user when there is a conflict.
- std::string Message;
- };
-
- /// \brief The list of conflicts.
- std::vector<Conflict> Conflicts;
-
- /// \brief 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
- /// current translation unit.
- bool isAvailable() const { return IsAvailable; }
-
- /// \brief Determine whether this module is available for use within the
- /// current translation unit.
- ///
- /// \param LangOpts The language options used for the current
- /// translation unit.
- ///
- /// \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.
- bool isAvailable(const LangOptions &LangOpts,
- const TargetInfo &Target,
- Requirement &Req,
- UnresolvedHeaderDirective &MissingHeader) const;
-
- /// \brief 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
- /// module.
- bool isSubModuleOf(const Module *Other) const;
-
- /// \brief 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 {
- for (const Module *Mod = this; Mod; Mod = Mod->Parent)
- if (Mod->IsFramework)
- return true;
-
- return false;
- }
-
- /// \brief Determine whether this module is a subframework of another
- /// framework.
- bool isSubFramework() const {
- return IsFramework && Parent && Parent->isPartOfFramework();
- }
-
- /// \brief Retrieve the full name of this module, including the path from
- /// its top-level module.
- std::string getFullModuleName() const;
-
- /// \brief 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
- /// 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
- /// be this module.
- const Module *getTopLevelModule() const;
-
- /// \brief 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.
- const FileEntry *getASTFile() const {
- return getTopLevelModule()->ASTFile;
- }
-
- /// \brief 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
- /// umbrella.
- DirectoryName getUmbrellaDir() const;
-
- /// \brief Retrieve the header that serves as the umbrella header for this
- /// module.
- Header getUmbrellaHeader() const {
- if (auto *E = Umbrella.dyn_cast<const FileEntry *>())
- return Header{UmbrellaAsWritten, E};
- return Header{};
- }
-
- /// \brief 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.
- void addTopHeader(const FileEntry *File) {
- assert(File);
- TopHeaders.insert(File);
- }
-
- /// \brief 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.
- ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr);
-
- /// \brief 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
- /// required by this module.
- ///
- /// \param Feature The feature that is required by this module (and
- /// its submodules).
- ///
- /// \param RequiredState The required state of this feature: \c true
- /// if it must be present, \c false if it must be absent.
- ///
- /// \param LangOpts The set of language options that will be used to
- /// evaluate the availability of this feature.
- ///
- /// \param Target The target options that will be used to evaluate the
- /// availability of this feature.
- void addRequirement(StringRef Feature, bool RequiredState,
- const LangOptions &LangOpts,
- const TargetInfo &Target);
-
- /// \brief Mark this module and all of its submodules as unavailable.
- void markUnavailable(bool MissingRequirement = false);
-
- /// \brief 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
- /// a lookup at the end of this module.
- ///
- /// FIXME: This may return incorrect results for (submodules of) the
- /// module currently being built, if it's queried before we see all
- /// of its imports.
- bool isModuleVisible(const Module *M) const {
- if (VisibleModulesCache.empty())
- buildVisibleModulesCache();
- return VisibleModulesCache.count(M);
- }
-
- unsigned getVisibilityID() const { return VisibilityID; }
-
- typedef std::vector<Module *>::iterator submodule_iterator;
- typedef std::vector<Module *>::const_iterator submodule_const_iterator;
-
- submodule_iterator submodule_begin() { return SubModules.begin(); }
- submodule_const_iterator submodule_begin() const {return SubModules.begin();}
- submodule_iterator submodule_end() { return SubModules.end(); }
- submodule_const_iterator submodule_end() const { return SubModules.end(); }
-
- llvm::iterator_range<submodule_iterator> submodules() {
- return llvm::make_range(submodule_begin(), submodule_end());
- }
- llvm::iterator_range<submodule_const_iterator> submodules() const {
- return llvm::make_range(submodule_begin(), submodule_end());
- }
-
- /// \brief 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.
- void getExportedModules(SmallVectorImpl<Module *> &Exported) const;
-
- static StringRef getModuleInputBufferName() {
- return "<module-includes>";
- }
-
- /// \brief 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.
- void dump() const;
-
-private:
- void buildVisibleModulesCache() const;
-};
-
-/// \brief A set of visible modules.
-class VisibleModuleSet {
-public:
- VisibleModuleSet() : Generation(0) {}
- VisibleModuleSet(VisibleModuleSet &&O)
- : ImportLocs(std::move(O.ImportLocs)), Generation(O.Generation ? 1 : 0) {
- O.ImportLocs.clear();
- ++O.Generation;
- }
-
- /// Move from another visible modules set. Guaranteed to leave the source
- /// empty and bump the generation on both.
- VisibleModuleSet &operator=(VisibleModuleSet &&O) {
- ImportLocs = std::move(O.ImportLocs);
- O.ImportLocs.clear();
- ++O.Generation;
- ++Generation;
- return *this;
- }
-
- /// \brief 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.
- bool isVisible(const Module *M) const {
- return getImportLoc(M).isValid();
- }
-
- /// \brief 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
- /// indirectly) by a call to \ref setVisible.
- typedef llvm::function_ref<void(Module *M)> VisibleCallback;
- /// \brief 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.
- typedef llvm::function_ref<void(ArrayRef<Module *> Path,
- Module *Conflict, StringRef Message)>
- ConflictCallback;
- /// \brief Make a specific module visible.
- void setVisible(Module *M, SourceLocation Loc,
- VisibleCallback Vis = [](Module *) {},
- ConflictCallback Cb = [](ArrayRef<Module *>, Module *,
- StringRef) {});
-
-private:
- /// Import locations for each visible module. Indexed by the module's
- /// VisibilityID.
- std::vector<SourceLocation> ImportLocs;
- /// Visibility generation, bumped every time the visibility state changes.
- unsigned Generation;
-};
-
-} // end namespace clang
-
-
-#endif // LLVM_CLANG_BASIC_MODULE_H
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
deleted file mode 100644
index cf51b14..0000000
--- a/include/clang/Basic/ObjCRuntime.h
+++ /dev/null
@@ -1,333 +0,0 @@
-//===--- ObjCRuntime.h - Objective-C Runtime Configuration ------*- 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 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 "llvm/ADT/Triple.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-
-/// \brief The basic abstraction for the target Objective-C runtime.
-class ObjCRuntime {
-public:
- /// \brief 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
- /// release of that OS.
- MacOSX,
-
- /// 'macosx-fragile' is the Apple-provided NeXT-derived runtime on
- /// Mac OS X platforms that use the fragile ABI; the version is a
- /// release of that OS.
- FragileMacOSX,
-
- /// 'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS
- /// simulator; it is always non-fragile. The version is a release
- /// version of iOS.
- iOS,
-
- /// 'watchos' is a variant of iOS for Apple's watchOS. The version
- /// is a release version of watchOS.
- WatchOS,
-
- /// 'gcc' is the Objective-C runtime shipped with GCC, implementing a
- /// fragile Objective-C ABI
- GCC,
-
- /// 'gnustep' is the modern non-fragile GNUstep runtime.
- GNUstep,
-
- /// 'objfw' is the Objective-C runtime included in ObjFW
- ObjFW
- };
-
-private:
- Kind TheKind;
- VersionTuple Version;
-
-public:
- /// A bogus initialization of the runtime.
- ObjCRuntime() : TheKind(MacOSX) {}
-
- ObjCRuntime(Kind kind, const VersionTuple &version)
- : TheKind(kind), Version(version) {}
-
- void set(Kind kind, VersionTuple version) {
- TheKind = kind;
- Version = version;
- }
-
- Kind getKind() const { return TheKind; }
- const VersionTuple &getVersion() const { return Version; }
-
- /// \brief Does this runtime follow the set of implied behaviors for a
- /// "non-fragile" ABI?
- bool isNonFragile() const {
- switch (getKind()) {
- case FragileMacOSX: return false;
- case GCC: return false;
- case MacOSX: return true;
- case GNUstep: return true;
- case ObjFW: return true;
- case iOS: return true;
- case WatchOS: return true;
- }
- llvm_unreachable("bad kind");
- }
-
- /// The inverse of isNonFragile(): does this runtime follow the set of
- /// implied behaviors for a "fragile" ABI?
- bool isFragile() const { return !isNonFragile(); }
-
- /// The default dispatch mechanism to use for the specified architecture
- bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) {
- // The GNUstep runtime uses a newer dispatch method by default from
- // version 1.6 onwards
- if (getKind() == GNUstep && getVersion() >= VersionTuple(1, 6)) {
- if (Arch == llvm::Triple::arm ||
- Arch == llvm::Triple::x86 ||
- Arch == llvm::Triple::x86_64)
- return false;
- }
- else if ((getKind() == MacOSX) && isNonFragile() &&
- (getVersion() >= VersionTuple(10, 0)) &&
- (getVersion() < VersionTuple(10, 6)))
- return Arch != llvm::Triple::x86_64;
- // Except for deployment target of 10.5 or less,
- // Mac runtimes use legacy dispatch everywhere now.
- return true;
- }
-
- /// \brief Is this runtime basically of the GNU family of runtimes?
- bool isGNUFamily() const {
- switch (getKind()) {
- case FragileMacOSX:
- case MacOSX:
- case iOS:
- case WatchOS:
- return false;
- case GCC:
- case GNUstep:
- case ObjFW:
- return true;
- }
- llvm_unreachable("bad kind");
- }
-
- /// \brief 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?
- bool allowsARC() const {
- switch (getKind()) {
- case FragileMacOSX:
- // No stub library for the fragile runtime.
- return getVersion() >= VersionTuple(10, 7);
- case MacOSX: return true;
- case iOS: return true;
- case WatchOS: return true;
- case GCC: return false;
- case GNUstep: return true;
- case ObjFW: return true;
- }
- llvm_unreachable("bad kind");
- }
-
- /// \brief 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
- /// library.
- bool hasNativeARC() const {
- switch (getKind()) {
- case FragileMacOSX: return getVersion() >= VersionTuple(10, 7);
- case MacOSX: return getVersion() >= VersionTuple(10, 7);
- case iOS: return getVersion() >= VersionTuple(5);
- case WatchOS: return true;
-
- case GCC: return false;
- case GNUstep: return getVersion() >= VersionTuple(1, 6);
- case ObjFW: return true;
- }
- llvm_unreachable("bad kind");
- }
-
- /// \brief Does this runtime supports optimized setter entrypoints?
- bool hasOptimizedSetter() const {
- switch (getKind()) {
- case MacOSX:
- return getVersion() >= VersionTuple(10, 8);
- case iOS:
- return (getVersion() >= VersionTuple(6));
- case WatchOS:
- return true;
- case GNUstep:
- return getVersion() >= VersionTuple(1, 7);
-
- default:
- return false;
- }
- }
-
- /// Does this runtime allow the use of __weak?
- bool allowsWeak() const {
- return hasNativeWeak();
- }
-
- /// \brief Does this runtime natively provide ARC-compliant 'weak'
- /// entrypoints?
- bool hasNativeWeak() const {
- // Right now, this is always equivalent to whether the runtime
- // natively supports ARC decision.
- return hasNativeARC();
- }
-
- /// \brief 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 WatchOS: return true;
-
- // This is really a lie, because some implementations and versions
- // of the runtime do not support ARC. Probably -fgnu-runtime
- // should imply a "maximal" runtime or something?
- case GCC: return true;
- case GNUstep: return true;
- case ObjFW: return true;
- }
- llvm_unreachable("bad kind");
- }
-
- /// \brief Does this runtime allow sizeof or alignof on object types?
- bool allowsSizeofAlignof() const {
- return isFragile();
- }
-
- /// \brief Does this runtime allow pointer arithmetic on objects?
- ///
- /// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic()
- /// yields true) [].
- bool allowsPointerArithmetic() const {
- switch (getKind()) {
- case FragileMacOSX:
- case GCC:
- return true;
- case MacOSX:
- case iOS:
- case WatchOS:
- case GNUstep:
- case ObjFW:
- return false;
- }
- llvm_unreachable("bad kind");
- }
-
- /// \brief Is subscripting pointer arithmetic?
- bool isSubscriptPointerArithmetic() const {
- return allowsPointerArithmetic();
- }
-
- /// \brief 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.
- bool hasTerminate() const {
- switch (getKind()) {
- case FragileMacOSX: return getVersion() >= VersionTuple(10, 8);
- case MacOSX: return getVersion() >= VersionTuple(10, 8);
- case iOS: return getVersion() >= VersionTuple(5);
- case WatchOS: return true;
- case GCC: return false;
- case GNUstep: return false;
- case ObjFW: return false;
- }
- llvm_unreachable("bad kind");
- }
-
- /// \brief Does this runtime support weakly importing classes?
- bool hasWeakClassImport() const {
- switch (getKind()) {
- case MacOSX: return true;
- case iOS: return true;
- case WatchOS: return true;
- case FragileMacOSX: return false;
- case GCC: return true;
- case GNUstep: return true;
- case ObjFW: return true;
- }
- llvm_unreachable("bad kind");
- }
-
- /// \brief Does this runtime use zero-cost exceptions?
- bool hasUnwindExceptions() const {
- switch (getKind()) {
- case MacOSX: return true;
- case iOS: return true;
- case WatchOS: return true;
- case FragileMacOSX: return false;
- case GCC: return true;
- case GNUstep: return true;
- case ObjFW: return true;
- }
- llvm_unreachable("bad kind");
- }
-
- bool hasAtomicCopyHelper() const {
- switch (getKind()) {
- case FragileMacOSX:
- case MacOSX:
- case iOS:
- case WatchOS:
- return true;
- case GNUstep:
- return getVersion() >= VersionTuple(1, 7);
- default: return false;
- }
- }
-
- /// \brief Try to parse an Objective-C runtime specification from the given
- /// string.
- ///
- /// \return true on error.
- bool tryParse(StringRef input);
-
- std::string getAsString() const;
-
- friend bool operator==(const ObjCRuntime &left, const ObjCRuntime &right) {
- return left.getKind() == right.getKind() &&
- left.getVersion() == right.getVersion();
- }
-
- friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) {
- return !(left == right);
- }
-};
-
-raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def
deleted file mode 100644
index 91fd919..0000000
--- a/include/clang/Basic/OpenCLExtensions.def
+++ /dev/null
@@ -1,35 +0,0 @@
-//===--- OpenCLExtensions.def - OpenCL extension list -----------*- 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 list of supported OpenCL extensions.
-//
-//===----------------------------------------------------------------------===//
-
-// OpenCL 1.1.
-OPENCLEXT(cl_khr_fp64)
-OPENCLEXT(cl_khr_int64_base_atomics)
-OPENCLEXT(cl_khr_int64_extended_atomics)
-OPENCLEXT(cl_khr_fp16)
-OPENCLEXT(cl_khr_gl_sharing)
-OPENCLEXT(cl_khr_gl_event)
-OPENCLEXT(cl_khr_d3d10_sharing)
-OPENCLEXT(cl_khr_global_int32_base_atomics)
-OPENCLEXT(cl_khr_global_int32_extended_atomics)
-OPENCLEXT(cl_khr_local_int32_base_atomics)
-OPENCLEXT(cl_khr_local_int32_extended_atomics)
-OPENCLEXT(cl_khr_byte_addressable_store)
-OPENCLEXT(cl_khr_3d_image_writes)
-
-// OpenCL 2.0
-OPENCLEXT(cl_khr_gl_msaa_sharing)
-
-// Clang Extensions.
-OPENCLEXT(cl_clang_storage_class_specifiers)
-
-#undef OPENCLEXT
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
deleted file mode 100644
index 44f77ad..0000000
--- a/include/clang/Basic/OpenMPKinds.def
+++ /dev/null
@@ -1,451 +0,0 @@
-//===--- OpenMPKinds.def - OpenMP directives and clauses list ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// \brief This file defines the list of supported OpenMP directives and
-/// clauses.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef OPENMP_DIRECTIVE
-# define OPENMP_DIRECTIVE(Name)
-#endif
-#ifndef OPENMP_DIRECTIVE_EXT
-#define OPENMP_DIRECTIVE_EXT(Name, Str)
-#endif
-#ifndef OPENMP_CLAUSE
-# define OPENMP_CLAUSE(Name, Class)
-#endif
-#ifndef OPENMP_PARALLEL_CLAUSE
-# define OPENMP_PARALLEL_CLAUSE(Name)
-#endif
-#ifndef OPENMP_SIMD_CLAUSE
-# define OPENMP_SIMD_CLAUSE(Name)
-#endif
-#ifndef OPENMP_FOR_CLAUSE
-# define OPENMP_FOR_CLAUSE(Name)
-#endif
-#ifndef OPENMP_FOR_SIMD_CLAUSE
-# define OPENMP_FOR_SIMD_CLAUSE(Name)
-#endif
-#ifndef OPENMP_SECTIONS_CLAUSE
-# define OPENMP_SECTIONS_CLAUSE(Name)
-#endif
-#ifndef OPENMP_SINGLE_CLAUSE
-# define OPENMP_SINGLE_CLAUSE(Name)
-#endif
-#ifndef OPENMP_PARALLEL_FOR_CLAUSE
-# define OPENMP_PARALLEL_FOR_CLAUSE(Name)
-#endif
-#ifndef OPENMP_PARALLEL_FOR_SIMD_CLAUSE
-# define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name)
-#endif
-#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE
-# define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)
-#endif
-#ifndef OPENMP_TASK_CLAUSE
-# define OPENMP_TASK_CLAUSE(Name)
-#endif
-#ifndef OPENMP_ATOMIC_CLAUSE
-# define OPENMP_ATOMIC_CLAUSE(Name)
-#endif
-#ifndef OPENMP_TARGET_CLAUSE
-# define OPENMP_TARGET_CLAUSE(Name)
-#endif
-#ifndef OPENMP_TARGET_DATA_CLAUSE
-# define OPENMP_TARGET_DATA_CLAUSE(Name)
-#endif
-#ifndef OPENMP_TEAMS_CLAUSE
-# define OPENMP_TEAMS_CLAUSE(Name)
-#endif
-#ifndef OPENMP_CANCEL_CLAUSE
-# define OPENMP_CANCEL_CLAUSE(Name)
-#endif
-#ifndef OPENMP_ORDERED_CLAUSE
-# define OPENMP_ORDERED_CLAUSE(Name)
-#endif
-#ifndef OPENMP_TASKLOOP_CLAUSE
-# define OPENMP_TASKLOOP_CLAUSE(Name)
-#endif
-#ifndef OPENMP_TASKLOOP_SIMD_CLAUSE
-# define OPENMP_TASKLOOP_SIMD_CLAUSE(Name)
-#endif
-#ifndef OPENMP_CRITICAL_CLAUSE
-# define OPENMP_CRITICAL_CLAUSE(Name)
-#endif
-#ifndef OPENMP_DISTRIBUTE_CLAUSE
-#define OPENMP_DISTRIBUTE_CLAUSE(Name)
-#endif
-#ifndef OPENMP_DEFAULT_KIND
-# define OPENMP_DEFAULT_KIND(Name)
-#endif
-#ifndef OPENMP_PROC_BIND_KIND
-# define OPENMP_PROC_BIND_KIND(Name)
-#endif
-#ifndef OPENMP_SCHEDULE_KIND
-#define OPENMP_SCHEDULE_KIND(Name)
-#endif
-#ifndef OPENMP_SCHEDULE_MODIFIER
-#define OPENMP_SCHEDULE_MODIFIER(Name)
-#endif
-#ifndef OPENMP_DEPEND_KIND
-#define OPENMP_DEPEND_KIND(Name)
-#endif
-#ifndef OPENMP_LINEAR_KIND
-#define OPENMP_LINEAR_KIND(Name)
-#endif
-#ifndef OPENMP_MAP_KIND
-#define OPENMP_MAP_KIND(Name)
-#endif
-
-// OpenMP directives.
-OPENMP_DIRECTIVE(threadprivate)
-OPENMP_DIRECTIVE(parallel)
-OPENMP_DIRECTIVE(task)
-OPENMP_DIRECTIVE(simd)
-OPENMP_DIRECTIVE(for)
-OPENMP_DIRECTIVE(sections)
-OPENMP_DIRECTIVE(section)
-OPENMP_DIRECTIVE(single)
-OPENMP_DIRECTIVE(master)
-OPENMP_DIRECTIVE(critical)
-OPENMP_DIRECTIVE(taskyield)
-OPENMP_DIRECTIVE(barrier)
-OPENMP_DIRECTIVE(taskwait)
-OPENMP_DIRECTIVE(taskgroup)
-OPENMP_DIRECTIVE(flush)
-OPENMP_DIRECTIVE(ordered)
-OPENMP_DIRECTIVE(atomic)
-OPENMP_DIRECTIVE(target)
-OPENMP_DIRECTIVE(teams)
-OPENMP_DIRECTIVE(cancel)
-OPENMP_DIRECTIVE_EXT(target_data, "target data")
-OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
-OPENMP_DIRECTIVE_EXT(parallel_for_simd, "parallel for simd")
-OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
-OPENMP_DIRECTIVE_EXT(for_simd, "for simd")
-OPENMP_DIRECTIVE_EXT(cancellation_point, "cancellation point")
-OPENMP_DIRECTIVE(taskloop)
-OPENMP_DIRECTIVE_EXT(taskloop_simd, "taskloop simd")
-OPENMP_DIRECTIVE(distribute)
-
-// OpenMP clauses.
-OPENMP_CLAUSE(if, OMPIfClause)
-OPENMP_CLAUSE(final, OMPFinalClause)
-OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
-OPENMP_CLAUSE(safelen, OMPSafelenClause)
-OPENMP_CLAUSE(simdlen, OMPSimdlenClause)
-OPENMP_CLAUSE(collapse, OMPCollapseClause)
-OPENMP_CLAUSE(default, OMPDefaultClause)
-OPENMP_CLAUSE(private, OMPPrivateClause)
-OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
-OPENMP_CLAUSE(lastprivate, OMPLastprivateClause)
-OPENMP_CLAUSE(shared, OMPSharedClause)
-OPENMP_CLAUSE(reduction, OMPReductionClause)
-OPENMP_CLAUSE(linear, OMPLinearClause)
-OPENMP_CLAUSE(aligned, OMPAlignedClause)
-OPENMP_CLAUSE(copyin, OMPCopyinClause)
-OPENMP_CLAUSE(copyprivate, OMPCopyprivateClause)
-OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
-OPENMP_CLAUSE(schedule, OMPScheduleClause)
-OPENMP_CLAUSE(ordered, OMPOrderedClause)
-OPENMP_CLAUSE(nowait, OMPNowaitClause)
-OPENMP_CLAUSE(untied, OMPUntiedClause)
-OPENMP_CLAUSE(mergeable, OMPMergeableClause)
-OPENMP_CLAUSE(flush, OMPFlushClause)
-OPENMP_CLAUSE(read, OMPReadClause)
-OPENMP_CLAUSE(write, OMPWriteClause)
-OPENMP_CLAUSE(update, OMPUpdateClause)
-OPENMP_CLAUSE(capture, OMPCaptureClause)
-OPENMP_CLAUSE(seq_cst, OMPSeqCstClause)
-OPENMP_CLAUSE(depend, OMPDependClause)
-OPENMP_CLAUSE(device, OMPDeviceClause)
-OPENMP_CLAUSE(threads, OMPThreadsClause)
-OPENMP_CLAUSE(simd, OMPSIMDClause)
-OPENMP_CLAUSE(map, OMPMapClause)
-OPENMP_CLAUSE(num_teams, OMPNumTeamsClause)
-OPENMP_CLAUSE(thread_limit, OMPThreadLimitClause)
-OPENMP_CLAUSE(priority, OMPPriorityClause)
-OPENMP_CLAUSE(grainsize, OMPGrainsizeClause)
-OPENMP_CLAUSE(nogroup, OMPNogroupClause)
-OPENMP_CLAUSE(num_tasks, OMPNumTasksClause)
-OPENMP_CLAUSE(hint, OMPHintClause)
-
-// Clauses allowed for OpenMP directive 'parallel'.
-OPENMP_PARALLEL_CLAUSE(if)
-OPENMP_PARALLEL_CLAUSE(num_threads)
-OPENMP_PARALLEL_CLAUSE(default)
-OPENMP_PARALLEL_CLAUSE(proc_bind)
-OPENMP_PARALLEL_CLAUSE(private)
-OPENMP_PARALLEL_CLAUSE(firstprivate)
-OPENMP_PARALLEL_CLAUSE(shared)
-OPENMP_PARALLEL_CLAUSE(reduction)
-OPENMP_PARALLEL_CLAUSE(copyin)
-
-// Clauses allowed for directive 'omp simd'.
-OPENMP_SIMD_CLAUSE(private)
-OPENMP_SIMD_CLAUSE(lastprivate)
-OPENMP_SIMD_CLAUSE(linear)
-OPENMP_SIMD_CLAUSE(aligned)
-OPENMP_SIMD_CLAUSE(safelen)
-OPENMP_SIMD_CLAUSE(simdlen)
-OPENMP_SIMD_CLAUSE(collapse)
-OPENMP_SIMD_CLAUSE(reduction)
-
-// Clauses allowed for directive 'omp for'.
-OPENMP_FOR_CLAUSE(private)
-OPENMP_FOR_CLAUSE(lastprivate)
-OPENMP_FOR_CLAUSE(firstprivate)
-OPENMP_FOR_CLAUSE(reduction)
-OPENMP_FOR_CLAUSE(collapse)
-OPENMP_FOR_CLAUSE(schedule)
-OPENMP_FOR_CLAUSE(ordered)
-OPENMP_FOR_CLAUSE(nowait)
-OPENMP_FOR_CLAUSE(linear)
-
-// Clauses allowed for directive 'omp for simd'.
-OPENMP_FOR_SIMD_CLAUSE(private)
-OPENMP_FOR_SIMD_CLAUSE(firstprivate)
-OPENMP_FOR_SIMD_CLAUSE(lastprivate)
-OPENMP_FOR_SIMD_CLAUSE(reduction)
-OPENMP_FOR_SIMD_CLAUSE(schedule)
-OPENMP_FOR_SIMD_CLAUSE(collapse)
-OPENMP_FOR_SIMD_CLAUSE(nowait)
-OPENMP_FOR_SIMD_CLAUSE(safelen)
-OPENMP_FOR_SIMD_CLAUSE(simdlen)
-OPENMP_FOR_SIMD_CLAUSE(linear)
-OPENMP_FOR_SIMD_CLAUSE(aligned)
-OPENMP_FOR_SIMD_CLAUSE(ordered)
-
-// Clauses allowed for OpenMP directive 'omp sections'.
-OPENMP_SECTIONS_CLAUSE(private)
-OPENMP_SECTIONS_CLAUSE(lastprivate)
-OPENMP_SECTIONS_CLAUSE(firstprivate)
-OPENMP_SECTIONS_CLAUSE(reduction)
-OPENMP_SECTIONS_CLAUSE(nowait)
-
-// Clauses allowed for directive 'omp single'.
-OPENMP_SINGLE_CLAUSE(private)
-OPENMP_SINGLE_CLAUSE(firstprivate)
-OPENMP_SINGLE_CLAUSE(copyprivate)
-OPENMP_SINGLE_CLAUSE(nowait)
-
-// Clauses allowed for OpenMP directive 'cancel'.
-OPENMP_CANCEL_CLAUSE(if)
-
-// Static attributes for 'default' clause.
-OPENMP_DEFAULT_KIND(none)
-OPENMP_DEFAULT_KIND(shared)
-
-// Static attributes for 'proc_bind' clause.
-OPENMP_PROC_BIND_KIND(master)
-OPENMP_PROC_BIND_KIND(close)
-OPENMP_PROC_BIND_KIND(spread)
-
-// Static attributes for 'schedule' clause.
-OPENMP_SCHEDULE_KIND(static)
-OPENMP_SCHEDULE_KIND(dynamic)
-OPENMP_SCHEDULE_KIND(guided)
-OPENMP_SCHEDULE_KIND(auto)
-OPENMP_SCHEDULE_KIND(runtime)
-
-// Modifiers for 'schedule' clause.
-OPENMP_SCHEDULE_MODIFIER(monotonic)
-OPENMP_SCHEDULE_MODIFIER(nonmonotonic)
-OPENMP_SCHEDULE_MODIFIER(simd)
-
-// Static attributes for 'depend' clause.
-OPENMP_DEPEND_KIND(in)
-OPENMP_DEPEND_KIND(out)
-OPENMP_DEPEND_KIND(inout)
-OPENMP_DEPEND_KIND(source)
-OPENMP_DEPEND_KIND(sink)
-
-// Modifiers for 'linear' clause.
-OPENMP_LINEAR_KIND(val)
-OPENMP_LINEAR_KIND(ref)
-OPENMP_LINEAR_KIND(uval)
-
-// Clauses allowed for OpenMP directive 'parallel for'.
-OPENMP_PARALLEL_FOR_CLAUSE(if)
-OPENMP_PARALLEL_FOR_CLAUSE(num_threads)
-OPENMP_PARALLEL_FOR_CLAUSE(default)
-OPENMP_PARALLEL_FOR_CLAUSE(proc_bind)
-OPENMP_PARALLEL_FOR_CLAUSE(private)
-OPENMP_PARALLEL_FOR_CLAUSE(firstprivate)
-OPENMP_PARALLEL_FOR_CLAUSE(shared)
-OPENMP_PARALLEL_FOR_CLAUSE(reduction)
-OPENMP_PARALLEL_FOR_CLAUSE(copyin)
-OPENMP_PARALLEL_FOR_CLAUSE(lastprivate)
-OPENMP_PARALLEL_FOR_CLAUSE(collapse)
-OPENMP_PARALLEL_FOR_CLAUSE(schedule)
-OPENMP_PARALLEL_FOR_CLAUSE(ordered)
-OPENMP_PARALLEL_FOR_CLAUSE(linear)
-
-// Clauses allowed for OpenMP directive 'parallel for simd'.
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(if)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(num_threads)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(default)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(proc_bind)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(private)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(firstprivate)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(shared)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(reduction)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(copyin)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(lastprivate)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(collapse)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(schedule)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(safelen)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned)
-OPENMP_PARALLEL_FOR_SIMD_CLAUSE(ordered)
-
-// Clauses allowed for OpenMP directive 'parallel sections'.
-OPENMP_PARALLEL_SECTIONS_CLAUSE(if)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(num_threads)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(default)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(proc_bind)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(private)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(firstprivate)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(shared)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin)
-OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate)
-
-// Clauses allowed for OpenMP directive 'task'.
-OPENMP_TASK_CLAUSE(if)
-OPENMP_TASK_CLAUSE(final)
-OPENMP_TASK_CLAUSE(default)
-OPENMP_TASK_CLAUSE(private)
-OPENMP_TASK_CLAUSE(firstprivate)
-OPENMP_TASK_CLAUSE(shared)
-OPENMP_TASK_CLAUSE(untied)
-OPENMP_TASK_CLAUSE(mergeable)
-OPENMP_TASK_CLAUSE(depend)
-OPENMP_TASK_CLAUSE(priority)
-
-// Clauses allowed for OpenMP directive 'atomic'.
-OPENMP_ATOMIC_CLAUSE(read)
-OPENMP_ATOMIC_CLAUSE(write)
-OPENMP_ATOMIC_CLAUSE(update)
-OPENMP_ATOMIC_CLAUSE(capture)
-OPENMP_ATOMIC_CLAUSE(seq_cst)
-
-// Clauses allowed for OpenMP directive 'target'.
-// TODO More clauses for 'target' directive.
-OPENMP_TARGET_CLAUSE(if)
-OPENMP_TARGET_CLAUSE(device)
-OPENMP_TARGET_CLAUSE(map)
-
-// Clauses allowed for OpenMP directive 'target data'.
-// TODO More clauses for 'target data' directive.
-OPENMP_TARGET_DATA_CLAUSE(if)
-OPENMP_TARGET_DATA_CLAUSE(device)
-OPENMP_TARGET_DATA_CLAUSE(map)
-
-// Clauses allowed for OpenMP directive 'teams'.
-// TODO More clauses for 'teams' directive.
-OPENMP_TEAMS_CLAUSE(default)
-OPENMP_TEAMS_CLAUSE(private)
-OPENMP_TEAMS_CLAUSE(firstprivate)
-OPENMP_TEAMS_CLAUSE(shared)
-OPENMP_TEAMS_CLAUSE(reduction)
-OPENMP_TEAMS_CLAUSE(num_teams)
-OPENMP_TEAMS_CLAUSE(thread_limit)
-
-// Clauses allowed for OpenMP directive 'ordered'.
-// TODO More clauses for 'ordered' directive.
-OPENMP_ORDERED_CLAUSE(threads)
-OPENMP_ORDERED_CLAUSE(simd)
-OPENMP_ORDERED_CLAUSE(depend)
-
-// Map types and map type modifier for 'map' clause.
-OPENMP_MAP_KIND(alloc)
-OPENMP_MAP_KIND(to)
-OPENMP_MAP_KIND(from)
-OPENMP_MAP_KIND(tofrom)
-OPENMP_MAP_KIND(delete)
-OPENMP_MAP_KIND(release)
-OPENMP_MAP_KIND(always)
-
-// Clauses allowed for OpenMP directive 'taskloop'.
-OPENMP_TASKLOOP_CLAUSE(if)
-OPENMP_TASKLOOP_CLAUSE(shared)
-OPENMP_TASKLOOP_CLAUSE(private)
-OPENMP_TASKLOOP_CLAUSE(firstprivate)
-OPENMP_TASKLOOP_CLAUSE(lastprivate)
-OPENMP_TASKLOOP_CLAUSE(default)
-OPENMP_TASKLOOP_CLAUSE(collapse)
-OPENMP_TASKLOOP_CLAUSE(final)
-OPENMP_TASKLOOP_CLAUSE(untied)
-OPENMP_TASKLOOP_CLAUSE(mergeable)
-OPENMP_TASKLOOP_CLAUSE(priority)
-OPENMP_TASKLOOP_CLAUSE(grainsize)
-OPENMP_TASKLOOP_CLAUSE(nogroup)
-OPENMP_TASKLOOP_CLAUSE(num_tasks)
-
-// Clauses allowed for OpenMP directive 'taskloop simd'.
-OPENMP_TASKLOOP_SIMD_CLAUSE(if)
-OPENMP_TASKLOOP_SIMD_CLAUSE(shared)
-OPENMP_TASKLOOP_SIMD_CLAUSE(private)
-OPENMP_TASKLOOP_SIMD_CLAUSE(firstprivate)
-OPENMP_TASKLOOP_SIMD_CLAUSE(lastprivate)
-OPENMP_TASKLOOP_SIMD_CLAUSE(default)
-OPENMP_TASKLOOP_SIMD_CLAUSE(collapse)
-OPENMP_TASKLOOP_SIMD_CLAUSE(final)
-OPENMP_TASKLOOP_SIMD_CLAUSE(untied)
-OPENMP_TASKLOOP_SIMD_CLAUSE(mergeable)
-OPENMP_TASKLOOP_SIMD_CLAUSE(priority)
-OPENMP_TASKLOOP_SIMD_CLAUSE(linear)
-OPENMP_TASKLOOP_SIMD_CLAUSE(aligned)
-OPENMP_TASKLOOP_SIMD_CLAUSE(safelen)
-OPENMP_TASKLOOP_SIMD_CLAUSE(simdlen)
-OPENMP_TASKLOOP_SIMD_CLAUSE(grainsize)
-OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup)
-OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks)
-
-// Clauses allowed for OpenMP directive 'critical'.
-OPENMP_CRITICAL_CLAUSE(hint)
-
-// Clauses allowed for OpenMP directive 'distribute'
-OPENMP_DISTRIBUTE_CLAUSE(private)
-OPENMP_DISTRIBUTE_CLAUSE(firstprivate)
-OPENMP_DISTRIBUTE_CLAUSE(lastprivate)
-OPENMP_DISTRIBUTE_CLAUSE(collapse)
-
-#undef OPENMP_TASKLOOP_SIMD_CLAUSE
-#undef OPENMP_TASKLOOP_CLAUSE
-#undef OPENMP_LINEAR_KIND
-#undef OPENMP_DEPEND_KIND
-#undef OPENMP_SCHEDULE_MODIFIER
-#undef OPENMP_SCHEDULE_KIND
-#undef OPENMP_PROC_BIND_KIND
-#undef OPENMP_DEFAULT_KIND
-#undef OPENMP_DIRECTIVE
-#undef OPENMP_DIRECTIVE_EXT
-#undef OPENMP_CLAUSE
-#undef OPENMP_CRITICAL_CLAUSE
-#undef OPENMP_ORDERED_CLAUSE
-#undef OPENMP_CANCEL_CLAUSE
-#undef OPENMP_SINGLE_CLAUSE
-#undef OPENMP_SECTIONS_CLAUSE
-#undef OPENMP_PARALLEL_CLAUSE
-#undef OPENMP_PARALLEL_FOR_CLAUSE
-#undef OPENMP_PARALLEL_FOR_SIMD_CLAUSE
-#undef OPENMP_PARALLEL_SECTIONS_CLAUSE
-#undef OPENMP_TASK_CLAUSE
-#undef OPENMP_ATOMIC_CLAUSE
-#undef OPENMP_TARGET_CLAUSE
-#undef OPENMP_TARGET_DATA_CLAUSE
-#undef OPENMP_TEAMS_CLAUSE
-#undef OPENMP_SIMD_CLAUSE
-#undef OPENMP_FOR_CLAUSE
-#undef OPENMP_FOR_SIMD_CLAUSE
-#undef OPENMP_MAP_KIND
-#undef OPENMP_DISTRIBUTE_CLAUSE
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
deleted file mode 100644
index d4d3db8..0000000
--- a/include/clang/Basic/OpenMPKinds.h
+++ /dev/null
@@ -1,175 +0,0 @@
-//===--- OpenMPKinds.h - OpenMP enums ---------------------------*- 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 some OpenMP-specific enums and functions.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_OPENMPKINDS_H
-#define LLVM_CLANG_BASIC_OPENMPKINDS_H
-
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-
-/// \brief OpenMP directives.
-enum OpenMPDirectiveKind {
-#define OPENMP_DIRECTIVE(Name) \
- OMPD_##Name,
-#define OPENMP_DIRECTIVE_EXT(Name, Str) \
- OMPD_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPD_unknown
-};
-
-/// \brief OpenMP clauses.
-enum OpenMPClauseKind {
-#define OPENMP_CLAUSE(Name, Class) \
- OMPC_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPC_threadprivate,
- OMPC_unknown
-};
-
-/// \brief OpenMP attributes for 'default' clause.
-enum OpenMPDefaultClauseKind {
-#define OPENMP_DEFAULT_KIND(Name) \
- OMPC_DEFAULT_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPC_DEFAULT_unknown
-};
-
-/// \brief OpenMP attributes for 'proc_bind' clause.
-enum OpenMPProcBindClauseKind {
-#define OPENMP_PROC_BIND_KIND(Name) \
- OMPC_PROC_BIND_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPC_PROC_BIND_unknown
-};
-
-/// \brief OpenMP attributes for 'schedule' clause.
-enum OpenMPScheduleClauseKind {
-#define OPENMP_SCHEDULE_KIND(Name) \
- OMPC_SCHEDULE_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPC_SCHEDULE_unknown
-};
-
-/// \brief OpenMP modifiers for 'schedule' clause.
-enum OpenMPScheduleClauseModifier {
- OMPC_SCHEDULE_MODIFIER_unknown = OMPC_SCHEDULE_unknown,
-#define OPENMP_SCHEDULE_MODIFIER(Name) \
- OMPC_SCHEDULE_MODIFIER_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPC_SCHEDULE_MODIFIER_last
-};
-
-/// \brief OpenMP attributes for 'depend' clause.
-enum OpenMPDependClauseKind {
-#define OPENMP_DEPEND_KIND(Name) \
- OMPC_DEPEND_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPC_DEPEND_unknown
-};
-
-/// \brief OpenMP attributes for 'linear' clause.
-enum OpenMPLinearClauseKind {
-#define OPENMP_LINEAR_KIND(Name) \
- OMPC_LINEAR_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPC_LINEAR_unknown
-};
-
-/// \brief OpenMP mapping kind for 'map' clause.
-enum OpenMPMapClauseKind {
-#define OPENMP_MAP_KIND(Name) \
- OMPC_MAP_##Name,
-#include "clang/Basic/OpenMPKinds.def"
- OMPC_MAP_unknown
-};
-
-OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
-const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind);
-
-OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str);
-const char *getOpenMPClauseName(OpenMPClauseKind Kind);
-
-unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str);
-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
-/// 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.
-/// \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.
-/// \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.
-/// \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-kind directive.
-/// \param DKind Specified directive.
-/// \return true - the directive is a target-like directive like 'omp target',
-/// otherwise - false.
-bool isOpenMPTargetDirective(OpenMPDirectiveKind DKind);
-
-/// \brief Checks if the specified directive is a teams-kind directive.
-/// \param DKind Specified directive.
-/// \return true - the directive is a teams-like directive like 'omp teams',
-/// otherwise - false.
-bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind);
-
-/// \brief 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.
-/// \param DKind Specified directive.
-/// \return true - the directive is a distribute-directive like 'omp
-/// distribute',
-/// otherwise - false.
-bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind);
-
-/// \brief 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
-/// 'threadprivate', 'copyin' or 'copyprivate'.
-/// \param Kind Clause kind.
-/// \return true - the clause is a threadprivate clause, otherwise - false.
-bool isOpenMPThreadPrivate(OpenMPClauseKind Kind);
-
-}
-
-#endif
-
diff --git a/include/clang/Basic/OperatorKinds.def b/include/clang/Basic/OperatorKinds.def
deleted file mode 100644
index 34ad764..0000000
--- a/include/clang/Basic/OperatorKinds.def
+++ /dev/null
@@ -1,107 +0,0 @@
-//===--- OperatorKinds.def - C++ Overloaded Operator 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 the OverloadedOperator database, which includes
-// all of the overloadable C++ operators.
-//
-//===----------------------------------------------------------------------===//
-//
-/// @file OperatorKinds.def
-///
-/// In this file, each of the overloadable C++ operators is enumerated
-/// with either the OVERLOADED_OPERATOR or OVERLOADED_OPERATOR_MULTI
-/// macro, each of which can be specified by the code including this
-/// file. OVERLOADED_OPERATOR is used for single-token operators
-/// (e.g., "+"), and has six arguments:
-///
-/// Name: The name of the token. OO_Name will be the name of the
-/// corresponding enumerator in OverloadedOperatorKind in
-/// OperatorKinds.h.
-///
-/// Spelling: A string that provides a canonical spelling for the
-/// operator, e.g., "operator+".
-///
-/// Token: The name of the token that specifies the operator, e.g.,
-/// "plus" for operator+ or "greatergreaterequal" for
-/// "operator>>=". With a "kw_" prefix, the token name can be used as
-/// an enumerator into the TokenKind enumeration.
-///
-/// Unary: True if the operator can be declared as a unary operator.
-///
-/// Binary: True if the operator can be declared as a binary
-/// operator. Note that some operators (e.g., "operator+" and
-/// "operator*") can be both unary and binary.
-///
-/// MemberOnly: True if this operator can only be declared as a
-/// non-static member function. False if the operator can be both a
-/// non-member function and a non-static member function.
-///
-/// OVERLOADED_OPERATOR_MULTI is used to enumerate the multi-token
-/// overloaded operator names, e.g., "operator delete []". The macro
-/// has all of the parameters of OVERLOADED_OPERATOR except Token,
-/// which is omitted.
-
-#ifndef OVERLOADED_OPERATOR
-# define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)
-#endif
-
-#ifndef OVERLOADED_OPERATOR_MULTI
-# define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) \
- OVERLOADED_OPERATOR(Name,Spelling,unknown,Unary,Binary,MemberOnly)
-#endif
-
-OVERLOADED_OPERATOR_MULTI(New , "new" , true , true , false)
-OVERLOADED_OPERATOR_MULTI(Delete , "delete" , true , true , false)
-OVERLOADED_OPERATOR_MULTI(Array_New , "new[]" , true , true , false)
-OVERLOADED_OPERATOR_MULTI(Array_Delete , "delete[]" , true , true , false)
-OVERLOADED_OPERATOR(Plus , "+" , plus , true , true , false)
-OVERLOADED_OPERATOR(Minus , "-" , minus , true , true , false)
-OVERLOADED_OPERATOR(Star , "*" , star , true , true , false)
-OVERLOADED_OPERATOR(Slash , "/" , slash , false, true , false)
-OVERLOADED_OPERATOR(Percent , "%" , percent , false, true , false)
-OVERLOADED_OPERATOR(Caret , "^" , caret , false, true , false)
-OVERLOADED_OPERATOR(Amp , "&" , amp , true , true , false)
-OVERLOADED_OPERATOR(Pipe , "|" , pipe , false, true , false)
-OVERLOADED_OPERATOR(Tilde , "~" , tilde , true , false, false)
-OVERLOADED_OPERATOR(Exclaim , "!" , exclaim , true , false, false)
-OVERLOADED_OPERATOR(Equal , "=" , equal , false, true , true)
-OVERLOADED_OPERATOR(Less , "<" , less , false, true , false)
-OVERLOADED_OPERATOR(Greater , ">" , greater , false, true , false)
-OVERLOADED_OPERATOR(PlusEqual , "+=" , plusequal , false, true , false)
-OVERLOADED_OPERATOR(MinusEqual , "-=" , minusequal , false, true , false)
-OVERLOADED_OPERATOR(StarEqual , "*=" , starequal , false, true , false)
-OVERLOADED_OPERATOR(SlashEqual , "/=" , slashequal , false, true , false)
-OVERLOADED_OPERATOR(PercentEqual , "%=" , percentequal , false, true , false)
-OVERLOADED_OPERATOR(CaretEqual , "^=" , caretequal , false, true , false)
-OVERLOADED_OPERATOR(AmpEqual , "&=" , ampequal , false, true , false)
-OVERLOADED_OPERATOR(PipeEqual , "|=" , pipeequal , false, true , false)
-OVERLOADED_OPERATOR(LessLess , "<<" , lessless , false, true , false)
-OVERLOADED_OPERATOR(GreaterGreater , ">>" , greatergreater , false, true , false)
-OVERLOADED_OPERATOR(LessLessEqual , "<<=" , lesslessequal , false, true , false)
-OVERLOADED_OPERATOR(GreaterGreaterEqual , ">>=" , greatergreaterequal, false, true , false)
-OVERLOADED_OPERATOR(EqualEqual , "==" , equalequal , false, true , false)
-OVERLOADED_OPERATOR(ExclaimEqual , "!=" , exclaimequal , false, true , false)
-OVERLOADED_OPERATOR(LessEqual , "<=" , lessequal , false, true , false)
-OVERLOADED_OPERATOR(GreaterEqual , ">=" , greaterequal , false, true , false)
-OVERLOADED_OPERATOR(AmpAmp , "&&" , ampamp , false, true , false)
-OVERLOADED_OPERATOR(PipePipe , "||" , pipepipe , false, true , false)
-OVERLOADED_OPERATOR(PlusPlus , "++" , plusplus , true , true , false)
-OVERLOADED_OPERATOR(MinusMinus , "--" , minusminus , true , true , false)
-OVERLOADED_OPERATOR(Comma , "," , comma , false, true , false)
-OVERLOADED_OPERATOR(ArrowStar , "->*" , arrowstar , false, true , false)
-OVERLOADED_OPERATOR(Arrow , "->" , arrow , true , false, true)
-OVERLOADED_OPERATOR_MULTI(Call , "()" , true , true , true)
-OVERLOADED_OPERATOR_MULTI(Subscript , "[]" , false, true , true)
-// ?: can *not* be overloaded, but we need the overload
-// resolution machinery for it.
-OVERLOADED_OPERATOR_MULTI(Conditional , "?" , false, true , false)
-OVERLOADED_OPERATOR(Coawait , "co_await", kw_co_await , true , false, false)
-
-#undef OVERLOADED_OPERATOR_MULTI
-#undef OVERLOADED_OPERATOR
diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h
deleted file mode 100644
index 7120bae..0000000
--- a/include/clang/Basic/OperatorKinds.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===--- OperatorKinds.h - C++ Overloaded Operators -------------*- 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 an enumeration for C++ overloaded operators.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_OPERATORKINDS_H
-#define LLVM_CLANG_BASIC_OPERATORKINDS_H
-
-namespace clang {
-
-/// \brief Enumeration specifying the different kinds of C++ overloaded
-/// operators.
-enum OverloadedOperatorKind : int {
- OO_None, ///< Not an overloaded operator
-#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
- OO_##Name,
-#include "clang/Basic/OperatorKinds.def"
- NUM_OVERLOADED_OPERATORS
-};
-
-/// \brief Retrieve the spelling of the given overloaded operator, without
-/// the preceding "operator" keyword.
-const char *getOperatorSpelling(OverloadedOperatorKind Operator);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h
deleted file mode 100644
index 640749f..0000000
--- a/include/clang/Basic/OperatorPrecedence.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===--- OperatorPrecedence.h - Operator precedence levels ------*- 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 and computes precedence levels for binary/ternary operators.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_OPERATORPRECEDENCE_H
-#define LLVM_CLANG_BASIC_OPERATORPRECEDENCE_H
-
-#include "clang/Basic/TokenKinds.h"
-
-namespace clang {
-
-/// PrecedenceLevels - These are precedences for the binary/ternary
-/// operators in the C99 grammar. These have been named to relate
-/// with the C99 grammar productions. Low precedences numbers bind
-/// more weakly than high numbers.
-namespace prec {
- enum Level {
- Unknown = 0, // Not binary operator.
- Comma = 1, // ,
- Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
- Conditional = 3, // ?
- LogicalOr = 4, // ||
- LogicalAnd = 5, // &&
- InclusiveOr = 6, // |
- ExclusiveOr = 7, // ^
- And = 8, // &
- Equality = 9, // ==, !=
- Relational = 10, // >=, <=, >, <
- Shift = 11, // <<, >>
- Additive = 12, // -, +
- Multiplicative = 13, // *, /, %
- PointerToMember = 14 // .*, ->*
- };
-}
-
-/// \brief Return the precedence of the specified binary operator token.
-prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator,
- bool CPlusPlus11);
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_OPERATOR_PRECEDENCE_H
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
deleted file mode 100644
index 53ce95c..0000000
--- a/include/clang/Basic/PartialDiagnostic.h
+++ /dev/null
@@ -1,410 +0,0 @@
-//===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief 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/SourceLocation.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-
-namespace clang {
-
-class PartialDiagnostic {
-public:
- enum {
- // The MaxArguments and MaxFixItHints member enum values from
- // DiagnosticsEngine are private but DiagnosticsEngine declares
- // PartialDiagnostic a friend. These enum values are redeclared
- // here so that the nested Storage class below can access them.
- MaxArguments = DiagnosticsEngine::MaxArguments
- };
-
- struct Storage {
- Storage() : NumDiagArgs(0) { }
-
- enum {
- /// \brief 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 anyway.
- MaxArguments = PartialDiagnostic::MaxArguments
- };
-
- /// \brief The number of entries in Arguments.
- unsigned char NumDiagArgs;
-
- /// \brief Specifies for each argument whether it is in DiagArgumentsStr
- /// or in DiagArguments.
- unsigned char DiagArgumentsKind[MaxArguments];
-
- /// \brief 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
- /// string arguments.
- std::string DiagArgumentsStr[MaxArguments];
-
- /// \brief 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
- /// modify at a particular position.
- SmallVector<FixItHint, 6> FixItHints;
- };
-
- /// \brief 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;
- Storage Cached[NumCached];
- Storage *FreeList[NumCached];
- unsigned NumFreeListEntries;
-
- public:
- StorageAllocator();
- ~StorageAllocator();
-
- /// \brief Allocate new storage.
- Storage *Allocate() {
- if (NumFreeListEntries == 0)
- return new Storage;
-
- Storage *Result = FreeList[--NumFreeListEntries];
- Result->NumDiagArgs = 0;
- Result->DiagRanges.clear();
- Result->FixItHints.clear();
- return Result;
- }
-
- /// \brief Free the given storage object.
- void Deallocate(Storage *S) {
- if (S >= Cached && S <= Cached + NumCached) {
- FreeList[NumFreeListEntries++] = S;
- return;
- }
-
- delete S;
- }
- };
-
-private:
- // NOTE: Sema assumes that PartialDiagnostic is location-invariant
- // in the sense that its bits can be safely memcpy'ed and destructed
- // in the new location.
-
- /// \brief The diagnostic ID.
- mutable unsigned DiagID;
-
- /// \brief Storage for args and ranges.
- mutable Storage *DiagStorage;
-
- /// \brief Allocator used to allocate storage for this diagnostic.
- StorageAllocator *Allocator;
-
- /// \brief Retrieve storage for this particular diagnostic.
- Storage *getStorage() const {
- if (DiagStorage)
- return DiagStorage;
-
- if (Allocator)
- DiagStorage = Allocator->Allocate();
- else {
- assert(Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)));
- DiagStorage = new Storage;
- }
- return DiagStorage;
- }
-
- void freeStorage() {
- if (!DiagStorage)
- return;
-
- // The hot path for PartialDiagnostic is when we just used it to wrap an ID
- // (typically so we have the flexibility of passing a more complex
- // diagnostic into the callee, but that does not commonly occur).
- //
- // Split this out into a slow function for silly compilers (*cough*) which
- // can't do decent partial inlining.
- freeStorageSlow();
- }
-
- void freeStorageSlow() {
- if (Allocator)
- Allocator->Deallocate(DiagStorage);
- else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
- delete DiagStorage;
- DiagStorage = nullptr;
- }
-
- void AddSourceRange(const CharSourceRange &R) const {
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- DiagStorage->DiagRanges.push_back(R);
- }
-
- void AddFixItHint(const FixItHint &Hint) const {
- if (Hint.isNull())
- return;
-
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- DiagStorage->FixItHints.push_back(Hint);
- }
-
-public:
- struct NullDiagnostic {};
- /// \brief 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(unsigned DiagID, StorageAllocator &Allocator)
- : DiagID(DiagID), DiagStorage(nullptr), Allocator(&Allocator) { }
-
- PartialDiagnostic(const PartialDiagnostic &Other)
- : DiagID(Other.DiagID), DiagStorage(nullptr), Allocator(Other.Allocator)
- {
- if (Other.DiagStorage) {
- DiagStorage = getStorage();
- *DiagStorage = *Other.DiagStorage;
- }
- }
-
- PartialDiagnostic(PartialDiagnostic &&Other)
- : 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)))
- {
- if (Other.DiagStorage)
- *this->DiagStorage = *Other.DiagStorage;
- }
-
- PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator)
- : DiagID(Other.getID()), DiagStorage(nullptr), Allocator(&Allocator)
- {
- // Copy arguments.
- for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) {
- if (Other.getArgKind(I) == DiagnosticsEngine::ak_std_string)
- AddString(Other.getArgStdStr(I));
- else
- AddTaggedVal(Other.getRawArg(I), Other.getArgKind(I));
- }
-
- // Copy source ranges.
- for (unsigned I = 0, N = Other.getNumRanges(); I != N; ++I)
- AddSourceRange(Other.getRange(I));
-
- // Copy fix-its.
- for (unsigned I = 0, N = Other.getNumFixItHints(); I != N; ++I)
- AddFixItHint(Other.getFixItHint(I));
- }
-
- PartialDiagnostic &operator=(const PartialDiagnostic &Other) {
- DiagID = Other.DiagID;
- if (Other.DiagStorage) {
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- *DiagStorage = *Other.DiagStorage;
- } else {
- freeStorage();
- }
-
- return *this;
- }
-
- PartialDiagnostic &operator=(PartialDiagnostic &&Other) {
- freeStorage();
-
- DiagID = Other.DiagID;
- DiagStorage = Other.DiagStorage;
- Allocator = Other.Allocator;
-
- Other.DiagStorage = nullptr;
- return *this;
- }
-
- ~PartialDiagnostic() {
- freeStorage();
- }
-
- void swap(PartialDiagnostic &PD) {
- std::swap(DiagID, PD.DiagID);
- std::swap(DiagStorage, PD.DiagStorage);
- std::swap(Allocator, PD.Allocator);
- }
-
- unsigned getDiagID() const { return DiagID; }
-
- void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
- "Too many arguments to diagnostic!");
- DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
- DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
- }
-
- void AddString(StringRef V) const {
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
- "Too many arguments to diagnostic!");
- DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs]
- = DiagnosticsEngine::ak_std_string;
- DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = V;
- }
-
- void Emit(const DiagnosticBuilder &DB) const {
- if (!DiagStorage)
- return;
-
- // Add all arguments.
- for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) {
- if ((DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]
- == DiagnosticsEngine::ak_std_string)
- DB.AddString(DiagStorage->DiagArgumentsStr[i]);
- else
- DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i],
- (DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
- }
-
- // Add all ranges.
- for (const CharSourceRange &Range : DiagStorage->DiagRanges)
- DB.AddSourceRange(Range);
-
- // Add all fix-its.
- for (const FixItHint &Fix : DiagStorage->FixItHints)
- DB.AddFixItHint(Fix);
- }
-
- void EmitToString(DiagnosticsEngine &Diags,
- SmallVectorImpl<char> &Buf) const {
- // FIXME: It should be possible to render a diagnostic to a string without
- // messing with the state of the diagnostics engine.
- DiagnosticBuilder DB(Diags.Report(getDiagID()));
- Emit(DB);
- DB.FlushCounts();
- Diagnostic(&Diags).FormatDiagnostic(Buf);
- DB.Clear();
- Diags.Clear();
- }
-
- /// \brief 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;
- freeStorage();
- }
-
- bool hasStorage() const { return DiagStorage != nullptr; }
-
- friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- unsigned I) {
- PD.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
- return PD;
- }
-
- friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- int I) {
- PD.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const char *S) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(S),
- DiagnosticsEngine::ak_c_string);
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- StringRef S) {
-
- PD.AddString(S);
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const IdentifierInfo *II) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(II),
- DiagnosticsEngine::ak_identifierinfo);
- return PD;
- }
-
- // Adds a DeclContext to the diagnostic. The enable_if template magic is here
- // so that we only match those arguments that are (statically) DeclContexts;
- // other arguments that derive from DeclContext (e.g., RecordDecls) will not
- // match.
- template<typename T>
- friend inline
- typename std::enable_if<std::is_same<T, DeclContext>::value,
- const PartialDiagnostic &>::type
- operator<<(const PartialDiagnostic &PD, T *DC) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
- DiagnosticsEngine::ak_declcontext);
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- SourceRange R) {
- PD.AddSourceRange(CharSourceRange::getTokenRange(R));
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const CharSourceRange &R) {
- PD.AddSourceRange(R);
- return PD;
- }
-
- friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const FixItHint &Hint) {
- PD.AddFixItHint(Hint);
- return PD;
- }
-
-};
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const PartialDiagnostic &PD) {
- PD.Emit(DB);
- return DB;
-}
-
-/// \brief A partial diagnostic along with the source location where this
-/// diagnostic occurs.
-typedef std::pair<SourceLocation, PartialDiagnostic> PartialDiagnosticAt;
-
-} // end namespace clang
-#endif
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
deleted file mode 100644
index 84dd291..0000000
--- a/include/clang/Basic/PlistSupport.h
+++ /dev/null
@@ -1,119 +0,0 @@
-//===---------- PlistSupport.h - Plist Output Utilities ---------*- 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_BASIC_PLISTSUPPORT_H
-#define LLVM_CLANG_BASIC_PLISTSUPPORT_H
-
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-namespace markup {
-typedef llvm::DenseMap<FileID, unsigned> FIDMap;
-
-inline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
- const SourceManager &SM, SourceLocation L) {
- FileID FID = SM.getFileID(SM.getExpansionLoc(L));
- FIDMap::iterator I = FIDs.find(FID);
- if (I != FIDs.end())
- return;
- FIDs[FID] = V.size();
- V.push_back(FID);
-}
-
-inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
- SourceLocation L) {
- FileID FID = SM.getFileID(SM.getExpansionLoc(L));
- FIDMap::const_iterator I = FIDs.find(FID);
- assert(I != FIDs.end());
- return I->second;
-}
-
-inline raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
- for (unsigned i = 0; i < indent; ++i)
- o << ' ';
- return o;
-}
-
-inline raw_ostream &EmitPlistHeader(raw_ostream &o) {
- static const char *PlistHeader =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
- "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
- "<plist version=\"1.0\">\n";
- return o << PlistHeader;
-}
-
-inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) {
- o << "<integer>";
- o << value;
- o << "</integer>";
- return o;
-}
-
-inline raw_ostream &EmitString(raw_ostream &o, StringRef s) {
- o << "<string>";
- for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
- char c = *I;
- switch (c) {
- default:
- o << c;
- break;
- case '&':
- o << "&amp;";
- break;
- case '<':
- o << "&lt;";
- break;
- case '>':
- o << "&gt;";
- break;
- case '\'':
- o << "&apos;";
- break;
- case '\"':
- o << "&quot;";
- break;
- }
- }
- o << "</string>";
- return o;
-}
-
-inline void EmitLocation(raw_ostream &o, const SourceManager &SM,
- SourceLocation L, const FIDMap &FM, unsigned indent) {
- if (L.isInvalid()) return;
-
- FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM));
-
- Indent(o, indent) << "<dict>\n";
- Indent(o, indent) << " <key>line</key>";
- EmitInteger(o, Loc.getExpansionLineNumber()) << '\n';
- Indent(o, indent) << " <key>col</key>";
- EmitInteger(o, Loc.getExpansionColumnNumber()) << '\n';
- Indent(o, indent) << " <key>file</key>";
- EmitInteger(o, GetFID(FM, SM, Loc)) << '\n';
- Indent(o, indent) << "</dict>\n";
-}
-
-inline void EmitRange(raw_ostream &o, const SourceManager &SM,
- CharSourceRange R, const FIDMap &FM, unsigned indent) {
- if (R.isInvalid()) return;
-
- assert(R.isCharRange() && "cannot handle a token range");
- Indent(o, indent) << "<array>\n";
- EmitLocation(o, SM, R.getBegin(), FM, indent + 1);
- EmitLocation(o, SM, R.getEnd(), FM, indent + 1);
- Indent(o, indent) << "</array>\n";
-}
-}
-}
-
-#endif
diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h
deleted file mode 100644
index 6badae5..0000000
--- a/include/clang/Basic/PrettyStackTrace.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===- clang/Basic/PrettyStackTrace.h - Pretty Crash 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 PrettyStackTraceEntry class, which is used to make
-/// crashes give more contextual information about what the program was doing
-/// when it crashed.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_PRETTYSTACKTRACE_H
-#define LLVM_CLANG_BASIC_PRETTYSTACKTRACE_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/PrettyStackTrace.h"
-
-namespace clang {
-
- /// If a crash happens while one of these objects are live, the message
- /// is printed out along with the specified source location.
- class PrettyStackTraceLoc : public llvm::PrettyStackTraceEntry {
- SourceManager &SM;
- SourceLocation Loc;
- const char *Message;
- public:
- PrettyStackTraceLoc(SourceManager &sm, SourceLocation L, const char *Msg)
- : SM(sm), Loc(L), Message(Msg) {}
- void print(raw_ostream &OS) const override;
- };
-}
-
-#endif
diff --git a/include/clang/Basic/SanitizerBlacklist.h b/include/clang/Basic/SanitizerBlacklist.h
deleted file mode 100644
index e651e18..0000000
--- a/include/clang/Basic/SanitizerBlacklist.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===--- SanitizerBlacklist.h - Blacklist for sanitizers --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// User-provided blacklist used to disable/alter instrumentation done in
-// sanitizers.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_SANITIZERBLACKLIST_H
-#define LLVM_CLANG_BASIC_SANITIZERBLACKLIST_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/SpecialCaseList.h"
-#include <memory>
-
-namespace clang {
-
-class SanitizerBlacklist {
- std::unique_ptr<llvm::SpecialCaseList> SCL;
- SourceManager &SM;
-
-public:
- SanitizerBlacklist(const std::vector<std::string> &BlacklistPaths,
- SourceManager &SM);
- bool isBlacklistedGlobal(StringRef GlobalName,
- StringRef Category = StringRef()) const;
- bool isBlacklistedType(StringRef MangledTypeName,
- StringRef Category = StringRef()) const;
- bool isBlacklistedFunction(StringRef FunctionName) const;
- bool isBlacklistedFile(StringRef FileName,
- StringRef Category = StringRef()) const;
- bool isBlacklistedLocation(SourceLocation Loc,
- StringRef Category = StringRef()) const;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
deleted file mode 100644
index 4b68593..0000000
--- a/include/clang/Basic/Sanitizers.def
+++ /dev/null
@@ -1,122 +0,0 @@
-//===--- Sanitizers.def - Runtime sanitizer options -------------*- 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 options for specifying which runtime sanitizers to
-// enable. Users of this file must define the SANITIZER macro to make use of
-// this information. Users of this file can also define the SANITIZER_GROUP
-// macro to get information on options which refer to sets of sanitizers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SANITIZER
-#error "Define SANITIZER prior to including this file!"
-#endif
-
-// SANITIZER(NAME, ID)
-
-// The first value is the name of the sanitizer as a string. The sanitizer can
-// be enabled by specifying -fsanitize=NAME.
-
-// The second value is an identifier which can be used to refer to the
-// sanitizer.
-
-
-// SANITIZER_GROUP(NAME, ID, ALIAS)
-
-// The first two values have the same semantics as the corresponding SANITIZER
-// values. The third value is an expression ORing together the IDs of individual
-// sanitizers in this group.
-
-#ifndef SANITIZER_GROUP
-#define SANITIZER_GROUP(NAME, ID, ALIAS)
-#endif
-
-
-// AddressSanitizer
-SANITIZER("address", Address)
-
-// Kernel AddressSanitizer (KASan)
-SANITIZER("kernel-address", KernelAddress)
-
-// MemorySanitizer
-SANITIZER("memory", Memory)
-
-// ThreadSanitizer
-SANITIZER("thread", Thread)
-
-// LeakSanitizer
-SANITIZER("leak", Leak)
-
-// UndefinedBehaviorSanitizer
-SANITIZER("alignment", Alignment)
-SANITIZER("array-bounds", ArrayBounds)
-SANITIZER("bool", Bool)
-SANITIZER("enum", Enum)
-SANITIZER("float-cast-overflow", FloatCastOverflow)
-SANITIZER("float-divide-by-zero", FloatDivideByZero)
-SANITIZER("function", Function)
-SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
-SANITIZER("nonnull-attribute", NonnullAttribute)
-SANITIZER("null", Null)
-SANITIZER("object-size", ObjectSize)
-SANITIZER("return", Return)
-SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute)
-SANITIZER("shift-base", ShiftBase)
-SANITIZER("shift-exponent", ShiftExponent)
-SANITIZER_GROUP("shift", Shift, ShiftBase | ShiftExponent)
-SANITIZER("signed-integer-overflow", SignedIntegerOverflow)
-SANITIZER("unreachable", Unreachable)
-SANITIZER("vla-bound", VLABound)
-SANITIZER("vptr", Vptr)
-
-// IntegerSanitizer
-SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow)
-
-// DataFlowSanitizer
-SANITIZER("dataflow", DataFlow)
-
-// Control Flow Integrity
-SANITIZER("cfi-cast-strict", CFICastStrict)
-SANITIZER("cfi-derived-cast", CFIDerivedCast)
-SANITIZER("cfi-icall", CFIICall)
-SANITIZER("cfi-unrelated-cast", CFIUnrelatedCast)
-SANITIZER("cfi-nvcall", CFINVCall)
-SANITIZER("cfi-vcall", CFIVCall)
-SANITIZER_GROUP("cfi", CFI,
- CFIDerivedCast | CFIICall | CFIUnrelatedCast | CFINVCall |
- CFIVCall)
-
-// Safe Stack
-SANITIZER("safe-stack", SafeStack)
-
-// -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,
- Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow |
- FloatDivideByZero | IntegerDivideByZero | NonnullAttribute |
- Null | ObjectSize | Return | ReturnsNonnullAttribute |
- Shift | SignedIntegerOverflow | Unreachable | VLABound |
- Function | Vptr)
-
-// -fsanitize=undefined-trap is an alias for -fsanitize=undefined.
-SANITIZER_GROUP("undefined-trap", UndefinedTrap, Undefined)
-
-SANITIZER_GROUP("integer", Integer,
- SignedIntegerOverflow | UnsignedIntegerOverflow | Shift |
- IntegerDivideByZero)
-
-SANITIZER("local-bounds", LocalBounds)
-SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
-
-// Magic group, containing all sanitizers. For example, "-fno-sanitize=all"
-// can be used to disable all the sanitizers.
-SANITIZER_GROUP("all", All, ~0ULL)
-
-#undef SANITIZER
-#undef SANITIZER_GROUP
diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h
deleted file mode 100644
index 98e70de..0000000
--- a/include/clang/Basic/Sanitizers.h
+++ /dev/null
@@ -1,86 +0,0 @@
-//===--- Sanitizers.h - C Language Family Language Options ------*- 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::SanitizerKind enum.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_SANITIZERS_H
-#define LLVM_CLANG_BASIC_SANITIZERS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/MathExtras.h"
-
-namespace clang {
-
-typedef uint64_t SanitizerMask;
-
-namespace SanitizerKind {
-
-// Assign ordinals to possible values of -fsanitize= flag, which we will use as
-// bit positions.
-enum SanitizerOrdinal : uint64_t {
-#define SANITIZER(NAME, ID) SO_##ID,
-#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
-#include "clang/Basic/Sanitizers.def"
- SO_Count
-};
-
-// Define the set of sanitizer kinds, as well as the set of sanitizers each
-// sanitizer group expands into.
-#define SANITIZER(NAME, ID) \
- const SanitizerMask ID = 1ULL << SO_##ID;
-#define SANITIZER_GROUP(NAME, ID, ALIAS) \
- const SanitizerMask ID = ALIAS; \
- const SanitizerMask ID##Group = 1ULL << SO_##ID##Group;
-#include "clang/Basic/Sanitizers.def"
-
-}
-
-struct SanitizerSet {
- SanitizerSet() : Mask(0) {}
-
- /// \brief 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.
- bool hasOneOf(SanitizerMask K) const { return Mask & K; }
-
- /// \brief Enable or disable a certain (single) sanitizer.
- void set(SanitizerMask K, bool Value) {
- assert(llvm::isPowerOf2_64(K));
- Mask = Value ? (Mask | K) : (Mask & ~K);
- }
-
- /// \brief Disable all sanitizers.
- void clear() { Mask = 0; }
-
- /// \brief Returns true if at least one sanitizer is enabled.
- bool empty() const { return Mask == 0; }
-
- /// \brief Bitmask of enabled sanitizers.
- SanitizerMask Mask;
-};
-
-/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
-/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
-SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
-
-/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
-/// this group enables.
-SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
deleted file mode 100644
index 0aeba5e..0000000
--- a/include/clang/Basic/SourceLocation.h
+++ /dev/null
@@ -1,438 +0,0 @@
-//===--- SourceLocation.h - Compact identifier for Source Files -*- 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::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/Support/PointerLikeTypeTraits.h"
-#include <cassert>
-#include <functional>
-#include <string>
-#include <utility>
-
-namespace llvm {
- class MemoryBuffer;
- template <typename T> struct DenseMapInfo;
- template <typename T> struct isPodLike;
-}
-
-namespace clang {
-
-class SourceManager;
-
-/// \brief 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
- /// this module, and <-1 is something loaded from another module.
- int ID;
-public:
- FileID() : ID(0) {}
-
- bool isValid() const { return ID != 0; }
- bool isInvalid() const { return ID == 0; }
-
- bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
- bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
- bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
- bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
- bool operator>(const FileID &RHS) const { return RHS < *this; }
- bool operator>=(const FileID &RHS) const { return RHS <= *this; }
-
- static FileID getSentinel() { return get(-1); }
- unsigned getHashValue() const { return static_cast<unsigned>(ID); }
-
-private:
- friend class SourceManager;
- friend class ASTWriter;
- friend class ASTReader;
-
- 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
-/// to get at the full include stack, line and column information.
-///
-/// Technically, a source location is simply an offset into the manager's view
-/// of the input source, which is all input buffers (including macro
-/// expansions) concatenated in an effectively arbitrary order. The manager
-/// actually maintains two blocks of input buffers. One, starting at offset
-/// 0 and growing upwards, contains all buffers from this module. The other,
-/// starting at the highest possible offset and growing downwards, contains
-/// buffers of loaded modules.
-///
-/// In addition, one bit of SourceLocation is used for quick access to the
-/// information whether the location is in a file or a macro expansion.
-///
-/// It is important that this type remains small. It is currently 32 bits wide.
-class SourceLocation {
- unsigned ID;
- friend class SourceManager;
- friend class ASTReader;
- friend class ASTWriter;
- enum : unsigned {
- MacroIDBit = 1U << 31
- };
-public:
-
- SourceLocation() : ID(0) {}
-
- bool isFileID() const { return (ID & MacroIDBit) == 0; }
- bool isMacroID() const { return (ID & MacroIDBit) != 0; }
-
- /// \brief 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
- /// option).
- bool isValid() const { return ID != 0; }
- bool isInvalid() const { return ID == 0; }
-
-private:
- /// \brief Return the offset into the manager's global input view.
- unsigned getOffset() const {
- return ID & ~MacroIDBit;
- }
-
- static SourceLocation getFileLoc(unsigned ID) {
- assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
- SourceLocation L;
- L.ID = ID;
- return L;
- }
-
- static SourceLocation getMacroLoc(unsigned ID) {
- assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
- SourceLocation L;
- L.ID = MacroIDBit | ID;
- return L;
- }
-public:
-
- /// \brief Return a source location with the specified offset from this
- /// SourceLocation.
- SourceLocation getLocWithOffset(int Offset) const {
- assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
- SourceLocation L;
- L.ID = ID+Offset;
- return L;
- }
-
- /// \brief 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
- /// a real SourceLocation.
- ///
- /// \see getRawEncoding.
- static SourceLocation getFromRawEncoding(unsigned Encoding) {
- SourceLocation X;
- X.ID = Encoding;
- return X;
- }
-
- /// \brief When a SourceLocation itself cannot be used, this returns
- /// an (opaque) pointer encoding for it.
- ///
- /// This should only be passed to SourceLocation::getFromPtrEncoding, it
- /// should not be inspected directly.
- void* getPtrEncoding() const {
- // Double cast to avoid a warning "cast to pointer from integer of different
- // size".
- return (void*)(uintptr_t)getRawEncoding();
- }
-
- /// \brief 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);
- }
-
- void print(raw_ostream &OS, const SourceManager &SM) const;
- std::string printToString(const SourceManager &SM) const;
- void dump(const SourceManager &SM) const;
-};
-
-inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
- return LHS.getRawEncoding() == RHS.getRawEncoding();
-}
-
-inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
- return !(LHS == RHS);
-}
-
-inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
- return LHS.getRawEncoding() < RHS.getRawEncoding();
-}
-
-/// \brief A trivial tuple used to represent a source range.
-class SourceRange {
- SourceLocation B;
- SourceLocation E;
-public:
- SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
- SourceRange(SourceLocation loc) : B(loc), E(loc) {}
- SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
-
- SourceLocation getBegin() const { return B; }
- SourceLocation getEnd() const { return E; }
-
- void setBegin(SourceLocation b) { B = b; }
- void setEnd(SourceLocation e) { E = e; }
-
- bool isValid() const { return B.isValid() && E.isValid(); }
- bool isInvalid() const { return !isValid(); }
-
- bool operator==(const SourceRange &X) const {
- return B == X.B && E == X.E;
- }
-
- bool operator!=(const SourceRange &X) const {
- return B != X.B || E != X.E;
- }
-};
-
-/// \brief 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
-/// last token of the range (a "token range"). In the token range case, the
-/// size of the last token must be measured to determine the actual end of the
-/// range.
-class CharSourceRange {
- SourceRange Range;
- bool IsTokenRange;
-public:
- CharSourceRange() : IsTokenRange(false) {}
- CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
-
- static CharSourceRange getTokenRange(SourceRange R) {
- return CharSourceRange(R, true);
- }
-
- static CharSourceRange getCharRange(SourceRange R) {
- return CharSourceRange(R, false);
- }
-
- 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
- /// the last token. Return false if the end of this range specifies the last
- /// character in the range.
- bool isTokenRange() const { return IsTokenRange; }
- bool isCharRange() const { return !IsTokenRange; }
-
- SourceLocation getBegin() const { return Range.getBegin(); }
- SourceLocation getEnd() const { return Range.getEnd(); }
- SourceRange getAsRange() const { return Range; }
-
- void setBegin(SourceLocation b) { Range.setBegin(b); }
- void setEnd(SourceLocation e) { Range.setEnd(e); }
-
- bool isValid() const { return Range.isValid(); }
- bool isInvalid() const { return !isValid(); }
-};
-
-/// \brief 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;
-public:
- /// \brief Creates a FullSourceLoc where isValid() returns \c false.
- explicit FullSourceLoc() : SrcMgr(nullptr) {}
-
- explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
- : SourceLocation(Loc), SrcMgr(&SM) {}
-
- /// \pre This FullSourceLoc has an associated SourceManager.
- const SourceManager &getManager() const {
- assert(SrcMgr && "SourceManager is NULL.");
- return *SrcMgr;
- }
-
- FileID getFileID() const;
-
- FullSourceLoc getExpansionLoc() const;
- FullSourceLoc getSpellingLoc() const;
-
- unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
- unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
-
- unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
- unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
-
- const char *getCharacterData(bool *Invalid = nullptr) const;
-
-
- /// \brief 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.
- ///
- /// The first element is the FileID, the second is the offset from the
- /// start of the buffer of the location.
- std::pair<FileID, unsigned> getDecomposedLoc() const;
-
- bool isInSystemHeader() const;
-
- /// \brief 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.
- ///
- /// \returns true if this source location comes before 'Loc', false otherwise.
- bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const {
- assert(Loc.isValid());
- assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
- return isBeforeInTranslationUnitThan((SourceLocation)Loc);
- }
-
- /// \brief Comparison function class, useful for sorting FullSourceLocs.
- struct BeforeThanCompare : public std::binary_function<FullSourceLoc,
- FullSourceLoc, bool> {
- bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
- return lhs.isBeforeInTranslationUnitThan(rhs);
- }
- };
-
- /// \brief Prints information about this FullSourceLoc to stderr.
- ///
- /// This is useful for debugging.
- void dump() const;
-
- friend inline bool
- operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
- return LHS.getRawEncoding() == RHS.getRawEncoding() &&
- LHS.SrcMgr == RHS.SrcMgr;
- }
-
- friend inline bool
- operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
- return !(LHS == RHS);
- }
-
-};
-
-/// \brief Represents an unpacked "presumed" location which can be presented
-/// to the user.
-///
-/// A 'presumed' location can be modified by \#line and GNU line marker
-/// directives and is always the expansion point of a normal location.
-///
-/// You can get a PresumedLoc from a SourceLocation with SourceManager.
-class PresumedLoc {
- const char *Filename;
- unsigned Line, Col;
- SourceLocation IncludeLoc;
-public:
- PresumedLoc() : Filename(nullptr) {}
- 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.
- ///
- /// 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.
- ///
- /// This can be affected by \#line etc.
- const char *getFilename() const { return Filename; }
-
- /// \brief Return the presumed line number of this location.
- ///
- /// This can be affected by \#line etc.
- unsigned getLine() const { return Line; }
-
- /// \brief Return the presumed column number of this location.
- ///
- /// This cannot be affected by \#line, but is packaged here for convenience.
- unsigned getColumn() const { return Col; }
-
- /// \brief Return the presumed include location of this location.
- ///
- /// This can be affected by GNU linemarker directives.
- SourceLocation getIncludeLoc() const { return IncludeLoc; }
-};
-
-
-} // end 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 inline clang::FileID getTombstoneKey() {
- return clang::FileID::getSentinel();
- }
-
- static unsigned getHashValue(clang::FileID S) {
- return S.getHashValue();
- }
-
- static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
- return LHS == RHS;
- }
- };
-
- template <>
- struct isPodLike<clang::SourceLocation> { static const bool value = true; };
- template <>
- struct isPodLike<clang::FileID> { static const bool value = true; };
-
- // Teach SmallPtrSet how to handle SourceLocation.
- template<>
- class PointerLikeTypeTraits<clang::SourceLocation> {
- public:
- static inline void *getAsVoidPointer(clang::SourceLocation L) {
- return L.getPtrEncoding();
- }
- static inline clang::SourceLocation getFromVoidPointer(void *P) {
- return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P);
- }
- enum { NumLowBitsAvailable = 0 };
- };
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
deleted file mode 100644
index 99392a0..0000000
--- a/include/clang/Basic/SourceManager.h
+++ /dev/null
@@ -1,1711 +0,0 @@
-//===--- SourceManager.h - Track and cache source files ---------*- 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 SourceManager interface.
-///
-/// There are three different types of locations in a %file: a spelling
-/// location, an expansion location, and a presumed location.
-///
-/// Given an example of:
-/// \code
-/// #define min(x, y) x < y ? x : y
-/// \endcode
-///
-/// and then later on a use of min:
-/// \code
-/// #line 17
-/// return min(a, b);
-/// \endcode
-///
-/// The expansion location is the line in the source code where the macro
-/// was expanded (the return statement), the spelling location is the
-/// location in the source where the macro was originally defined,
-/// and the presumed location is where the line directive states that
-/// the line is 17, or any other line.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_SOURCEMANAGER_H
-#define LLVM_CLANG_BASIC_SOURCEMANAGER_H
-
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <cassert>
-#include <map>
-#include <memory>
-#include <vector>
-
-namespace clang {
-
-class DiagnosticsEngine;
-class SourceManager;
-class FileManager;
-class FileEntry;
-class LineTableInfo;
-class LangOptions;
-class ASTWriter;
-class ASTReader;
-
-/// \brief 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,
- /// system code, or system code which is implicitly 'extern "C"' in C++ mode.
- ///
- /// Entire directories can be tagged with this (this is maintained by
- /// DirectoryLookup and friends) as can specific FileInfos when a \#pragma
- /// system_header is seen or in various other cases.
- ///
- enum CharacteristicKind {
- C_User, C_System, C_ExternCSystem
- };
-
- /// \brief One instance of this struct is kept for every file loaded or used.
- ///
- /// This object owns the MemoryBuffer object.
- class LLVM_ALIGNAS(8) ContentCache {
- enum CCFlags {
- /// \brief Whether the buffer is invalid.
- InvalidFlag = 0x01,
- /// \brief Whether the buffer should not be freed on destruction.
- DoNotFreeFlag = 0x02
- };
-
- /// \brief The actual buffer containing the characters from the input
- /// file.
- ///
- /// This is owned by the ContentCache object. The bits indicate
- /// whether the buffer is invalid.
- mutable llvm::PointerIntPair<llvm::MemoryBuffer *, 2> Buffer;
-
- public:
- /// \brief Reference to the file entry representing this ContentCache.
- ///
- /// This reference does not own the FileEntry object.
- ///
- /// It is possible for this to be NULL if the ContentCache encapsulates
- /// an imaginary text buffer.
- const FileEntry *OrigEntry;
-
- /// \brief 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.
- ///
- /// This is lazily computed. This is owned by the SourceManager
- /// BumpPointerAllocator object.
- unsigned *SourceLineCache;
-
- /// \brief The number of lines in this ContentCache.
- ///
- /// This is only valid if SourceLineCache is non-null.
- unsigned NumLines;
-
- /// \brief 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
- /// file considered as a system one.
- unsigned IsSystemFile : 1;
-
- /// \brief 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;
-
- ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {}
-
- ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
- : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt),
- SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
- IsSystemFile(false), IsTransient(false) {}
-
- ~ContentCache();
-
- /// The copy ctor does not allow copies where source object has either
- /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
- /// is not transferred, so this is a logical error.
- ContentCache(const ContentCache &RHS)
- : Buffer(nullptr, false), SourceLineCache(nullptr),
- BufferOverridden(false), IsSystemFile(false), IsTransient(false) {
- OrigEntry = RHS.OrigEntry;
- ContentsEntry = RHS.ContentsEntry;
-
- assert(RHS.Buffer.getPointer() == nullptr &&
- RHS.SourceLineCache == nullptr &&
- "Passed ContentCache object cannot own a buffer.");
-
- NumLines = RHS.NumLines;
- }
-
- /// \brief Returns the memory buffer for the associated content.
- ///
- /// \param Diag Object through which diagnostics will be emitted if the
- /// buffer cannot be retrieved.
- ///
- /// \param Loc If specified, is the location that invalid file diagnostics
- /// will be emitted at.
- ///
- /// \param Invalid If non-NULL, will be set \c true if an error occurred.
- llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
- const SourceManager &SM,
- SourceLocation Loc = SourceLocation(),
- bool *Invalid = nullptr) const;
-
- /// \brief Returns the size of the content encapsulated by this
- /// ContentCache.
- ///
- /// This can be the size of the source file or the size of an
- /// arbitrary scratch buffer. If the ContentCache encapsulates a source
- /// file this size is retrieved from the file's FileEntry.
- unsigned getSize() const;
-
- /// \brief Returns the number of bytes actually mapped for this
- /// ContentCache.
- ///
- /// This can be 0 if the MemBuffer was not actually expanded.
- unsigned getSizeBytesMapped() const;
-
- /// Returns the kind of memory used to back the memory buffer for
- /// this content cache. This is used for performance analysis.
- llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
-
- void setBuffer(std::unique_ptr<llvm::MemoryBuffer> B) {
- assert(!Buffer.getPointer() && "MemoryBuffer already set.");
- Buffer.setPointer(B.release());
- Buffer.setInt(0);
- }
-
- /// \brief 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)
- /// with the given buffer.
- void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree = false);
-
- /// \brief Determine whether the buffer itself is invalid.
- bool isBufferInvalid() const {
- return Buffer.getInt() & InvalidFlag;
- }
-
- /// \brief Determine whether the buffer should be freed.
- bool shouldFreeBuffer() const {
- return (Buffer.getInt() & DoNotFreeFlag) == 0;
- }
-
- private:
- // Disable assignments.
- ContentCache &operator=(const ContentCache& RHS) = delete;
- };
-
- // Assert that the \c ContentCache objects will always be 8-byte aligned so
- // that we can pack 3 bits of integer into pointers to such objects.
- static_assert(llvm::AlignOf<ContentCache>::Alignment >= 8,
- "ContentCache must be 8-byte aligned.");
-
- /// \brief 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
- /// from. This information encodes the \#include chain that a token was
- /// expanded from. The main include file has an invalid IncludeLoc.
- ///
- /// FileInfos contain a "ContentCache *", with the contents of the file.
- ///
- class FileInfo {
- /// \brief 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
- /// preprocessing of this \#include, including this SLocEntry.
- ///
- /// Zero means the preprocessor didn't provide such info for this SLocEntry.
- unsigned NumCreatedFIDs;
-
- /// \brief Contains the ContentCache* and the bits indicating the
- /// characteristic of the file and whether it has \#line info, all
- /// bitmangled together.
- uintptr_t Data;
-
- friend class clang::SourceManager;
- friend class clang::ASTWriter;
- friend class clang::ASTReader;
- public:
- /// \brief Return a FileInfo object.
- static FileInfo get(SourceLocation IL, const ContentCache *Con,
- CharacteristicKind FileCharacter) {
- FileInfo X;
- X.IncludeLoc = IL.getRawEncoding();
- X.NumCreatedFIDs = 0;
- X.Data = (uintptr_t)Con;
- assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
- assert((unsigned)FileCharacter < 4 && "invalid file character");
- X.Data |= (unsigned)FileCharacter;
- return X;
- }
-
- SourceLocation getIncludeLoc() const {
- return SourceLocation::getFromRawEncoding(IncludeLoc);
- }
- const ContentCache* getContentCache() const {
- return reinterpret_cast<const ContentCache*>(Data & ~uintptr_t(7));
- }
-
- /// \brief Return whether this is a system header or not.
- CharacteristicKind getFileCharacteristic() const {
- return (CharacteristicKind)(Data & 3);
- }
-
- /// \brief Return true if this FileID has \#line directives in it.
- bool hasLineDirectives() const { return (Data & 4) != 0; }
-
- /// \brief Set the flag that indicates that this FileID has
- /// line table entries associated with it.
- void setHasLineDirectives() {
- Data |= 4;
- }
- };
-
- /// \brief 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.
- unsigned SpellingLoc;
-
- /// In a macro expansion, ExpansionLocStart and ExpansionLocEnd
- /// indicate the start and end of the expansion. In object-like macros,
- /// they will be the same. In a function-like macro expansion, the start
- /// will be the identifier and the end will be the ')'. Finally, in
- /// macro-argument instantiations, the end will be 'SourceLocation()', an
- /// invalid location.
- unsigned ExpansionLocStart, ExpansionLocEnd;
-
- public:
- SourceLocation getSpellingLoc() const {
- return SourceLocation::getFromRawEncoding(SpellingLoc);
- }
- SourceLocation getExpansionLocStart() const {
- return SourceLocation::getFromRawEncoding(ExpansionLocStart);
- }
- SourceLocation getExpansionLocEnd() const {
- SourceLocation EndLoc =
- SourceLocation::getFromRawEncoding(ExpansionLocEnd);
- return EndLoc.isInvalid() ? getExpansionLocStart() : EndLoc;
- }
-
- std::pair<SourceLocation,SourceLocation> getExpansionLocRange() const {
- return std::make_pair(getExpansionLocStart(), getExpansionLocEnd());
- }
-
- bool isMacroArgExpansion() const {
- // Note that this needs to return false for default constructed objects.
- return getExpansionLocStart().isValid() &&
- SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid();
- }
-
- bool isMacroBodyExpansion() const {
- return getExpansionLocStart().isValid() &&
- SourceLocation::getFromRawEncoding(ExpansionLocEnd).isValid();
- }
-
- bool isFunctionMacroExpansion() const {
- return getExpansionLocStart().isValid() &&
- getExpansionLocStart() != getExpansionLocEnd();
- }
-
- /// \brief 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) {
- ExpansionInfo X;
- X.SpellingLoc = SpellingLoc.getRawEncoding();
- X.ExpansionLocStart = Start.getRawEncoding();
- X.ExpansionLocEnd = End.getRawEncoding();
- return X;
- }
-
- /// \brief 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
- /// expanded). This doesn't need to be a range because a macro is always
- /// expanded at a macro parameter reference, and macro parameters are
- /// always exactly one token. SpellingLoc specifies the spelling location
- /// (where the characters from the token come from). ExpansionLoc and
- /// SpellingLoc can both refer to normal File SLocs or expansion locations.
- ///
- /// Given the code:
- /// \code
- /// #define F(x) f(x)
- /// F(42);
- /// \endcode
- ///
- /// When expanding '\c F(42)', the '\c x' would call this with an
- /// SpellingLoc pointing at '\c 42' and an ExpansionLoc pointing at its
- /// location in the definition of '\c F'.
- 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.
- return create(SpellingLoc, ExpansionLoc, SourceLocation());
- }
- };
-
- /// \brief 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.
- class SLocEntry {
- unsigned Offset : 31;
- unsigned IsExpansion : 1;
- union {
- FileInfo File;
- ExpansionInfo Expansion;
- };
- public:
- unsigned getOffset() const { return Offset; }
-
- bool isExpansion() const { return IsExpansion; }
- bool isFile() const { return !isExpansion(); }
-
- const FileInfo &getFile() const {
- assert(isFile() && "Not a file SLocEntry!");
- return File;
- }
-
- const ExpansionInfo &getExpansion() const {
- assert(isExpansion() && "Not a macro expansion SLocEntry!");
- return Expansion;
- }
-
- static SLocEntry get(unsigned Offset, const FileInfo &FI) {
- assert(!(Offset & (1 << 31)) && "Offset is too large");
- SLocEntry E;
- E.Offset = Offset;
- E.IsExpansion = false;
- E.File = FI;
- return E;
- }
-
- static SLocEntry get(unsigned Offset, const ExpansionInfo &Expansion) {
- assert(!(Offset & (1 << 31)) && "Offset is too large");
- SLocEntry E;
- E.Offset = Offset;
- E.IsExpansion = true;
- E.Expansion = Expansion;
- return E;
- }
- };
-} // end SrcMgr namespace.
-
-/// \brief External source of source location entries.
-class ExternalSLocEntrySource {
-public:
- virtual ~ExternalSLocEntrySource();
-
- /// \brief 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
- /// 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.
-///
-/// The cache structure is complex enough to be worth breaking out of
-/// SourceManager.
-class InBeforeInTUCacheEntry {
- /// \brief 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.
- ///
- /// This is used to compare macro expansion locations.
- bool IsLQFIDBeforeRQFID;
-
- /// \brief 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.
- ///
- /// 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
- /// random token in the parent.
- unsigned LCommonOffset, RCommonOffset;
-public:
- /// \brief Return true if the currently cached values match up with
- /// the specified LHS/RHS query.
- ///
- /// If not, we can't use the cache.
- bool isCacheValid(FileID LHS, FileID RHS) const {
- return LQueryFID == LHS && RQueryFID == RHS;
- }
-
- /// \brief 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,
- // use the #include loc in the common file.
- if (LQueryFID != CommonFID) LOffset = LCommonOffset;
- if (RQueryFID != CommonFID) ROffset = RCommonOffset;
-
- // It is common for multiple macro expansions to be "included" from the same
- // location (expansion location), in which case use the order of the FileIDs
- // to determine which came first. This will also take care the case where
- // one of the locations points at the inclusion/expansion point of the other
- // in which case its FileID will come before the other.
- if (LOffset == ROffset)
- return IsLQFIDBeforeRQFID;
-
- return LOffset < ROffset;
- }
-
- /// \brief Set up a new query.
- void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) {
- assert(LHS != RHS);
- LQueryFID = LHS;
- RQueryFID = RHS;
- IsLQFIDBeforeRQFID = isLFIDBeforeRFID;
- }
-
- void clear() {
- LQueryFID = RQueryFID = FileID();
- IsLQFIDBeforeRQFID = false;
- }
-
- void setCommonLoc(FileID commonFID, unsigned lCommonOffset,
- unsigned rCommonOffset) {
- CommonFID = commonFID;
- LCommonOffset = lCommonOffset;
- RCommonOffset = rCommonOffset;
- }
-
-};
-
-/// \brief The stack used when building modules on demand, which is used
-/// to provide a link between the source managers of the different compiler
-/// instances.
-typedef ArrayRef<std::pair<std::string, FullSourceLoc> > ModuleBuildStack;
-
-/// \brief 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.
-///
-/// The SourceManager can be queried for information about SourceLocation
-/// objects, turning them into either spelling or expansion locations. Spelling
-/// locations represent where the bytes corresponding to a token came from and
-/// expansion locations represent where the location is in the user's view. In
-/// the case of a macro expansion, for example, the spelling location indicates
-/// where the expanded token came from and the expansion location specifies
-/// where it was expanded.
-class SourceManager : public RefCountedBase<SourceManager> {
- /// \brief DiagnosticsEngine object.
- DiagnosticsEngine &Diag;
-
- FileManager &FileMgr;
-
- mutable llvm::BumpPtrAllocator ContentCacheAlloc;
-
- /// \brief Memoized information about all of the files tracked by this
- /// SourceManager.
- ///
- /// This map allows us to merge ContentCache entries based
- /// on their FileEntry*. All ContentCache objects will thus have unique,
- /// non-null, FileEntry pointers.
- llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
-
- /// \brief True if the ContentCache for files that are overridden by other
- /// files, should report the original file name. Defaults to true.
- bool OverridenFilesKeepOriginalName;
-
- /// \brief 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
- /// as transient (may not be present in later compilations using a module
- /// file created from this compilation). Defaults to false.
- bool FilesAreTransient;
-
- struct OverriddenFilesInfoTy {
- /// \brief 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.
- llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer;
- };
-
- /// \brief Lazily create the object keeping overridden files info, since
- /// it is uncommonly used.
- std::unique_ptr<OverriddenFilesInfoTy> OverriddenFilesInfo;
-
- OverriddenFilesInfoTy &getOverriddenFilesInfo() {
- if (!OverriddenFilesInfo)
- OverriddenFilesInfo.reset(new OverriddenFilesInfoTy);
- return *OverriddenFilesInfo;
- }
-
- /// \brief 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.
- ///
- /// 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.
- ///
- /// 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.
- ///
- /// This is LocalSLocEntryTable.back().Offset + the size of that entry.
- unsigned NextLocalOffset;
-
- /// \brief 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
- /// starts at 2^31.
- static const unsigned MaxLoadedOffset = 1U << 31U;
-
- /// \brief 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.
- ExternalSLocEntrySource *ExternalSLocEntries;
-
- /// \brief 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.
- ///
- /// This is referenced by indices from SLocEntryTable.
- LineTableInfo *LineTable;
-
- /// \brief 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.
- FileID MainFileID;
-
- /// \brief The file ID for the precompiled preamble there is one.
- FileID PreambleFileID;
-
- // Statistics for -print-stats.
- mutable unsigned NumLinearScans, NumBinaryProbes;
-
- /// \brief Associates a FileID with its "included/expanded in" decomposed
- /// location.
- ///
- /// Used to cache results from and speed-up \c getDecomposedIncludedLoc
- /// function.
- mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned> > IncludedLocMap;
-
- /// The key value into the IsBeforeInTUCache table.
- typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
-
- /// The IsBeforeInTranslationUnitCache is a mapping from FileID pairs
- /// to cache results.
- typedef llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>
- InBeforeInTUCache;
-
- /// Cache results for the isBeforeInTranslationUnit method.
- mutable InBeforeInTUCache IBTUCache;
- mutable InBeforeInTUCacheEntry IBTUCacheOverflow;
-
- /// Return the cache entry for comparing the given file IDs
- /// for isBeforeInTranslationUnit.
- InBeforeInTUCacheEntry &getInBeforeInTUCache(FileID LFID, FileID RFID) const;
-
- // Cache for the "fake" buffer used for error-recovery purposes.
- mutable std::unique_ptr<llvm::MemoryBuffer> FakeBufferForRecovery;
-
- mutable std::unique_ptr<SrcMgr::ContentCache> FakeContentCacheForRecovery;
-
- /// \brief Lazily computed map of macro argument chunks to their expanded
- /// source location.
- typedef std::map<unsigned, SourceLocation> MacroArgsMap;
-
- mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap;
-
- /// \brief 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.
- ///
- /// There is no way to set this value from the command line. If we ever need
- /// to do so (e.g., if on-demand module construction moves out-of-process),
- /// we can add a cc1-level option to do so.
- SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack;
-
- // SourceManager doesn't support copy construction.
- explicit SourceManager(const SourceManager&) = delete;
- void operator=(const SourceManager&) = delete;
-public:
- SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr,
- bool UserFilesAreVolatile = false);
- ~SourceManager();
-
- void clearIDTables();
-
- DiagnosticsEngine &getDiagnostics() const { return Diag; }
-
- FileManager &getFileManager() const { return FileMgr; }
-
- /// \brief 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
- /// (likely to change while trying to use them).
- bool userFilesAreVolatile() const { return UserFilesAreVolatile; }
-
- /// \brief Retrieve the module build stack.
- ModuleBuildStack getModuleBuildStack() const {
- return StoredModuleBuildStack;
- }
-
- /// \brief 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.
- void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc) {
- StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc));
- }
-
- //===--------------------------------------------------------------------===//
- // MainFileID creation and querying methods.
- //===--------------------------------------------------------------------===//
-
- /// \brief Returns the FileID of the main source file.
- FileID getMainFileID() const { return MainFileID; }
-
- /// \brief Set the file ID for the main source file.
- void setMainFileID(FileID FID) {
- MainFileID = FID;
- }
-
- /// \brief 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.
- FileID getPreambleFileID() const { return PreambleFileID; }
-
- //===--------------------------------------------------------------------===//
- // Methods to create new FileID's and macro expansions.
- //===--------------------------------------------------------------------===//
-
- /// \brief Create a new FileID that represents the specified file
- /// being \#included from the specified IncludePosition.
- ///
- /// This translates NULL into standard input.
- FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
- SrcMgr::CharacteristicKind FileCharacter,
- int LoadedID = 0, unsigned LoadedOffset = 0) {
- const SrcMgr::ContentCache *
- IR = getOrCreateContentCache(SourceFile,
- /*isSystemFile=*/FileCharacter != SrcMgr::C_User);
- assert(IR && "getOrCreateContentCache() cannot return NULL");
- return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset);
- }
-
- /// \brief 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.
- FileID createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer,
- SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
- int LoadedID = 0, unsigned LoadedOffset = 0,
- SourceLocation IncludeLoc = SourceLocation()) {
- return createFileID(createMemBufferContentCache(std::move(Buffer)),
- IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
- }
-
- /// \brief 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.
- SourceLocation createMacroArgExpansionLoc(SourceLocation Loc,
- SourceLocation ExpansionLoc,
- unsigned TokLength);
-
- /// \brief 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,
- int LoadedID = 0,
- unsigned LoadedOffset = 0);
-
- /// \brief 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
- /// already-allocated buffer.
- ///
- /// \param SourceFile the source file whose contents will be overridden.
- ///
- /// \param Buffer the memory buffer whose contents will be used as the
- /// data in the given source file.
- ///
- /// \param DoNotFree If true, then the buffer will not be freed when the
- /// source manager is destroyed.
- void overrideFileContents(const FileEntry *SourceFile,
- llvm::MemoryBuffer *Buffer, bool DoNotFree);
- void overrideFileContents(const FileEntry *SourceFile,
- std::unique_ptr<llvm::MemoryBuffer> Buffer) {
- overrideFileContents(SourceFile, Buffer.release(), /*DoNotFree*/ false);
- }
-
- /// \brief Override the given source file with another one.
- ///
- /// \param SourceFile the source file which will be overridden.
- ///
- /// \param NewFile the file whose contents will be used as the
- /// data instead of the contents of the given source file.
- void overrideFileContents(const FileEntry *SourceFile,
- const FileEntry *NewFile);
-
- /// \brief Returns true if the file contents have been overridden.
- bool isFileOverridden(const FileEntry *File) {
- if (OverriddenFilesInfo) {
- if (OverriddenFilesInfo->OverriddenFilesWithBuffer.count(File))
- return true;
- if (OverriddenFilesInfo->OverriddenFiles.find(File) !=
- OverriddenFilesInfo->OverriddenFiles.end())
- return true;
- }
- return false;
- }
-
- /// \brief 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.
- void setFileIsTransient(const FileEntry *SourceFile);
-
- /// \brief Specify that all files that are read during this compilation are
- /// transient.
- void setAllFilesAreTransient(bool Transient) {
- FilesAreTransient = Transient;
- }
-
- //===--------------------------------------------------------------------===//
- // FileID manipulation methods.
- //===--------------------------------------------------------------------===//
-
- /// \brief 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.
- llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
- bool *Invalid = nullptr) const {
- bool MyInvalid = false;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
- if (MyInvalid || !Entry.isFile()) {
- if (Invalid)
- *Invalid = true;
-
- return getFakeBufferForRecovery();
- }
-
- return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc,
- Invalid);
- }
-
- llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = nullptr) const {
- bool MyInvalid = false;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
- if (MyInvalid || !Entry.isFile()) {
- if (Invalid)
- *Invalid = true;
-
- return getFakeBufferForRecovery();
- }
-
- return Entry.getFile().getContentCache()->getBuffer(Diag, *this,
- SourceLocation(),
- Invalid);
- }
-
- /// \brief Returns the FileEntry record for the provided FileID.
- const FileEntry *getFileEntryForID(FileID FID) const {
- bool MyInvalid = false;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
- if (MyInvalid || !Entry.isFile())
- return nullptr;
-
- const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache();
- if (!Content)
- return nullptr;
- return Content->OrigEntry;
- }
-
- /// \brief Returns the FileEntry record for the provided SLocEntry.
- const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const
- {
- const SrcMgr::ContentCache *Content = sloc.getFile().getContentCache();
- if (!Content)
- return nullptr;
- return Content->OrigEntry;
- }
-
- /// \brief 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
- /// during preprocessing of \p FID, including it.
- unsigned getNumCreatedFIDsForFileID(FileID FID) const {
- bool Invalid = false;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
- if (Invalid || !Entry.isFile())
- return 0;
-
- return Entry.getFile().NumCreatedFIDs;
- }
-
- /// \brief 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;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
- if (Invalid || !Entry.isFile())
- return;
-
- assert(Entry.getFile().NumCreatedFIDs == 0 && "Already set!");
- const_cast<SrcMgr::FileInfo &>(Entry.getFile()).NumCreatedFIDs = NumFIDs;
- }
-
- //===--------------------------------------------------------------------===//
- // SourceLocation manipulation methods.
- //===--------------------------------------------------------------------===//
-
- /// \brief 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
- /// the entry in SLocEntryTable which contains the specified location.
- ///
- FileID getFileID(SourceLocation SpellingLoc) const {
- unsigned SLocOffset = SpellingLoc.getOffset();
-
- // If our one-entry cache covers this offset, just return it.
- if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
- return LastFileIDLookup;
-
- return getFileIDSlow(SLocOffset);
- }
-
- /// \brief 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
- /// the specified file.
- SourceLocation getLocForStartOfFile(FileID FID) const {
- bool Invalid = false;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
- if (Invalid || !Entry.isFile())
- return SourceLocation();
-
- unsigned FileOffset = Entry.getOffset();
- return SourceLocation::getFileLoc(FileOffset);
- }
-
- /// \brief Return the source location corresponding to the last byte of the
- /// specified file.
- SourceLocation getLocForEndOfFile(FileID FID) const {
- bool Invalid = false;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
- if (Invalid || !Entry.isFile())
- return SourceLocation();
-
- unsigned FileOffset = Entry.getOffset();
- return SourceLocation::getFileLoc(FileOffset + getFileIDSize(FID));
- }
-
- /// \brief 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;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
- if (Invalid || !Entry.isFile())
- return SourceLocation();
-
- return Entry.getFile().getIncludeLoc();
- }
-
- // \brief 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>
- getModuleImportLoc(SourceLocation Loc) const {
- FileID FID = getFileID(Loc);
-
- // Positive file IDs are in the current translation unit, and -1 is a
- // placeholder.
- if (FID.ID >= -1)
- return std::make_pair(SourceLocation(), "");
-
- return ExternalSLocEntries->getModuleImportLoc(FID.ID);
- }
-
- /// \brief 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
- // expansions.
- if (Loc.isFileID()) return Loc;
- return getExpansionLocSlowCase(Loc);
- }
-
- /// \brief 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 {
- if (Loc.isFileID()) return Loc;
- return getFileLocSlowCase(Loc);
- }
-
- /// \brief 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;
-
- /// \brief 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;
-
- /// \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);
- }
-
- /// \brief 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
- /// can be found.
- SourceLocation getSpellingLoc(SourceLocation Loc) const {
- // Handle the non-mapped case inline, defer to out of line code to handle
- // expansions.
- if (Loc.isFileID()) return Loc;
- return getSpellingLocSlowCase(Loc);
- }
-
- /// \brief Given a SourceLocation object, return the spelling location
- /// referenced by the ID.
- ///
- /// This is the first level down towards the place where the characters
- /// that make up the lexed token can be found. This should not generally
- /// be used by clients.
- SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
-
- /// \brief 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.
- std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const {
- FileID FID = getFileID(Loc);
- bool Invalid = false;
- const SrcMgr::SLocEntry &E = getSLocEntry(FID, &Invalid);
- if (Invalid)
- return std::make_pair(FileID(), 0);
- return std::make_pair(FID, Loc.getOffset()-E.getOffset());
- }
-
- /// \brief 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.
- std::pair<FileID, unsigned>
- getDecomposedExpansionLoc(SourceLocation Loc) const {
- FileID FID = getFileID(Loc);
- bool Invalid = false;
- const SrcMgr::SLocEntry *E = &getSLocEntry(FID, &Invalid);
- if (Invalid)
- return std::make_pair(FileID(), 0);
-
- unsigned Offset = Loc.getOffset()-E->getOffset();
- if (Loc.isFileID())
- return std::make_pair(FID, Offset);
-
- return getDecomposedExpansionLocSlowCase(E);
- }
-
- /// \brief 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.
- std::pair<FileID, unsigned>
- getDecomposedSpellingLoc(SourceLocation Loc) const {
- FileID FID = getFileID(Loc);
- bool Invalid = false;
- const SrcMgr::SLocEntry *E = &getSLocEntry(FID, &Invalid);
- if (Invalid)
- return std::make_pair(FileID(), 0);
-
- unsigned Offset = Loc.getOffset()-E->getOffset();
- if (Loc.isFileID())
- return std::make_pair(FID, Offset);
- return getDecomposedSpellingLocSlowCase(E, Offset);
- }
-
- /// \brief 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
- /// specified SourceLocation represents.
- ///
- /// This is not very meaningful for a macro ID.
- unsigned getFileOffset(SourceLocation SpellingLoc) const {
- return getDecomposedLoc(SpellingLoc).second;
- }
-
- /// \brief 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
- /// start location of the macro argument expansion.
- ///
- /// Such source locations only appear inside of the expansion
- /// locations representing where a particular function-like macro was
- /// expanded.
- bool isMacroArgExpansion(SourceLocation Loc,
- SourceLocation *StartLoc = nullptr) const;
-
- /// \brief 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
- /// of the immediate macro expansion.
- ///
- /// \param MacroBegin If non-null and function returns true, it is set to the
- /// begin location of the immediate macro expansion.
- bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc,
- SourceLocation *MacroBegin = nullptr) const;
-
- /// \brief 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
- /// character end location of the immediate macro expansion.
- bool
- isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
- SourceLocation *MacroEnd = nullptr) const;
-
- /// \brief 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
- /// relative offset of \p Loc inside the chunk.
- bool isInSLocAddrSpace(SourceLocation Loc,
- SourceLocation Start, unsigned Length,
- unsigned *RelativeOffset = nullptr) const {
- assert(((Start.getOffset() < NextLocalOffset &&
- Start.getOffset()+Length <= NextLocalOffset) ||
- (Start.getOffset() >= CurrentLoadedOffset &&
- Start.getOffset()+Length < MaxLoadedOffset)) &&
- "Chunk is not valid SLoc address space");
- unsigned LocOffs = Loc.getOffset();
- unsigned BeginOffs = Start.getOffset();
- unsigned EndOffs = BeginOffs + Length;
- if (LocOffs >= BeginOffs && LocOffs < EndOffs) {
- if (RelativeOffset)
- *RelativeOffset = LocOffs - BeginOffs;
- return true;
- }
-
- return false;
- }
-
- /// \brief 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
- /// offset of \p RHS relative to \p LHS.
- bool isInSameSLocAddrSpace(SourceLocation LHS, SourceLocation RHS,
- int *RelativeOffset) const {
- unsigned LHSOffs = LHS.getOffset(), RHSOffs = RHS.getOffset();
- bool LHSLoaded = LHSOffs >= CurrentLoadedOffset;
- bool RHSLoaded = RHSOffs >= CurrentLoadedOffset;
-
- if (LHSLoaded == RHSLoaded) {
- if (RelativeOffset)
- *RelativeOffset = RHSOffs - LHSOffs;
- return true;
- }
-
- return false;
- }
-
- //===--------------------------------------------------------------------===//
- // Queries about the code at a SourceLocation.
- //===--------------------------------------------------------------------===//
-
- /// \brief 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.
- ///
- /// 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
- /// on a file sloc, so you must choose a spelling or expansion location
- /// before calling this method.
- unsigned getColumnNumber(FileID FID, unsigned FilePos,
- bool *Invalid = nullptr) const;
- unsigned getSpellingColumnNumber(SourceLocation Loc,
- bool *Invalid = nullptr) const;
- unsigned getExpansionColumnNumber(SourceLocation Loc,
- bool *Invalid = nullptr) const;
- unsigned getPresumedColumnNumber(SourceLocation Loc,
- bool *Invalid = nullptr) const;
-
- /// \brief Given a SourceLocation, return the spelling line number
- /// for the position indicated.
- ///
- /// This requires building and caching a table of line offsets for the
- /// MemoryBuffer, so this is not cheap: use only when about to emit a
- /// diagnostic.
- unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = nullptr) const;
- unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
- 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
- /// location is in.
- ///
- /// Note that this name does not respect \#line directives. Use
- /// getPresumedLoc for normal clients.
- const char *getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
-
- /// \brief 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.
- ///
- /// This state can be modified with flags on GNU linemarker directives like:
- /// \code
- /// # 4 "foo.h" 3
- /// \endcode
- /// which changes all source locations in the current file after that to be
- /// considered to be from a system header.
- SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
-
- /// \brief 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
- /// in diagnostics, for example.
- ///
- /// Note that a presumed location is always given as the expansion point of
- /// an expansion location, not at the spelling location.
- ///
- /// \returns The presumed location of the specified SourceLocation. If the
- /// presumed location cannot be calculated (e.g., because \p Loc is invalid
- /// or the file containing \p Loc has changed on disk), returns an invalid
- /// presumed location.
- PresumedLoc getPresumedLoc(SourceLocation Loc,
- bool UseLineDirectives = true) const;
-
- /// \brief Returns whether the PresumedLoc for a given SourceLocation is
- /// in the main file.
- ///
- /// This computes the "presumed" location for a SourceLocation, then checks
- /// whether it came from a file other than the main file. This is different
- /// from isWrittenInMainFile() because it takes line marker directives into
- /// account.
- bool isInMainFile(SourceLocation Loc) const;
-
- /// \brief Returns true if the spelling locations for both SourceLocations
- /// are part of the same file buffer.
- ///
- /// This check ignores line marker directives.
- bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
- return getFileID(Loc1) == getFileID(Loc2);
- }
-
- /// \brief Returns true if the spelling location for the given location
- /// is in the main file buffer.
- ///
- /// This check ignores line marker directives.
- bool isWrittenInMainFile(SourceLocation Loc) const {
- return getFileID(Loc) == getMainFileID();
- }
-
- /// \brief Returns if a SourceLocation is in a system header.
- bool isInSystemHeader(SourceLocation Loc) const {
- return getFileCharacteristic(Loc) != SrcMgr::C_User;
- }
-
- /// \brief 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.
- bool isInSystemMacro(SourceLocation loc) {
- return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
- }
-
- /// \brief 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
- /// FileID chunk and sets relative offset (offset of \p Loc from beginning
- /// of FileID) to \p relativeOffset.
- bool isInFileID(SourceLocation Loc, FileID FID,
- unsigned *RelativeOffset = nullptr) const {
- unsigned Offs = Loc.getOffset();
- if (isOffsetInFileID(FID, Offs)) {
- if (RelativeOffset)
- *RelativeOffset = Offs - getSLocEntry(FID).getOffset();
- return true;
- }
-
- return false;
- }
-
- //===--------------------------------------------------------------------===//
- // Line Table Manipulation Routines
- //===--------------------------------------------------------------------===//
-
- /// \brief 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
- /// specified by Loc.
- ///
- /// If FilenameID is -1, it is considered to be unspecified.
- void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
- void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
- bool IsFileEntry, bool IsFileExit,
- bool IsSystemHeader, bool IsExternCHeader);
-
- /// \brief Determine if the source manager has a line table.
- bool hasLineTable() const { return LineTable != nullptr; }
-
- /// \brief Retrieve the stored line table.
- LineTableInfo &getLineTable();
-
- //===--------------------------------------------------------------------===//
- // Queries for performance analysis.
- //===--------------------------------------------------------------------===//
-
- /// \brief Return the total amount of physical memory allocated by the
- /// ContentCache allocator.
- size_t getContentCacheSize() const {
- return ContentCacheAlloc.getTotalMemory();
- }
-
- struct MemoryBufferSizes {
- const size_t malloc_bytes;
- const size_t mmap_bytes;
-
- MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
- : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
- };
-
- /// \brief 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
- /// data structures in the SourceManager.
- size_t getDataStructureSizes() const;
-
- //===--------------------------------------------------------------------===//
- // Other miscellaneous methods.
- //===--------------------------------------------------------------------===//
-
- /// \brief 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.
- ///
- /// 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.
- /// 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
- /// 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.
- /// e.g.
- /// MY_MACRO(foo);
- /// ^
- /// Passing a file location pointing at 'foo', will yield a macro location
- /// where 'foo' was expanded into.
- SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const;
-
- /// \brief 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 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
- /// offset in the "source location address space".
- ///
- /// Note that we always consider source locations loaded from
- bool isBeforeInSLocAddrSpace(SourceLocation LHS, unsigned RHS) const {
- unsigned LHSOffset = LHS.getOffset();
- bool LHSLoaded = LHSOffset >= CurrentLoadedOffset;
- bool RHSLoaded = RHS >= CurrentLoadedOffset;
- if (LHSLoaded == RHSLoaded)
- return LHSOffset < RHS;
-
- return LHSLoaded;
- }
-
- // Iterators over FileInfos.
- typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
- ::const_iterator fileinfo_iterator;
- fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
- fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
- bool hasFileInfo(const FileEntry *File) const {
- return FileInfos.find(File) != FileInfos.end();
- }
-
- /// \brief Print statistics to stderr.
- ///
- void PrintStats() const;
-
- void dump() const;
-
- /// \brief 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.
- 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.
- unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();}
-
- /// \brief 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");
- if (SLocEntryLoaded[Index])
- return LoadedSLocEntryTable[Index];
- return loadSLocEntry(Index, Invalid);
- }
-
- const SrcMgr::SLocEntry &getSLocEntry(FileID FID,
- bool *Invalid = nullptr) const {
- if (FID.ID == 0 || FID.ID == -1) {
- if (Invalid) *Invalid = true;
- return LocalSLocEntryTable[0];
- }
- return getSLocEntryByID(FID.ID, Invalid);
- }
-
- unsigned getNextLocalOffset() const { return NextLocalOffset; }
-
- void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) {
- assert(LoadedSLocEntryTable.empty() &&
- "Invalidating existing loaded entries");
- ExternalSLocEntries = Source;
- }
-
- /// \brief 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
- /// in the global source view. The lowest ID and the base offset of the
- /// entries will be returned.
- std::pair<int, unsigned>
- AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize);
-
- /// \brief 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.
- bool isLocalSourceLocation(SourceLocation Loc) const {
- return Loc.getOffset() < NextLocalOffset;
- }
-
- /// \brief 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.
- bool isLocalFileID(FileID FID) const {
- return !isLoadedFileID(FID);
- }
-
- /// Gets the location of the immediate macro caller, one level up the stack
- /// toward the initial macro typed into the source.
- SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const {
- if (!Loc.isMacroID()) return Loc;
-
- // When we have the location of (part of) an expanded parameter, its
- // spelling location points to the argument as expanded in the macro call,
- // and therefore is used to locate the macro caller.
- if (isMacroArgExpansion(Loc))
- return getImmediateSpellingLoc(Loc);
-
- // 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;
- }
-
-private:
- llvm::MemoryBuffer *getFakeBufferForRecovery() const;
- const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
-
- const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
-
- /// \brief 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");
- if (ID < 0)
- return getLoadedSLocEntryByID(ID, Invalid);
- return getLocalSLocEntry(static_cast<unsigned>(ID), Invalid);
- }
-
- const SrcMgr::SLocEntry &
- getLoadedSLocEntryByID(int ID, bool *Invalid = nullptr) const {
- return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2), Invalid);
- }
-
- /// Implements the common elements of storing an expansion info struct into
- /// the SLocEntry table and producing a source location that refers to it.
- SourceLocation createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion,
- unsigned TokLength,
- int LoadedID = 0,
- unsigned LoadedOffset = 0);
-
- /// \brief 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);
- // If the entry is after the offset, it can't contain it.
- if (SLocOffset < Entry.getOffset()) return false;
-
- // If this is the very last entry then it does.
- if (FID.ID == -2)
- return true;
-
- // If it is the last local entry, then it does if the location is local.
- if (FID.ID+1 == static_cast<int>(LocalSLocEntryTable.size()))
- return SLocOffset < NextLocalOffset;
-
- // Otherwise, the entry after it has to not include it. This works for both
- // local and loaded entries.
- return SLocOffset < getSLocEntryByID(FID.ID+1).getOffset();
- }
-
- /// \brief 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
- /// no next one.
- FileID getNextFileID(FileID FID) const;
-
- /// \brief Create a new fileID for the specified ContentCache and
- /// include position.
- ///
- /// This works regardless of whether the ContentCache corresponds to a
- /// file or some other input source.
- FileID createFileID(const SrcMgr::ContentCache* File,
- SourceLocation IncludePos,
- SrcMgr::CharacteristicKind DirCharacter,
- int LoadedID, unsigned LoadedOffset);
-
- const SrcMgr::ContentCache *
- getOrCreateContentCache(const FileEntry *SourceFile,
- bool isSystemFile = false);
-
- /// \brief Create a new ContentCache for the specified memory buffer.
- const SrcMgr::ContentCache *
- createMemBufferContentCache(std::unique_ptr<llvm::MemoryBuffer> Buf);
-
- FileID getFileIDSlow(unsigned SLocOffset) const;
- FileID getFileIDLocal(unsigned SLocOffset) const;
- FileID getFileIDLoaded(unsigned SLocOffset) const;
-
- SourceLocation getExpansionLocSlowCase(SourceLocation Loc) const;
- SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
- SourceLocation getFileLocSlowCase(SourceLocation Loc) const;
-
- std::pair<FileID, unsigned>
- getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const;
- std::pair<FileID, unsigned>
- getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
- unsigned Offset) const;
- void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const;
- void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache,
- FileID FID,
- SourceLocation SpellLoc,
- SourceLocation ExpansionLoc,
- unsigned ExpansionLength) const;
- friend class ASTReader;
- friend class ASTWriter;
-};
-
-/// \brief Comparison function object.
-template<typename T>
-class BeforeThanCompare;
-
-/// \brief Compare two source locations.
-template<>
-class BeforeThanCompare<SourceLocation> {
- SourceManager &SM;
-
-public:
- explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { }
-
- bool operator()(SourceLocation LHS, SourceLocation RHS) const {
- return SM.isBeforeInTranslationUnit(LHS, RHS);
- }
-};
-
-/// \brief Compare two non-overlapping source ranges.
-template<>
-class BeforeThanCompare<SourceRange> {
- SourceManager &SM;
-
-public:
- explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { }
-
- bool operator()(SourceRange LHS, SourceRange RHS) const {
- return SM.isBeforeInTranslationUnit(LHS.getBegin(), RHS.getBegin());
- }
-};
-
-} // end namespace clang
-
-
-#endif
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
deleted file mode 100644
index 27dea9f..0000000
--- a/include/clang/Basic/SourceManagerInternals.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//===--- SourceManagerInternals.h - SourceManager Internals -----*- 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 implementation details of the clang::SourceManager class.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
-#define LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/StringMap.h"
-#include <map>
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-// Line Table Implementation
-//===----------------------------------------------------------------------===//
-
-struct LineEntry {
- /// \brief The offset in this file that the line entry occurs at.
- unsigned FileOffset;
-
- /// \brief The presumed line number of this line entry: \#line 4.
- unsigned LineNo;
-
- /// \brief 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,
- SrcMgr::CharacteristicKind FileKind;
-
- /// \brief 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.
- unsigned IncludeOffset;
-
- static LineEntry get(unsigned Offs, unsigned Line, int Filename,
- SrcMgr::CharacteristicKind FileKind,
- unsigned IncludeOffset) {
- LineEntry E;
- E.FileOffset = Offs;
- E.LineNo = Line;
- E.FilenameID = Filename;
- E.FileKind = FileKind;
- E.IncludeOffset = IncludeOffset;
- return E;
- }
-};
-
-// needed for FindNearestLineEntry (upper_bound of LineEntry)
-inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) {
- // FIXME: should check the other field?
- return lhs.FileOffset < rhs.FileOffset;
-}
-
-inline bool operator<(const LineEntry &E, unsigned Offset) {
- return E.FileOffset < Offset;
-}
-
-inline bool operator<(unsigned Offset, const LineEntry &E) {
- return Offset < E.FileOffset;
-}
-
-/// \brief 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.
- ///
- /// This allows us to unique the filenames that
- /// frequently reoccur and reference them with indices. FilenameIDs holds
- /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
- /// to string.
- 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
- /// at which they occur in the file).
- std::map<FileID, std::vector<LineEntry> > LineEntries;
-public:
- void clear() {
- FilenameIDs.clear();
- FilenamesByID.clear();
- LineEntries.clear();
- }
-
- unsigned getLineTableFilenameID(StringRef Str);
- const char *getFilename(unsigned ID) const {
- assert(ID < FilenamesByID.size() && "Invalid FilenameID");
- return FilenamesByID[ID]->getKeyData();
- }
- unsigned getNumFilenames() const { return FilenamesByID.size(); }
-
- void AddLineNote(FileID FID, unsigned Offset,
- unsigned LineNo, int FilenameID);
- void AddLineNote(FileID FID, unsigned Offset,
- unsigned LineNo, int FilenameID,
- unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
-
-
- /// \brief 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);
-
- // Low-level access
- typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator;
- iterator begin() { return LineEntries.begin(); }
- iterator end() { return LineEntries.end(); }
-
- /// \brief 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);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
deleted file mode 100644
index 1d59d64..0000000
--- a/include/clang/Basic/Specifiers.h
+++ /dev/null
@@ -1,283 +0,0 @@
-//===--- Specifiers.h - Declaration and Type Specifiers ---------*- 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 various enumerations that describe declaration and
-/// type specifiers.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
-#define LLVM_CLANG_BASIC_SPECIFIERS_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
- /// \brief Specifies the width of a type, e.g., short, long, or long long.
- enum TypeSpecifierWidth {
- TSW_unspecified,
- TSW_short,
- TSW_long,
- TSW_longlong
- };
-
- /// \brief Specifies the signedness of a type, e.g., signed or unsigned.
- enum TypeSpecifierSign {
- TSS_unspecified,
- TSS_signed,
- TSS_unsigned
- };
-
- /// \brief Specifies the kind of type.
- enum TypeSpecifierType {
- TST_unspecified,
- TST_void,
- TST_char,
- TST_wchar, // C++ wchar_t
- TST_char16, // C++11 char16_t
- TST_char32, // C++11 char32_t
- TST_int,
- TST_int128,
- TST_half, // OpenCL half, ARM NEON __fp16
- TST_float,
- TST_double,
- TST_bool, // _Bool
- TST_decimal32, // _Decimal32
- TST_decimal64, // _Decimal64
- TST_decimal128, // _Decimal128
- TST_enum,
- TST_union,
- TST_struct,
- TST_class, // C++ class type
- TST_interface, // C++ (Microsoft-specific) __interface type
- TST_typename, // Typedef, C++ class-name or enum name, etc.
- TST_typeofType,
- TST_typeofExpr,
- TST_decltype, // C++11 decltype
- TST_underlyingType, // __underlying_type for C++11
- TST_auto, // C++11 auto
- TST_decltype_auto, // C++1y decltype(auto)
- TST_auto_type, // __auto_type extension
- TST_unknown_anytype, // __unknown_anytype extension
- TST_atomic, // C11 _Atomic
- TST_error // erroneous type
- };
-
- /// \brief Structure that packs information about the type specifiers that
- /// were written in a particular type specifier sequence.
- struct WrittenBuiltinSpecs {
- /*DeclSpec::TST*/ unsigned Type : 5;
- /*DeclSpec::TSS*/ unsigned Sign : 2;
- /*DeclSpec::TSW*/ unsigned Width : 2;
- bool ModeAttr : 1;
- };
-
- /// \brief A C++ access specifier (public, private, protected), plus the
- /// special value "none" which means different things in different contexts.
- enum AccessSpecifier {
- AS_public,
- AS_protected,
- AS_private,
- AS_none
- };
-
- /// \brief 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)
- /// produces a temporary value.
- VK_RValue,
-
- /// \brief 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
- /// 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
- /// l-value or x-value.
- enum ExprObjectKind {
- /// An ordinary object is located at an address in memory.
- OK_Ordinary,
-
- /// A bitfield object is a bitfield on a C or C++ record.
- OK_BitField,
-
- /// A vector component is an element or range of elements on a vector.
- OK_VectorComponent,
-
- /// An Objective-C property is a logical field of an Objective-C
- /// object which is read and written via Objective-C method calls.
- OK_ObjCProperty,
-
- /// An Objective-C array/dictionary subscripting which reads an
- /// object or writes at the subscripted array/dictionary element via
- /// Objective-C method calls.
- OK_ObjCSubscript
- };
-
- /// \brief 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
- /// has not yet been declared, defined, or instantiated.
- TSK_Undeclared = 0,
- /// This template specialization was implicitly instantiated from a
- /// template. (C++ [temp.inst]).
- TSK_ImplicitInstantiation,
- /// This template specialization was declared or defined by an
- /// explicit specialization (C++ [temp.expl.spec]) or partial
- /// specialization (C++ [temp.class.spec]).
- TSK_ExplicitSpecialization,
- /// This template specialization was instantiated from a template
- /// due to an explicit instantiation declaration request
- /// (C++11 [temp.explicit]).
- TSK_ExplicitInstantiationDeclaration,
- /// This template specialization was instantiated from a template
- /// due to an explicit instantiation definition request
- /// (C++ [temp.explicit]).
- TSK_ExplicitInstantiationDefinition
- };
-
- /// \brief 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
- /// specialization, explicit instantiation declaration, or explicit
- /// instantiation definition.
- inline bool isTemplateExplicitInstantiationOrSpecialization(
- TemplateSpecializationKind Kind) {
- switch (Kind) {
- case TSK_ExplicitSpecialization:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- return true;
-
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- return false;
- }
- llvm_unreachable("bad template specialization kind");
- }
-
- /// \brief Thread storage-class-specifier.
- enum ThreadStorageClassSpecifier {
- TSCS_unspecified,
- /// GNU __thread.
- TSCS___thread,
- /// C++11 thread_local. Implies 'static' at block scope, but not at
- /// class scope.
- TSCS_thread_local,
- /// C11 _Thread_local. Must be combined with either 'static' or 'extern'
- /// if used at block scope.
- TSCS__Thread_local
- };
-
- /// \brief Storage classes.
- enum StorageClass {
- // These are legal on both functions and variables.
- SC_None,
- SC_Extern,
- SC_Static,
- SC_PrivateExtern,
-
- // These are only legal on variables.
- SC_Auto,
- SC_Register
- };
-
- /// \brief 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.
- inline bool isLegalForVariable(StorageClass SC) {
- return true;
- }
-
- /// \brief 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.
- enum CallingConv {
- CC_C, // __attribute__((cdecl))
- CC_X86StdCall, // __attribute__((stdcall))
- CC_X86FastCall, // __attribute__((fastcall))
- CC_X86ThisCall, // __attribute__((thiscall))
- CC_X86VectorCall, // __attribute__((vectorcall))
- CC_X86Pascal, // __attribute__((pascal))
- CC_X86_64Win64, // __attribute__((ms_abi))
- CC_X86_64SysV, // __attribute__((sysv_abi))
- CC_AAPCS, // __attribute__((pcs("aapcs")))
- CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
- CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
- CC_SpirFunction, // default for OpenCL functions on SPIR target
- CC_SpirKernel // inferred for OpenCL kernels on SPIR target
- };
-
- /// \brief Checks whether the given calling convention supports variadic
- /// calls. Unprototyped calls also use the variadic call rules.
- inline bool supportsVariadicCall(CallingConv CC) {
- switch (CC) {
- case CC_X86StdCall:
- case CC_X86FastCall:
- case CC_X86ThisCall:
- case CC_X86Pascal:
- case CC_X86VectorCall:
- case CC_SpirFunction:
- case CC_SpirKernel:
- return false;
- default:
- return true;
- }
- }
-
- /// \brief 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).
- SD_Thread, ///< Thread storage duration.
- SD_Static, ///< Static storage duration.
- SD_Dynamic ///< Dynamic storage duration.
- };
-
- /// Describes the nullability of a particular type.
- enum class NullabilityKind : uint8_t {
- /// Values of this type can never be null.
- NonNull = 0,
- /// Values of this type can be null.
- Nullable,
- /// Whether values of this type can be null is (explicitly)
- /// unspecified. This captures a (fairly rare) case where we
- /// can't conclude anything about the nullability of the type even
- /// though it has been considered.
- Unspecified
- };
-
- /// Retrieve the spelling of the given nullability kind.
- llvm::StringRef getNullabilitySpelling(NullabilityKind kind,
- bool isContextSensitive = false);
-} // end namespace clang
-
-#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
deleted file mode 100644
index 36519ea..0000000
--- a/include/clang/Basic/StmtNodes.td
+++ /dev/null
@@ -1,224 +0,0 @@
-class AttrSubject;
-
-class Stmt<bit abstract = 0> : AttrSubject {
- bit Abstract = abstract;
-}
-
-class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> {
- Stmt Base = base;
-}
-
-// Statements
-def NullStmt : Stmt;
-def CompoundStmt : Stmt;
-def LabelStmt : Stmt;
-def AttributedStmt : Stmt;
-def IfStmt : Stmt;
-def SwitchStmt : Stmt;
-def WhileStmt : Stmt;
-def DoStmt : Stmt;
-def ForStmt : Stmt;
-def GotoStmt : Stmt;
-def IndirectGotoStmt : Stmt;
-def ContinueStmt : Stmt;
-def BreakStmt : Stmt;
-def ReturnStmt : Stmt;
-def DeclStmt : Stmt;
-def SwitchCase : Stmt<1>;
-def CaseStmt : DStmt<SwitchCase>;
-def DefaultStmt : DStmt<SwitchCase>;
-def CapturedStmt : Stmt;
-
-// Asm statements
-def AsmStmt : Stmt<1>;
-def GCCAsmStmt : DStmt<AsmStmt>;
-def MSAsmStmt : DStmt<AsmStmt>;
-
-// Obj-C statements
-def ObjCAtTryStmt : Stmt;
-def ObjCAtCatchStmt : Stmt;
-def ObjCAtFinallyStmt : Stmt;
-def ObjCAtThrowStmt : Stmt;
-def ObjCAtSynchronizedStmt : Stmt;
-def ObjCForCollectionStmt : Stmt;
-def ObjCAutoreleasePoolStmt : Stmt;
-
-// C++ statments
-def CXXCatchStmt : Stmt;
-def CXXTryStmt : Stmt;
-def CXXForRangeStmt : Stmt;
-
-// C++ Coroutines TS statements
-def CoroutineBodyStmt : Stmt;
-def CoreturnStmt : Stmt;
-
-// Expressions
-def Expr : Stmt<1>;
-def PredefinedExpr : DStmt<Expr>;
-def DeclRefExpr : DStmt<Expr>;
-def IntegerLiteral : DStmt<Expr>;
-def FloatingLiteral : DStmt<Expr>;
-def ImaginaryLiteral : DStmt<Expr>;
-def StringLiteral : DStmt<Expr>;
-def CharacterLiteral : DStmt<Expr>;
-def ParenExpr : DStmt<Expr>;
-def UnaryOperator : DStmt<Expr>;
-def OffsetOfExpr : DStmt<Expr>;
-def UnaryExprOrTypeTraitExpr : DStmt<Expr>;
-def ArraySubscriptExpr : DStmt<Expr>;
-def OMPArraySectionExpr : DStmt<Expr>;
-def CallExpr : DStmt<Expr>;
-def MemberExpr : DStmt<Expr>;
-def CastExpr : DStmt<Expr, 1>;
-def BinaryOperator : DStmt<Expr>;
-def CompoundAssignOperator : DStmt<BinaryOperator>;
-def AbstractConditionalOperator : DStmt<Expr, 1>;
-def ConditionalOperator : DStmt<AbstractConditionalOperator>;
-def BinaryConditionalOperator : DStmt<AbstractConditionalOperator>;
-def ImplicitCastExpr : DStmt<CastExpr>;
-def ExplicitCastExpr : DStmt<CastExpr, 1>;
-def CStyleCastExpr : DStmt<ExplicitCastExpr>;
-def CompoundLiteralExpr : DStmt<Expr>;
-def ExtVectorElementExpr : DStmt<Expr>;
-def InitListExpr : DStmt<Expr>;
-def DesignatedInitExpr : DStmt<Expr>;
-def DesignatedInitUpdateExpr : DStmt<Expr>;
-def ImplicitValueInitExpr : DStmt<Expr>;
-def NoInitExpr : DStmt<Expr>;
-def ParenListExpr : DStmt<Expr>;
-def VAArgExpr : DStmt<Expr>;
-def GenericSelectionExpr : DStmt<Expr>;
-def PseudoObjectExpr : DStmt<Expr>;
-
-// Atomic expressions
-def AtomicExpr : DStmt<Expr>;
-
-// GNU Extensions.
-def AddrLabelExpr : DStmt<Expr>;
-def StmtExpr : DStmt<Expr>;
-def ChooseExpr : DStmt<Expr>;
-def GNUNullExpr : DStmt<Expr>;
-
-// C++ Expressions.
-def CXXOperatorCallExpr : DStmt<CallExpr>;
-def CXXMemberCallExpr : DStmt<CallExpr>;
-def CXXNamedCastExpr : DStmt<ExplicitCastExpr, 1>;
-def CXXStaticCastExpr : DStmt<CXXNamedCastExpr>;
-def CXXDynamicCastExpr : DStmt<CXXNamedCastExpr>;
-def CXXReinterpretCastExpr : DStmt<CXXNamedCastExpr>;
-def CXXConstCastExpr : DStmt<CXXNamedCastExpr>;
-def CXXFunctionalCastExpr : DStmt<ExplicitCastExpr>;
-def CXXTypeidExpr : DStmt<Expr>;
-def UserDefinedLiteral : DStmt<CallExpr>;
-def CXXBoolLiteralExpr : DStmt<Expr>;
-def CXXNullPtrLiteralExpr : DStmt<Expr>;
-def CXXThisExpr : DStmt<Expr>;
-def CXXThrowExpr : DStmt<Expr>;
-def CXXDefaultArgExpr : DStmt<Expr>;
-def CXXDefaultInitExpr : DStmt<Expr>;
-def CXXScalarValueInitExpr : DStmt<Expr>;
-def CXXStdInitializerListExpr : DStmt<Expr>;
-def CXXNewExpr : DStmt<Expr>;
-def CXXDeleteExpr : DStmt<Expr>;
-def CXXPseudoDestructorExpr : DStmt<Expr>;
-def TypeTraitExpr : DStmt<Expr>;
-def ArrayTypeTraitExpr : DStmt<Expr>;
-def ExpressionTraitExpr : DStmt<Expr>;
-def DependentScopeDeclRefExpr : DStmt<Expr>;
-def CXXConstructExpr : DStmt<Expr>;
-def CXXBindTemporaryExpr : DStmt<Expr>;
-def ExprWithCleanups : DStmt<Expr>;
-def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
-def CXXUnresolvedConstructExpr : DStmt<Expr>;
-def CXXDependentScopeMemberExpr : DStmt<Expr>;
-def OverloadExpr : DStmt<Expr, 1>;
-def UnresolvedLookupExpr : DStmt<OverloadExpr>;
-def UnresolvedMemberExpr : DStmt<OverloadExpr>;
-def CXXNoexceptExpr : DStmt<Expr>;
-def PackExpansionExpr : DStmt<Expr>;
-def SizeOfPackExpr : DStmt<Expr>;
-def SubstNonTypeTemplateParmExpr : DStmt<Expr>;
-def SubstNonTypeTemplateParmPackExpr : DStmt<Expr>;
-def FunctionParmPackExpr : DStmt<Expr>;
-def MaterializeTemporaryExpr : DStmt<Expr>;
-def LambdaExpr : DStmt<Expr>;
-def CXXFoldExpr : DStmt<Expr>;
-
-// C++ Coroutines TS expressions
-def CoroutineSuspendExpr : DStmt<Expr, 1>;
-def CoawaitExpr : DStmt<CoroutineSuspendExpr>;
-def CoyieldExpr : DStmt<CoroutineSuspendExpr>;
-
-// Obj-C Expressions.
-def ObjCStringLiteral : DStmt<Expr>;
-def ObjCBoxedExpr : DStmt<Expr>;
-def ObjCArrayLiteral : DStmt<Expr>;
-def ObjCDictionaryLiteral : DStmt<Expr>;
-def ObjCEncodeExpr : DStmt<Expr>;
-def ObjCMessageExpr : DStmt<Expr>;
-def ObjCSelectorExpr : DStmt<Expr>;
-def ObjCProtocolExpr : DStmt<Expr>;
-def ObjCIvarRefExpr : DStmt<Expr>;
-def ObjCPropertyRefExpr : DStmt<Expr>;
-def ObjCIsaExpr : DStmt<Expr>;
-def ObjCIndirectCopyRestoreExpr : DStmt<Expr>;
-def ObjCBoolLiteralExpr : DStmt<Expr>;
-def ObjCSubscriptRefExpr : DStmt<Expr>;
-
-// Obj-C ARC Expressions.
-def ObjCBridgedCastExpr : DStmt<ExplicitCastExpr>;
-
-// CUDA Expressions.
-def CUDAKernelCallExpr : DStmt<CallExpr>;
-
-// Clang Extensions.
-def ShuffleVectorExpr : DStmt<Expr>;
-def ConvertVectorExpr : DStmt<Expr>;
-def BlockExpr : DStmt<Expr>;
-def OpaqueValueExpr : DStmt<Expr>;
-def TypoExpr : DStmt<Expr>;
-
-// Microsoft Extensions.
-def MSPropertyRefExpr : DStmt<Expr>;
-def MSPropertySubscriptExpr : DStmt<Expr>;
-def CXXUuidofExpr : DStmt<Expr>;
-def SEHTryStmt : Stmt;
-def SEHExceptStmt : Stmt;
-def SEHFinallyStmt : Stmt;
-def SEHLeaveStmt : Stmt;
-def MSDependentExistsStmt : Stmt;
-
-// OpenCL Extensions.
-def AsTypeExpr : DStmt<Expr>;
-
-// OpenMP Directives.
-def OMPExecutableDirective : Stmt<1>;
-def OMPLoopDirective : DStmt<OMPExecutableDirective, 1>;
-def OMPParallelDirective : DStmt<OMPExecutableDirective>;
-def OMPSimdDirective : DStmt<OMPLoopDirective>;
-def OMPForDirective : DStmt<OMPLoopDirective>;
-def OMPForSimdDirective : DStmt<OMPLoopDirective>;
-def OMPSectionsDirective : DStmt<OMPExecutableDirective>;
-def OMPSectionDirective : DStmt<OMPExecutableDirective>;
-def OMPSingleDirective : DStmt<OMPExecutableDirective>;
-def OMPMasterDirective : DStmt<OMPExecutableDirective>;
-def OMPCriticalDirective : DStmt<OMPExecutableDirective>;
-def OMPParallelForDirective : DStmt<OMPLoopDirective>;
-def OMPParallelForSimdDirective : DStmt<OMPLoopDirective>;
-def OMPParallelSectionsDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskyieldDirective : DStmt<OMPExecutableDirective>;
-def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskgroupDirective : DStmt<OMPExecutableDirective>;
-def OMPFlushDirective : DStmt<OMPExecutableDirective>;
-def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
-def OMPAtomicDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetDataDirective : DStmt<OMPExecutableDirective>;
-def OMPTeamsDirective : DStmt<OMPExecutableDirective>;
-def OMPCancellationPointDirective : DStmt<OMPExecutableDirective>;
-def OMPCancelDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskLoopDirective : DStmt<OMPLoopDirective>;
-def OMPTaskLoopSimdDirective : DStmt<OMPLoopDirective>;
-def OMPDistributeDirective : DStmt<OMPLoopDirective>;
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
deleted file mode 100644
index 623c0b6..0000000
--- a/include/clang/Basic/TargetBuiltins.h
+++ /dev/null
@@ -1,201 +0,0 @@
-//===--- TargetBuiltins.h - Target specific builtin IDs ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Enumerates target-specific builtins in their own namespaces within
-/// namespace ::clang.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_TARGETBUILTINS_H
-#define LLVM_CLANG_BASIC_TARGETBUILTINS_H
-
-#include <stdint.h>
-#include "clang/Basic/Builtins.h"
-#undef PPC
-
-namespace clang {
-
- namespace NEON {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsNEON.def"
- FirstTSBuiltin
- };
- }
-
- /// \brief ARM builtins
- namespace ARM {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
- LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsARM.def"
- LastTSBuiltin
- };
- }
-
- /// \brief AArch64 builtins
- namespace AArch64 {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
- LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
- #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
- #include "clang/Basic/BuiltinsAArch64.def"
- LastTSBuiltin
- };
- }
-
- /// \brief PPC builtins
- namespace PPC {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsPPC.def"
- LastTSBuiltin
- };
- }
-
- /// \brief NVPTX builtins
- namespace NVPTX {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsNVPTX.def"
- LastTSBuiltin
- };
- }
-
- /// \brief AMDGPU builtins
- namespace AMDGPU {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
- #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
- #include "clang/Basic/BuiltinsAMDGPU.def"
- LastTSBuiltin
- };
- }
-
- /// \brief X86 builtins
- namespace X86 {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsX86.def"
- LastTSBuiltin
- };
- }
-
- /// \brief 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 {
- enum {
- EltTypeMask = 0xf,
- UnsignedFlag = 0x10,
- QuadFlag = 0x20
- };
- uint32_t Flags;
-
- public:
- enum EltType {
- Int8,
- Int16,
- Int32,
- Int64,
- Poly8,
- Poly16,
- Poly64,
- Poly128,
- Float16,
- Float32,
- Float64
- };
-
- NeonTypeFlags(unsigned F) : Flags(F) {}
- NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
- if (IsUnsigned)
- Flags |= UnsignedFlag;
- if (IsQuad)
- Flags |= QuadFlag;
- }
-
- EltType getEltType() const { return (EltType)(Flags & EltTypeMask); }
- bool isPoly() const {
- EltType ET = getEltType();
- return ET == Poly8 || ET == Poly16;
- }
- bool isUnsigned() const { return (Flags & UnsignedFlag) != 0; }
- bool isQuad() const { return (Flags & QuadFlag) != 0; }
- };
-
- /// \brief Hexagon builtins
- namespace Hexagon {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsHexagon.def"
- LastTSBuiltin
- };
- }
-
- /// \brief MIPS builtins
- namespace Mips {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsMips.def"
- LastTSBuiltin
- };
- }
-
- /// \brief XCore builtins
- namespace XCore {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsXCore.def"
- LastTSBuiltin
- };
- }
-
- /// \brief Le64 builtins
- namespace Le64 {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
- #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
- #include "clang/Basic/BuiltinsLe64.def"
- LastTSBuiltin
- };
- }
-
- /// \brief SystemZ builtins
- namespace SystemZ {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsSystemZ.def"
- LastTSBuiltin
- };
- }
-
- /// \brief WebAssembly builtins
- namespace WebAssembly {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsWebAssembly.def"
- LastTSBuiltin
- };
- }
-
-} // end namespace clang.
-
-#endif
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
deleted file mode 100644
index 67247ea..0000000
--- a/include/clang/Basic/TargetCXXABI.h
+++ /dev/null
@@ -1,354 +0,0 @@
-//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- 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 TargetCXXABI class, which abstracts details of the
-/// C++ ABI that we're targeting.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H
-#define LLVM_CLANG_BASIC_TARGETCXXABI_H
-
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-
-/// \brief The basic abstraction for the target C++ ABI.
-class TargetCXXABI {
-public:
- /// \brief 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
- /// many compilers, including Clang and GCC.
- ///
- /// It is documented here:
- /// http://www.codesourcery.com/public/cxx-abi/
- GenericItanium,
-
- /// The generic ARM ABI is a modified version of the Itanium ABI
- /// proposed by ARM for use on ARM-based platforms.
- ///
- /// These changes include:
- /// - the representation of member function pointers is adjusted
- /// to not conflict with the 'thumb' bit of ARM function pointers;
- /// - constructors and destructors return 'this';
- /// - guard variables are smaller;
- /// - inline functions are never key functions;
- /// - array cookies have a slightly different layout;
- /// - additional convenience functions are specified;
- /// - and more!
- ///
- /// It is documented here:
- /// http://infocenter.arm.com
- /// /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
- GenericARM,
-
- /// The iOS ABI is a partial implementation of the ARM ABI.
- /// Several of the features of the ARM ABI were not fully implemented
- /// in the compilers that iOS was launched with.
- ///
- /// Essentially, the iOS ABI includes the ARM changes to:
- /// - member function pointers,
- /// - guard variables,
- /// - array cookies, and
- /// - constructor/destructor signatures.
- iOS,
-
- /// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more
- /// closely, but we don't guarantee to follow it perfectly.
- ///
- /// It is documented here:
- /// http://infocenter.arm.com
- /// /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf
- iOS64,
-
- /// WatchOS is a modernisation of the iOS ABI, which roughly means it's
- /// the iOS64 ABI ported to 32-bits. The primary difference from iOS64 is
- /// that RTTI objects must still be unique at the moment.
- WatchOS,
-
- /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
- /// but it has fewer divergences than the 32-bit ARM ABI.
- ///
- /// The relevant changes from the generic ABI in this case are:
- /// - representation of member function pointers adjusted as in ARM.
- /// - guard variables are smaller.
- GenericAArch64,
-
- /// The generic Mips ABI is a modified version of the Itanium ABI.
- ///
- /// At the moment, only change from the generic ABI in this case is:
- /// - representation of member function pointers adjusted as in ARM.
- GenericMIPS,
-
- /// The WebAssembly ABI is a modified version of the Itanium ABI.
- ///
- /// The changes from the Itanium ABI are:
- /// - representation of member function pointers is adjusted, as in ARM;
- /// - member functions are not specially aligned;
- /// - constructors and destructors return 'this', as in ARM;
- /// - guard variables are 32-bit on wasm32, as in ARM;
- /// - unused bits of guard variables are reserved, as in ARM;
- /// - inline functions are never key functions, as in ARM;
- /// - C++11 POD rules are used for tail padding, as in iOS64.
- ///
- /// TODO: At present the WebAssembly ABI is not considered stable, so none
- /// of these details is necessarily final yet.
- WebAssembly,
-
- /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
- /// compatible compilers).
- ///
- /// FIXME: should this be split into Win32 and Win64 variants?
- ///
- /// Only scattered and incomplete official documentation exists.
- Microsoft
- };
-
-private:
- // Right now, this class is passed around as a cheap value type.
- // If you add more members, especially non-POD members, please
- // audit the users to pass it by reference instead.
- Kind TheKind;
-
-public:
- /// A bogus initialization of the platform ABI.
- TargetCXXABI() : TheKind(GenericItanium) {}
-
- TargetCXXABI(Kind kind) : TheKind(kind) {}
-
- void set(Kind kind) {
- TheKind = kind;
- }
-
- Kind getKind() const { return TheKind; }
-
- /// \brief Does this ABI generally fall into the Itanium family of ABIs?
- bool isItaniumFamily() const {
- switch (getKind()) {
- case GenericAArch64:
- case GenericItanium:
- case GenericARM:
- case iOS:
- case iOS64:
- case WatchOS:
- case GenericMIPS:
- case WebAssembly:
- return true;
-
- case Microsoft:
- return false;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- /// \brief Is this ABI an MSVC-compatible ABI?
- bool isMicrosoft() const {
- switch (getKind()) {
- case GenericAArch64:
- case GenericItanium:
- case GenericARM:
- case iOS:
- case iOS64:
- case WatchOS:
- case GenericMIPS:
- case WebAssembly:
- return false;
-
- case Microsoft:
- return true;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- /// \brief 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
- /// least significant bit, so that pointers to member functions can use that
- /// bit to distinguish between virtual and non-virtual functions. However,
- /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual
- /// functions via other means, and consequently don't require that member
- /// functions be aligned.
- bool areMemberFunctionsAligned() const {
- switch (getKind()) {
- case WebAssembly:
- // WebAssembly doesn't require any special alignment for member functions.
- return false;
- case GenericARM:
- case GenericAArch64:
- case GenericMIPS:
- // TODO: ARM-style pointers to member functions put the discriminator in
- // the this adjustment, so they don't require functions to have any
- // special alignment and could therefore also return false.
- case GenericItanium:
- case iOS:
- case iOS64:
- case WatchOS:
- case Microsoft:
- return true;
- }
- 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.
- /// Temporaries passed to a function taking a const reference live to the end
- /// of the full expression as usual. Both the caller and the callee must
- /// have access to the destructor, while only the caller needs the
- /// destructor if this is false.
- bool areArgsDestroyedLeftToRightInCallee() const {
- return isMicrosoft();
- }
-
- /// \brief 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?
- bool hasPrimaryVBases() const {
- return isItaniumFamily();
- }
-
- /// \brief 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?
- ///
- /// This flag is only useful in ABIs where type data (for example,
- /// v-tables and type_info objects) are emitted only after processing
- /// the definition of a special "key" virtual function. (This is safe
- /// because the ODR requires that every virtual function be defined
- /// somewhere in a program.) This usually permits such data to be
- /// emitted in only a single object file, as opposed to redundantly
- /// in every object file that requires it.
- ///
- /// One simple and common definition of "key function" is the first
- /// virtual function in the class definition which is not defined there.
- /// This rule works very well when that function has a non-inline
- /// definition in some non-header file. Unfortunately, when that
- /// function is defined inline, this rule requires the type data
- /// to be emitted weakly, as if there were no key function.
- ///
- /// The ARM ABI observes that the ODR provides an additional guarantee:
- /// a virtual function is always ODR-used, so if it is defined inline,
- /// that definition must appear in every translation unit that defines
- /// the class. Therefore, there is no reason to allow such functions
- /// to serve as key functions.
- ///
- /// Because this changes the rules for emitting type data,
- /// it can cause type data to be emitted with both weak and strong
- /// linkage, which is not allowed on all platforms. Therefore,
- /// exploiting this observation requires an ABI break and cannot be
- /// done on a generic Itanium platform.
- bool canKeyFunctionBeInline() const {
- switch (getKind()) {
- case GenericARM:
- case iOS64:
- case WebAssembly:
- case WatchOS:
- return false;
-
- case GenericAArch64:
- case GenericItanium:
- case iOS: // old iOS compilers did not follow this rule
- case Microsoft:
- case GenericMIPS:
- return true;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- /// When is record layout allowed to allocate objects in the tail
- /// padding of a base class?
- ///
- /// This decision cannot be changed without breaking platform ABI
- /// compatibility, and yet it is tied to language guarantees which
- /// the committee has so far seen fit to strengthen no less than
- /// three separate times:
- /// - originally, there were no restrictions at all;
- /// - C++98 declared that objects could not be allocated in the
- /// tail padding of a POD type;
- /// - C++03 extended the definition of POD to include classes
- /// containing member pointers; and
- /// - C++11 greatly broadened the definition of POD to include
- /// all trivial standard-layout classes.
- /// Each of these changes technically took several existing
- /// platforms and made them permanently non-conformant.
- enum TailPaddingUseRules {
- /// The tail-padding of a base class is always theoretically
- /// available, even if it's POD. This is not strictly conforming
- /// in any language mode.
- AlwaysUseTailPadding,
-
- /// Only allocate objects in the tail padding of a base class if
- /// the base class is not POD according to the rules of C++ TR1.
- /// This is non-strictly conforming in C++11 mode.
- UseTailPaddingUnlessPOD03,
-
- /// Only allocate objects in the tail padding of a base class if
- /// the base class is not POD according to the rules of C++11.
- UseTailPaddingUnlessPOD11
- };
- TailPaddingUseRules getTailPaddingUseRules() const {
- switch (getKind()) {
- // To preserve binary compatibility, the generic Itanium ABI has
- // permanently locked the definition of POD to the rules of C++ TR1,
- // and that trickles down to derived ABIs.
- case GenericItanium:
- case GenericAArch64:
- case GenericARM:
- case iOS:
- case GenericMIPS:
- return UseTailPaddingUnlessPOD03;
-
- // iOS on ARM64 and WebAssembly use the C++11 POD rules. They do not honor
- // the Itanium exception about classes with over-large bitfields.
- case iOS64:
- case WebAssembly:
- case WatchOS:
- return UseTailPaddingUnlessPOD11;
-
- // MSVC always allocates fields in the tail-padding of a base class
- // subobject, even if they're POD.
- case Microsoft:
- return AlwaysUseTailPadding;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
- return left.getKind() == right.getKind();
- }
-
- friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
- return !(left == right);
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
deleted file mode 100644
index f1d8338..0000000
--- a/include/clang/Basic/TargetInfo.h
+++ /dev/null
@@ -1,953 +0,0 @@
-//===--- TargetInfo.h - Expose information about the target -----*- 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::TargetInfo interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
-#define LLVM_CLANG_BASIC_TARGETINFO_H
-
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/TargetCXXABI.h"
-#include "clang/Basic/TargetOptions.h"
-#include "clang/Basic/VersionTuple.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-#include <string>
-#include <vector>
-
-namespace llvm {
-struct fltSemantics;
-}
-
-namespace clang {
-class DiagnosticsEngine;
-class LangOptions;
-class MacroBuilder;
-class SourceLocation;
-class SourceManager;
-
-namespace Builtin { struct Info; }
-
-/// \brief Exposes information about the current target.
-///
-class TargetInfo : public RefCountedBase<TargetInfo> {
- std::shared_ptr<TargetOptions> TargetOpts;
- llvm::Triple Triple;
-protected:
- // Target values set by the ctor of the actual target implementation. Default
- // values are specified by the TargetInfo constructor.
- bool BigEndian;
- bool TLSSupported;
- bool NoAsmVariants; // True if {|} are normal characters.
- unsigned char PointerWidth, PointerAlign;
- unsigned char BoolWidth, BoolAlign;
- unsigned char IntWidth, IntAlign;
- unsigned char HalfWidth, HalfAlign;
- unsigned char FloatWidth, FloatAlign;
- unsigned char DoubleWidth, DoubleAlign;
- unsigned char LongDoubleWidth, LongDoubleAlign;
- unsigned char LargeArrayMinWidth, LargeArrayAlign;
- unsigned char LongWidth, LongAlign;
- unsigned char LongLongWidth, LongLongAlign;
- unsigned char SuitableAlign;
- unsigned char DefaultAlignForAttributeAligned;
- unsigned char MinGlobalAlign;
- unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
- unsigned short MaxVectorAlign;
- unsigned short MaxTLSAlign;
- unsigned short SimdDefaultAlign;
- const char *DataLayoutString;
- const char *UserLabelPrefix;
- const char *MCountName;
- const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
- *LongDoubleFormat;
- unsigned char RegParmMax, SSERegParmMax;
- TargetCXXABI TheCXXABI;
- const LangAS::Map *AddrSpaceMap;
-
- mutable StringRef PlatformName;
- mutable VersionTuple PlatformMinVersion;
-
- unsigned HasAlignMac68kSupport : 1;
- unsigned RealTypeUsesObjCFPRet : 3;
- unsigned ComplexLongDoubleUsesFP2Ret : 1;
-
- unsigned HasBuiltinMSVaList : 1;
-
- // TargetInfo Constructor. Default initializes all fields.
- TargetInfo(const llvm::Triple &T);
-
-public:
- /// \brief 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
- /// what the backend expects.
- static TargetInfo *
- CreateTargetInfo(DiagnosticsEngine &Diags,
- const std::shared_ptr<TargetOptions> &Opts);
-
- virtual ~TargetInfo();
-
- /// \brief Retrieve the target options.
- TargetOptions &getTargetOpts() const {
- assert(TargetOpts && "Missing target options");
- return *TargetOpts;
- }
-
- ///===---- Target Data Type Query Methods -------------------------------===//
- enum IntType {
- NoInt = 0,
- SignedChar,
- UnsignedChar,
- SignedShort,
- UnsignedShort,
- SignedInt,
- UnsignedInt,
- SignedLong,
- UnsignedLong,
- SignedLongLong,
- UnsignedLongLong
- };
-
- enum RealType {
- NoFloat = 255,
- Float = 0,
- Double,
- LongDouble
- };
-
- /// \brief The different kinds of __builtin_va_list types defined by
- /// the target implementation.
- enum BuiltinVaListKind {
- /// typedef char* __builtin_va_list;
- CharPtrBuiltinVaList = 0,
-
- /// typedef void* __builtin_va_list;
- VoidPtrBuiltinVaList,
-
- /// __builtin_va_list as defind by the AArch64 ABI
- /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
- AArch64ABIBuiltinVaList,
-
- /// __builtin_va_list as defined by the PNaCl ABI:
- /// http://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Machine-Types
- PNaClABIBuiltinVaList,
-
- /// __builtin_va_list as defined by the Power ABI:
- /// https://www.power.org
- /// /resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf
- PowerABIBuiltinVaList,
-
- /// __builtin_va_list as defined by the x86-64 ABI:
- /// http://www.x86-64.org/documentation/abi.pdf
- X86_64ABIBuiltinVaList,
-
- /// __builtin_va_list as defined by ARM AAPCS ABI
- /// http://infocenter.arm.com
- // /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
- AAPCSABIBuiltinVaList,
-
- // typedef struct __va_list_tag
- // {
- // long __gpr;
- // long __fpr;
- // void *__overflow_arg_area;
- // void *__reg_save_area;
- // } va_list[1];
- SystemZBuiltinVaList
- };
-
-protected:
- IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType,
- WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
- ProcessIDType;
-
- /// \brief 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.
- unsigned UseSignedCharForObjCBool : 1;
-
- /// Control whether the alignment of bit-field types is respected when laying
- /// out structures. If true, then the alignment of the bit-field type will be
- /// used to (a) impact the alignment of the containing structure, and (b)
- /// ensure that the individual bit-field will not straddle an alignment
- /// boundary.
- unsigned UseBitFieldTypeAlignment : 1;
-
- /// \brief 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
- /// that follows it, `bar', `bar' will be aligned as the type of the
- /// zero-length bitfield.
- unsigned UseZeroLengthBitfieldAlignment : 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
- /// not for language specific address spaces
- bool UseAddrSpaceMapMangling;
-
-public:
- IntType getSizeType() const { return SizeType; }
- IntType getIntMaxType() const { return IntMaxType; }
- IntType getUIntMaxType() const {
- return getCorrespondingUnsignedType(IntMaxType);
- }
- IntType getPtrDiffType(unsigned AddrSpace) const {
- return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
- }
- IntType getIntPtrType() const { return IntPtrType; }
- IntType getUIntPtrType() const {
- return getCorrespondingUnsignedType(IntPtrType);
- }
- IntType getWCharType() const { return WCharType; }
- IntType getWIntType() const { return WIntType; }
- IntType getChar16Type() const { return Char16Type; }
- IntType getChar32Type() const { return Char32Type; }
- IntType getInt64Type() const { return Int64Type; }
- IntType getUInt64Type() const {
- return getCorrespondingUnsignedType(Int64Type);
- }
- IntType getSigAtomicType() const { return SigAtomicType; }
- IntType getProcessIDType() const { return ProcessIDType; }
-
- static IntType getCorrespondingUnsignedType(IntType T) {
- switch (T) {
- case SignedChar:
- return UnsignedChar;
- case SignedShort:
- return UnsignedShort;
- case SignedInt:
- return UnsignedInt;
- case SignedLong:
- return UnsignedLong;
- case SignedLongLong:
- return UnsignedLongLong;
- default:
- llvm_unreachable("Unexpected signed integer type");
- }
- }
-
- /// \brief 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.
- virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
-
- /// \brief 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.
- RealType getRealTypeByWidth(unsigned BitWidth) const;
-
- /// \brief 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.
- static bool isTypeSigned(IntType T);
-
- /// \brief 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);
- }
- uint64_t getPointerAlign(unsigned AddrSpace) const {
- return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
- }
-
- /// \brief 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.
- 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
- /// target, in bits.
- unsigned getShortWidth() const { return 16; } // FIXME
-
- /// \brief Return the alignment of 'signed short' and 'unsigned short' for
- /// this target.
- unsigned getShortAlign() const { return 16; } // FIXME
-
- /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
- /// this target, in bits.
- unsigned getIntWidth() const { return IntWidth; }
- unsigned getIntAlign() const { return IntAlign; }
-
- /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
- /// for this target, in bits.
- unsigned getLongWidth() const { return LongWidth; }
- unsigned getLongAlign() const { return LongAlign; }
-
- /// getLongLongWidth/Align - Return the size of 'signed long long' and
- /// 'unsigned long long' for this target, in bits.
- unsigned getLongLongWidth() const { return LongLongWidth; }
- unsigned getLongLongAlign() const { return LongLongAlign; }
-
- /// \brief Determine whether the __int128 type is supported on this target.
- virtual bool hasInt128Type() const {
- return getPointerWidth(0) >= 64;
- } // FIXME
-
- /// \brief 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
- /// this target, to be used if no alignment value is specified.
- unsigned getDefaultAlignForAttributeAligned() const {
- return DefaultAlignForAttributeAligned;
- }
-
- /// getMinGlobalAlign - Return the minimum alignment of a global variable,
- /// unless its alignment is explicitly reduced via attributes.
- unsigned getMinGlobalAlign() const { return MinGlobalAlign; }
-
- /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
- /// bits.
- unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
- unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
-
- /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
- /// bits.
- unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
- unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
-
- /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
- /// bits.
- unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
- unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
-
- /// getHalfWidth/Align/Format - Return the size/align/format of 'half'.
- unsigned getHalfWidth() const { return HalfWidth; }
- unsigned getHalfAlign() const { return HalfAlign; }
- const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; }
-
- /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
- unsigned getFloatWidth() const { return FloatWidth; }
- unsigned getFloatAlign() const { return FloatAlign; }
- const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
-
- /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
- unsigned getDoubleWidth() const { return DoubleWidth; }
- unsigned getDoubleAlign() const { return DoubleAlign; }
- const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
-
- /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
- /// double'.
- unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
- unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
- const llvm::fltSemantics &getLongDoubleFormat() const {
- return *LongDoubleFormat;
- }
-
- /// \brief 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.
- virtual unsigned getFloatEvalMethod() const { return 0; }
-
- // getLargeArrayMinWidth/Align - Return the minimum array size that is
- // 'large' and its alignment.
- unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
- unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
-
- /// \brief 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
- /// inlined given the supported features of the given target.
- unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
- /// \brief 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 {
- return AtomicSizeInBits <= AlignmentInBits &&
- AtomicSizeInBits <= getMaxAtomicInlineWidth() &&
- (AtomicSizeInBits <= getCharWidth() ||
- llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth()));
- }
-
- /// \brief 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
- /// 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.
- unsigned getIntMaxTWidth() const {
- return getTypeWidth(IntMaxType);
- }
-
- // Return the size of unwind_word for this target.
- unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
-
- /// \brief Return the "preferred" register width on this target.
- 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
- // it.
- return PointerWidth;
- }
-
- /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro,
- /// which is the prefix given to user symbols by default.
- ///
- /// On most platforms this is "_", but it is "" on some, and "." on others.
- const char *getUserLabelPrefix() const {
- return UserLabelPrefix;
- }
-
- /// \brief 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
- /// char.
- ///
- /// Otherwise, if this returns false, the normal built-in boolean type
- /// should also be used for Objective-C.
- bool useSignedCharForObjCBool() const {
- return UseSignedCharForObjCBool;
- }
- void noSignedCharForObjCBool() {
- UseSignedCharForObjCBool = false;
- }
-
- /// \brief 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
- /// the next member.
- bool useZeroLengthBitfieldAlignment() const {
- return UseZeroLengthBitfieldAlignment;
- }
-
- /// \brief Get the fixed alignment value in bits for a member that follows
- /// a zero length bitfield.
- unsigned getZeroLengthBitfieldBoundary() const {
- return ZeroLengthBitfieldBoundary;
- }
-
- /// \brief 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.
- ///
- /// For example, SignedShort -> "short".
- static const char *getTypeName(IntType T);
-
- /// \brief 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
- /// 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
- /// 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
- /// of Objective-C message passing on this target.
- bool useObjCFP2RetForComplexLongDouble() const {
- return ComplexLongDoubleUsesFP2Ret;
- }
-
- /// \brief Specify if mangling based on address space map should be used or
- /// not for language specific address spaces
- bool useAddressSpaceMapMangling() const {
- return UseAddrSpaceMapMangling;
- }
-
- ///===---- Other target property query methods --------------------------===//
-
- /// \brief Appends the target-specific \#define values for this
- /// target set to the specified buffer.
- virtual void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const = 0;
-
-
- /// Return information about target-specific builtins for
- /// the current primary target, and info about which builtins are non-portable
- /// across the current set of primary and secondary targets.
- virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
-
- /// The __builtin_clz* and __builtin_ctz* built-in
- /// functions are specified to have undefined results for zero inputs, but
- /// on targets that support these operations in a way that provides
- /// well-defined results for zero without loss of performance, it is a good
- /// 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
- /// with this target.
- virtual BuiltinVaListKind getBuiltinVaListKind() const = 0;
-
- /// Returns whether or not type \c __builtin_ms_va_list type is
- /// available on this target.
- bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; }
-
- /// \brief 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
- /// according to GCC.
- ///
- /// This is used by Sema for inline asm statements.
- bool isValidGCCRegisterName(StringRef Name) const;
-
- /// \brief Returns the "normalized" GCC register name.
- ///
- /// For example, on x86 it will return "ax" when "eax" is passed in.
- StringRef getNormalizedGCCRegisterName(StringRef Name) const;
-
- struct ConstraintInfo {
- enum {
- CI_None = 0x00,
- CI_AllowsMemory = 0x01,
- CI_AllowsRegister = 0x02,
- CI_ReadWrite = 0x04, // "+r" output constraint (read and write).
- CI_HasMatchingInput = 0x08, // This output operand has a matching input.
- CI_ImmediateConstant = 0x10, // This operand must be an immediate constant
- CI_EarlyClobber = 0x20, // "&" output constraint (early clobber).
- };
- unsigned Flags;
- int TiedOperand;
- struct {
- int Min;
- int Max;
- } ImmRange;
- llvm::SmallSet<int, 4> ImmSet;
-
- std::string ConstraintStr; // constraint: "=rm"
- std::string Name; // Operand name: [foo] with no []'s.
- public:
- ConstraintInfo(StringRef ConstraintStr, StringRef Name)
- : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
- Name(Name.str()) {
- ImmRange.Min = ImmRange.Max = 0;
- }
-
- const std::string &getConstraintStr() const { return ConstraintStr; }
- const std::string &getName() const { return Name; }
- bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
- bool earlyClobber() { return (Flags & CI_EarlyClobber) != 0; }
- 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
- /// (tied) input operand.
- bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
-
- /// \brief 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
- /// operand this is tied to.
- bool hasTiedOperand() const { return TiedOperand != -1; }
- unsigned getTiedOperand() const {
- assert(hasTiedOperand() && "Has no tied operand!");
- return (unsigned)TiedOperand;
- }
-
- bool requiresImmediateConstant() const {
- return (Flags & CI_ImmediateConstant) != 0;
- }
- bool isValidAsmImmediate(const llvm::APInt &Value) const {
- return (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)) ||
- ImmSet.count(Value.getZExtValue()) != 0;
- }
-
- void setIsReadWrite() { Flags |= CI_ReadWrite; }
- void setEarlyClobber() { Flags |= CI_EarlyClobber; }
- void setAllowsMemory() { Flags |= CI_AllowsMemory; }
- void setAllowsRegister() { Flags |= CI_AllowsRegister; }
- void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
- void setRequiresImmediate(int Min, int Max) {
- Flags |= CI_ImmediateConstant;
- ImmRange.Min = Min;
- ImmRange.Max = Max;
- }
- void setRequiresImmediate(llvm::ArrayRef<int> Exacts) {
- Flags |= CI_ImmediateConstant;
- for (int Exact : Exacts)
- ImmSet.insert(Exact);
- }
- void setRequiresImmediate(int Exact) {
- Flags |= CI_ImmediateConstant;
- ImmSet.insert(Exact);
- }
- void setRequiresImmediate() {
- Flags |= CI_ImmediateConstant;
- ImmRange.Min = INT_MIN;
- ImmRange.Max = INT_MAX;
- }
-
- /// \brief Indicate that this is an input operand that is tied to
- /// the specified output operand.
- ///
- /// Copy over the various constraint information from the output.
- void setTiedOperand(unsigned N, ConstraintInfo &Output) {
- Output.setHasMatchingInput();
- Flags = Output.Flags;
- TiedOperand = N;
- // Don't copy Name or constraint string.
- }
- };
-
- /// \brief 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
- /// true in HasSizeMismatch if the size of the register doesn't match the
- /// variable size passed in RegSize.
- virtual bool validateGlobalRegisterVariable(StringRef RegName,
- unsigned RegSize,
- bool &HasSizeMismatch) const {
- HasSizeMismatch = false;
- return true;
- }
-
- // validateOutputConstraint, validateInputConstraint - Checks that
- // a constraint is valid and provides information about it.
- // FIXME: These should return a real error instead of just true/false.
- bool validateOutputConstraint(ConstraintInfo &Info) const;
- bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,
- ConstraintInfo &info) const;
-
- virtual bool validateOutputSize(StringRef /*Constraint*/,
- unsigned /*Size*/) const {
- return true;
- }
-
- virtual bool validateInputSize(StringRef /*Constraint*/,
- unsigned /*Size*/) const {
- return true;
- }
- virtual bool
- validateConstraintModifier(StringRef /*Constraint*/,
- char /*Modifier*/,
- unsigned /*Size*/,
- std::string &/*SuggestedModifier*/) const {
- return true;
- }
- virtual bool
- validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const = 0;
-
- bool resolveSymbolicName(const char *&Name,
- ArrayRef<ConstraintInfo> OutputConstraints,
- unsigned &Index) const;
-
- // Constraint parm will be left pointing at the last character of
- // the constraint. In practice, it won't be changed unless the
- // constraint is longer than one character.
- virtual std::string convertConstraint(const char *&Constraint) const {
- // 'p' defaults to 'r', but can be overridden by targets.
- if (*Constraint == 'p')
- return std::string("r");
- return std::string(1, *Constraint);
- }
-
- /// \brief 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.
- /// Only MIPS allows a different encoding.
- virtual bool isNan2008() const {
- return true;
- }
-
- /// \brief Returns the target triple of the primary target.
- const llvm::Triple &getTriple() const {
- return Triple;
- }
-
- const char *getDataLayoutString() const {
- assert(DataLayoutString && "Uninitialized DataLayoutString!");
- return DataLayoutString;
- }
-
- struct GCCRegAlias {
- const char * const Aliases[5];
- const char * const Register;
- };
-
- struct AddlRegName {
- const char * const Names[5];
- const unsigned RegNum;
- };
-
- /// \brief Does this target support "protected" visibility?
- ///
- /// Any target which dynamic libraries will naturally support
- /// something like "default" (meaning that the symbol is visible
- /// outside this shared object) and "hidden" (meaning that it isn't)
- /// visibilities, but "protected" is really an ELF-specific concept
- /// with weird semantics designed around the convenience of dynamic
- /// linker implementations. Which is not to suggest that there's
- /// consistent target-independent semantics for "default" visibility
- /// 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
- /// checking on attribute((section("foo"))) specifiers.
- ///
- /// In this case, "foo" is passed in to be checked. If the section
- /// specifier is invalid, the backend should return a non-empty string
- /// that indicates the problem.
- ///
- /// This hook is a simple quality of implementation feature to catch errors
- /// and give good diagnostics in cases when the assembler or code generator
- /// would otherwise reject the section specifier.
- ///
- virtual std::string isValidSectionSpecifier(StringRef SR) const {
- return "";
- }
-
- /// \brief Set forced language options.
- ///
- /// Apply changes to the target information with respect to certain
- /// language options which change the target configuration.
- virtual void adjust(const LangOptions &Opts);
-
- /// \brief 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).
- virtual bool initFeatureMap(llvm::StringMap<bool> &Features,
- DiagnosticsEngine &Diags, StringRef CPU,
- const std::vector<std::string> &FeatureVec) const;
-
- /// \brief Get the ABI currently in use.
- virtual StringRef getABI() const { return StringRef(); }
-
- /// \brief Get the C++ ABI currently in use.
- TargetCXXABI getCXXABI() const {
- return TheCXXABI;
- }
-
- /// \brief Target the specified CPU.
- ///
- /// \return False on error (invalid CPU name).
- virtual bool setCPU(const std::string &Name) {
- return false;
- }
-
- /// \brief 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.
- ///
- /// \return False on error (invalid unit name).
- virtual bool setFPMath(StringRef Name) {
- return false;
- }
-
- /// \brief Enable or disable a specific target feature;
- /// the feature name must be valid.
- virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const {
- Features[Name] = Enabled;
- }
-
- /// \brief 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.
- ///
- /// The target may modify the features list, to change which options are
- /// passed onwards to the backend.
- /// FIXME: This part should be fixed so that we can change handleTargetFeatures
- /// to merely a TargetInfo initialization routine.
- ///
- /// \return False on error.
- virtual bool handleTargetFeatures(std::vector<std::string> &Features,
- DiagnosticsEngine &Diags) {
- return true;
- }
-
- /// \brief 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*)
- // argument.
- virtual bool validateCpuSupports(StringRef Name) const { return false; }
-
- // \brief 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.
- bool isTLSSupported() const {
- return TLSSupported;
- }
-
- /// \brief 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.
- unsigned short getMaxTLSAlign() const {
- return MaxTLSAlign;
- }
-
- /// \brief 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.
- ///
- /// If this returns false (the default), then {abc|xyz} is syntax
- /// that says that when compiling for asm variant #0, "abc" should be
- /// generated, but when compiling for asm variant #1, "xyz" should be
- /// generated.
- bool hasNoAsmVariants() const {
- return NoAsmVariants;
- }
-
- /// \brief Return the register number that __builtin_eh_return_regno would
- /// return with the specified argument.
- virtual int getEHDataRegisterNumber(unsigned RegNo) const {
- return -1;
- }
-
- /// \brief Return the section to use for C++ static initialization functions.
- virtual const char *getStaticInitSectionSpecifier() const {
- return nullptr;
- }
-
- const LangAS::Map &getAddressSpaceMap() const {
- return *AddrSpaceMap;
- }
-
- /// \brief 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
- /// which the program should be compiled.
- VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
-
- bool isBigEndian() const { return BigEndian; }
-
- enum CallingConvMethodType {
- CCMT_Unknown,
- CCMT_Member,
- CCMT_NonMember
- };
-
- /// \brief 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
- // express. This will always do the right thing, even though it's not
- // an explicit calling convention.
- return CC_C;
- }
-
- enum CallingConvCheckResult {
- CCCR_OK,
- CCCR_Warning,
- CCCR_Ignore,
- };
-
- /// \brief 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).
- virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
- switch (CC) {
- default:
- return CCCR_Warning;
- case CC_C:
- return CCCR_OK;
- }
- }
-
- /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
- /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
- virtual bool hasSjLjLowering() const {
- return false;
- }
-
-protected:
- virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
- return PointerWidth;
- }
- virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
- return PointerAlign;
- }
- virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const {
- return PtrDiffType;
- }
- virtual ArrayRef<const char *> getGCCRegNames() const = 0;
- virtual ArrayRef<GCCRegAlias> getGCCRegAliases() const = 0;
- virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const {
- return None;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
deleted file mode 100644
index ca0cca7..0000000
--- a/include/clang/Basic/TargetOptions.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===--- TargetOptions.h ----------------------------------------*- 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::TargetOptions class.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_TARGETOPTIONS_H
-#define LLVM_CLANG_BASIC_TARGETOPTIONS_H
-
-#include <string>
-#include <vector>
-
-namespace clang {
-
-/// \brief Options for controlling the target.
-class TargetOptions {
-public:
- /// If given, the name of the target triple to compile for. If not given the
- /// target will be selected to match the host.
- std::string Triple;
-
- /// If given, the name of the target CPU to generate code for.
- std::string CPU;
-
- /// If given, the unit to use for floating point math.
- std::string FPMath;
-
- /// If given, the name of the target ABI to use.
- std::string ABI;
-
- /// 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.
- std::vector<std::string> FeaturesAsWritten;
-
- /// The list of target specific features to enable or disable -- this should
- /// be a list of strings starting with by '+' or '-'.
- std::vector<std::string> Features;
-
- std::vector<std::string> Reciprocals;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h
deleted file mode 100644
index aed287b..0000000
--- a/include/clang/Basic/TemplateKinds.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- TemplateKinds.h - Enum values for C++ Template Kinds ---*- 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::TemplateNameKind enum.
-///
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_TEMPLATEKINDS_H
-#define LLVM_CLANG_BASIC_TEMPLATEKINDS_H
-
-namespace clang {
-
-/// \brief 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.
- TNK_Non_template = 0,
- /// The name refers to a function template or a set of overloaded
- /// functions that includes at least one function template.
- TNK_Function_template,
- /// The name refers to a template whose specialization produces a
- /// type. The template itself could be a class template, template
- /// template parameter, or C++0x template alias.
- TNK_Type_template,
- /// The name refers to a variable template whose specialization produces a
- /// variable.
- TNK_Var_template,
- /// The name refers to a dependent template name. Whether the
- /// template name is assumed to refer to a type template or a
- /// function template depends on the context in which the template
- /// name occurs.
- TNK_Dependent_template_name
-};
-
-}
-#endif
-
-
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
deleted file mode 100644
index 9252d99..0000000
--- a/include/clang/Basic/TokenKinds.def
+++ /dev/null
@@ -1,781 +0,0 @@
-//===--- TokenKinds.def - C Family Token Kind 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 the TokenKind database. This includes normal tokens like
-// tok::ampamp (corresponding to the && token) as well as keywords for various
-// languages. Users of this file must optionally #define the TOK, KEYWORD,
-// CXX11_KEYWORD, CONCEPTS_KEYWORD, ALIAS, or PPKEYWORD macros to make use of
-// this file.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TOK
-#define TOK(X)
-#endif
-#ifndef PUNCTUATOR
-#define PUNCTUATOR(X,Y) TOK(X)
-#endif
-#ifndef KEYWORD
-#define KEYWORD(X,Y) TOK(kw_ ## X)
-#endif
-#ifndef CXX11_KEYWORD
-#define CXX11_KEYWORD(X,Y) KEYWORD(X,KEYCXX11|(Y))
-#endif
-#ifndef CONCEPTS_KEYWORD
-#define CONCEPTS_KEYWORD(X) KEYWORD(X,KEYCONCEPTS)
-#endif
-#ifndef TYPE_TRAIT
-#define TYPE_TRAIT(N,I,K) KEYWORD(I,K)
-#endif
-#ifndef TYPE_TRAIT_1
-#define TYPE_TRAIT_1(I,E,K) TYPE_TRAIT(1,I,K)
-#endif
-#ifndef TYPE_TRAIT_2
-#define TYPE_TRAIT_2(I,E,K) TYPE_TRAIT(2,I,K)
-#endif
-#ifndef TYPE_TRAIT_N
-#define TYPE_TRAIT_N(I,E,K) TYPE_TRAIT(0,I,K)
-#endif
-#ifndef ALIAS
-#define ALIAS(X,Y,Z)
-#endif
-#ifndef PPKEYWORD
-#define PPKEYWORD(X)
-#endif
-#ifndef CXX_KEYWORD_OPERATOR
-#define CXX_KEYWORD_OPERATOR(X,Y)
-#endif
-#ifndef OBJC1_AT_KEYWORD
-#define OBJC1_AT_KEYWORD(X)
-#endif
-#ifndef OBJC2_AT_KEYWORD
-#define OBJC2_AT_KEYWORD(X)
-#endif
-#ifndef TESTING_KEYWORD
-#define TESTING_KEYWORD(X, L) KEYWORD(X, L)
-#endif
-#ifndef ANNOTATION
-#define ANNOTATION(X) TOK(annot_ ## X)
-#endif
-
-//===----------------------------------------------------------------------===//
-// Preprocessor keywords.
-//===----------------------------------------------------------------------===//
-
-// These have meaning after a '#' at the start of a line. These define enums in
-// the tok::pp_* namespace. Note that IdentifierInfo::getPPKeywordID must be
-// manually updated if something is added here.
-PPKEYWORD(not_keyword)
-
-// C99 6.10.1 - Conditional Inclusion.
-PPKEYWORD(if)
-PPKEYWORD(ifdef)
-PPKEYWORD(ifndef)
-PPKEYWORD(elif)
-PPKEYWORD(else)
-PPKEYWORD(endif)
-PPKEYWORD(defined)
-
-// C99 6.10.2 - Source File Inclusion.
-PPKEYWORD(include)
-PPKEYWORD(__include_macros)
-
-// C99 6.10.3 - Macro Replacement.
-PPKEYWORD(define)
-PPKEYWORD(undef)
-
-// C99 6.10.4 - Line Control.
-PPKEYWORD(line)
-
-// C99 6.10.5 - Error Directive.
-PPKEYWORD(error)
-
-// C99 6.10.6 - Pragma Directive.
-PPKEYWORD(pragma)
-
-// GNU Extensions.
-PPKEYWORD(import)
-PPKEYWORD(include_next)
-PPKEYWORD(warning)
-PPKEYWORD(ident)
-PPKEYWORD(sccs)
-PPKEYWORD(assert)
-PPKEYWORD(unassert)
-
-// Clang extensions
-PPKEYWORD(__public_macro)
-PPKEYWORD(__private_macro)
-
-//===----------------------------------------------------------------------===//
-// Language keywords.
-//===----------------------------------------------------------------------===//
-
-// These define members of the tok::* namespace.
-
-TOK(unknown) // Not a token.
-TOK(eof) // End of file.
-TOK(eod) // End of preprocessing directive (end of line inside a
- // directive).
-TOK(code_completion) // Code completion marker
-
-// C99 6.4.9: Comments.
-TOK(comment) // Comment (only in -E -C[C] mode)
-
-// C99 6.4.2: Identifiers.
-TOK(identifier) // abcde123
-TOK(raw_identifier) // Used only in raw lexing mode.
-
-// C99 6.4.4.1: Integer Constants
-// C99 6.4.4.2: Floating Constants
-TOK(numeric_constant) // 0x123
-
-// C99 6.4.4: Character Constants
-TOK(char_constant) // 'a'
-TOK(wide_char_constant) // L'b'
-
-// C++1z Character Constants
-TOK(utf8_char_constant) // u8'a'
-
-// C++11 Character Constants
-TOK(utf16_char_constant) // u'a'
-TOK(utf32_char_constant) // U'a'
-
-// C99 6.4.5: String Literals.
-TOK(string_literal) // "foo"
-TOK(wide_string_literal) // L"foo"
-TOK(angle_string_literal)// <foo>
-
-// C++11 String Literals.
-TOK(utf8_string_literal) // u8"foo"
-TOK(utf16_string_literal)// u"foo"
-TOK(utf32_string_literal)// U"foo"
-
-// C99 6.4.6: Punctuators.
-PUNCTUATOR(l_square, "[")
-PUNCTUATOR(r_square, "]")
-PUNCTUATOR(l_paren, "(")
-PUNCTUATOR(r_paren, ")")
-PUNCTUATOR(l_brace, "{")
-PUNCTUATOR(r_brace, "}")
-PUNCTUATOR(period, ".")
-PUNCTUATOR(ellipsis, "...")
-PUNCTUATOR(amp, "&")
-PUNCTUATOR(ampamp, "&&")
-PUNCTUATOR(ampequal, "&=")
-PUNCTUATOR(star, "*")
-PUNCTUATOR(starequal, "*=")
-PUNCTUATOR(plus, "+")
-PUNCTUATOR(plusplus, "++")
-PUNCTUATOR(plusequal, "+=")
-PUNCTUATOR(minus, "-")
-PUNCTUATOR(arrow, "->")
-PUNCTUATOR(minusminus, "--")
-PUNCTUATOR(minusequal, "-=")
-PUNCTUATOR(tilde, "~")
-PUNCTUATOR(exclaim, "!")
-PUNCTUATOR(exclaimequal, "!=")
-PUNCTUATOR(slash, "/")
-PUNCTUATOR(slashequal, "/=")
-PUNCTUATOR(percent, "%")
-PUNCTUATOR(percentequal, "%=")
-PUNCTUATOR(less, "<")
-PUNCTUATOR(lessless, "<<")
-PUNCTUATOR(lessequal, "<=")
-PUNCTUATOR(lesslessequal, "<<=")
-PUNCTUATOR(greater, ">")
-PUNCTUATOR(greatergreater, ">>")
-PUNCTUATOR(greaterequal, ">=")
-PUNCTUATOR(greatergreaterequal, ">>=")
-PUNCTUATOR(caret, "^")
-PUNCTUATOR(caretequal, "^=")
-PUNCTUATOR(pipe, "|")
-PUNCTUATOR(pipepipe, "||")
-PUNCTUATOR(pipeequal, "|=")
-PUNCTUATOR(question, "?")
-PUNCTUATOR(colon, ":")
-PUNCTUATOR(semi, ";")
-PUNCTUATOR(equal, "=")
-PUNCTUATOR(equalequal, "==")
-PUNCTUATOR(comma, ",")
-PUNCTUATOR(hash, "#")
-PUNCTUATOR(hashhash, "##")
-PUNCTUATOR(hashat, "#@")
-
-// C++ Support
-PUNCTUATOR(periodstar, ".*")
-PUNCTUATOR(arrowstar, "->*")
-PUNCTUATOR(coloncolon, "::")
-
-// Objective C support.
-PUNCTUATOR(at, "@")
-
-// CUDA support.
-PUNCTUATOR(lesslessless, "<<<")
-PUNCTUATOR(greatergreatergreater, ">>>")
-
-// C99 6.4.1: Keywords. These turn into kw_* tokens.
-// Flags allowed:
-// KEYALL - This is a keyword in all variants of C and C++, or it
-// is a keyword in the implementation namespace that should
-// always be treated as a keyword
-// KEYC99 - This is a keyword introduced to C in C99
-// KEYC11 - This is a keyword introduced to C in C11
-// KEYCXX - This is a C++ keyword, or a C++-specific keyword in the
-// implementation namespace
-// KEYNOCXX - This is a keyword in every non-C++ dialect.
-// KEYCXX11 - This is a C++ keyword introduced to C++ in C++11
-// KEYCONCEPTS - This is a keyword if the C++ extensions for concepts
-// are enabled.
-// KEYGNU - This is a keyword if GNU extensions are enabled
-// 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
-// KEYALTIVEC - This is a keyword in AltiVec
-// KEYZVECTOR - This is a keyword for the System z vector extensions,
-// which are heavily based on AltiVec
-// KEYBORLAND - This is a keyword if Borland extensions are enabled
-// KEYCOROUTINES - This is a keyword if support for the C++ coroutines
-// TS is enabled
-// 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
-//
-KEYWORD(auto , KEYALL)
-KEYWORD(break , KEYALL)
-KEYWORD(case , KEYALL)
-KEYWORD(char , KEYALL)
-KEYWORD(const , KEYALL)
-KEYWORD(continue , KEYALL)
-KEYWORD(default , KEYALL)
-KEYWORD(do , KEYALL)
-KEYWORD(double , KEYALL)
-KEYWORD(else , KEYALL)
-KEYWORD(enum , KEYALL)
-KEYWORD(extern , KEYALL)
-KEYWORD(float , KEYALL)
-KEYWORD(for , KEYALL)
-KEYWORD(goto , KEYALL)
-KEYWORD(if , KEYALL)
-KEYWORD(inline , KEYC99|KEYCXX|KEYGNU)
-KEYWORD(int , KEYALL)
-KEYWORD(long , KEYALL)
-KEYWORD(register , KEYALL)
-KEYWORD(restrict , KEYC99)
-KEYWORD(return , KEYALL)
-KEYWORD(short , KEYALL)
-KEYWORD(signed , KEYALL)
-KEYWORD(sizeof , KEYALL)
-KEYWORD(static , KEYALL)
-KEYWORD(struct , KEYALL)
-KEYWORD(switch , KEYALL)
-KEYWORD(typedef , KEYALL)
-KEYWORD(union , KEYALL)
-KEYWORD(unsigned , KEYALL)
-KEYWORD(void , KEYALL)
-KEYWORD(volatile , KEYALL)
-KEYWORD(while , KEYALL)
-KEYWORD(_Alignas , KEYALL)
-KEYWORD(_Alignof , KEYALL)
-KEYWORD(_Atomic , KEYALL|KEYNOOPENCL)
-KEYWORD(_Bool , KEYNOCXX)
-KEYWORD(_Complex , KEYALL)
-KEYWORD(_Generic , KEYALL)
-KEYWORD(_Imaginary , KEYALL)
-KEYWORD(_Noreturn , KEYALL)
-KEYWORD(_Static_assert , KEYALL)
-KEYWORD(_Thread_local , KEYALL)
-KEYWORD(__func__ , KEYALL)
-KEYWORD(__objc_yes , KEYALL)
-KEYWORD(__objc_no , KEYALL)
-
-
-// C++ 2.11p1: Keywords.
-KEYWORD(asm , KEYCXX|KEYGNU)
-KEYWORD(bool , BOOLSUPPORT)
-KEYWORD(catch , KEYCXX)
-KEYWORD(class , KEYCXX)
-KEYWORD(const_cast , KEYCXX)
-KEYWORD(delete , KEYCXX)
-KEYWORD(dynamic_cast , KEYCXX)
-KEYWORD(explicit , KEYCXX)
-KEYWORD(export , KEYCXX)
-KEYWORD(false , BOOLSUPPORT)
-KEYWORD(friend , KEYCXX)
-KEYWORD(mutable , KEYCXX)
-KEYWORD(namespace , KEYCXX)
-KEYWORD(new , KEYCXX)
-KEYWORD(operator , KEYCXX)
-KEYWORD(private , KEYCXX)
-KEYWORD(protected , KEYCXX)
-KEYWORD(public , KEYCXX)
-KEYWORD(reinterpret_cast , KEYCXX)
-KEYWORD(static_cast , KEYCXX)
-KEYWORD(template , KEYCXX)
-KEYWORD(this , KEYCXX)
-KEYWORD(throw , KEYCXX)
-KEYWORD(true , BOOLSUPPORT)
-KEYWORD(try , KEYCXX)
-KEYWORD(typename , KEYCXX)
-KEYWORD(typeid , KEYCXX)
-KEYWORD(using , KEYCXX)
-KEYWORD(virtual , KEYCXX)
-KEYWORD(wchar_t , WCHARSUPPORT)
-
-// C++ 2.5p2: Alternative Representations.
-CXX_KEYWORD_OPERATOR(and , ampamp)
-CXX_KEYWORD_OPERATOR(and_eq , ampequal)
-CXX_KEYWORD_OPERATOR(bitand , amp)
-CXX_KEYWORD_OPERATOR(bitor , pipe)
-CXX_KEYWORD_OPERATOR(compl , tilde)
-CXX_KEYWORD_OPERATOR(not , exclaim)
-CXX_KEYWORD_OPERATOR(not_eq , exclaimequal)
-CXX_KEYWORD_OPERATOR(or , pipepipe)
-CXX_KEYWORD_OPERATOR(or_eq , pipeequal)
-CXX_KEYWORD_OPERATOR(xor , caret)
-CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
-
-// C++11 keywords
-CXX11_KEYWORD(alignas , 0)
-CXX11_KEYWORD(alignof , 0)
-CXX11_KEYWORD(char16_t , KEYNOMS18)
-CXX11_KEYWORD(char32_t , KEYNOMS18)
-CXX11_KEYWORD(constexpr , 0)
-CXX11_KEYWORD(decltype , 0)
-CXX11_KEYWORD(noexcept , 0)
-CXX11_KEYWORD(nullptr , 0)
-CXX11_KEYWORD(static_assert , 0)
-CXX11_KEYWORD(thread_local , 0)
-
-// C++ concepts TS keywords
-CONCEPTS_KEYWORD(concept)
-CONCEPTS_KEYWORD(requires)
-
-// C++ coroutines TS keywords
-KEYWORD(co_await , KEYCOROUTINES)
-KEYWORD(co_return , KEYCOROUTINES)
-KEYWORD(co_yield , KEYCOROUTINES)
-
-// GNU Extensions (in impl-reserved namespace)
-KEYWORD(_Decimal32 , KEYALL)
-KEYWORD(_Decimal64 , KEYALL)
-KEYWORD(_Decimal128 , KEYALL)
-KEYWORD(__null , KEYCXX)
-KEYWORD(__alignof , KEYALL)
-KEYWORD(__attribute , KEYALL)
-KEYWORD(__builtin_choose_expr , KEYALL)
-KEYWORD(__builtin_offsetof , KEYALL)
-// __builtin_types_compatible_p is a GNU C extension that we handle like a C++
-// type trait.
-TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
-KEYWORD(__builtin_va_arg , KEYALL)
-KEYWORD(__extension__ , KEYALL)
-KEYWORD(__imag , KEYALL)
-KEYWORD(__int128 , KEYALL)
-KEYWORD(__label__ , KEYALL)
-KEYWORD(__real , KEYALL)
-KEYWORD(__thread , KEYALL)
-KEYWORD(__FUNCTION__ , KEYALL)
-KEYWORD(__PRETTY_FUNCTION__ , KEYALL)
-KEYWORD(__auto_type , KEYALL)
-
-// GNU Extensions (outside impl-reserved namespace)
-KEYWORD(typeof , KEYGNU)
-
-// MS Extensions
-KEYWORD(__FUNCDNAME__ , KEYMS)
-KEYWORD(__FUNCSIG__ , KEYMS)
-KEYWORD(L__FUNCTION__ , KEYMS)
-TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS)
-TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
-
-// MSVC12.0 / VS2013 Type Traits
-TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS)
-TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS)
-TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX)
-TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX)
-TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX)
-
-// GNU and MS Type Traits
-TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX)
-TYPE_TRAIT_1(__has_nothrow_move_assign, HasNothrowMoveAssign, KEYCXX)
-TYPE_TRAIT_1(__has_nothrow_copy, HasNothrowCopy, KEYCXX)
-TYPE_TRAIT_1(__has_nothrow_constructor, HasNothrowConstructor, KEYCXX)
-TYPE_TRAIT_1(__has_trivial_assign, HasTrivialAssign, KEYCXX)
-TYPE_TRAIT_1(__has_trivial_move_assign, HasTrivialMoveAssign, KEYCXX)
-TYPE_TRAIT_1(__has_trivial_copy, HasTrivialCopy, KEYCXX)
-TYPE_TRAIT_1(__has_trivial_constructor, HasTrivialDefaultConstructor, KEYCXX)
-TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX)
-TYPE_TRAIT_1(__has_trivial_destructor, HasTrivialDestructor, KEYCXX)
-TYPE_TRAIT_1(__has_virtual_destructor, HasVirtualDestructor, KEYCXX)
-TYPE_TRAIT_1(__is_abstract, IsAbstract, KEYCXX)
-TYPE_TRAIT_2(__is_base_of, IsBaseOf, KEYCXX)
-TYPE_TRAIT_1(__is_class, IsClass, KEYCXX)
-TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEYCXX)
-TYPE_TRAIT_1(__is_empty, IsEmpty, KEYCXX)
-TYPE_TRAIT_1(__is_enum, IsEnum, KEYCXX)
-TYPE_TRAIT_1(__is_final, IsFinal, KEYCXX)
-// Tentative name - there's no implementation of std::is_literal_type yet.
-TYPE_TRAIT_1(__is_literal, IsLiteral, KEYCXX)
-// Name for GCC 4.6 compatibility - people have already written libraries using
-// this name unfortunately.
-ALIAS("__is_literal_type", __is_literal, KEYCXX)
-TYPE_TRAIT_1(__is_pod, IsPOD, KEYCXX)
-TYPE_TRAIT_1(__is_polymorphic, IsPolymorphic, KEYCXX)
-TYPE_TRAIT_1(__is_trivial, IsTrivial, KEYCXX)
-TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX)
-
-// Clang-only C++ Type Traits
-TYPE_TRAIT_N(__is_trivially_constructible, IsTriviallyConstructible, KEYCXX)
-TYPE_TRAIT_1(__is_trivially_copyable, IsTriviallyCopyable, KEYCXX)
-TYPE_TRAIT_2(__is_trivially_assignable, IsTriviallyAssignable, KEYCXX)
-KEYWORD(__underlying_type , KEYCXX)
-
-// Embarcadero Expression Traits
-KEYWORD(__is_lvalue_expr , KEYCXX)
-KEYWORD(__is_rvalue_expr , KEYCXX)
-
-// Embarcadero Unary Type Traits
-TYPE_TRAIT_1(__is_arithmetic, IsArithmetic, KEYCXX)
-TYPE_TRAIT_1(__is_floating_point, IsFloatingPoint, KEYCXX)
-TYPE_TRAIT_1(__is_integral, IsIntegral, KEYCXX)
-TYPE_TRAIT_1(__is_complete_type, IsCompleteType, KEYCXX)
-TYPE_TRAIT_1(__is_void, IsVoid, KEYCXX)
-TYPE_TRAIT_1(__is_array, IsArray, KEYCXX)
-TYPE_TRAIT_1(__is_function, IsFunction, KEYCXX)
-TYPE_TRAIT_1(__is_reference, IsReference, KEYCXX)
-TYPE_TRAIT_1(__is_lvalue_reference, IsLvalueReference, KEYCXX)
-TYPE_TRAIT_1(__is_rvalue_reference, IsRvalueReference, KEYCXX)
-TYPE_TRAIT_1(__is_fundamental, IsFundamental, KEYCXX)
-TYPE_TRAIT_1(__is_object, IsObject, KEYCXX)
-TYPE_TRAIT_1(__is_scalar, IsScalar, KEYCXX)
-TYPE_TRAIT_1(__is_compound, IsCompound, KEYCXX)
-TYPE_TRAIT_1(__is_pointer, IsPointer, KEYCXX)
-TYPE_TRAIT_1(__is_member_object_pointer, IsMemberObjectPointer, KEYCXX)
-TYPE_TRAIT_1(__is_member_function_pointer, IsMemberFunctionPointer, KEYCXX)
-TYPE_TRAIT_1(__is_member_pointer, IsMemberPointer, KEYCXX)
-TYPE_TRAIT_1(__is_const, IsConst, KEYCXX)
-TYPE_TRAIT_1(__is_volatile, IsVolatile, KEYCXX)
-TYPE_TRAIT_1(__is_standard_layout, IsStandardLayout, KEYCXX)
-TYPE_TRAIT_1(__is_signed, IsSigned, KEYCXX)
-TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX)
-
-// Embarcadero Binary Type Traits
-TYPE_TRAIT_2(__is_same, IsSame, KEYCXX)
-TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX)
-KEYWORD(__array_rank , KEYCXX)
-KEYWORD(__array_extent , KEYCXX)
-
-// Apple Extension.
-KEYWORD(__private_extern__ , KEYALL)
-KEYWORD(__module_private__ , KEYALL)
-
-// Extension that will be enabled for Microsoft, Borland and PS4, but can be
-// disabled via '-fno-declspec'.
-KEYWORD(__declspec , 0)
-
-// Microsoft Extension.
-KEYWORD(__cdecl , KEYALL)
-KEYWORD(__stdcall , KEYALL)
-KEYWORD(__fastcall , KEYALL)
-KEYWORD(__thiscall , KEYALL)
-KEYWORD(__vectorcall , KEYALL)
-KEYWORD(__forceinline , KEYMS)
-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)
-// OpenCL function qualifiers
-KEYWORD(__kernel , KEYOPENCL)
-ALIAS("kernel", __kernel , KEYOPENCL)
-// 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)
-// OpenCL builtins
-KEYWORD(__builtin_astype , KEYOPENCL)
-KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC|KEYZVECTOR)
-
-// OpenMP Type Traits
-KEYWORD(__builtin_omp_required_simd_align, KEYALL)
-
-// Borland Extensions.
-KEYWORD(__pascal , KEYALL)
-
-// Altivec Extension.
-KEYWORD(__vector , KEYALTIVEC|KEYZVECTOR)
-KEYWORD(__pixel , KEYALTIVEC)
-KEYWORD(__bool , KEYALTIVEC|KEYZVECTOR)
-
-// ARM NEON extensions.
-ALIAS("__fp16", half , KEYALL)
-
-// OpenCL Extension.
-KEYWORD(half , HALFSUPPORT)
-
-// Objective-C ARC keywords.
-KEYWORD(__bridge , KEYARC)
-KEYWORD(__bridge_transfer , KEYARC)
-KEYWORD(__bridge_retained , KEYARC)
-KEYWORD(__bridge_retain , KEYARC)
-
-// Objective-C keywords.
-KEYWORD(__covariant , KEYOBJC2)
-KEYWORD(__contravariant , KEYOBJC2)
-KEYWORD(__kindof , KEYOBJC2)
-
-// Alternate spelling for various tokens. There are GCC extensions in all
-// languages, but should not be disabled in strict conformance mode.
-ALIAS("__alignof__" , __alignof , KEYALL)
-ALIAS("__asm" , asm , KEYALL)
-ALIAS("__asm__" , asm , KEYALL)
-ALIAS("__attribute__", __attribute, KEYALL)
-ALIAS("__complex" , _Complex , KEYALL)
-ALIAS("__complex__" , _Complex , KEYALL)
-ALIAS("__const" , const , KEYALL)
-ALIAS("__const__" , const , KEYALL)
-ALIAS("__decltype" , decltype , KEYCXX)
-ALIAS("__imag__" , __imag , KEYALL)
-ALIAS("__inline" , inline , KEYALL)
-ALIAS("__inline__" , inline , KEYALL)
-ALIAS("__nullptr" , nullptr , KEYCXX)
-ALIAS("__real__" , __real , KEYALL)
-ALIAS("__restrict" , restrict , KEYALL)
-ALIAS("__restrict__" , restrict , KEYALL)
-ALIAS("__signed" , signed , KEYALL)
-ALIAS("__signed__" , signed , KEYALL)
-ALIAS("__typeof" , typeof , KEYALL)
-ALIAS("__typeof__" , typeof , KEYALL)
-ALIAS("__volatile" , volatile , KEYALL)
-ALIAS("__volatile__" , volatile , KEYALL)
-
-// Type nullability.
-KEYWORD(_Nonnull , KEYALL)
-KEYWORD(_Nullable , KEYALL)
-KEYWORD(_Null_unspecified , KEYALL)
-
-// Microsoft extensions which should be disabled in strict conformance mode
-KEYWORD(__ptr64 , KEYMS)
-KEYWORD(__ptr32 , KEYMS)
-KEYWORD(__sptr , KEYMS)
-KEYWORD(__uptr , KEYMS)
-KEYWORD(__w64 , KEYMS)
-KEYWORD(__uuidof , KEYMS | KEYBORLAND)
-KEYWORD(__try , KEYMS | KEYBORLAND)
-KEYWORD(__finally , KEYMS | KEYBORLAND)
-KEYWORD(__leave , KEYMS | KEYBORLAND)
-KEYWORD(__int64 , KEYMS)
-KEYWORD(__if_exists , KEYMS)
-KEYWORD(__if_not_exists , KEYMS)
-KEYWORD(__single_inheritance , KEYMS)
-KEYWORD(__multiple_inheritance , KEYMS)
-KEYWORD(__virtual_inheritance , KEYMS)
-KEYWORD(__interface , KEYMS)
-ALIAS("__int8" , char , KEYMS)
-ALIAS("_int8" , char , KEYMS)
-ALIAS("__int16" , short , KEYMS)
-ALIAS("_int16" , short , KEYMS)
-ALIAS("__int32" , int , KEYMS)
-ALIAS("_int32" , int , KEYMS)
-ALIAS("_int64" , __int64 , KEYMS)
-ALIAS("__wchar_t" , wchar_t , KEYMS)
-ALIAS("_asm" , asm , KEYMS)
-ALIAS("_alignof" , __alignof , KEYMS)
-ALIAS("__builtin_alignof", __alignof , KEYMS)
-ALIAS("_cdecl" , __cdecl , KEYMS | KEYBORLAND)
-ALIAS("_fastcall" , __fastcall , KEYMS | KEYBORLAND)
-ALIAS("_stdcall" , __stdcall , KEYMS | KEYBORLAND)
-ALIAS("_thiscall" , __thiscall , KEYMS)
-ALIAS("_vectorcall" , __vectorcall, KEYMS)
-ALIAS("_uuidof" , __uuidof , KEYMS | KEYBORLAND)
-ALIAS("_inline" , inline , KEYMS)
-ALIAS("_declspec" , __declspec , KEYMS)
-
-// Borland Extensions which should be disabled in strict conformance mode.
-ALIAS("_pascal" , __pascal , KEYBORLAND)
-
-// Clang Extensions.
-KEYWORD(__builtin_convertvector , KEYALL)
-ALIAS("__char16_t" , char16_t , KEYCXX)
-ALIAS("__char32_t" , char32_t , KEYCXX)
-
-// Clang-specific keywords enabled only in testing.
-TESTING_KEYWORD(__unknown_anytype , KEYALL)
-
-
-//===----------------------------------------------------------------------===//
-// Objective-C @-preceded keywords.
-//===----------------------------------------------------------------------===//
-
-// These have meaning after an '@' in Objective-C mode. These define enums in
-// the tok::objc_* namespace.
-
-OBJC1_AT_KEYWORD(not_keyword)
-OBJC1_AT_KEYWORD(class)
-OBJC1_AT_KEYWORD(compatibility_alias)
-OBJC1_AT_KEYWORD(defs)
-OBJC1_AT_KEYWORD(encode)
-OBJC1_AT_KEYWORD(end)
-OBJC1_AT_KEYWORD(implementation)
-OBJC1_AT_KEYWORD(interface)
-OBJC1_AT_KEYWORD(private)
-OBJC1_AT_KEYWORD(protected)
-OBJC1_AT_KEYWORD(protocol)
-OBJC1_AT_KEYWORD(public)
-OBJC1_AT_KEYWORD(selector)
-OBJC1_AT_KEYWORD(throw)
-OBJC1_AT_KEYWORD(try)
-OBJC1_AT_KEYWORD(catch)
-OBJC1_AT_KEYWORD(finally)
-OBJC1_AT_KEYWORD(synchronized)
-OBJC1_AT_KEYWORD(autoreleasepool)
-
-OBJC2_AT_KEYWORD(property)
-OBJC2_AT_KEYWORD(package)
-OBJC2_AT_KEYWORD(required)
-OBJC2_AT_KEYWORD(optional)
-OBJC2_AT_KEYWORD(synthesize)
-OBJC2_AT_KEYWORD(dynamic)
-OBJC2_AT_KEYWORD(import)
-
-// TODO: What to do about context-sensitive keywords like:
-// bycopy/byref/in/inout/oneway/out?
-
-ANNOTATION(cxxscope) // annotation for a C++ scope spec, e.g. "::foo::bar::"
-ANNOTATION(typename) // annotation for a C typedef name, a C++ (possibly
- // qualified) typename, e.g. "foo::MyClass", or
- // template-id that names a type ("std::vector<int>")
-ANNOTATION(template_id) // annotation for a C++ template-id that names a
- // function template specialization (not a type),
- // e.g., "std::swap<int>"
-ANNOTATION(primary_expr) // annotation for a primary expression
-ANNOTATION(decltype) // annotation for a decltype expression,
- // e.g., "decltype(foo.bar())"
-
-// Annotation for #pragma unused(...)
-// For each argument inside the parentheses the pragma handler will produce
-// one 'pragma_unused' annotation token followed by the argument token.
-ANNOTATION(pragma_unused)
-
-// Annotation for #pragma GCC visibility...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_vis)
-
-// Annotation for #pragma pack...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_pack)
-
-// Annotation for #pragma clang __debug parser_crash...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_parser_crash)
-
-// Annotation for #pragma clang __debug captured...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_captured)
-
-// Annotation for #pragma ms_struct...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_msstruct)
-
-// Annotation for #pragma align...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_align)
-
-// Annotation for #pragma weak id
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_weak)
-
-// Annotation for #pragma weak id = id
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_weakalias)
-
-// Annotation for #pragma redefine_extname...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_redefine_extname)
-
-// Annotation for #pragma STDC FP_CONTRACT...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_fp_contract)
-
-// Annotation for #pragma pointers_to_members...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_ms_pointers_to_members)
-
-// Annotation for #pragma vtordisp...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_ms_vtordisp)
-
-// Annotation for all microsoft #pragmas...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_ms_pragma)
-
-// Annotation for #pragma OPENCL EXTENSION...
-// The lexer produces these so that they only take effect when the parser
-// handles them.
-ANNOTATION(pragma_opencl_extension)
-
-// Annotations for OpenMP pragma directives - #pragma omp ...
-// The lexer produces these so that they only take effect when the parser
-// handles #pragma omp ... directives.
-ANNOTATION(pragma_openmp)
-ANNOTATION(pragma_openmp_end)
-
-// Annotations for loop pragma directives #pragma clang loop ...
-// The lexer produces these so that they only take effect when the parser
-// handles #pragma loop ... directives.
-ANNOTATION(pragma_loop_hint)
-
-// Annotations for module import translated from #include etc.
-ANNOTATION(module_include)
-ANNOTATION(module_begin)
-ANNOTATION(module_end)
-
-#undef ANNOTATION
-#undef TESTING_KEYWORD
-#undef OBJC2_AT_KEYWORD
-#undef OBJC1_AT_KEYWORD
-#undef CXX_KEYWORD_OPERATOR
-#undef PPKEYWORD
-#undef ALIAS
-#undef TYPE_TRAIT_N
-#undef TYPE_TRAIT_2
-#undef TYPE_TRAIT_1
-#undef TYPE_TRAIT
-#undef CONCEPTS_KEYWORD
-#undef CXX11_KEYWORD
-#undef KEYWORD
-#undef PUNCTUATOR
-#undef TOK
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
deleted file mode 100644
index f4ecb3e..0000000
--- a/include/clang/Basic/TokenKinds.h
+++ /dev/null
@@ -1,106 +0,0 @@
-//===--- TokenKinds.h - Enum values for C Token Kinds -----------*- 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::TokenKind enum and support functions.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_TOKENKINDS_H
-#define LLVM_CLANG_BASIC_TOKENKINDS_H
-
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-namespace tok {
-
-/// \brief 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
-/// '#' at the beginning of the line.
-enum PPKeywordKind {
-#define PPKEYWORD(X) pp_##X,
-#include "clang/Basic/TokenKinds.def"
- NUM_PP_KEYWORDS
-};
-
-/// \brief Provides a namespace for Objective-C keywords which start with
-/// an '@'.
-enum ObjCKeywordKind {
-#define OBJC1_AT_KEYWORD(X) objc_##X,
-#define OBJC2_AT_KEYWORD(X) objc_##X,
-#include "clang/Basic/TokenKinds.def"
- NUM_OBJC_KEYWORDS
-};
-
-/// \brief 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.
-///
-/// 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
-/// '!' or '%', and returns NULL for literal and annotation tokens.
-///
-/// This routine only retrieves the "simple" spelling of the token,
-/// and will not produce any alternative spellings (e.g., a
-/// digraph). For the actual spelling of a given Token, use
-/// Preprocessor::getSpelling().
-const char *getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE;
-
-/// \brief 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.
-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
-/// C++11 user-defined-string-literal) token.
-inline bool isStringLiteral(TokenKind K) {
- return K == tok::string_literal || K == tok::wide_string_literal ||
- K == tok::utf8_string_literal || K == tok::utf16_string_literal ||
- K == tok::utf32_string_literal;
-}
-
-/// \brief 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 ||
- K == tok::wide_char_constant || K == tok::utf8_char_constant ||
- K == tok::utf16_char_constant || K == tok::utf32_char_constant ||
- isStringLiteral(K) || K == tok::angle_string_literal;
-}
-
-/// \brief Return true if this is any of tok::annot_* kinds.
-inline bool isAnnotation(TokenKind K) {
-#define ANNOTATION(NAME) \
- if (K == tok::annot_##NAME) \
- return true;
-#include "clang/Basic/TokenKinds.def"
- return false;
-}
-
-} // end namespace tok
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
deleted file mode 100644
index 765246b..0000000
--- a/include/clang/Basic/TypeTraits.h
+++ /dev/null
@@ -1,100 +0,0 @@
-//===--- TypeTraits.h - C++ Type Traits Support Enumerations ----*- 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 enumerations for the type traits support.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_TYPETRAITS_H
-#define LLVM_CLANG_BASIC_TYPETRAITS_H
-
-namespace clang {
-
- /// \brief Names for traits that operate specifically on types.
- enum TypeTrait {
- UTT_HasNothrowAssign,
- UTT_HasNothrowMoveAssign,
- UTT_HasNothrowCopy,
- UTT_HasNothrowConstructor,
- UTT_HasTrivialAssign,
- UTT_HasTrivialMoveAssign,
- UTT_HasTrivialCopy,
- UTT_HasTrivialDefaultConstructor,
- UTT_HasTrivialMoveConstructor,
- UTT_HasTrivialDestructor,
- UTT_HasVirtualDestructor,
- UTT_IsAbstract,
- UTT_IsArithmetic,
- UTT_IsArray,
- UTT_IsClass,
- UTT_IsCompleteType,
- UTT_IsCompound,
- UTT_IsConst,
- UTT_IsDestructible,
- UTT_IsEmpty,
- UTT_IsEnum,
- UTT_IsFinal,
- UTT_IsFloatingPoint,
- UTT_IsFunction,
- UTT_IsFundamental,
- UTT_IsIntegral,
- UTT_IsInterfaceClass,
- UTT_IsLiteral,
- UTT_IsLvalueReference,
- UTT_IsMemberFunctionPointer,
- UTT_IsMemberObjectPointer,
- UTT_IsMemberPointer,
- UTT_IsNothrowDestructible,
- UTT_IsObject,
- UTT_IsPOD,
- UTT_IsPointer,
- UTT_IsPolymorphic,
- UTT_IsReference,
- UTT_IsRvalueReference,
- UTT_IsScalar,
- UTT_IsSealed,
- UTT_IsSigned,
- UTT_IsStandardLayout,
- UTT_IsTrivial,
- UTT_IsTriviallyCopyable,
- UTT_IsUnion,
- UTT_IsUnsigned,
- UTT_IsVoid,
- UTT_IsVolatile,
- UTT_Last = UTT_IsVolatile,
- BTT_IsBaseOf,
- BTT_IsConvertible,
- BTT_IsConvertibleTo,
- BTT_IsSame,
- BTT_TypeCompatible,
- BTT_IsNothrowAssignable,
- BTT_IsTriviallyAssignable,
- BTT_Last = BTT_IsTriviallyAssignable,
- TT_IsConstructible,
- TT_IsNothrowConstructible,
- TT_IsTriviallyConstructible
- };
-
- /// \brief Names for the array type traits.
- enum ArrayTypeTrait {
- ATT_ArrayRank,
- ATT_ArrayExtent
- };
-
- /// \brief Names for the "expression or type" traits.
- enum UnaryExprOrTypeTrait {
- UETT_SizeOf,
- UETT_AlignOf,
- UETT_VecStep,
- UETT_OpenMPRequiredSimdAlign,
- };
-}
-
-#endif
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
deleted file mode 100644
index 02da432..0000000
--- a/include/clang/Basic/Version.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===- Version.h - Clang Version Number -------------------------*- 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 version macros and version-related utility functions
-/// for Clang.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_VERSION_H
-#define LLVM_CLANG_BASIC_VERSION_H
-
-#include "clang/Basic/Version.inc"
-#include "llvm/ADT/StringRef.h"
-
-/// \brief Helper macro for CLANG_VERSION_STRING.
-#define CLANG_MAKE_VERSION_STRING2(X) #X
-
-#ifdef CLANG_VERSION_PATCHLEVEL
-/// \brief Helper macro for CLANG_VERSION_STRING.
-#define CLANG_MAKE_VERSION_STRING(X,Y,Z) CLANG_MAKE_VERSION_STRING2(X.Y.Z)
-
-/// \brief A string that describes the Clang version number, e.g., "1.0".
-#define CLANG_VERSION_STRING \
- CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR, \
- CLANG_VERSION_PATCHLEVEL)
-#else
-/// \brief Helper macro for CLANG_VERSION_STRING.
-#define CLANG_MAKE_VERSION_STRING(X,Y) CLANG_MAKE_VERSION_STRING2(X.Y)
-
-/// \brief A string that describes the Clang version number, e.g., "1.0".
-#define CLANG_VERSION_STRING \
- CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR)
-#endif
-
-namespace clang {
- /// \brief 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.
- ///
- /// This supports LLVM residing in a separate repository from clang.
- std::string getLLVMRepositoryPath();
-
- /// \brief Retrieves the repository revision number (or identifer) from which
- /// this Clang was built.
- std::string getClangRevision();
-
- /// \brief Retrieves the repository revision number (or identifer) 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
- /// the information in getClangRepositoryPath() and getClangRevision().
- std::string getClangFullRepositoryVersion();
-
- /// \brief 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.
- std::string getClangToolFullVersion(llvm::StringRef ToolName);
-
- /// \brief 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();
-}
-
-#endif // LLVM_CLANG_BASIC_VERSION_H
diff --git a/include/clang/Basic/Version.inc.in b/include/clang/Basic/Version.inc.in
deleted file mode 100644
index ccf8430..0000000
--- a/include/clang/Basic/Version.inc.in
+++ /dev/null
@@ -1,6 +0,0 @@
-#define CLANG_VERSION @CLANG_VERSION@
-#define CLANG_VERSION_MAJOR @CLANG_VERSION_MAJOR@
-#define CLANG_VERSION_MINOR @CLANG_VERSION_MINOR@
-#if @CLANG_HAS_VERSION_PATCHLEVEL@
-#define CLANG_VERSION_PATCHLEVEL @CLANG_VERSION_PATCHLEVEL@
-#endif
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
deleted file mode 100644
index 784f3f3..0000000
--- a/include/clang/Basic/VersionTuple.h
+++ /dev/null
@@ -1,163 +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 Minor : 31;
- unsigned Subminor : 31;
- unsigned Build : 31;
- unsigned HasMinor : 1;
- unsigned HasSubminor : 1;
- unsigned HasBuild : 1;
- unsigned UsesUnderscores : 1;
-
-public:
- VersionTuple()
- : Major(0), Minor(0), Subminor(0), Build(0), HasMinor(false),
- HasSubminor(false), HasBuild(false), UsesUnderscores(false) {}
-
- explicit VersionTuple(unsigned Major)
- : Major(Major), Minor(0), Subminor(0), Build(0), HasMinor(false),
- HasSubminor(false), HasBuild(false), UsesUnderscores(false) {}
-
- explicit VersionTuple(unsigned Major, unsigned Minor,
- bool UsesUnderscores = false)
- : Major(Major), Minor(Minor), Subminor(0), Build(0), HasMinor(true),
- HasSubminor(false), HasBuild(false), UsesUnderscores(UsesUnderscores) {}
-
- explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
- bool UsesUnderscores = false)
- : Major(Major), Minor(Minor), Subminor(Subminor), Build(0),
- HasMinor(true), HasSubminor(true), HasBuild(false),
- UsesUnderscores(UsesUnderscores) {}
-
- explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
- unsigned Build, bool UsesUnderscores = false)
- : Major(Major), Minor(Minor), Subminor(Subminor), Build(Build),
- HasMinor(true), HasSubminor(true), HasBuild(true),
- UsesUnderscores(UsesUnderscores) {}
-
- /// \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
deleted file mode 100644
index 1df4947..0000000
--- a/include/clang/Basic/VirtualFileSystem.h
+++ /dev/null
@@ -1,341 +0,0 @@
-//===- VirtualFileSystem.h - Virtual File System Layer ----------*- 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 virtual file system interface vfs::FileSystem.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
-#define LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-class MemoryBuffer;
-}
-
-namespace clang {
-namespace vfs {
-
-/// \brief The result of a \p status operation.
-class Status {
- std::string Name;
- llvm::sys::fs::UniqueID UID;
- llvm::sys::TimeValue MTime;
- uint32_t User;
- uint32_t Group;
- uint64_t Size;
- llvm::sys::fs::file_type Type;
- llvm::sys::fs::perms Perms;
-
-public:
- bool IsVFSMapped; // FIXME: remove when files support multiple names
-
-public:
- Status() : Type(llvm::sys::fs::file_type::status_error) {}
- Status(const llvm::sys::fs::file_status &Status);
- Status(StringRef Name, llvm::sys::fs::UniqueID UID,
- llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group,
- uint64_t Size, llvm::sys::fs::file_type Type,
- llvm::sys::fs::perms Perms);
-
- /// Get a copy of a Status with a different name.
- static Status copyWithNewName(const Status &In, StringRef NewName);
- 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.
- StringRef getName() const { return Name; }
-
- /// @name Status interface from llvm::sys::fs
- /// @{
- llvm::sys::fs::file_type getType() const { return Type; }
- llvm::sys::fs::perms getPermissions() const { return Perms; }
- llvm::sys::TimeValue getLastModificationTime() const { return MTime; }
- llvm::sys::fs::UniqueID getUniqueID() const { return UID; }
- uint32_t getUser() const { return User; }
- uint32_t getGroup() const { return Group; }
- uint64_t getSize() const { return Size; }
- /// @}
- /// @name Status queries
- /// These are static queries in llvm::sys::fs.
- /// @{
- bool equivalent(const Status &Other) const;
- bool isDirectory() const;
- bool isRegularFile() const;
- bool isOther() const;
- bool isSymlink() const;
- bool isStatusKnown() const;
- bool exists() const;
- /// @}
-};
-
-/// \brief Represents an open file.
-class File {
-public:
- /// \brief 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.
- virtual llvm::ErrorOr<Status> status() = 0;
- /// \brief 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.
- virtual std::error_code close() = 0;
-};
-
-namespace detail {
-/// \brief 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,
- /// or returns a system-defined \c error_code.
- virtual std::error_code increment() = 0;
- Status CurrentEntry;
-};
-} // end namespace detail
-
-/// \brief 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
-
-public:
- directory_iterator(std::shared_ptr<detail::DirIterImpl> I) : Impl(I) {
- assert(Impl.get() != nullptr && "requires non-null implementation");
- if (!Impl->CurrentEntry.isStatusKnown())
- Impl.reset(); // Normalize the end iterator to Impl == nullptr.
- }
-
- /// \brief Construct an 'end' iterator.
- directory_iterator() { }
-
- /// \brief Equivalent to operator++, with an error code.
- directory_iterator &increment(std::error_code &EC) {
- assert(Impl && "attempting to increment past end");
- EC = Impl->increment();
- if (EC || !Impl->CurrentEntry.isStatusKnown())
- Impl.reset(); // Normalize the end iterator to Impl == nullptr.
- return *this;
- }
-
- const Status &operator*() const { return Impl->CurrentEntry; }
- const Status *operator->() const { return &Impl->CurrentEntry; }
-
- bool operator==(const directory_iterator &RHS) const {
- if (Impl && RHS.Impl)
- return Impl->CurrentEntry.equivalent(RHS.Impl->CurrentEntry);
- return !Impl && !RHS.Impl;
- }
- bool operator!=(const directory_iterator &RHS) const {
- return !(*this == RHS);
- }
-};
-
-class FileSystem;
-
-/// \brief 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;
-
- FileSystem *FS;
- std::shared_ptr<IterState> State; // Input iterator semantics on copy.
-
-public:
- recursive_directory_iterator(FileSystem &FS, const Twine &Path,
- std::error_code &EC);
- /// \brief Construct an 'end' iterator.
- recursive_directory_iterator() { }
-
- /// \brief Equivalent to operator++, with an error code.
- recursive_directory_iterator &increment(std::error_code &EC);
-
- const Status &operator*() const { return *State->top(); }
- const Status *operator->() const { return &*State->top(); }
-
- bool operator==(const recursive_directory_iterator &Other) const {
- return State == Other.State; // identity
- }
- bool operator!=(const recursive_directory_iterator &RHS) const {
- return !(*this == RHS);
- }
-};
-
-/// \brief 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.
- virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
- /// \brief 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;
-
- /// This is a convenience method that opens a file, gets its content and then
- /// closes the file.
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
- getBufferForFile(const Twine &Name, int64_t FileSize = -1,
- bool RequiresNullTerminator = true, bool IsVolatile = false);
-
- /// \brief 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;
-
- /// 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;
-
- /// Check whether a file exists. Provided for convenience.
- bool exists(const Twine &Path);
-
- /// Make \a Path an absolute path.
- ///
- /// Makes \a Path absolute using the current directory if it is not already.
- /// An empty \a Path will result in the current directory.
- ///
- /// /absolute/path => /absolute/path
- /// relative/../path => <current-directory>/relative/../path
- ///
- /// \param Path A path that is modified to be an absolute path.
- /// \returns success if \a path has been made absolute, otherwise a
- /// platform-specific error_code.
- std::error_code makeAbsolute(SmallVectorImpl<char> &Path) const;
-};
-
-/// \brief 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
-/// of another.
-///
-/// Consists of a stack of >=1 \p FileSystem objects, which are treated as being
-/// one merged file system. When there is a directory that exists in more than
-/// one file system, the \p OverlayFileSystem contains a directory containing
-/// the union of their contents. The attributes (permissions, etc.) of the
-/// top-most (most recently added) directory are used. When there is a file
-/// 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
- /// their addition.
- FileSystemList FSList;
-
-public:
- OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base);
- /// \brief Pushes a file system on top of the stack.
- void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
-
- llvm::ErrorOr<Status> status(const Twine &Path) override;
- 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;
- std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
-
- typedef FileSystemList::reverse_iterator iterator;
-
- /// \brief Get an iterator pointing to the most recently added file system.
- iterator overlays_begin() { return FSList.rbegin(); }
-
- /// \brief Get an iterator pointing one-past the least recently added file
- /// system.
- iterator overlays_end() { return FSList.rend(); }
-};
-
-namespace detail {
-class InMemoryDirectory;
-} // end namespace detail
-
-/// An in-memory file system.
-class InMemoryFileSystem : public FileSystem {
- std::unique_ptr<detail::InMemoryDirectory> Root;
- std::string WorkingDirectory;
- bool UseNormalizedPaths = true;
-
-public:
- explicit InMemoryFileSystem(bool UseNormalizedPaths = true);
- ~InMemoryFileSystem() override;
- /// Add a buffer to the VFS with a path. The VFS owns the buffer.
- /// \return true if the file was successfully added, false if the file already
- /// exists in the file system with different contents.
- bool addFile(const Twine &Path, time_t ModificationTime,
- std::unique_ptr<llvm::MemoryBuffer> Buffer);
- /// Add a buffer to the VFS with a path. The VFS does not own the buffer.
- /// \return true if the file was successfully added, false if the file already
- /// exists in the file system with different contents.
- bool addFileNoOwn(const Twine &Path, time_t ModificationTime,
- llvm::MemoryBuffer *Buffer);
- std::string toString() const;
- /// Return true if this file system normalizes . and .. in paths.
- bool useNormalizedPaths() const { return UseNormalizedPaths; }
-
- llvm::ErrorOr<Status> status(const Twine &Path) override;
- 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;
- }
- std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
- WorkingDirectory = Path.str();
- return std::error_code();
- }
-};
-
-/// \brief 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
-/// format.
-IntrusiveRefCntPtr<FileSystem>
-getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer,
- llvm::SourceMgr::DiagHandlerTy DiagHandler,
- void *DiagContext = nullptr,
- IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
-
-struct YAMLVFSEntry {
- template <typename T1, typename T2> YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
- : VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)) {}
- std::string VPath;
- std::string RPath;
-};
-
-class YAMLVFSWriter {
- std::vector<YAMLVFSEntry> Mappings;
- Optional<bool> IsCaseSensitive;
-
-public:
- YAMLVFSWriter() {}
- void addFileMapping(StringRef VirtualPath, StringRef RealPath);
- void setCaseSensitivity(bool CaseSensitive) {
- IsCaseSensitive = CaseSensitive;
- }
- void write(llvm::raw_ostream &OS);
-};
-
-} // end namespace vfs
-} // end namespace clang
-#endif
diff --git a/include/clang/Basic/Visibility.h b/include/clang/Basic/Visibility.h
deleted file mode 100644
index 6ac52ed..0000000
--- a/include/clang/Basic/Visibility.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//===--- Visibility.h - Visibility enumeration and utilities ----*- 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::Visibility enumeration and various utility
-/// functions.
-///
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_VISIBILITY_H
-#define LLVM_CLANG_BASIC_VISIBILITY_H
-
-#include "clang/Basic/Linkage.h"
-
-namespace clang {
-
-/// \brief Describes the different kinds of visibility that a declaration
-/// may have.
-///
-/// Visibility determines how a declaration interacts with the dynamic
-/// linker. It may also affect whether the symbol can be found by runtime
-/// symbol lookup APIs.
-///
-/// Visibility is not described in any language standard and
-/// (nonetheless) sometimes has odd behavior. Not all platforms
-/// support all visibility kinds.
-enum Visibility {
- /// Objects with "hidden" visibility are not seen by the dynamic
- /// linker.
- HiddenVisibility,
-
- /// Objects with "protected" visibility are seen by the dynamic
- /// linker but always dynamically resolve to an object within this
- /// shared object.
- ProtectedVisibility,
-
- /// Objects with "default" visibility are seen by the dynamic linker
- /// and act like normal objects.
- DefaultVisibility
-};
-
-inline Visibility minVisibility(Visibility L, Visibility R) {
- return L < R ? L : R;
-}
-
-class LinkageInfo {
- uint8_t linkage_ : 3;
- uint8_t visibility_ : 2;
- uint8_t explicit_ : 1;
-
- void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; }
-public:
- LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility),
- explicit_(false) {}
- LinkageInfo(Linkage L, Visibility V, bool E)
- : linkage_(L), visibility_(V), explicit_(E) {
- assert(getLinkage() == L && getVisibility() == V &&
- isVisibilityExplicit() == E && "Enum truncated!");
- }
-
- static LinkageInfo external() {
- return LinkageInfo();
- }
- static LinkageInfo internal() {
- return LinkageInfo(InternalLinkage, DefaultVisibility, false);
- }
- static LinkageInfo uniqueExternal() {
- return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false);
- }
- static LinkageInfo none() {
- return LinkageInfo(NoLinkage, DefaultVisibility, false);
- }
-
- Linkage getLinkage() const { return (Linkage)linkage_; }
- Visibility getVisibility() const { return (Visibility)visibility_; }
- bool isVisibilityExplicit() const { return explicit_; }
-
- void setLinkage(Linkage L) { linkage_ = L; }
-
- void mergeLinkage(Linkage L) {
- setLinkage(minLinkage(getLinkage(), L));
- }
- void mergeLinkage(LinkageInfo other) {
- mergeLinkage(other.getLinkage());
- }
-
- void mergeExternalVisibility(Linkage L) {
- Linkage ThisL = getLinkage();
- if (!isExternallyVisible(L)) {
- if (ThisL == VisibleNoLinkage)
- ThisL = NoLinkage;
- else if (ThisL == ExternalLinkage)
- ThisL = UniqueExternalLinkage;
- }
- setLinkage(ThisL);
- }
- void mergeExternalVisibility(LinkageInfo Other) {
- mergeExternalVisibility(Other.getLinkage());
- }
-
- /// Merge in the visibility 'newVis'.
- void mergeVisibility(Visibility newVis, bool newExplicit) {
- Visibility oldVis = getVisibility();
-
- // Never increase visibility.
- if (oldVis < newVis)
- return;
-
- // If the new visibility is the same as the old and the new
- // visibility isn't explicit, we have nothing to add.
- if (oldVis == newVis && !newExplicit)
- return;
-
- // Otherwise, we're either decreasing visibility or making our
- // existing visibility explicit.
- setVisibility(newVis, newExplicit);
- }
- void mergeVisibility(LinkageInfo other) {
- mergeVisibility(other.getVisibility(), other.isVisibilityExplicit());
- }
-
- /// Merge both linkage and visibility.
- void merge(LinkageInfo other) {
- mergeLinkage(other);
- mergeVisibility(other);
- }
-
- /// Merge linkage and conditionally merge visibility.
- void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) {
- mergeLinkage(other);
- if (withVis) mergeVisibility(other);
- }
-};
-}
-
-#endif // LLVM_CLANG_BASIC_VISIBILITY_H
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
deleted file mode 100644
index 6d95c1e..0000000
--- a/include/clang/Basic/arm_neon.td
+++ /dev/null
@@ -1,1657 +0,0 @@
-//===--- arm_neon.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 the TableGen definitions from which the ARM NEON header
-// 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)
-// 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
-//===----------------------------------------------------------------------===//
-
-def OP_ADD : Op<(op "+", $p0, $p1)>;
-def OP_ADDL : Op<(op "+", (call "vmovl", $p0), (call "vmovl", $p1))>;
-def OP_ADDLHi : Op<(op "+", (call "vmovl_high", $p0),
- (call "vmovl_high", $p1))>;
-def OP_ADDW : Op<(op "+", $p0, (call "vmovl", $p1))>;
-def OP_ADDWHi : Op<(op "+", $p0, (call "vmovl_high", $p1))>;
-def OP_SUB : Op<(op "-", $p0, $p1)>;
-def OP_SUBL : Op<(op "-", (call "vmovl", $p0), (call "vmovl", $p1))>;
-def OP_SUBLHi : Op<(op "-", (call "vmovl_high", $p0),
- (call "vmovl_high", $p1))>;
-def OP_SUBW : Op<(op "-", $p0, (call "vmovl", $p1))>;
-def OP_SUBWHi : Op<(op "-", $p0, (call "vmovl_high", $p1))>;
-def OP_MUL : Op<(op "*", $p0, $p1)>;
-def OP_MLA : Op<(op "+", $p0, (op "*", $p1, $p2))>;
-def OP_MLAL : Op<(op "+", $p0, (call "vmull", $p1, $p2))>;
-def OP_MULLHi : Op<(call "vmull", (call "vget_high", $p0),
- (call "vget_high", $p1))>;
-def OP_MULLHi_P64 : Op<(call "vmull",
- (cast "poly64_t", (call "vget_high", $p0)),
- (cast "poly64_t", (call "vget_high", $p1)))>;
-def OP_MULLHi_N : Op<(call "vmull_n", (call "vget_high", $p0), $p1)>;
-def OP_MLALHi : Op<(call "vmlal", $p0, (call "vget_high", $p1),
- (call "vget_high", $p2))>;
-def OP_MLALHi_N : Op<(call "vmlal_n", $p0, (call "vget_high", $p1), $p2)>;
-def OP_MLS : Op<(op "-", $p0, (op "*", $p1, $p2))>;
-def OP_MLSL : Op<(op "-", $p0, (call "vmull", $p1, $p2))>;
-def OP_MLSLHi : Op<(call "vmlsl", $p0, (call "vget_high", $p1),
- (call "vget_high", $p2))>;
-def OP_MLSLHi_N : Op<(call "vmlsl_n", $p0, (call "vget_high", $p1), $p2)>;
-def OP_MUL_N : Op<(op "*", $p0, (dup $p1))>;
-def OP_MLA_N : Op<(op "+", $p0, (op "*", $p1, (dup $p2)))>;
-def OP_MLS_N : Op<(op "-", $p0, (op "*", $p1, (dup $p2)))>;
-def OP_FMLA_N : Op<(call "vfma", $p0, $p1, (dup $p2))>;
-def OP_FMLS_N : Op<(call "vfms", $p0, $p1, (dup $p2))>;
-def OP_MLAL_N : Op<(op "+", $p0, (call "vmull", $p1, (dup $p2)))>;
-def OP_MLSL_N : Op<(op "-", $p0, (call "vmull", $p1, (dup $p2)))>;
-def OP_MUL_LN : Op<(op "*", $p0, (splat $p1, $p2))>;
-def OP_MULX_LN : Op<(call "vmulx", $p0, (splat $p1, $p2))>;
-def OP_MULL_LN : Op<(call "vmull", $p0, (splat $p1, $p2))>;
-def OP_MULLHi_LN: Op<(call "vmull", (call "vget_high", $p0), (splat $p1, $p2))>;
-def OP_MLA_LN : Op<(op "+", $p0, (op "*", $p1, (splat $p2, $p3)))>;
-def OP_MLS_LN : Op<(op "-", $p0, (op "*", $p1, (splat $p2, $p3)))>;
-def OP_MLAL_LN : Op<(op "+", $p0, (call "vmull", $p1, (splat $p2, $p3)))>;
-def OP_MLALHi_LN: Op<(op "+", $p0, (call "vmull", (call "vget_high", $p1),
- (splat $p2, $p3)))>;
-def OP_MLSL_LN : Op<(op "-", $p0, (call "vmull", $p1, (splat $p2, $p3)))>;
-def OP_MLSLHi_LN : Op<(op "-", $p0, (call "vmull", (call "vget_high", $p1),
- (splat $p2, $p3)))>;
-def OP_QDMULL_LN : Op<(call "vqdmull", $p0, (splat $p1, $p2))>;
-def OP_QDMULLHi_LN : Op<(call "vqdmull", (call "vget_high", $p0),
- (splat $p1, $p2))>;
-def OP_QDMLAL_LN : Op<(call "vqdmlal", $p0, $p1, (splat $p2, $p3))>;
-def OP_QDMLALHi_LN : Op<(call "vqdmlal", $p0, (call "vget_high", $p1),
- (splat $p2, $p3))>;
-def OP_QDMLSL_LN : Op<(call "vqdmlsl", $p0, $p1, (splat $p2, $p3))>;
-def OP_QDMLSLHi_LN : Op<(call "vqdmlsl", $p0, (call "vget_high", $p1),
- (splat $p2, $p3))>;
-def OP_QDMULH_LN : Op<(call "vqdmulh", $p0, (splat $p1, $p2))>;
-def OP_QRDMULH_LN : Op<(call "vqrdmulh", $p0, (splat $p1, $p2))>;
-def OP_QRDMLAH : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, $p2))>;
-def OP_QRDMLSH : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, $p2))>;
-def OP_QRDMLAH_LN : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, (splat $p2, $p3)))>;
-def OP_QRDMLSH_LN : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, (splat $p2, $p3)))>;
-def OP_FMS_LN : Op<(call "vfma_lane", $p0, $p1, (op "-", $p2), $p3)>;
-def OP_FMS_LNQ : Op<(call "vfma_laneq", $p0, $p1, (op "-", $p2), $p3)>;
-def OP_TRN1 : Op<(shuffle $p0, $p1, (interleave (decimate mask0, 2),
- (decimate mask1, 2)))>;
-def OP_ZIP1 : Op<(shuffle $p0, $p1, (lowhalf (interleave mask0, mask1)))>;
-def OP_UZP1 : Op<(shuffle $p0, $p1, (add (decimate mask0, 2),
- (decimate mask1, 2)))>;
-def OP_TRN2 : Op<(shuffle $p0, $p1, (interleave
- (decimate (rotl mask0, 1), 2),
- (decimate (rotl mask1, 1), 2)))>;
-def OP_ZIP2 : Op<(shuffle $p0, $p1, (highhalf (interleave mask0, mask1)))>;
-def OP_UZP2 : Op<(shuffle $p0, $p1, (add (decimate (rotl mask0, 1), 2),
- (decimate (rotl mask1, 1), 2)))>;
-def OP_EQ : Op<(cast "R", (op "==", $p0, $p1))>;
-def OP_GE : Op<(cast "R", (op ">=", $p0, $p1))>;
-def OP_LE : Op<(cast "R", (op "<=", $p0, $p1))>;
-def OP_GT : Op<(cast "R", (op ">", $p0, $p1))>;
-def OP_LT : Op<(cast "R", (op "<", $p0, $p1))>;
-def OP_NEG : Op<(op "-", $p0)>;
-def OP_NOT : Op<(op "~", $p0)>;
-def OP_AND : Op<(op "&", $p0, $p1)>;
-def OP_OR : Op<(op "|", $p0, $p1)>;
-def OP_XOR : Op<(op "^", $p0, $p1)>;
-def OP_ANDN : Op<(op "&", $p0, (op "~", $p1))>;
-def OP_ORN : Op<(op "|", $p0, (op "~", $p1))>;
-def OP_CAST : Op<(cast "R", $p0)>;
-def OP_HI : Op<(shuffle $p0, $p0, (highhalf mask0))>;
-def OP_LO : Op<(shuffle $p0, $p0, (lowhalf mask0))>;
-def OP_CONC : Op<(shuffle $p0, $p1, (add mask0, mask1))>;
-def OP_DUP : Op<(dup $p0)>;
-def OP_DUP_LN : Op<(splat $p0, $p1)>;
-def OP_SEL : Op<(cast "R", (op "|",
- (op "&", $p0, (cast $p0, $p1)),
- (op "&", (op "~", $p0), (cast $p0, $p2))))>;
-def OP_REV16 : Op<(shuffle $p0, $p0, (rev 16, mask0))>;
-def OP_REV32 : Op<(shuffle $p0, $p0, (rev 32, mask0))>;
-def OP_REV64 : Op<(shuffle $p0, $p0, (rev 64, mask0))>;
-def OP_XTN : Op<(call "vcombine", $p0, (call "vmovn", $p1))>;
-def OP_SQXTUN : Op<(call "vcombine", (cast $p0, "U", $p0),
- (call "vqmovun", $p1))>;
-def OP_QXTN : Op<(call "vcombine", $p0, (call "vqmovn", $p1))>;
-def OP_VCVT_NA_HI_F16 : Op<(call "vcombine", $p0, (call "vcvt_f16_f32", $p1))>;
-def OP_VCVT_NA_HI_F32 : Op<(call "vcombine", $p0, (call "vcvt_f32_f64", $p1))>;
-def OP_VCVT_EX_HI_F32 : Op<(call "vcvt_f32_f16", (call "vget_high", $p0))>;
-def OP_VCVT_EX_HI_F64 : Op<(call "vcvt_f64_f32", (call "vget_high", $p0))>;
-def OP_VCVTX_HI : Op<(call "vcombine", $p0, (call "vcvtx_f32", $p1))>;
-def OP_REINT : Op<(cast "R", $p0)>;
-def OP_ADDHNHi : Op<(call "vcombine", $p0, (call "vaddhn", $p1, $p2))>;
-def OP_RADDHNHi : Op<(call "vcombine", $p0, (call "vraddhn", $p1, $p2))>;
-def OP_SUBHNHi : Op<(call "vcombine", $p0, (call "vsubhn", $p1, $p2))>;
-def OP_RSUBHNHi : Op<(call "vcombine", $p0, (call "vrsubhn", $p1, $p2))>;
-def OP_ABDL : Op<(cast "R", (call "vmovl", (cast $p0, "U",
- (call "vabd", $p0, $p1))))>;
-def OP_ABDLHi : Op<(call "vabdl", (call "vget_high", $p0),
- (call "vget_high", $p1))>;
-def OP_ABA : Op<(op "+", $p0, (call "vabd", $p1, $p2))>;
-def OP_ABAL : Op<(op "+", $p0, (call "vabdl", $p1, $p2))>;
-def OP_ABALHi : Op<(call "vabal", $p0, (call "vget_high", $p1),
- (call "vget_high", $p2))>;
-def OP_QDMULLHi : Op<(call "vqdmull", (call "vget_high", $p0),
- (call "vget_high", $p1))>;
-def OP_QDMULLHi_N : Op<(call "vqdmull_n", (call "vget_high", $p0), $p1)>;
-def OP_QDMLALHi : Op<(call "vqdmlal", $p0, (call "vget_high", $p1),
- (call "vget_high", $p2))>;
-def OP_QDMLALHi_N : Op<(call "vqdmlal_n", $p0, (call "vget_high", $p1), $p2)>;
-def OP_QDMLSLHi : Op<(call "vqdmlsl", $p0, (call "vget_high", $p1),
- (call "vget_high", $p2))>;
-def OP_QDMLSLHi_N : Op<(call "vqdmlsl_n", $p0, (call "vget_high", $p1), $p2)>;
-def OP_DIV : Op<(op "/", $p0, $p1)>;
-def OP_LONG_HI : Op<(cast "R", (call (name_replace "_high_", "_"),
- (call "vget_high", $p0), $p1))>;
-def OP_NARROW_HI : Op<(cast "R", (call "vcombine",
- (cast "R", "H", $p0),
- (cast "R", "H",
- (call (name_replace "_high_", "_"),
- $p1, $p2))))>;
-def OP_MOVL_HI : LOp<[(save_temp $a1, (call "vget_high", $p0)),
- (cast "R",
- (call "vshll_n", $a1, (literal "int32_t", "0")))]>;
-def OP_COPY_LN : Op<(call "vset_lane", (call "vget_lane", $p2, $p3), $p0, $p1)>;
-def OP_SCALAR_MUL_LN : Op<(op "*", $p0, (call "vget_lane", $p1, $p2))>;
-def OP_SCALAR_MULX_LN : Op<(call "vmulx", $p0, (call "vget_lane", $p1, $p2))>;
-def OP_SCALAR_VMULX_LN : LOp<[(save_temp $x, (call "vget_lane", $p0,
- (literal "int32_t", "0"))),
- (save_temp $y, (call "vget_lane", $p1, $p2)),
- (save_temp $z, (call "vmulx", $x, $y)),
- (call "vset_lane", $z, $p0, $p2)]>;
-def OP_SCALAR_VMULX_LNQ : LOp<[(save_temp $x, (call "vget_lane", $p0,
- (literal "int32_t", "0"))),
- (save_temp $y, (call "vget_lane", $p1, $p2)),
- (save_temp $z, (call "vmulx", $x, $y)),
- (call "vset_lane", $z, $p0, (literal "int32_t",
- "0"))]>;
-class ScalarMulOp<string opname> :
- Op<(call opname, $p0, (call "vget_lane", $p1, $p2))>;
-
-def OP_SCALAR_QDMULL_LN : ScalarMulOp<"vqdmull">;
-def OP_SCALAR_QDMULH_LN : ScalarMulOp<"vqdmulh">;
-def OP_SCALAR_QRDMULH_LN : ScalarMulOp<"vqrdmulh">;
-
-def OP_SCALAR_QRDMLAH_LN : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1,
- (call "vget_lane", $p2, $p3)))>;
-def OP_SCALAR_QRDMLSH_LN : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1,
- (call "vget_lane", $p2, $p3)))>;
-
-def OP_SCALAR_HALF_GET_LN : Op<(bitcast "float16_t",
- (call "vget_lane",
- (bitcast "int16x4_t", $p0), $p1))>;
-def OP_SCALAR_HALF_GET_LNQ : Op<(bitcast "float16_t",
- (call "vget_lane",
- (bitcast "int16x8_t", $p0), $p1))>;
-def OP_SCALAR_HALF_SET_LN : Op<(bitcast "float16x4_t",
- (call "vset_lane",
- (bitcast "int16_t", $p0),
- (bitcast "int16x4_t", $p1), $p2))>;
-def OP_SCALAR_HALF_SET_LNQ : Op<(bitcast "float16x8_t",
- (call "vset_lane",
- (bitcast "int16_t", $p0),
- (bitcast "int16x8_t", $p1), $p2))>;
-
-//===----------------------------------------------------------------------===//
-// Instructions
-//===----------------------------------------------------------------------===//
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.1 Addition
-def VADD : IOpInst<"vadd", "ddd",
- "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_ADD>;
-def VADDL : SOpInst<"vaddl", "wdd", "csiUcUsUi", OP_ADDL>;
-def VADDW : SOpInst<"vaddw", "wwd", "csiUcUsUi", OP_ADDW>;
-def VHADD : SInst<"vhadd", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-def VRHADD : SInst<"vrhadd", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-def VQADD : SInst<"vqadd", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VADDHN : IInst<"vaddhn", "hkk", "silUsUiUl">;
-def VRADDHN : IInst<"vraddhn", "hkk", "silUsUiUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.2 Multiplication
-def VMUL : IOpInst<"vmul", "ddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MUL>;
-def VMULP : SInst<"vmul", "ddd", "PcQPc">;
-def VMLA : IOpInst<"vmla", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLA>;
-def VMLAL : SOpInst<"vmlal", "wwdd", "csiUcUsUi", OP_MLAL>;
-def VMLS : IOpInst<"vmls", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLS>;
-def VMLSL : SOpInst<"vmlsl", "wwdd", "csiUcUsUi", OP_MLSL>;
-def VQDMULH : SInst<"vqdmulh", "ddd", "siQsQi">;
-def VQRDMULH : SInst<"vqrdmulh", "ddd", "siQsQi">;
-
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX)" in {
-def VQRDMLAH : SOpInst<"vqrdmlah", "dddd", "siQsQi", OP_QRDMLAH>;
-def VQRDMLSH : SOpInst<"vqrdmlsh", "dddd", "siQsQi", OP_QRDMLSH>;
-}
-
-def VQDMLAL : SInst<"vqdmlal", "wwdd", "si">;
-def VQDMLSL : SInst<"vqdmlsl", "wwdd", "si">;
-def VMULL : SInst<"vmull", "wdd", "csiUcUsUiPc">;
-def VQDMULL : SInst<"vqdmull", "wdd", "si">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.3 Subtraction
-def VSUB : IOpInst<"vsub", "ddd",
- "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_SUB>;
-def VSUBL : SOpInst<"vsubl", "wdd", "csiUcUsUi", OP_SUBL>;
-def VSUBW : SOpInst<"vsubw", "wwd", "csiUcUsUi", OP_SUBW>;
-def VQSUB : SInst<"vqsub", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VHSUB : SInst<"vhsub", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-def VSUBHN : IInst<"vsubhn", "hkk", "silUsUiUl">;
-def VRSUBHN : IInst<"vrsubhn", "hkk", "silUsUiUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.4 Comparison
-def VCEQ : IOpInst<"vceq", "udd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_EQ>;
-def VCGE : SOpInst<"vcge", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GE>;
-let InstName = "vcge" in
-def VCLE : SOpInst<"vcle", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LE>;
-def VCGT : SOpInst<"vcgt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GT>;
-let InstName = "vcgt" in
-def VCLT : SOpInst<"vclt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LT>;
-let InstName = "vacge" in {
-def VCAGE : IInst<"vcage", "udd", "fQf">;
-def VCALE : IInst<"vcale", "udd", "fQf">;
-}
-let InstName = "vacgt" in {
-def VCAGT : IInst<"vcagt", "udd", "fQf">;
-def VCALT : IInst<"vcalt", "udd", "fQf">;
-}
-def VTST : WInst<"vtst", "udd", "csiUcUsUiPcPsQcQsQiQUcQUsQUiQPcQPs">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.5 Absolute Difference
-def VABD : SInst<"vabd", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
-def VABDL : SOpInst<"vabdl", "wdd", "csiUcUsUi", OP_ABDL>;
-def VABA : SOpInst<"vaba", "dddd", "csiUcUsUiQcQsQiQUcQUsQUi", OP_ABA>;
-def VABAL : SOpInst<"vabal", "wwdd", "csiUcUsUi", OP_ABAL>;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.6 Max/Min
-def VMAX : SInst<"vmax", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
-def VMIN : SInst<"vmin", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.7 Pairwise Addition
-def VPADD : IInst<"vpadd", "ddd", "csiUcUsUif">;
-def VPADDL : SInst<"vpaddl", "nd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-def VPADAL : SInst<"vpadal", "nnd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.8-9 Folding Max/Min
-def VPMAX : SInst<"vpmax", "ddd", "csiUcUsUif">;
-def VPMIN : SInst<"vpmin", "ddd", "csiUcUsUif">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.10 Reciprocal/Sqrt
-def VRECPS : IInst<"vrecps", "ddd", "fQf">;
-def VRSQRTS : IInst<"vrsqrts", "ddd", "fQf">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.11 Shifts by signed variable
-def VSHL : SInst<"vshl", "ddx", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VQSHL : SInst<"vqshl", "ddx", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VRSHL : SInst<"vrshl", "ddx", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VQRSHL : SInst<"vqrshl", "ddx", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.12 Shifts by constant
-let isShift = 1 in {
-def VSHR_N : SInst<"vshr_n", "ddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VSHL_N : IInst<"vshl_n", "ddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VRSHR_N : SInst<"vrshr_n", "ddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VSRA_N : SInst<"vsra_n", "dddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VRSRA_N : SInst<"vrsra_n", "dddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VQSHL_N : SInst<"vqshl_n", "ddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
-def VQSHLU_N : SInst<"vqshlu_n", "udi", "csilQcQsQiQl">;
-def VSHRN_N : IInst<"vshrn_n", "hki", "silUsUiUl">;
-def VQSHRUN_N : SInst<"vqshrun_n", "eki", "sil">;
-def VQRSHRUN_N : SInst<"vqrshrun_n", "eki", "sil">;
-def VQSHRN_N : SInst<"vqshrn_n", "hki", "silUsUiUl">;
-def VRSHRN_N : IInst<"vrshrn_n", "hki", "silUsUiUl">;
-def VQRSHRN_N : SInst<"vqrshrn_n", "hki", "silUsUiUl">;
-def VSHLL_N : SInst<"vshll_n", "wdi", "csiUcUsUi">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.13 Shifts with insert
-def VSRI_N : WInst<"vsri_n", "dddi",
- "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs">;
-def VSLI_N : WInst<"vsli_n", "dddi",
- "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.14 Loads and stores of a single vector
-def VLD1 : WInst<"vld1", "dc",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VLD1_LANE : WInst<"vld1_lane", "dcdi",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VLD1_DUP : WInst<"vld1_dup", "dc",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VST1 : WInst<"vst1", "vpd",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VST1_LANE : WInst<"vst1_lane", "vpdi",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.15 Loads and stores of an N-element structure
-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_LANE : WInst<"vld2_lane", "2c2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VLD3_LANE : WInst<"vld3_lane", "3c3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VLD4_LANE : WInst<"vld4_lane", "4c4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VST2 : WInst<"vst2", "vp2", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VST3 : WInst<"vst3", "vp3", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VST4 : WInst<"vst4", "vp4", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VST2_LANE : WInst<"vst2_lane", "vp2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VST3_LANE : WInst<"vst3_lane", "vp3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VST4_LANE : WInst<"vst4_lane", "vp4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.16 Extract lanes from a vector
-let InstName = "vmov" in
-def VGET_LANE : IInst<"vget_lane", "sdi",
- "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.17 Set lanes within a vector
-let InstName = "vmov" in
-def VSET_LANE : IInst<"vset_lane", "dsdi",
- "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.18 Initialize a vector from bit pattern
-def VCREATE : NoTestOpInst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST> {
- let BigEndianSafe = 1;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.19 Set all lanes to same value
-let InstName = "vmov" in {
-def VDUP_N : WOpInst<"vdup_n", "ds",
- "UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
- OP_DUP>;
-def VMOV_N : WOpInst<"vmov_n", "ds",
- "UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
- OP_DUP>;
-}
-let InstName = "" in
-def VDUP_LANE: WOpInst<"vdup_lane", "dgi",
- "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl",
- OP_DUP_LN>;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.20 Combining vectors
-def VCOMBINE : NoTestOpInst<"vcombine", "kdd", "csilhfUcUsUiUlPcPs", OP_CONC>;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.21 Splitting vectors
-let InstName = "vmov" in {
-def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>;
-def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.22 Converting vectors
-
-def VCVT_F16_F32 : SInst<"vcvt_f16_f32", "md", "Hf">;
-def VCVT_F32_F16 : SInst<"vcvt_f32_f16", "wd", "h">;
-
-def VCVT_S32 : SInst<"vcvt_s32", "xd", "fQf">;
-def VCVT_U32 : SInst<"vcvt_u32", "ud", "fQf">;
-def VCVT_F32 : SInst<"vcvt_f32", "fd", "iUiQiQUi">;
-let isVCVT_N = 1 in {
-def VCVT_N_S32 : SInst<"vcvt_n_s32", "xdi", "fQf">;
-def VCVT_N_U32 : SInst<"vcvt_n_u32", "udi", "fQf">;
-def VCVT_N_F32 : SInst<"vcvt_n_f32", "fdi", "iUiQiQUi">;
-}
-
-def VMOVN : IInst<"vmovn", "hk", "silUsUiUl">;
-def VMOVL : SInst<"vmovl", "wd", "csiUcUsUi">;
-def VQMOVN : SInst<"vqmovn", "hk", "silUsUiUl">;
-def VQMOVUN : SInst<"vqmovun", "ek", "sil">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.23-24 Table lookup, Extended table lookup
-let InstName = "vtbl" in {
-def VTBL1 : WInst<"vtbl1", "ddt", "UccPc">;
-def VTBL2 : WInst<"vtbl2", "d2t", "UccPc">;
-def VTBL3 : WInst<"vtbl3", "d3t", "UccPc">;
-def VTBL4 : WInst<"vtbl4", "d4t", "UccPc">;
-}
-let InstName = "vtbx" in {
-def VTBX1 : WInst<"vtbx1", "dddt", "UccPc">;
-def VTBX2 : WInst<"vtbx2", "dd2t", "UccPc">;
-def VTBX3 : WInst<"vtbx3", "dd3t", "UccPc">;
-def VTBX4 : WInst<"vtbx4", "dd4t", "UccPc">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.25 Operations with a scalar value
-def VMLA_LANE : IOpInst<"vmla_lane", "dddgi",
- "siUsUifQsQiQUsQUiQf", OP_MLA_LN>;
-def VMLAL_LANE : SOpInst<"vmlal_lane", "wwddi", "siUsUi", OP_MLAL_LN>;
-def VQDMLAL_LANE : SOpInst<"vqdmlal_lane", "wwddi", "si", OP_QDMLAL_LN>;
-def VMLS_LANE : IOpInst<"vmls_lane", "dddgi",
- "siUsUifQsQiQUsQUiQf", OP_MLS_LN>;
-def VMLSL_LANE : SOpInst<"vmlsl_lane", "wwddi", "siUsUi", OP_MLSL_LN>;
-def VQDMLSL_LANE : SOpInst<"vqdmlsl_lane", "wwddi", "si", OP_QDMLSL_LN>;
-def VMUL_N : IOpInst<"vmul_n", "dds", "sifUsUiQsQiQfQUsQUi", OP_MUL_N>;
-def VMUL_LANE : IOpInst<"vmul_lane", "ddgi",
- "sifUsUiQsQiQfQUsQUi", OP_MUL_LN>;
-def VMULL_N : SInst<"vmull_n", "wda", "siUsUi">;
-def VMULL_LANE : SOpInst<"vmull_lane", "wddi", "siUsUi", OP_MULL_LN>;
-def VQDMULL_N : SInst<"vqdmull_n", "wda", "si">;
-def VQDMULL_LANE : SOpInst<"vqdmull_lane", "wddi", "si", OP_QDMULL_LN>;
-def VQDMULH_N : SInst<"vqdmulh_n", "dda", "siQsQi">;
-def VQDMULH_LANE : SOpInst<"vqdmulh_lane", "ddgi", "siQsQi", OP_QDMULH_LN>;
-def VQRDMULH_N : SInst<"vqrdmulh_n", "dda", "siQsQi">;
-def VQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ddgi", "siQsQi", OP_QRDMULH_LN>;
-
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX)" in {
-def VQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "dddgi", "siQsQi", OP_QRDMLAH_LN>;
-def VQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "dddgi", "siQsQi", OP_QRDMLSH_LN>;
-}
-
-def VMLA_N : IOpInst<"vmla_n", "ddda", "siUsUifQsQiQUsQUiQf", OP_MLA_N>;
-def VMLAL_N : SOpInst<"vmlal_n", "wwda", "siUsUi", OP_MLAL_N>;
-def VQDMLAL_N : SInst<"vqdmlal_n", "wwda", "si">;
-def VMLS_N : IOpInst<"vmls_n", "ddds", "siUsUifQsQiQUsQUiQf", OP_MLS_N>;
-def VMLSL_N : SOpInst<"vmlsl_n", "wwda", "siUsUi", OP_MLSL_N>;
-def VQDMLSL_N : SInst<"vqdmlsl_n", "wwda", "si">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.26 Vector Extract
-def VEXT : WInst<"vext", "dddi",
- "cUcPcsUsPsiUilUlfQcQUcQPcQsQUsQPsQiQUiQlQUlQf">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.27 Reverse vector elements
-def VREV64 : WOpInst<"vrev64", "dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf",
- OP_REV64>;
-def VREV32 : WOpInst<"vrev32", "dd", "csUcUsPcPsQcQsQUcQUsQPcQPs", OP_REV32>;
-def VREV16 : WOpInst<"vrev16", "dd", "cUcPcQcQUcQPc", OP_REV16>;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.28 Other single operand arithmetic
-def VABS : SInst<"vabs", "dd", "csifQcQsQiQf">;
-def VQABS : SInst<"vqabs", "dd", "csiQcQsQi">;
-def VNEG : SOpInst<"vneg", "dd", "csifQcQsQiQf", OP_NEG>;
-def VQNEG : SInst<"vqneg", "dd", "csiQcQsQi">;
-def VCLS : SInst<"vcls", "dd", "csiQcQsQi">;
-def VCLZ : IInst<"vclz", "dd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-def VCNT : WInst<"vcnt", "dd", "UccPcQUcQcQPc">;
-def VRECPE : SInst<"vrecpe", "dd", "fUiQfQUi">;
-def VRSQRTE : SInst<"vrsqrte", "dd", "fUiQfQUi">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.29 Logical operations
-def VMVN : LOpInst<"vmvn", "dd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc", OP_NOT>;
-def VAND : LOpInst<"vand", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_AND>;
-def VORR : LOpInst<"vorr", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_OR>;
-def VEOR : LOpInst<"veor", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_XOR>;
-def VBIC : LOpInst<"vbic", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ANDN>;
-def VORN : LOpInst<"vorn", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ORN>;
-let isHiddenLInst = 1 in
-def VBSL : SInst<"vbsl", "dudd",
- "csilUcUsUiUlfPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPs">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.30 Transposition operations
-def VTRN : WInst<"vtrn", "2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
-def VZIP : WInst<"vzip", "2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
-def VUZP : WInst<"vuzp", "2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
-
-////////////////////////////////////////////////////////////////////////////////
-// E.3.31 Vector reinterpret cast operations
-def VREINTERPRET
- : NoTestOpInst<"vreinterpret", "dd",
- "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT> {
- let CartesianProductOfTypes = 1;
- let ArchGuard = "!defined(__aarch64__)";
- let BigEndianSafe = 1;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Vector fused multiply-add operations
-
-def VFMA : SInst<"vfma", "dddd", "fQf">;
-
-////////////////////////////////////////////////////////////////////////////////
-// fp16 vector operations
-def SCALAR_HALF_GET_LANE : IOpInst<"vget_lane", "sdi", "h", OP_SCALAR_HALF_GET_LN>;
-def SCALAR_HALF_SET_LANE : IOpInst<"vset_lane", "dsdi", "h", OP_SCALAR_HALF_SET_LN>;
-def SCALAR_HALF_GET_LANEQ : IOpInst<"vget_lane", "sdi", "Qh", OP_SCALAR_HALF_GET_LNQ>;
-def SCALAR_HALF_SET_LANEQ : IOpInst<"vset_lane", "dsdi", "Qh", OP_SCALAR_HALF_SET_LNQ>;
-
-////////////////////////////////////////////////////////////////////////////////
-// AArch64 Intrinsics
-
-let ArchGuard = "defined(__aarch64__)" in {
-
-////////////////////////////////////////////////////////////////////////////////
-// Load/Store
-def LD1 : WInst<"vld1", "dc", "dQdPlQPl">;
-def LD2 : WInst<"vld2", "2c", "QUlQldQdPlQPl">;
-def LD3 : WInst<"vld3", "3c", "QUlQldQdPlQPl">;
-def LD4 : WInst<"vld4", "4c", "QUlQldQdPlQPl">;
-def ST1 : WInst<"vst1", "vpd", "dQdPlQPl">;
-def ST2 : WInst<"vst2", "vp2", "QUlQldQdPlQPl">;
-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">;
-
-def LD1_LANE : WInst<"vld1_lane", "dcdi", "dQdPlQPl">;
-def LD2_LANE : WInst<"vld2_lane", "2c2i", "lUlQcQUcQPcQlQUldQdPlQPl">;
-def LD3_LANE : WInst<"vld3_lane", "3c3i", "lUlQcQUcQPcQlQUldQdPlQPl">;
-def LD4_LANE : WInst<"vld4_lane", "4c4i", "lUlQcQUcQPcQlQUldQdPlQPl">;
-def ST1_LANE : WInst<"vst1_lane", "vpdi", "dQdPlQPl">;
-def ST2_LANE : WInst<"vst2_lane", "vp2i", "lUlQcQUcQPcQlQUldQdPlQPl">;
-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 VLDRQ : WInst<"vldrq", "sc", "Pk">;
-def VSTRQ : WInst<"vstrq", "vps", "Pk">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Addition
-def ADD : IOpInst<"vadd", "ddd", "dQd", OP_ADD>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Subtraction
-def SUB : IOpInst<"vsub", "ddd", "dQd", OP_SUB>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Multiplication
-def MUL : IOpInst<"vmul", "ddd", "dQd", OP_MUL>;
-def MLA : IOpInst<"vmla", "dddd", "dQd", OP_MLA>;
-def MLS : IOpInst<"vmls", "dddd", "dQd", OP_MLS>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Multiplication Extended
-def MULX : SInst<"vmulx", "ddd", "fdQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Division
-def FDIV : IOpInst<"vdiv", "ddd", "fdQfQd", OP_DIV>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Vector fused multiply-add operations
-def FMLA : SInst<"vfma", "dddd", "dQd">;
-def FMLS : SInst<"vfms", "dddd", "fdQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// 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 MLA_N : SOpInst<"vmla_n", "ddds", "Qd", OP_MLA_N>;
-def MLS_N : SOpInst<"vmls_n", "ddds", "Qd", OP_MLS_N>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Logical operations
-def BSL : SInst<"vbsl", "dudd", "dPlQdQPl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Absolute Difference
-def ABD : SInst<"vabd", "ddd", "dQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// saturating absolute/negate
-def ABS : SInst<"vabs", "dd", "dQdlQl">;
-def QABS : SInst<"vqabs", "dd", "lQl">;
-def NEG : SOpInst<"vneg", "dd", "dlQdQl", OP_NEG>;
-def QNEG : SInst<"vqneg", "dd", "lQl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Signed Saturating Accumulated of Unsigned Value
-def SUQADD : SInst<"vuqadd", "ddd", "csilQcQsQiQl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Unsigned Saturating Accumulated of Signed Value
-def USQADD : SInst<"vsqadd", "ddd", "UcUsUiUlQUcQUsQUiQUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Reciprocal/Sqrt
-def FRECPS : IInst<"vrecps", "ddd", "dQd">;
-def FRSQRTS : IInst<"vrsqrts", "ddd", "dQd">;
-def FRECPE : SInst<"vrecpe", "dd", "dQd">;
-def FRSQRTE : SInst<"vrsqrte", "dd", "dQd">;
-def FSQRT : SInst<"vsqrt", "dd", "fdQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// bitwise reverse
-def RBIT : IInst<"vrbit", "dd", "cUcPcQcQUcQPc">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Integer extract and narrow to high
-def XTN2 : SOpInst<"vmovn_high", "qhk", "silUsUiUl", OP_XTN>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Signed integer saturating extract and unsigned narrow to high
-def SQXTUN2 : SOpInst<"vqmovun_high", "qhk", "sil", OP_SQXTUN>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Integer saturating extract and narrow to high
-def QXTN2 : SOpInst<"vqmovn_high", "qhk", "silUsUiUl", OP_QXTN>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Converting vectors
-
-def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "md", "Qd">;
-def VCVT_F64_F32 : SInst<"vcvt_f64_f32", "wd", "f">;
-
-def VCVT_S64 : SInst<"vcvt_s64", "xd", "dQd">;
-def VCVT_U64 : SInst<"vcvt_u64", "ud", "dQd">;
-def VCVT_F64 : SInst<"vcvt_f64", "Fd", "lUlQlQUl">;
-
-def VCVT_HIGH_F16_F32 : SOpInst<"vcvt_high_f16", "hmj", "Hf", OP_VCVT_NA_HI_F16>;
-def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI_F32>;
-def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI_F32>;
-def VCVT_HIGH_F64_F32 : SOpInst<"vcvt_high_f64", "wj", "f", OP_VCVT_EX_HI_F64>;
-
-def VCVTX_F32_F64 : SInst<"vcvtx_f32", "fj", "d">;
-def VCVTX_HIGH_F32_F64 : SOpInst<"vcvtx_high_f32", "qfj", "d", OP_VCVTX_HI>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Comparison
-def FCAGE : IInst<"vcage", "udd", "dQd">;
-def FCAGT : IInst<"vcagt", "udd", "dQd">;
-def FCALE : IInst<"vcale", "udd", "dQd">;
-def FCALT : IInst<"vcalt", "udd", "dQd">;
-def CMTST : WInst<"vtst", "udd", "lUlPlQlQUlQPl">;
-def CFMEQ : SOpInst<"vceq", "udd", "lUldQdQlQUlPlQPl", OP_EQ>;
-def CFMGE : SOpInst<"vcge", "udd", "lUldQdQlQUl", OP_GE>;
-def CFMLE : SOpInst<"vcle", "udd", "lUldQdQlQUl", OP_LE>;
-def CFMGT : SOpInst<"vcgt", "udd", "lUldQdQlQUl", OP_GT>;
-def CFMLT : SOpInst<"vclt", "udd", "lUldQdQlQUl", OP_LT>;
-
-def CMEQ : SInst<"vceqz", "ud",
- "csilfUcUsUiUlPcPsPlQcQsQiQlQfQUcQUsQUiQUlQPcQPsdQdQPl">;
-def CMGE : SInst<"vcgez", "ud", "csilfdQcQsQiQlQfQd">;
-def CMLE : SInst<"vclez", "ud", "csilfdQcQsQiQlQfQd">;
-def CMGT : SInst<"vcgtz", "ud", "csilfdQcQsQiQlQfQd">;
-def CMLT : SInst<"vcltz", "ud", "csilfdQcQsQiQlQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Max/Min Integer
-def MAX : SInst<"vmax", "ddd", "dQd">;
-def MIN : SInst<"vmin", "ddd", "dQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Pairwise Max/Min
-def MAXP : SInst<"vpmax", "ddd", "QcQsQiQUcQUsQUiQfQd">;
-def MINP : SInst<"vpmin", "ddd", "QcQsQiQUcQUsQUiQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Pairwise MaxNum/MinNum Floating Point
-def FMAXNMP : SInst<"vpmaxnm", "ddd", "fQfQd">;
-def FMINNMP : SInst<"vpminnm", "ddd", "fQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Pairwise Addition
-def ADDP : IInst<"vpadd", "ddd", "QcQsQiQlQUcQUsQUiQUlQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Shifts by constant
-let isShift = 1 in {
-// Left shift long high
-def SHLL_HIGH_N : SOpInst<"vshll_high_n", "ndi", "HcHsHiHUcHUsHUi",
- OP_LONG_HI>;
-
-////////////////////////////////////////////////////////////////////////////////
-def SRI_N : WInst<"vsri_n", "dddi", "PlQPl">;
-def SLI_N : WInst<"vsli_n", "dddi", "PlQPl">;
-
-// Right shift narrow high
-def SHRN_HIGH_N : IOpInst<"vshrn_high_n", "hmdi",
- "HsHiHlHUsHUiHUl", OP_NARROW_HI>;
-def QSHRUN_HIGH_N : SOpInst<"vqshrun_high_n", "hmdi",
- "HsHiHl", OP_NARROW_HI>;
-def RSHRN_HIGH_N : IOpInst<"vrshrn_high_n", "hmdi",
- "HsHiHlHUsHUiHUl", OP_NARROW_HI>;
-def QRSHRUN_HIGH_N : SOpInst<"vqrshrun_high_n", "hmdi",
- "HsHiHl", OP_NARROW_HI>;
-def QSHRN_HIGH_N : SOpInst<"vqshrn_high_n", "hmdi",
- "HsHiHlHUsHUiHUl", OP_NARROW_HI>;
-def QRSHRN_HIGH_N : SOpInst<"vqrshrn_high_n", "hmdi",
- "HsHiHlHUsHUiHUl", OP_NARROW_HI>;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Converting vectors
-def VMOVL_HIGH : SOpInst<"vmovl_high", "nd", "HcHsHiHUcHUsHUi", OP_MOVL_HI>;
-
-let isVCVT_N = 1 in {
-def CVTF_N_F64 : SInst<"vcvt_n_f64", "Fdi", "lUlQlQUl">;
-def FCVTZS_N_S64 : SInst<"vcvt_n_s64", "xdi", "dQd">;
-def FCVTZS_N_U64 : SInst<"vcvt_n_u64", "udi", "dQd">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// 3VDiff class using high 64-bit in operands
-def VADDL_HIGH : SOpInst<"vaddl_high", "wkk", "csiUcUsUi", OP_ADDLHi>;
-def VADDW_HIGH : SOpInst<"vaddw_high", "wwk", "csiUcUsUi", OP_ADDWHi>;
-def VSUBL_HIGH : SOpInst<"vsubl_high", "wkk", "csiUcUsUi", OP_SUBLHi>;
-def VSUBW_HIGH : SOpInst<"vsubw_high", "wwk", "csiUcUsUi", OP_SUBWHi>;
-
-def VABDL_HIGH : SOpInst<"vabdl_high", "wkk", "csiUcUsUi", OP_ABDLHi>;
-def VABAL_HIGH : SOpInst<"vabal_high", "wwkk", "csiUcUsUi", OP_ABALHi>;
-
-def VMULL_HIGH : SOpInst<"vmull_high", "wkk", "csiUcUsUiPc", OP_MULLHi>;
-def VMULL_HIGH_N : SOpInst<"vmull_high_n", "wks", "siUsUi", OP_MULLHi_N>;
-def VMLAL_HIGH : SOpInst<"vmlal_high", "wwkk", "csiUcUsUi", OP_MLALHi>;
-def VMLAL_HIGH_N : SOpInst<"vmlal_high_n", "wwks", "siUsUi", OP_MLALHi_N>;
-def VMLSL_HIGH : SOpInst<"vmlsl_high", "wwkk", "csiUcUsUi", OP_MLSLHi>;
-def VMLSL_HIGH_N : SOpInst<"vmlsl_high_n", "wwks", "siUsUi", OP_MLSLHi_N>;
-
-def VADDHN_HIGH : SOpInst<"vaddhn_high", "qhkk", "silUsUiUl", OP_ADDHNHi>;
-def VRADDHN_HIGH : SOpInst<"vraddhn_high", "qhkk", "silUsUiUl", OP_RADDHNHi>;
-def VSUBHN_HIGH : SOpInst<"vsubhn_high", "qhkk", "silUsUiUl", OP_SUBHNHi>;
-def VRSUBHN_HIGH : SOpInst<"vrsubhn_high", "qhkk", "silUsUiUl", OP_RSUBHNHi>;
-
-def VQDMULL_HIGH : SOpInst<"vqdmull_high", "wkk", "si", OP_QDMULLHi>;
-def VQDMULL_HIGH_N : SOpInst<"vqdmull_high_n", "wks", "si", OP_QDMULLHi_N>;
-def VQDMLAL_HIGH : SOpInst<"vqdmlal_high", "wwkk", "si", OP_QDMLALHi>;
-def VQDMLAL_HIGH_N : SOpInst<"vqdmlal_high_n", "wwks", "si", OP_QDMLALHi_N>;
-def VQDMLSL_HIGH : SOpInst<"vqdmlsl_high", "wwkk", "si", OP_QDMLSLHi>;
-def VQDMLSL_HIGH_N : SOpInst<"vqdmlsl_high_n", "wwks", "si", OP_QDMLSLHi_N>;
-def VMULL_P64 : SInst<"vmull", "rss", "Pl">;
-def VMULL_HIGH_P64 : SOpInst<"vmull_high", "rdd", "HPl", OP_MULLHi_P64>;
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Extract or insert element from vector
-def GET_LANE : IInst<"vget_lane", "sdi", "dQdPlQPl">;
-def SET_LANE : IInst<"vset_lane", "dsdi", "dQdPlQPl">;
-def COPY_LANE : IOpInst<"vcopy_lane", "ddidi",
- "csilUcUsUiUlPcPsPlfd", OP_COPY_LN>;
-def COPYQ_LANE : IOpInst<"vcopy_lane", "ddigi",
- "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>;
-def COPY_LANEQ : IOpInst<"vcopy_laneq", "ddiki",
- "csilPcPsPlUcUsUiUlfd", OP_COPY_LN>;
-def COPYQ_LANEQ : IOpInst<"vcopy_laneq", "ddidi",
- "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Set all lanes to same value
-def VDUP_LANE1: WOpInst<"vdup_lane", "dgi", "hdQhQdPlQPl", OP_DUP_LN>;
-def VDUP_LANE2: WOpInst<"vdup_laneq", "dji",
- "csilUcUsUiUlPcPshfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
- OP_DUP_LN>;
-def DUP_N : WOpInst<"vdup_n", "ds", "dQdPlQPl", OP_DUP>;
-def MOV_N : WOpInst<"vmov_n", "ds", "dQdPlQPl", OP_DUP>;
-
-////////////////////////////////////////////////////////////////////////////////
-def COMBINE : NoTestOpInst<"vcombine", "kdd", "dPl", OP_CONC>;
-
-////////////////////////////////////////////////////////////////////////////////
-//Initialize a vector from bit pattern
-def CREATE : NoTestOpInst<"vcreate", "dl", "dPl", OP_CAST> {
- let BigEndianSafe = 1;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-def VMLA_LANEQ : IOpInst<"vmla_laneq", "dddji",
- "siUsUifQsQiQUsQUiQf", OP_MLA_LN>;
-def VMLS_LANEQ : IOpInst<"vmls_laneq", "dddji",
- "siUsUifQsQiQUsQUiQf", OP_MLS_LN>;
-
-def VFMA_LANE : IInst<"vfma_lane", "dddgi", "fdQfQd">;
-def VFMA_LANEQ : IInst<"vfma_laneq", "dddji", "fdQfQd"> {
- let isLaneQ = 1;
-}
-def VFMS_LANE : IOpInst<"vfms_lane", "dddgi", "fdQfQd", OP_FMS_LN>;
-def VFMS_LANEQ : IOpInst<"vfms_laneq", "dddji", "fdQfQd", OP_FMS_LNQ>;
-
-def VMLAL_LANEQ : SOpInst<"vmlal_laneq", "wwdki", "siUsUi", OP_MLAL_LN>;
-def VMLAL_HIGH_LANE : SOpInst<"vmlal_high_lane", "wwkdi", "siUsUi",
- OP_MLALHi_LN>;
-def VMLAL_HIGH_LANEQ : SOpInst<"vmlal_high_laneq", "wwkki", "siUsUi",
- OP_MLALHi_LN>;
-def VMLSL_LANEQ : SOpInst<"vmlsl_laneq", "wwdki", "siUsUi", OP_MLSL_LN>;
-def VMLSL_HIGH_LANE : SOpInst<"vmlsl_high_lane", "wwkdi", "siUsUi",
- OP_MLSLHi_LN>;
-def VMLSL_HIGH_LANEQ : SOpInst<"vmlsl_high_laneq", "wwkki", "siUsUi",
- OP_MLSLHi_LN>;
-
-def VQDMLAL_LANEQ : SOpInst<"vqdmlal_laneq", "wwdki", "si", OP_QDMLAL_LN>;
-def VQDMLAL_HIGH_LANE : SOpInst<"vqdmlal_high_lane", "wwkdi", "si",
- OP_QDMLALHi_LN>;
-def VQDMLAL_HIGH_LANEQ : SOpInst<"vqdmlal_high_laneq", "wwkki", "si",
- OP_QDMLALHi_LN>;
-def VQDMLSL_LANEQ : SOpInst<"vqdmlsl_laneq", "wwdki", "si", OP_QDMLSL_LN>;
-def VQDMLSL_HIGH_LANE : SOpInst<"vqdmlsl_high_lane", "wwkdi", "si",
- OP_QDMLSLHi_LN>;
-def VQDMLSL_HIGH_LANEQ : SOpInst<"vqdmlsl_high_laneq", "wwkki", "si",
- OP_QDMLSLHi_LN>;
-
-// Newly add double parameter for vmul_lane in aarch64
-// Note: d type is handled by SCALAR_VMUL_LANE
-def VMUL_LANE_A64 : IOpInst<"vmul_lane", "ddgi", "Qd", OP_MUL_LN>;
-
-// Note: d type is handled by SCALAR_VMUL_LANEQ
-def VMUL_LANEQ : IOpInst<"vmul_laneq", "ddji",
- "sifUsUiQsQiQUsQUiQfQd", OP_MUL_LN>;
-def VMULL_LANEQ : SOpInst<"vmull_laneq", "wdki", "siUsUi", OP_MULL_LN>;
-def VMULL_HIGH_LANE : SOpInst<"vmull_high_lane", "wkdi", "siUsUi",
- OP_MULLHi_LN>;
-def VMULL_HIGH_LANEQ : SOpInst<"vmull_high_laneq", "wkki", "siUsUi",
- OP_MULLHi_LN>;
-
-def VQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "wdki", "si", OP_QDMULL_LN>;
-def VQDMULL_HIGH_LANE : SOpInst<"vqdmull_high_lane", "wkdi", "si",
- OP_QDMULLHi_LN>;
-def VQDMULL_HIGH_LANEQ : SOpInst<"vqdmull_high_laneq", "wkki", "si",
- OP_QDMULLHi_LN>;
-
-def VQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ddji", "siQsQi", OP_QDMULH_LN>;
-def VQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ddji", "siQsQi", OP_QRDMULH_LN>;
-
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in {
-def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "dddji", "siQsQi", OP_QRDMLAH_LN>;
-def VQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "dddji", "siQsQi", OP_QRDMLSH_LN>;
-}
-
-// Note: d type implemented by SCALAR_VMULX_LANE
-def VMULX_LANE : IOpInst<"vmulx_lane", "ddgi", "fQfQd", OP_MULX_LN>;
-// Note: d type is implemented by SCALAR_VMULX_LANEQ
-def VMULX_LANEQ : IOpInst<"vmulx_laneq", "ddji", "fQfQd", OP_MULX_LN>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Across vectors class
-def VADDLV : SInst<"vaddlv", "rd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-def VMAXV : SInst<"vmaxv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQd">;
-def VMINV : SInst<"vminv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQd">;
-def VADDV : SInst<"vaddv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQdQlQUl">;
-def FMAXNMV : SInst<"vmaxnmv", "sd", "fQfQd">;
-def FMINNMV : SInst<"vminnmv", "sd", "fQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Newly added Vector Extract for f64
-def VEXT_A64 : WInst<"vext", "dddi", "dQdPlQPl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Crypto
-let ArchGuard = "__ARM_FEATURE_CRYPTO" in {
-def AESE : SInst<"vaese", "ddd", "QUc">;
-def AESD : SInst<"vaesd", "ddd", "QUc">;
-def AESMC : SInst<"vaesmc", "dd", "QUc">;
-def AESIMC : SInst<"vaesimc", "dd", "QUc">;
-
-def SHA1H : SInst<"vsha1h", "ss", "Ui">;
-def SHA1SU1 : SInst<"vsha1su1", "ddd", "QUi">;
-def SHA256SU0 : SInst<"vsha256su0", "ddd", "QUi">;
-
-def SHA1C : SInst<"vsha1c", "ddsd", "QUi">;
-def SHA1P : SInst<"vsha1p", "ddsd", "QUi">;
-def SHA1M : SInst<"vsha1m", "ddsd", "QUi">;
-def SHA1SU0 : SInst<"vsha1su0", "dddd", "QUi">;
-def SHA256H : SInst<"vsha256h", "dddd", "QUi">;
-def SHA256H2 : SInst<"vsha256h2", "dddd", "QUi">;
-def SHA256SU1 : SInst<"vsha256su1", "dddd", "QUi">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Float -> Int conversions with explicit rounding mode
-
-let ArchGuard = "__ARM_ARCH >= 8" in {
-def FCVTNS_S32 : SInst<"vcvtn_s32", "xd", "fQf">;
-def FCVTNU_S32 : SInst<"vcvtn_u32", "ud", "fQf">;
-def FCVTPS_S32 : SInst<"vcvtp_s32", "xd", "fQf">;
-def FCVTPU_S32 : SInst<"vcvtp_u32", "ud", "fQf">;
-def FCVTMS_S32 : SInst<"vcvtm_s32", "xd", "fQf">;
-def FCVTMU_S32 : SInst<"vcvtm_u32", "ud", "fQf">;
-def FCVTAS_S32 : SInst<"vcvta_s32", "xd", "fQf">;
-def FCVTAU_S32 : SInst<"vcvta_u32", "ud", "fQf">;
-}
-
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)" in {
-def FCVTNS_S64 : SInst<"vcvtn_s64", "xd", "dQd">;
-def FCVTNU_S64 : SInst<"vcvtn_u64", "ud", "dQd">;
-def FCVTPS_S64 : SInst<"vcvtp_s64", "xd", "dQd">;
-def FCVTPU_S64 : SInst<"vcvtp_u64", "ud", "dQd">;
-def FCVTMS_S64 : SInst<"vcvtm_s64", "xd", "dQd">;
-def FCVTMU_S64 : SInst<"vcvtm_u64", "ud", "dQd">;
-def FCVTAS_S64 : SInst<"vcvta_s64", "xd", "dQd">;
-def FCVTAU_S64 : SInst<"vcvta_u64", "ud", "dQd">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Round to Integral
-
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in {
-def FRINTN_S32 : SInst<"vrndn", "dd", "fQf">;
-def FRINTA_S32 : SInst<"vrnda", "dd", "fQf">;
-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">;
-}
-
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in {
-def FRINTN_S64 : SInst<"vrndn", "dd", "dQd">;
-def FRINTA_S64 : SInst<"vrnda", "dd", "dQd">;
-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">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// MaxNum/MinNum Floating Point
-
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN)" in {
-def FMAXNM_S32 : SInst<"vmaxnm", "ddd", "fQf">;
-def FMINNM_S32 : SInst<"vminnm", "ddd", "fQf">;
-}
-
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_NUMERIC_MAXMIN)" in {
-def FMAXNM_S64 : SInst<"vmaxnm", "ddd", "dQd">;
-def FMINNM_S64 : SInst<"vminnm", "ddd", "dQd">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Permutation
-def VTRN1 : SOpInst<"vtrn1", "ddd",
- "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_TRN1>;
-def VZIP1 : SOpInst<"vzip1", "ddd",
- "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_ZIP1>;
-def VUZP1 : SOpInst<"vuzp1", "ddd",
- "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_UZP1>;
-def VTRN2 : SOpInst<"vtrn2", "ddd",
- "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_TRN2>;
-def VZIP2 : SOpInst<"vzip2", "ddd",
- "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_ZIP2>;
-def VUZP2 : SOpInst<"vuzp2", "ddd",
- "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_UZP2>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Table lookup
-let InstName = "vtbl" in {
-def VQTBL1_A64 : WInst<"vqtbl1", "djt", "UccPcQUcQcQPc">;
-def VQTBL2_A64 : WInst<"vqtbl2", "dBt", "UccPcQUcQcQPc">;
-def VQTBL3_A64 : WInst<"vqtbl3", "dCt", "UccPcQUcQcQPc">;
-def VQTBL4_A64 : WInst<"vqtbl4", "dDt", "UccPcQUcQcQPc">;
-}
-let InstName = "vtbx" in {
-def VQTBX1_A64 : WInst<"vqtbx1", "ddjt", "UccPcQUcQcQPc">;
-def VQTBX2_A64 : WInst<"vqtbx2", "ddBt", "UccPcQUcQcQPc">;
-def VQTBX3_A64 : WInst<"vqtbx3", "ddCt", "UccPcQUcQcQPc">;
-def VQTBX4_A64 : WInst<"vqtbx4", "ddDt", "UccPcQUcQcQPc">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Vector reinterpret cast operations
-
-// NeonEmitter implicitly takes the cartesian product of the type string with
-// itself during generation so, unlike all other intrinsics, this one should
-// include *all* types, not just additional ones.
-def VVREINTERPRET
- : NoTestOpInst<"vreinterpret", "dd",
- "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", OP_REINT> {
- let CartesianProductOfTypes = 1;
- let BigEndianSafe = 1;
- let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)";
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Intrinsics
-// Scalar Arithmetic
-
-// Scalar Addition
-def SCALAR_ADD : SInst<"vadd", "sss", "SlSUl">;
-// Scalar Saturating Add
-def SCALAR_QADD : SInst<"vqadd", "sss", "ScSsSiSlSUcSUsSUiSUl">;
-
-// Scalar Subtraction
-def SCALAR_SUB : SInst<"vsub", "sss", "SlSUl">;
-// Scalar Saturating Sub
-def SCALAR_QSUB : SInst<"vqsub", "sss", "ScSsSiSlSUcSUsSUiSUl">;
-
-let InstName = "vmov" in {
-def VGET_HIGH_A64 : NoTestOpInst<"vget_high", "dk", "dPl", OP_HI>;
-def VGET_LOW_A64 : NoTestOpInst<"vget_low", "dk", "dPl", OP_LO>;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Shift
-// Scalar Shift Left
-def SCALAR_SHL: SInst<"vshl", "sss", "SlSUl">;
-// Scalar Saturating Shift Left
-def SCALAR_QSHL: SInst<"vqshl", "sss", "ScSsSiSlSUcSUsSUiSUl">;
-// Scalar Saturating Rounding Shift Left
-def SCALAR_QRSHL: SInst<"vqrshl", "sss", "ScSsSiSlSUcSUsSUiSUl">;
-// Scalar Shift Rouding Left
-def SCALAR_RSHL: SInst<"vrshl", "sss", "SlSUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Shift (Immediate)
-let isScalarShift = 1 in {
-// Signed/Unsigned Shift Right (Immediate)
-def SCALAR_SSHR_N: SInst<"vshr_n", "ssi", "SlSUl">;
-// Signed/Unsigned Rounding Shift Right (Immediate)
-def SCALAR_SRSHR_N: SInst<"vrshr_n", "ssi", "SlSUl">;
-
-// Signed/Unsigned Shift Right and Accumulate (Immediate)
-def SCALAR_SSRA_N: SInst<"vsra_n", "sssi", "SlSUl">;
-// Signed/Unsigned Rounding Shift Right and Accumulate (Immediate)
-def SCALAR_SRSRA_N: SInst<"vrsra_n", "sssi", "SlSUl">;
-
-// Shift Left (Immediate)
-def SCALAR_SHL_N: SInst<"vshl_n", "ssi", "SlSUl">;
-// Signed/Unsigned Saturating Shift Left (Immediate)
-def SCALAR_SQSHL_N: SInst<"vqshl_n", "ssi", "ScSsSiSlSUcSUsSUiSUl">;
-// Signed Saturating Shift Left Unsigned (Immediate)
-def SCALAR_SQSHLU_N: SInst<"vqshlu_n", "ssi", "ScSsSiSl">;
-
-// Shift Right And Insert (Immediate)
-def SCALAR_SRI_N: SInst<"vsri_n", "sssi", "SlSUl">;
-// Shift Left And Insert (Immediate)
-def SCALAR_SLI_N: SInst<"vsli_n", "sssi", "SlSUl">;
-
-let isScalarNarrowShift = 1 in {
- // Signed/Unsigned Saturating Shift Right Narrow (Immediate)
- def SCALAR_SQSHRN_N: SInst<"vqshrn_n", "zsi", "SsSiSlSUsSUiSUl">;
- // Signed/Unsigned Saturating Rounded Shift Right Narrow (Immediate)
- def SCALAR_SQRSHRN_N: SInst<"vqrshrn_n", "zsi", "SsSiSlSUsSUiSUl">;
- // Signed Saturating Shift Right Unsigned Narrow (Immediate)
- def SCALAR_SQSHRUN_N: SInst<"vqshrun_n", "zsi", "SsSiSl">;
- // Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate)
- def SCALAR_SQRSHRUN_N: SInst<"vqrshrun_n", "zsi", "SsSiSl">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Signed/Unsigned Fixed-point Convert To Floating-Point (Immediate)
-def SCALAR_SCVTF_N_F32: SInst<"vcvt_n_f32", "ysi", "SiSUi">;
-def SCALAR_SCVTF_N_F64: SInst<"vcvt_n_f64", "osi", "SlSUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Convert To Signed/Unsigned Fixed-point (Immediate)
-def SCALAR_FCVTZS_N_S32 : SInst<"vcvt_n_s32", "$si", "Sf">;
-def SCALAR_FCVTZU_N_U32 : SInst<"vcvt_n_u32", "bsi", "Sf">;
-def SCALAR_FCVTZS_N_S64 : SInst<"vcvt_n_s64", "$si", "Sd">;
-def SCALAR_FCVTZU_N_U64 : SInst<"vcvt_n_u64", "bsi", "Sd">;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Reduce Pairwise Addition (Scalar and Floating Point)
-def SCALAR_ADDP : SInst<"vpadd", "sd", "SfSHlSHdSHUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Reduce Floating Point Pairwise Max/Min
-def SCALAR_FMAXP : SInst<"vpmax", "sd", "SfSQd">;
-
-def SCALAR_FMINP : SInst<"vpmin", "sd", "SfSQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Reduce Floating Point Pairwise maxNum/minNum
-def SCALAR_FMAXNMP : SInst<"vpmaxnm", "sd", "SfSQd">;
-def SCALAR_FMINNMP : SInst<"vpminnm", "sd", "SfSQd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Integer Saturating Doubling Multiply Half High
-def SCALAR_SQDMULH : SInst<"vqdmulh", "sss", "SsSi">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Integer Saturating Rounding Doubling Multiply Half High
-def SCALAR_SQRDMULH : SInst<"vqrdmulh", "sss", "SsSi">;
-
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in {
-////////////////////////////////////////////////////////////////////////////////
-// Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half
-def SCALAR_SQRDMLAH : SOpInst<"vqrdmlah", "ssss", "SsSi", OP_QRDMLAH>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Signed Saturating Rounding Doubling Multiply Subtract Returning High Half
-def SCALAR_SQRDMLSH : SOpInst<"vqrdmlsh", "ssss", "SsSi", OP_QRDMLSH>;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Multiply Extended
-def SCALAR_FMULX : IInst<"vmulx", "sss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Reciprocal Step
-def SCALAR_FRECPS : IInst<"vrecps", "sss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Reciprocal Square Root Step
-def SCALAR_FRSQRTS : IInst<"vrsqrts", "sss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Signed Integer Convert To Floating-point
-def SCALAR_SCVTFS : SInst<"vcvt_f32", "ys", "Si">;
-def SCALAR_SCVTFD : SInst<"vcvt_f64", "os", "Sl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Unsigned Integer Convert To Floating-point
-def SCALAR_UCVTFS : SInst<"vcvt_f32", "ys", "SUi">;
-def SCALAR_UCVTFD : SInst<"vcvt_f64", "os", "SUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Converts
-def SCALAR_FCVTXN : IInst<"vcvtx_f32", "ys", "Sd">;
-def SCALAR_FCVTNSS : SInst<"vcvtn_s32", "$s", "Sf">;
-def SCALAR_FCVTNUS : SInst<"vcvtn_u32", "bs", "Sf">;
-def SCALAR_FCVTNSD : SInst<"vcvtn_s64", "$s", "Sd">;
-def SCALAR_FCVTNUD : SInst<"vcvtn_u64", "bs", "Sd">;
-def SCALAR_FCVTMSS : SInst<"vcvtm_s32", "$s", "Sf">;
-def SCALAR_FCVTMUS : SInst<"vcvtm_u32", "bs", "Sf">;
-def SCALAR_FCVTMSD : SInst<"vcvtm_s64", "$s", "Sd">;
-def SCALAR_FCVTMUD : SInst<"vcvtm_u64", "bs", "Sd">;
-def SCALAR_FCVTASS : SInst<"vcvta_s32", "$s", "Sf">;
-def SCALAR_FCVTAUS : SInst<"vcvta_u32", "bs", "Sf">;
-def SCALAR_FCVTASD : SInst<"vcvta_s64", "$s", "Sd">;
-def SCALAR_FCVTAUD : SInst<"vcvta_u64", "bs", "Sd">;
-def SCALAR_FCVTPSS : SInst<"vcvtp_s32", "$s", "Sf">;
-def SCALAR_FCVTPUS : SInst<"vcvtp_u32", "bs", "Sf">;
-def SCALAR_FCVTPSD : SInst<"vcvtp_s64", "$s", "Sd">;
-def SCALAR_FCVTPUD : SInst<"vcvtp_u64", "bs", "Sd">;
-def SCALAR_FCVTZSS : SInst<"vcvt_s32", "$s", "Sf">;
-def SCALAR_FCVTZUS : SInst<"vcvt_u32", "bs", "Sf">;
-def SCALAR_FCVTZSD : SInst<"vcvt_s64", "$s", "Sd">;
-def SCALAR_FCVTZUD : SInst<"vcvt_u64", "bs", "Sd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Reciprocal Estimate
-def SCALAR_FRECPE : IInst<"vrecpe", "ss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Reciprocal Exponent
-def SCALAR_FRECPX : IInst<"vrecpx", "ss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Reciprocal Square Root Estimate
-def SCALAR_FRSQRTE : IInst<"vrsqrte", "ss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Integer Comparison
-def SCALAR_CMEQ : SInst<"vceq", "sss", "SlSUl">;
-def SCALAR_CMEQZ : SInst<"vceqz", "ss", "SlSUl">;
-def SCALAR_CMGE : SInst<"vcge", "sss", "Sl">;
-def SCALAR_CMGEZ : SInst<"vcgez", "ss", "Sl">;
-def SCALAR_CMHS : SInst<"vcge", "sss", "SUl">;
-def SCALAR_CMLE : SInst<"vcle", "sss", "SlSUl">;
-def SCALAR_CMLEZ : SInst<"vclez", "ss", "Sl">;
-def SCALAR_CMLT : SInst<"vclt", "sss", "SlSUl">;
-def SCALAR_CMLTZ : SInst<"vcltz", "ss", "Sl">;
-def SCALAR_CMGT : SInst<"vcgt", "sss", "Sl">;
-def SCALAR_CMGTZ : SInst<"vcgtz", "ss", "Sl">;
-def SCALAR_CMHI : SInst<"vcgt", "sss", "SUl">;
-def SCALAR_CMTST : SInst<"vtst", "sss", "SlSUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Comparison
-def SCALAR_FCMEQ : IInst<"vceq", "bss", "SfSd">;
-def SCALAR_FCMEQZ : IInst<"vceqz", "bs", "SfSd">;
-def SCALAR_FCMGE : IInst<"vcge", "bss", "SfSd">;
-def SCALAR_FCMGEZ : IInst<"vcgez", "bs", "SfSd">;
-def SCALAR_FCMGT : IInst<"vcgt", "bss", "SfSd">;
-def SCALAR_FCMGTZ : IInst<"vcgtz", "bs", "SfSd">;
-def SCALAR_FCMLE : IInst<"vcle", "bss", "SfSd">;
-def SCALAR_FCMLEZ : IInst<"vclez", "bs", "SfSd">;
-def SCALAR_FCMLT : IInst<"vclt", "bss", "SfSd">;
-def SCALAR_FCMLTZ : IInst<"vcltz", "bs", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Absolute Compare Mask Greater Than Or Equal
-def SCALAR_FACGE : IInst<"vcage", "bss", "SfSd">;
-def SCALAR_FACLE : IInst<"vcale", "bss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Floating-point Absolute Compare Mask Greater Than
-def SCALAR_FACGT : IInst<"vcagt", "bss", "SfSd">;
-def SCALAR_FACLT : IInst<"vcalt", "bss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Absolute Value
-def SCALAR_ABS : SInst<"vabs", "ss", "Sl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Absolute Difference
-def SCALAR_ABD : IInst<"vabd", "sss", "SfSd">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Signed Saturating Absolute Value
-def SCALAR_SQABS : SInst<"vqabs", "ss", "ScSsSiSl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Negate
-def SCALAR_NEG : SInst<"vneg", "ss", "Sl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Signed Saturating Negate
-def SCALAR_SQNEG : SInst<"vqneg", "ss", "ScSsSiSl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Signed Saturating Accumulated of Unsigned Value
-def SCALAR_SUQADD : SInst<"vuqadd", "sss", "ScSsSiSl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Unsigned Saturating Accumulated of Signed Value
-def SCALAR_USQADD : SInst<"vsqadd", "sss", "SUcSUsSUiSUl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Signed Saturating Doubling Multiply-Add Long
-def SCALAR_SQDMLAL : SInst<"vqdmlal", "rrss", "SsSi">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Signed Saturating Doubling Multiply-Subtract Long
-def SCALAR_SQDMLSL : SInst<"vqdmlsl", "rrss", "SsSi">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Signed Saturating Doubling Multiply Long
-def SCALAR_SQDMULL : SInst<"vqdmull", "rss", "SsSi">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Signed Saturating Extract Unsigned Narrow
-def SCALAR_SQXTUN : SInst<"vqmovun", "zs", "SsSiSl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Signed Saturating Extract Narrow
-def SCALAR_SQXTN : SInst<"vqmovn", "zs", "SsSiSl">;
-
-////////////////////////////////////////////////////////////////////////////////
-// Scalar Unsigned Saturating Extract Narrow
-def SCALAR_UQXTN : SInst<"vqmovn", "zs", "SUsSUiSUl">;
-
-// Scalar Floating Point multiply (scalar, by element)
-def SCALAR_FMUL_LANE : IOpInst<"vmul_lane", "ssdi", "SfSd", OP_SCALAR_MUL_LN>;
-def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "ssji", "SfSd", OP_SCALAR_MUL_LN>;
-
-// Scalar Floating Point multiply extended (scalar, by element)
-def SCALAR_FMULX_LANE : IOpInst<"vmulx_lane", "ssdi", "SfSd", OP_SCALAR_MULX_LN>;
-def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "ssji", "SfSd", OP_SCALAR_MULX_LN>;
-
-def SCALAR_VMUL_N : IInst<"vmul_n", "dds", "d">;
-
-// VMUL_LANE_A64 d type implemented using scalar mul lane
-def SCALAR_VMUL_LANE : IInst<"vmul_lane", "ddgi", "d">;
-
-// VMUL_LANEQ d type implemented using scalar mul lane
-def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "ddji", "d"> {
- let isLaneQ = 1;
-}
-
-// VMULX_LANE d type implemented using scalar vmulx_lane
-def SCALAR_VMULX_LANE : IOpInst<"vmulx_lane", "ddgi", "d", OP_SCALAR_VMULX_LN>;
-
-// VMULX_LANEQ d type implemented using scalar vmulx_laneq
-def SCALAR_VMULX_LANEQ : IOpInst<"vmulx_laneq", "ddji", "d", OP_SCALAR_VMULX_LNQ>;
-
-// Scalar Floating Point fused multiply-add (scalar, by element)
-def SCALAR_FMLA_LANE : IInst<"vfma_lane", "sssdi", "SfSd">;
-def SCALAR_FMLA_LANEQ : IInst<"vfma_laneq", "sssji", "SfSd">;
-
-// Scalar Floating Point fused multiply-subtract (scalar, by element)
-def SCALAR_FMLS_LANE : IOpInst<"vfms_lane", "sssdi", "SfSd", OP_FMS_LN>;
-def SCALAR_FMLS_LANEQ : IOpInst<"vfms_laneq", "sssji", "SfSd", OP_FMS_LNQ>;
-
-// Signed Saturating Doubling Multiply Long (scalar by element)
-def SCALAR_SQDMULL_LANE : SOpInst<"vqdmull_lane", "rsdi", "SsSi", OP_SCALAR_QDMULL_LN>;
-def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "rsji", "SsSi", OP_SCALAR_QDMULL_LN>;
-
-// Signed Saturating Doubling Multiply-Add Long (scalar by element)
-def SCALAR_SQDMLAL_LANE : SInst<"vqdmlal_lane", "rrsdi", "SsSi">;
-def SCALAR_SQDMLAL_LANEQ : SInst<"vqdmlal_laneq", "rrsji", "SsSi">;
-
-// Signed Saturating Doubling Multiply-Subtract Long (scalar by element)
-def SCALAR_SQDMLS_LANE : SInst<"vqdmlsl_lane", "rrsdi", "SsSi">;
-def SCALAR_SQDMLS_LANEQ : SInst<"vqdmlsl_laneq", "rrsji", "SsSi">;
-
-// Scalar Integer Saturating Doubling Multiply Half High (scalar by element)
-def SCALAR_SQDMULH_LANE : SOpInst<"vqdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QDMULH_LN>;
-def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QDMULH_LN>;
-
-// Scalar Integer Saturating Rounding Doubling Multiply Half High
-def SCALAR_SQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QRDMULH_LN>;
-def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QRDMULH_LN>;
-
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in {
-// Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half
-def SCALAR_SQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "sssdi", "SsSi", OP_SCALAR_QRDMLAH_LN>;
-def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "sssji", "SsSi", OP_SCALAR_QRDMLAH_LN>;
-
-// Signed Saturating Rounding Doubling Multiply Subtract Returning High Half
-def SCALAR_SQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "sssdi", "SsSi", OP_SCALAR_QRDMLSH_LN>;
-def SCALAR_SQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "sssji", "SsSi", OP_SCALAR_QRDMLSH_LN>;
-}
-
-def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
-def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
-}
diff --git a/include/clang/CMakeLists.txt b/include/clang/CMakeLists.txt
deleted file mode 100644
index 1d8aecd..0000000
--- a/include/clang/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-add_subdirectory(AST)
-add_subdirectory(Basic)
-add_subdirectory(Driver)
-add_subdirectory(Parse)
-add_subdirectory(Sema)
-add_subdirectory(Serialization)
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
deleted file mode 100644
index ba5dc39..0000000
--- a/include/clang/CodeGen/BackendUtil.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- BackendUtil.h - LLVM Backend Utilities -----------------*- 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_CODEGEN_BACKENDUTIL_H
-#define LLVM_CLANG_CODEGEN_BACKENDUTIL_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/IR/FunctionInfo.h"
-#include <memory>
-
-namespace llvm {
- class Module;
-}
-
-namespace clang {
- class DiagnosticsEngine;
- class CodeGenOptions;
- class TargetOptions;
- class LangOptions;
-
- enum BackendAction {
- Backend_EmitAssembly, ///< Emit native assembly files
- Backend_EmitBC, ///< Emit LLVM bitcode files
- Backend_EmitLL, ///< Emit human-readable LLVM assembly
- Backend_EmitNothing, ///< Don't emit anything (benchmarking mode)
- Backend_EmitMCNull, ///< Run CodeGen, but don't emit anything
- Backend_EmitObj ///< Emit native object files
- };
-
- void
- EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
- const TargetOptions &TOpts, const LangOptions &LOpts,
- StringRef TDesc, llvm::Module *M, BackendAction Action,
- raw_pwrite_stream *OS,
- std::unique_ptr<llvm::FunctionInfoIndex> Index = nullptr);
-}
-
-#endif
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
deleted file mode 100644
index bb6ceb4..0000000
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ /dev/null
@@ -1,538 +0,0 @@
-//==-- CGFunctionInfo.h - Representation of function argument/return types -==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines CGFunctionInfo and associated types used in representing the
-// LLVM source types and ABI-coerced types for function arguments and
-// return values.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
-#define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
-
-#include "clang/AST/CanonicalType.h"
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/Type.h"
-#include "llvm/ADT/FoldingSet.h"
-#include <cassert>
-
-namespace llvm {
- class Type;
- class StructType;
-}
-
-namespace clang {
-class Decl;
-
-namespace CodeGen {
-
-/// ABIArgInfo - Helper class to encapsulate information about how a
-/// specific C type should be passed to or returned from a function.
-class ABIArgInfo {
-public:
- enum Kind : uint8_t {
- /// Direct - Pass the argument directly using the normal converted LLVM
- /// type, or by coercing to another specified type stored in
- /// 'CoerceToType'). If an offset is specified (in UIntData), then the
- /// argument passed is offset by some number of bytes in the memory
- /// representation. A dummy argument is emitted before the real argument
- /// if the specified type stored in "PaddingType" is not zero.
- Direct,
-
- /// Extend - Valid only for integer argument types. Same as 'direct'
- /// but also emit a zero/sign extension attribute.
- Extend,
-
- /// Indirect - Pass the argument indirectly via a hidden pointer
- /// with the specified alignment (0 indicates default alignment).
- Indirect,
-
- /// Ignore - Ignore the argument (treat as void). Useful for void and
- /// empty structs.
- Ignore,
-
- /// Expand - Only valid for aggregate argument types. The structure should
- /// be expanded into consecutive arguments for its constituent fields.
- /// Currently expand is only allowed on structures whose fields
- /// are all scalar types or are themselves expandable types.
- Expand,
-
- /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
- /// This is similar to indirect with byval, except it only applies to
- /// arguments stored in memory and forbids any implicit copies. When
- /// applied to a return type, it means the value is returned indirectly via
- /// an implicit sret parameter stored in the argument struct.
- InAlloca,
- KindFirst = Direct,
- KindLast = InAlloca
- };
-
-private:
- llvm::Type *TypeData; // isDirect() || isExtend()
- llvm::Type *PaddingType;
- union {
- unsigned DirectOffset; // isDirect() || isExtend()
- unsigned IndirectAlign; // isIndirect()
- unsigned AllocaFieldIndex; // isInAlloca()
- };
- Kind TheKind;
- bool PaddingInReg : 1;
- bool InAllocaSRet : 1; // isInAlloca()
- bool IndirectByVal : 1; // isIndirect()
- bool IndirectRealign : 1; // isIndirect()
- bool SRetAfterThis : 1; // isIndirect()
- bool InReg : 1; // isDirect() || isExtend() || isIndirect()
- bool CanBeFlattened: 1; // isDirect()
-
- ABIArgInfo(Kind K)
- : PaddingType(nullptr), TheKind(K), PaddingInReg(false), InReg(false) {}
-
-public:
- ABIArgInfo()
- : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
- TheKind(Direct), PaddingInReg(false), InReg(false) {}
-
- static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
- llvm::Type *Padding = nullptr,
- bool CanBeFlattened = true) {
- auto AI = ABIArgInfo(Direct);
- AI.setCoerceToType(T);
- AI.setDirectOffset(Offset);
- AI.setPaddingType(Padding);
- AI.setCanBeFlattened(CanBeFlattened);
- return AI;
- }
- static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
- auto AI = getDirect(T);
- AI.setInReg(true);
- return AI;
- }
- static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
- auto AI = ABIArgInfo(Extend);
- AI.setCoerceToType(T);
- AI.setDirectOffset(0);
- return AI;
- }
- static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
- auto AI = getExtend(T);
- AI.setInReg(true);
- return AI;
- }
- static ABIArgInfo getIgnore() {
- return ABIArgInfo(Ignore);
- }
- static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
- bool Realign = false,
- llvm::Type *Padding = nullptr) {
- auto AI = ABIArgInfo(Indirect);
- AI.setIndirectAlign(Alignment);
- AI.setIndirectByVal(ByVal);
- AI.setIndirectRealign(Realign);
- AI.setSRetAfterThis(false);
- AI.setPaddingType(Padding);
- return AI;
- }
- static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
- bool Realign = false) {
- auto AI = getIndirect(Alignment, ByVal, Realign);
- AI.setInReg(true);
- return AI;
- }
- static ABIArgInfo getInAlloca(unsigned FieldIndex) {
- auto AI = ABIArgInfo(InAlloca);
- AI.setInAllocaFieldIndex(FieldIndex);
- return AI;
- }
- static ABIArgInfo getExpand() {
- return ABIArgInfo(Expand);
- }
- static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
- llvm::Type *Padding) {
- auto AI = getExpand();
- AI.setPaddingInReg(PaddingInReg);
- AI.setPaddingType(Padding);
- return AI;
- }
-
- Kind getKind() const { return TheKind; }
- bool isDirect() const { return TheKind == Direct; }
- bool isInAlloca() const { return TheKind == InAlloca; }
- bool isExtend() const { return TheKind == Extend; }
- bool isIgnore() const { return TheKind == Ignore; }
- bool isIndirect() const { return TheKind == Indirect; }
- bool isExpand() const { return TheKind == Expand; }
-
- bool canHaveCoerceToType() const { return isDirect() || isExtend(); }
-
- // Direct/Extend accessors
- unsigned getDirectOffset() const {
- assert((isDirect() || isExtend()) && "Not a direct or extend kind");
- return DirectOffset;
- }
- void setDirectOffset(unsigned Offset) {
- assert((isDirect() || isExtend()) && "Not a direct or extend kind");
- DirectOffset = Offset;
- }
-
- llvm::Type *getPaddingType() const { return PaddingType; }
-
- void setPaddingType(llvm::Type *T) { PaddingType = T; }
-
- bool getPaddingInReg() const {
- return PaddingInReg;
- }
- void setPaddingInReg(bool PIR) {
- PaddingInReg = PIR;
- }
-
- llvm::Type *getCoerceToType() const {
- assert(canHaveCoerceToType() && "Invalid kind!");
- return TypeData;
- }
-
- void setCoerceToType(llvm::Type *T) {
- assert(canHaveCoerceToType() && "Invalid kind!");
- TypeData = T;
- }
-
- bool getInReg() const {
- assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
- return InReg;
- }
-
- void setInReg(bool IR) {
- assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
- InReg = IR;
- }
-
- // Indirect accessors
- CharUnits getIndirectAlign() const {
- assert(isIndirect() && "Invalid kind!");
- return CharUnits::fromQuantity(IndirectAlign);
- }
- void setIndirectAlign(CharUnits IA) {
- assert(isIndirect() && "Invalid kind!");
- IndirectAlign = IA.getQuantity();
- }
-
- bool getIndirectByVal() const {
- assert(isIndirect() && "Invalid kind!");
- return IndirectByVal;
- }
- void setIndirectByVal(bool IBV) {
- assert(isIndirect() && "Invalid kind!");
- IndirectByVal = IBV;
- }
-
- bool getIndirectRealign() const {
- assert(isIndirect() && "Invalid kind!");
- return IndirectRealign;
- }
- void setIndirectRealign(bool IR) {
- assert(isIndirect() && "Invalid kind!");
- IndirectRealign = IR;
- }
-
- bool isSRetAfterThis() const {
- assert(isIndirect() && "Invalid kind!");
- return SRetAfterThis;
- }
- void setSRetAfterThis(bool AfterThis) {
- assert(isIndirect() && "Invalid kind!");
- SRetAfterThis = AfterThis;
- }
-
- unsigned getInAllocaFieldIndex() const {
- assert(isInAlloca() && "Invalid kind!");
- return AllocaFieldIndex;
- }
- void setInAllocaFieldIndex(unsigned FieldIndex) {
- assert(isInAlloca() && "Invalid kind!");
- AllocaFieldIndex = FieldIndex;
- }
-
- /// \brief 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!");
- return InAllocaSRet;
- }
-
- void setInAllocaSRet(bool SRet) {
- assert(isInAlloca() && "Invalid kind!");
- InAllocaSRet = SRet;
- }
-
- bool getCanBeFlattened() const {
- assert(isDirect() && "Invalid kind!");
- return CanBeFlattened;
- }
-
- void setCanBeFlattened(bool Flatten) {
- assert(isDirect() && "Invalid kind!");
- CanBeFlattened = Flatten;
- }
-
- void dump() const;
-};
-
-/// A class for recording the number of arguments that a function
-/// signature requires.
-class RequiredArgs {
- /// The number of required arguments, or ~0 if the signature does
- /// not permit optional arguments.
- unsigned NumRequired;
-public:
- enum All_t { All };
-
- RequiredArgs(All_t _) : NumRequired(~0U) {}
- explicit RequiredArgs(unsigned n) : NumRequired(n) {
- assert(n != ~0U);
- }
-
- /// Compute the arguments required by the given formal prototype,
- /// given that there may be some additional, non-formal arguments
- /// in play.
- static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
- unsigned additional) {
- if (!prototype->isVariadic()) return All;
- return RequiredArgs(prototype->getNumParams() + additional);
- }
-
- static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
- return forPrototypePlus(prototype, 0);
- }
-
- static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
- return forPrototype(prototype.getTypePtr());
- }
-
- static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
- unsigned additional) {
- return forPrototypePlus(prototype.getTypePtr(), additional);
- }
-
- bool allowsOptionalArgs() const { return NumRequired != ~0U; }
- unsigned getNumRequiredArgs() const {
- assert(allowsOptionalArgs());
- return NumRequired;
- }
-
- unsigned getOpaqueData() const { return NumRequired; }
- static RequiredArgs getFromOpaqueData(unsigned value) {
- if (value == ~0U) return All;
- return RequiredArgs(value);
- }
-};
-
-/// CGFunctionInfo - Class to encapsulate the information about a
-/// function definition.
-class CGFunctionInfo : public llvm::FoldingSetNode {
- struct ArgInfo {
- CanQualType type;
- ABIArgInfo info;
- };
-
- /// The LLVM::CallingConv to use for this function (as specified by the
- /// user).
- unsigned CallingConvention : 8;
-
- /// The LLVM::CallingConv to actually use for this function, which may
- /// depend on the ABI.
- unsigned EffectiveCallingConvention : 8;
-
- /// The clang::CallingConv that this was originally created with.
- unsigned ASTCallingConvention : 8;
-
- /// Whether this is an instance method.
- unsigned InstanceMethod : 1;
-
- /// Whether this is a chain call.
- unsigned ChainCall : 1;
-
- /// Whether this function is noreturn.
- unsigned NoReturn : 1;
-
- /// Whether this function is returns-retained.
- unsigned ReturnsRetained : 1;
-
- /// How many arguments to pass inreg.
- unsigned HasRegParm : 1;
- unsigned RegParm : 3;
-
- RequiredArgs Required;
-
- /// The struct representing all arguments passed in memory. Only used when
- /// passing non-trivial types with inalloca. Not part of the profile.
- llvm::StructType *ArgStruct;
- unsigned ArgStructAlign;
-
- unsigned NumArgs;
- ArgInfo *getArgsBuffer() {
- return reinterpret_cast<ArgInfo*>(this+1);
- }
- const ArgInfo *getArgsBuffer() const {
- return reinterpret_cast<const ArgInfo*>(this + 1);
- }
-
- CGFunctionInfo() : Required(RequiredArgs::All) {}
-
-public:
- static CGFunctionInfo *create(unsigned llvmCC,
- bool instanceMethod,
- bool chainCall,
- const FunctionType::ExtInfo &extInfo,
- CanQualType resultType,
- ArrayRef<CanQualType> argTypes,
- RequiredArgs required);
-
- typedef const ArgInfo *const_arg_iterator;
- typedef ArgInfo *arg_iterator;
-
- typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
-
- arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
- }
-
- const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
- const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
- arg_iterator arg_begin() { return getArgsBuffer() + 1; }
- arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
-
- unsigned arg_size() const { return NumArgs; }
-
- bool isVariadic() const { return Required.allowsOptionalArgs(); }
- RequiredArgs getRequiredArgs() const { return Required; }
- unsigned getNumRequiredArgs() const {
- return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size();
- }
-
- bool isInstanceMethod() const { return InstanceMethod; }
-
- bool isChainCall() const { return ChainCall; }
-
- bool isNoReturn() const { return NoReturn; }
-
- /// In ARC, whether this function retains its return value. This
- /// is not always reliable for call sites.
- bool isReturnsRetained() const { return ReturnsRetained; }
-
- /// getASTCallingConvention() - Return the AST-specified calling
- /// convention.
- CallingConv getASTCallingConvention() const {
- return CallingConv(ASTCallingConvention);
- }
-
- /// getCallingConvention - Return the user specified calling
- /// convention, which has been translated into an LLVM CC.
- unsigned getCallingConvention() const { return CallingConvention; }
-
- /// getEffectiveCallingConvention - Return the actual calling convention to
- /// use, which may depend on the ABI.
- unsigned getEffectiveCallingConvention() const {
- return EffectiveCallingConvention;
- }
- void setEffectiveCallingConvention(unsigned Value) {
- EffectiveCallingConvention = Value;
- }
-
- bool getHasRegParm() const { return HasRegParm; }
- unsigned getRegParm() const { return RegParm; }
-
- FunctionType::ExtInfo getExtInfo() const {
- return FunctionType::ExtInfo(isNoReturn(),
- getHasRegParm(), getRegParm(),
- getASTCallingConvention(),
- isReturnsRetained());
- }
-
- CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
-
- ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
- const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
-
- /// \brief 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.
- llvm::StructType *getArgStruct() const { return ArgStruct; }
- CharUnits getArgStructAlignment() const {
- return CharUnits::fromQuantity(ArgStructAlign);
- }
- void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
- ArgStruct = Ty;
- ArgStructAlign = Align.getQuantity();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- ID.AddInteger(getASTCallingConvention());
- ID.AddBoolean(InstanceMethod);
- ID.AddBoolean(ChainCall);
- ID.AddBoolean(NoReturn);
- ID.AddBoolean(ReturnsRetained);
- ID.AddBoolean(HasRegParm);
- ID.AddInteger(RegParm);
- ID.AddInteger(Required.getOpaqueData());
- getReturnType().Profile(ID);
- for (const auto &I : arguments())
- I.type.Profile(ID);
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- bool InstanceMethod,
- bool ChainCall,
- const FunctionType::ExtInfo &info,
- RequiredArgs required,
- CanQualType resultType,
- ArrayRef<CanQualType> argTypes) {
- ID.AddInteger(info.getCC());
- ID.AddBoolean(InstanceMethod);
- ID.AddBoolean(ChainCall);
- ID.AddBoolean(info.getNoReturn());
- ID.AddBoolean(info.getProducesResult());
- ID.AddBoolean(info.getHasRegParm());
- ID.AddInteger(info.getRegParm());
- ID.AddInteger(required.getOpaqueData());
- resultType.Profile(ID);
- for (ArrayRef<CanQualType>::iterator
- i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
- i->Profile(ID);
- }
- }
-};
-
-/// CGCalleeInfo - Class to encapsulate the information about a callee to be
-/// used during the generation of call/invoke instructions.
-class CGCalleeInfo {
- /// \brief The function proto type of the callee.
- const FunctionProtoType *CalleeProtoTy;
- /// \brief The function declaration of the callee.
- const Decl *CalleeDecl;
-
-public:
- explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl(nullptr) {}
- CGCalleeInfo(const FunctionProtoType *calleeProtoTy, const Decl *calleeDecl)
- : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
- CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
- : CalleeProtoTy(calleeProtoTy), CalleeDecl(nullptr) {}
- CGCalleeInfo(const Decl *calleeDecl)
- : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}
-
- const FunctionProtoType *getCalleeFunctionProtoType() {
- return CalleeProtoTy;
- }
- const Decl *getCalleeDecl() { return CalleeDecl; }
-};
-
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h
deleted file mode 100644
index 9d9504a..0000000
--- a/include/clang/CodeGen/CodeGenABITypes.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//==---- CodeGenABITypes.h - Convert Clang types to LLVM types for ABI -----==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// CodeGenABITypes is a simple interface for getting LLVM types for
-// the parameters and the return value of a function given the Clang
-// types.
-//
-// The class is implemented as a public wrapper around the private
-// CodeGenTypes class in lib/CodeGen.
-//
-// It allows other clients, like LLDB, to determine the LLVM types that are
-// actually used in function calls, which makes it possible to then determine
-// the acutal ABI locations (e.g. registers, stack locations, etc.) that
-// these parameters are stored in.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_CODEGEN_CODEGENABITYPES_H
-#define LLVM_CLANG_CODEGEN_CODEGENABITYPES_H
-
-#include "clang/AST/CanonicalType.h"
-#include "clang/AST/Type.h"
-#include "clang/CodeGen/CGFunctionInfo.h"
-
-namespace llvm {
- class DataLayout;
- class Module;
-}
-
-namespace clang {
-class ASTContext;
-class CXXRecordDecl;
-class CXXMethodDecl;
-class CodeGenOptions;
-class CoverageSourceInfo;
-class DiagnosticsEngine;
-class HeaderSearchOptions;
-class ObjCMethodDecl;
-class PreprocessorOptions;
-
-namespace CodeGen {
-class CGFunctionInfo;
-class CodeGenModule;
-
-class CodeGenABITypes
-{
-public:
- CodeGenABITypes(ASTContext &C, llvm::Module &M,
- CoverageSourceInfo *CoverageInfo = nullptr);
- ~CodeGenABITypes();
-
- /// These methods all forward to methods in the private implementation class
- /// CodeGenTypes.
-
- const CGFunctionInfo &arrangeObjCMessageSendSignature(
- const ObjCMethodDecl *MD,
- QualType receiverType);
- const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty,
- const FunctionDecl *FD);
- const CGFunctionInfo &arrangeFreeFunctionType(
- CanQual<FunctionNoProtoType> Ty);
- const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,
- const FunctionProtoType *FTP,
- const CXXMethodDecl *MD);
- const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType,
- ArrayRef<CanQualType> argTypes,
- FunctionType::ExtInfo info,
- RequiredArgs args);
-
-private:
- /// Default CodeGenOptions object used to initialize the
- /// CodeGenModule and otherwise not used. More specifically, it is
- /// not used in ABI type generation, so none of the options matter.
- std::unique_ptr<CodeGenOptions> CGO;
- std::unique_ptr<HeaderSearchOptions> HSO;
- std::unique_ptr<PreprocessorOptions> PPO;
-
- /// The CodeGenModule we use get to the CodeGenTypes object.
- std::unique_ptr<CodeGen::CodeGenModule> CGM;
-};
-
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
deleted file mode 100644
index cc38e24..0000000
--- a/include/clang/CodeGen/CodeGenAction.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- 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_CODEGEN_CODEGENACTION_H
-#define LLVM_CLANG_CODEGEN_CODEGENACTION_H
-
-#include "clang/Frontend/FrontendAction.h"
-#include <memory>
-
-namespace llvm {
- class LLVMContext;
- class Module;
-}
-
-namespace clang {
-class BackendConsumer;
-
-class CodeGenAction : public ASTFrontendAction {
-private:
- unsigned Act;
- std::unique_ptr<llvm::Module> TheModule;
- // Vector of {Linker::Flags, Module*} pairs to specify bitcode
- // modules to link in using corresponding linker flags.
- SmallVector<std::pair<unsigned, llvm::Module *>, 4> LinkModules;
- llvm::LLVMContext *VMContext;
- bool OwnsVMContext;
-
-protected:
- /// Create a new code generation action. If the optional \p _VMContext
- /// parameter is supplied, the action uses it without taking ownership,
- /// otherwise it creates a fresh LLVM context and takes ownership.
- CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = nullptr);
-
- bool hasIRSupport() const override;
-
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
- void ExecuteAction() override;
-
- void EndSourceFileAction() override;
-
-public:
- ~CodeGenAction() override;
-
- /// setLinkModule - Set the link module to be used by this action. If a link
- /// module is not provided, and CodeGenOptions::LinkBitcodeFile is non-empty,
- /// the action will load it from the specified file.
- void addLinkModule(llvm::Module *Mod, unsigned LinkFlags) {
- LinkModules.push_back(std::make_pair(LinkFlags, Mod));
- }
-
- /// Take the generated LLVM module, for use after the action has been run.
- /// The result may be null on failure.
- std::unique_ptr<llvm::Module> takeModule();
-
- /// Take the LLVM context used by this action.
- llvm::LLVMContext *takeLLVMContext();
-
- BackendConsumer *BEConsumer;
-};
-
-class EmitAssemblyAction : public CodeGenAction {
- virtual void anchor();
-public:
- EmitAssemblyAction(llvm::LLVMContext *_VMContext = nullptr);
-};
-
-class EmitBCAction : public CodeGenAction {
- virtual void anchor();
-public:
- EmitBCAction(llvm::LLVMContext *_VMContext = nullptr);
-};
-
-class EmitLLVMAction : public CodeGenAction {
- virtual void anchor();
-public:
- EmitLLVMAction(llvm::LLVMContext *_VMContext = nullptr);
-};
-
-class EmitLLVMOnlyAction : public CodeGenAction {
- virtual void anchor();
-public:
- EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
-};
-
-class EmitCodeGenOnlyAction : public CodeGenAction {
- virtual void anchor();
-public:
- EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
-};
-
-class EmitObjAction : public CodeGenAction {
- virtual void anchor();
-public:
- EmitObjAction(llvm::LLVMContext *_VMContext = nullptr);
-};
-
-}
-
-#endif
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
deleted file mode 100644
index 52497d9..0000000
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- 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 ModuleBuilder interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_CODEGEN_MODULEBUILDER_H
-#define LLVM_CLANG_CODEGEN_MODULEBUILDER_H
-
-#include "clang/AST/ASTConsumer.h"
-#include <string>
-
-namespace llvm {
- class LLVMContext;
- class Module;
-}
-
-namespace clang {
- class DiagnosticsEngine;
- class CoverageSourceInfo;
- class LangOptions;
- class HeaderSearchOptions;
- class PreprocessorOptions;
- class CodeGenOptions;
- class Decl;
-
- class CodeGenerator : public ASTConsumer {
- virtual void anchor();
- public:
- virtual llvm::Module* GetModule() = 0;
- virtual llvm::Module* ReleaseModule() = 0;
- virtual const Decl *GetDeclForMangledName(llvm::StringRef MangledName) = 0;
- };
-
- /// CreateLLVMCodeGen - Create a CodeGenerator instance.
- /// It is the responsibility of the caller to call delete on
- /// the allocated CodeGenerator instance.
- CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags,
- const std::string &ModuleName,
- const HeaderSearchOptions &HeaderSearchOpts,
- const PreprocessorOptions &PreprocessorOpts,
- const CodeGenOptions &CGO,
- llvm::LLVMContext& C,
- CoverageSourceInfo *CoverageInfo = nullptr);
-}
-
-#endif
diff --git a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
deleted file mode 100644
index 15132ac..0000000
--- a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- CodeGen/ObjectFilePCHContainerOperations.h - ------------*- 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_CODEGEN_OBJECT_FILE_PCH_CONTAINER_OPERATIONS_H
-#define LLVM_CLANG_CODEGEN_OBJECT_FILE_PCH_CONTAINER_OPERATIONS_H
-
-#include "clang/Frontend/PCHContainerOperations.h"
-
-namespace clang {
-
-/// A PCHContainerWriter implementation that uses LLVM to
-/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
-class ObjectFilePCHContainerWriter : public PCHContainerWriter {
- StringRef getFormat() const override { return "obj"; }
-
- /// Return an ASTConsumer that can be chained with a
- /// PCHGenerator that produces a wrapper file format
- /// that also contains full debug info for the module.
- std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator(
- CompilerInstance &CI, const std::string &MainFileName,
- const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
- std::shared_ptr<PCHBuffer> Buffer) const override;
-};
-
-/// A PCHContainerReader implementation that uses LLVM to
-/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
-class ObjectFilePCHContainerReader : public PCHContainerReader {
- StringRef getFormat() const override { return "obj"; }
-
- /// Initialize an llvm::BitstreamReader with the serialized
- /// AST inside the PCH container Buffer.
- void ExtractPCH(llvm::MemoryBufferRef Buffer,
- llvm::BitstreamReader &StreamFile) const override;
-};
-}
-
-#endif
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
deleted file mode 100644
index b7486f3..0000000
--- a/include/clang/Config/config.h.cmake
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This generated file is for internal use. Do not include it from headers. */
-
-#ifdef CLANG_CONFIG_H
-#error config.h can only be included once
-#else
-#define CLANG_CONFIG_H
-
-/* Bug report URL. */
-#define BUG_REPORT_URL "${BUG_REPORT_URL}"
-
-/* Default OpenMP runtime used by -fopenmp. */
-#define CLANG_DEFAULT_OPENMP_RUNTIME "${CLANG_DEFAULT_OPENMP_RUNTIME}"
-
-/* Multilib suffix for libdir. */
-#define CLANG_LIBDIR_SUFFIX "${CLANG_LIBDIR_SUFFIX}"
-
-/* Relative directory for resource files */
-#define CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}"
-
-/* Directories clang will search for headers */
-#define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}"
-
-/* Default <path> to all compiler invocations for --sysroot=<path>. */
-#define DEFAULT_SYSROOT "${DEFAULT_SYSROOT}"
-
-/* Directory where gcc is installed. */
-#define GCC_INSTALL_PREFIX "${GCC_INSTALL_PREFIX}"
-
-/* Define if we have libxml2 */
-#cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML}
-
-/* The LLVM product name and version */
-#define BACKEND_PACKAGE_STRING "${BACKEND_PACKAGE_STRING}"
-
-/* Linker version detected at compile time. */
-#cmakedefine HOST_LINK_VERSION "${HOST_LINK_VERSION}"
-
-#endif
diff --git a/include/clang/Config/config.h.in b/include/clang/Config/config.h.in
deleted file mode 100644
index 91983f6..0000000
--- a/include/clang/Config/config.h.in
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This generated file is for internal use. Do not include it from headers. */
-
-#ifdef CLANG_CONFIG_H
-#error config.h can only be included once
-#else
-#define CLANG_CONFIG_H
-
-/* Bug report URL. */
-#undef BUG_REPORT_URL
-
-/* Default OpenMP runtime used by -fopenmp. */
-#undef CLANG_DEFAULT_OPENMP_RUNTIME
-
-/* Multilib suffix for libdir. */
-#undef CLANG_LIBDIR_SUFFIX
-
-/* Relative directory for resource files */
-#undef CLANG_RESOURCE_DIR
-
-/* Directories clang will search for headers */
-#undef C_INCLUDE_DIRS
-
-/* Default <path> to all compiler invocations for --sysroot=<path>. */
-#undef DEFAULT_SYSROOT
-
-/* Directory where gcc is installed. */
-#undef GCC_INSTALL_PREFIX
-
-/* Define if we have libxml2 */
-#undef CLANG_HAVE_LIBXML
-
-#undef PACKAGE_STRING
-
-/* The LLVM product name and version */
-#define BACKEND_PACKAGE_STRING PACKAGE_STRING
-
-/* Linker version detected at compile time. */
-#undef HOST_LINK_VERSION
-
-#endif
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
deleted file mode 100644
index fc31d4b..0000000
--- a/include/clang/Driver/Action.h
+++ /dev/null
@@ -1,317 +0,0 @@
-//===--- Action.h - Abstract compilation steps ------------------*- 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_DRIVER_ACTION_H
-#define LLVM_CLANG_DRIVER_ACTION_H
-
-#include "clang/Driver/Types.h"
-#include "clang/Driver/Util.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace llvm {
-namespace opt {
- class Arg;
-}
-}
-
-namespace clang {
-namespace driver {
-
-/// Action - Represent an abstract compilation step to perform.
-///
-/// An action represents an edge in the compilation graph; typically
-/// it is a job to transform an input using some tool.
-///
-/// The current driver is hard wired to expect actions which produce a
-/// single primary output, at least in terms of controlling the
-/// compilation. Actions can produce auxiliary files, but can only
-/// produce a single output to feed into subsequent actions.
-class Action {
-public:
- typedef ActionList::size_type size_type;
- typedef ActionList::iterator iterator;
- typedef ActionList::const_iterator const_iterator;
-
- enum ActionClass {
- InputClass = 0,
- BindArchClass,
- CudaDeviceClass,
- CudaHostClass,
- PreprocessJobClass,
- PrecompileJobClass,
- AnalyzeJobClass,
- MigrateJobClass,
- CompileJobClass,
- BackendJobClass,
- AssembleJobClass,
- LinkJobClass,
- LipoJobClass,
- DsymutilJobClass,
- VerifyDebugInfoJobClass,
- VerifyPCHJobClass,
-
- JobClassFirst=PreprocessJobClass,
- JobClassLast=VerifyPCHJobClass
- };
-
- static const char *getClassName(ActionClass AC);
-
-private:
- ActionClass Kind;
-
- /// The output type of this action.
- types::ID Type;
-
- ActionList Inputs;
-
- unsigned OwnsInputs : 1;
-
-protected:
- Action(ActionClass Kind, types::ID Type)
- : Kind(Kind), Type(Type), OwnsInputs(true) {}
- Action(ActionClass Kind, std::unique_ptr<Action> Input, types::ID Type)
- : Kind(Kind), Type(Type), Inputs(1, Input.release()), OwnsInputs(true) {
- }
- Action(ActionClass Kind, std::unique_ptr<Action> Input)
- : Kind(Kind), Type(Input->getType()), Inputs(1, Input.release()),
- OwnsInputs(true) {}
- Action(ActionClass Kind, const ActionList &Inputs, types::ID Type)
- : Kind(Kind), Type(Type), Inputs(Inputs), OwnsInputs(true) {}
-public:
- virtual ~Action();
-
- const char *getClassName() const { return Action::getClassName(getKind()); }
-
- bool getOwnsInputs() { return OwnsInputs; }
- void setOwnsInputs(bool Value) { OwnsInputs = Value; }
-
- ActionClass getKind() const { return Kind; }
- types::ID getType() const { return Type; }
-
- ActionList &getInputs() { return Inputs; }
- const ActionList &getInputs() const { return Inputs; }
-
- size_type size() const { return Inputs.size(); }
-
- iterator begin() { return Inputs.begin(); }
- iterator end() { return Inputs.end(); }
- const_iterator begin() const { return Inputs.begin(); }
- const_iterator end() const { return Inputs.end(); }
-};
-
-class InputAction : public Action {
- virtual void anchor();
- const llvm::opt::Arg &Input;
-
-public:
- InputAction(const llvm::opt::Arg &Input, types::ID Type);
-
- const llvm::opt::Arg &getInputArg() const { return Input; }
-
- static bool classof(const Action *A) {
- return A->getKind() == InputClass;
- }
-};
-
-class BindArchAction : public Action {
- virtual void anchor();
- /// The architecture to bind, or 0 if the default architecture
- /// should be bound.
- const char *ArchName;
-
-public:
- BindArchAction(std::unique_ptr<Action> Input, const char *ArchName);
-
- const char *getArchName() const { return ArchName; }
-
- static bool classof(const Action *A) {
- return A->getKind() == BindArchClass;
- }
-};
-
-class CudaDeviceAction : public Action {
- virtual void anchor();
- /// GPU architecture to bind -- e.g 'sm_35'.
- const char *GpuArchName;
- /// True when action results are not consumed by the host action (e.g when
- /// -fsyntax-only or --cuda-device-only options are used).
- bool AtTopLevel;
-
-public:
- CudaDeviceAction(std::unique_ptr<Action> Input, const char *ArchName,
- bool AtTopLevel);
-
- const char *getGpuArchName() const { return GpuArchName; }
- bool isAtTopLevel() const { return AtTopLevel; }
-
- static bool classof(const Action *A) {
- return A->getKind() == CudaDeviceClass;
- }
-};
-
-class CudaHostAction : public Action {
- virtual void anchor();
- ActionList DeviceActions;
-
-public:
- CudaHostAction(std::unique_ptr<Action> Input,
- const ActionList &DeviceActions);
- ~CudaHostAction() override;
-
- const ActionList &getDeviceActions() const { return DeviceActions; }
-
- static bool classof(const Action *A) { return A->getKind() == CudaHostClass; }
-};
-
-class JobAction : public Action {
- virtual void anchor();
-protected:
- JobAction(ActionClass Kind, std::unique_ptr<Action> Input, types::ID Type);
- JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
-
-public:
- static bool classof(const Action *A) {
- return (A->getKind() >= JobClassFirst &&
- A->getKind() <= JobClassLast);
- }
-};
-
-class PreprocessJobAction : public JobAction {
- void anchor() override;
-public:
- PreprocessJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
-
- static bool classof(const Action *A) {
- return A->getKind() == PreprocessJobClass;
- }
-};
-
-class PrecompileJobAction : public JobAction {
- void anchor() override;
-public:
- PrecompileJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
-
- static bool classof(const Action *A) {
- return A->getKind() == PrecompileJobClass;
- }
-};
-
-class AnalyzeJobAction : public JobAction {
- void anchor() override;
-public:
- AnalyzeJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
-
- static bool classof(const Action *A) {
- return A->getKind() == AnalyzeJobClass;
- }
-};
-
-class MigrateJobAction : public JobAction {
- void anchor() override;
-public:
- MigrateJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
-
- static bool classof(const Action *A) {
- return A->getKind() == MigrateJobClass;
- }
-};
-
-class CompileJobAction : public JobAction {
- void anchor() override;
-public:
- CompileJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
-
- static bool classof(const Action *A) {
- return A->getKind() == CompileJobClass;
- }
-};
-
-class BackendJobAction : public JobAction {
- void anchor() override;
-public:
- BackendJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
-
- static bool classof(const Action *A) {
- return A->getKind() == BackendJobClass;
- }
-};
-
-class AssembleJobAction : public JobAction {
- void anchor() override;
-public:
- AssembleJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
-
- static bool classof(const Action *A) {
- return A->getKind() == AssembleJobClass;
- }
-};
-
-class LinkJobAction : public JobAction {
- void anchor() override;
-public:
- LinkJobAction(ActionList &Inputs, types::ID Type);
-
- static bool classof(const Action *A) {
- return A->getKind() == LinkJobClass;
- }
-};
-
-class LipoJobAction : public JobAction {
- void anchor() override;
-public:
- LipoJobAction(ActionList &Inputs, types::ID Type);
-
- static bool classof(const Action *A) {
- return A->getKind() == LipoJobClass;
- }
-};
-
-class DsymutilJobAction : public JobAction {
- void anchor() override;
-public:
- DsymutilJobAction(ActionList &Inputs, types::ID Type);
-
- static bool classof(const Action *A) {
- return A->getKind() == DsymutilJobClass;
- }
-};
-
-class VerifyJobAction : public JobAction {
- void anchor() override;
-public:
- VerifyJobAction(ActionClass Kind, std::unique_ptr<Action> Input,
- types::ID Type);
- static bool classof(const Action *A) {
- return A->getKind() == VerifyDebugInfoJobClass ||
- A->getKind() == VerifyPCHJobClass;
- }
-};
-
-class VerifyDebugInfoJobAction : public VerifyJobAction {
- void anchor() override;
-public:
- VerifyDebugInfoJobAction(std::unique_ptr<Action> Input, types::ID Type);
- static bool classof(const Action *A) {
- return A->getKind() == VerifyDebugInfoJobClass;
- }
-};
-
-class VerifyPCHJobAction : public VerifyJobAction {
- void anchor() override;
-public:
- VerifyPCHJobAction(std::unique_ptr<Action> Input, types::ID Type);
- static bool classof(const Action *A) {
- return A->getKind() == VerifyPCHJobClass;
- }
-};
-
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
deleted file mode 100644
index 051f903..0000000
--- a/include/clang/Driver/CC1Options.td
+++ /dev/null
@@ -1,718 +0,0 @@
-//===--- CC1Options.td - Options for clang -cc1 ---------------------------===//
-//
-// 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 options accepted by clang -cc1 and clang -cc1as.
-//
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1Option, NoDriverOption] in {
-
-//===----------------------------------------------------------------------===//
-// Target Options
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
-
-def target_cpu : Separate<["-"], "target-cpu">,
- HelpText<"Target a specific cpu type">;
-def target_feature : Separate<["-"], "target-feature">,
- HelpText<"Target specific attributes">;
-def triple : Separate<["-"], "triple">,
- HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
-def target_abi : Separate<["-"], "target-abi">,
- HelpText<"Target a particular ABI type">;
-
-}
-
-def target_linker_version : Separate<["-"], "target-linker-version">,
- HelpText<"Target linker version">;
-def triple_EQ : Joined<["-"], "triple=">, Alias<triple>;
-def mfpmath : Separate<["-"], "mfpmath">,
- HelpText<"Which unit to use for fp math">;
-
-//===----------------------------------------------------------------------===//
-// Analyzer Options
-//===----------------------------------------------------------------------===//
-
-def analysis_UnoptimizedCFG : Flag<["-"], "unoptimized-cfg">,
- HelpText<"Generate unoptimized CFGs for all analyses">;
-def analysis_CFGAddImplicitDtors : Flag<["-"], "cfg-add-implicit-dtors">,
- HelpText<"Add C++ implicit destructors to CFGs for all analyses">;
-
-def analyzer_store : Separate<["-"], "analyzer-store">,
- HelpText<"Source Code Analysis - Abstract Memory Store Models">;
-def analyzer_store_EQ : Joined<["-"], "analyzer-store=">, Alias<analyzer_store>;
-
-def analyzer_constraints : Separate<["-"], "analyzer-constraints">,
- HelpText<"Source Code Analysis - Symbolic Constraint Engines">;
-def analyzer_constraints_EQ : Joined<["-"], "analyzer-constraints=">,
- Alias<analyzer_constraints>;
-
-def analyzer_output : Separate<["-"], "analyzer-output">,
- HelpText<"Source Code Analysis - Output Options">;
-def analyzer_output_EQ : Joined<["-"], "analyzer-output=">,
- Alias<analyzer_output>;
-
-def analyzer_purge : Separate<["-"], "analyzer-purge">,
- HelpText<"Source Code Analysis - Dead Symbol Removal Frequency">;
-def analyzer_purge_EQ : Joined<["-"], "analyzer-purge=">, Alias<analyzer_purge>;
-
-def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">,
- HelpText<"Force the static analyzer to analyze functions defined in header files">;
-def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-nested-blocks">,
- HelpText<"Analyze the definitions of blocks in addition to functions">;
-def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">,
- HelpText<"Emit verbose output about the analyzer's progress">;
-def analyze_function : Separate<["-"], "analyze-function">,
- HelpText<"Run analysis on specific function">;
-def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias<analyze_function>;
-def analyzer_eagerly_assume : Flag<["-"], "analyzer-eagerly-assume">,
- HelpText<"Eagerly assume the truth/falseness of some symbolic constraints">;
-def trim_egraph : Flag<["-"], "trim-egraph">,
- HelpText<"Only show error-related paths in the analysis graph">;
-def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">,
- HelpText<"Display exploded graph using GraphViz">;
-def analyzer_viz_egraph_ubigraph : Flag<["-"], "analyzer-viz-egraph-ubigraph">,
- HelpText<"Display exploded graph using Ubigraph">;
-
-def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack-depth">,
- HelpText<"Bound on stack depth while inlining (4 by default)">;
-def analyzer_inline_max_stack_depth_EQ : Joined<["-"], "analyzer-inline-max-stack-depth=">,
- Alias<analyzer_inline_max_stack_depth>;
-
-def analyzer_inlining_mode : Separate<["-"], "analyzer-inlining-mode">,
- HelpText<"Specify the function selection heuristic used during inlining">;
-def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias<analyzer_inlining_mode>;
-
-def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">,
- HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">;
-
-def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">,
- HelpText<"The maximum number of times the analyzer will go through a loop">;
-def analyzer_stats : Flag<["-"], "analyzer-stats">,
- HelpText<"Print internal analyzer statistics.">;
-
-def analyzer_checker : Separate<["-"], "analyzer-checker">,
- HelpText<"Choose analyzer checkers to enable">;
-def analyzer_checker_EQ : Joined<["-"], "analyzer-checker=">,
- Alias<analyzer_checker>;
-
-def analyzer_disable_checker : Separate<["-"], "analyzer-disable-checker">,
- HelpText<"Choose analyzer checkers to disable">;
-def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">,
- Alias<analyzer_disable_checker>;
-
-def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">,
- HelpText<"Disable all static analyzer checks">;
-
-def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
- HelpText<"Display the list of analyzer checkers that are available">;
-
-def analyzer_config : Separate<["-"], "analyzer-config">,
- HelpText<"Choose analyzer options to enable">;
-
-//===----------------------------------------------------------------------===//
-// Migrator Options
-//===----------------------------------------------------------------------===//
-def migrator_no_nsalloc_error : Flag<["-"], "no-ns-alloc-error">,
- HelpText<"Do not error on use of NSAllocateCollectable/NSReallocateCollectable">;
-
-def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">,
- HelpText<"Do not remove finalize method in gc mode">;
-
-//===----------------------------------------------------------------------===//
-// CodeGen Options
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
-
-def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
-def dwarf_version_EQ : Joined<["-"], "dwarf-version=">;
-def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">;
-def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
- HelpText<"The compilation directory to embed in the debug info.">;
-def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
- HelpText<"The string to embed in the Dwarf debug flags record.">;
-def mno_exec_stack : Flag<["-"], "mnoexecstack">,
- HelpText<"Mark the file as not needing an executable stack">;
-def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">,
- HelpText<"Make assembler warnings fatal">;
-def compress_debug_sections : Flag<["-"], "compress-debug-sections">,
- HelpText<"Compress DWARF debug sections using zlib">;
-def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
- HelpText<"Save temporary labels in the symbol table. "
- "Note this may change .s semantics and shouldn't generally be used "
- "on compiler-generated code.">;
-def mrelocation_model : Separate<["-"], "mrelocation-model">,
- HelpText<"The relocation model to use">;
-}
-
-def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
- HelpText<"Don't run LLVM optimization passes">;
-def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">,
- HelpText<"Don't run the LLVM IR verifier pass">;
-def disable_llvm_passes : Flag<["-"], "disable-llvm-passes">,
- HelpText<"Use together with -emit-llvm to get pristine LLVM IR from the "
- "frontend by not running any LLVM passes at all">;
-def disable_red_zone : Flag<["-"], "disable-red-zone">,
- HelpText<"Do not emit code that uses the red zone.">;
-def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
- HelpText<"Turn on column location information.">;
-def split_dwarf : Flag<["-"], "split-dwarf">,
- HelpText<"Split out the dwarf .dwo sections">;
-def gnu_pubnames : Flag<["-"], "gnu-pubnames">,
- HelpText<"Emit newer GNU style pubnames">;
-def arange_sections : Flag<["-"], "arange_sections">,
- HelpText<"Emit DWARF .debug_arange sections">;
-def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">,
- HelpText<"Generate debug info with external references to clang modules"
- " or precompiled headers">;
-def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">,
- HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
-def no_implicit_float : Flag<["-"], "no-implicit-float">,
- HelpText<"Don't generate implicit floating point instructions">;
-def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">,
- HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
-def fmerge_functions : Flag<["-"], "fmerge-functions">,
- HelpText<"Permit merging of identical functions when optimizing.">;
-def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">,
- HelpText<"Emit a gcov coverage notes file when compiling.">;
-def femit_coverage_data: Flag<["-"], "femit-coverage-data">,
- HelpText<"Instrument the program to emit gcov coverage data when run.">;
-def coverage_file : Separate<["-"], "coverage-file">,
- HelpText<"Emit coverage data to this filename. The extension will be replaced.">;
-def coverage_file_EQ : Joined<["-"], "coverage-file=">, Alias<coverage_file>;
-def coverage_cfg_checksum : Flag<["-"], "coverage-cfg-checksum">,
- HelpText<"Emit CFG checksum for functions in .gcno files.">;
-def coverage_no_function_names_in_data : Flag<["-"], "coverage-no-function-names-in-data">,
- HelpText<"Emit function names in .gcda files.">;
-def coverage_exit_block_before_body : Flag<["-"], "coverage-exit-block-before-body">,
- HelpText<"Emit the exit block before the body blocks in .gcno files.">;
-def coverage_version_EQ : Joined<["-"], "coverage-version=">,
- HelpText<"Four-byte version string for gcov files.">;
-def test_coverage : Flag<["-"], "test-coverage">,
- HelpText<"Do not generate coverage files or remove coverage changes from IR">;
-def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">,
- HelpText<"Dump the coverage mapping records, for testing">;
-def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">,
- HelpText<"Use register sized accesses to bit-fields, when possible.">;
-def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
- HelpText<"Turn off Type Based Alias Analysis">;
-def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">,
- HelpText<"Turn off struct-path aware Type Based Alias Analysis">;
-def masm_verbose : Flag<["-"], "masm-verbose">,
- HelpText<"Generate verbose assembly output">;
-def mcode_model : Separate<["-"], "mcode-model">,
- HelpText<"The code model to use">;
-def mdebug_pass : Separate<["-"], "mdebug-pass">,
- HelpText<"Enable additional debug output">;
-def mdisable_fp_elim : Flag<["-"], "mdisable-fp-elim">,
- HelpText<"Disable frame pointer elimination optimization">;
-def mdisable_tail_calls : Flag<["-"], "mdisable-tail-calls">,
- HelpText<"Disable tail call optimization, keeping the call stack accurate">;
-def menable_no_infinities : Flag<["-"], "menable-no-infs">,
- HelpText<"Allow optimization to assume there are no infinities.">;
-def menable_no_nans : Flag<["-"], "menable-no-nans">,
- HelpText<"Allow optimization to assume there are no NaNs.">;
-def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">,
- HelpText<"Allow unsafe floating-point math optimizations which may decrease "
- "precision">;
-def mfloat_abi : Separate<["-"], "mfloat-abi">,
- HelpText<"The float ABI to use">;
-def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">,
- HelpText<"Limit float precision to the given value">;
-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">,
- HelpText<"Generate unwinding tables for all functions">;
-def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">,
- HelpText<"Emit complete constructors and destructors as aliases when possible">;
-def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">,
- HelpText<"Link the given bitcode file before performing optimizations.">;
-def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">,
- HelpText<"Link and internalize needed symbols from the given bitcode file "
- "before performing optimizations.">;
-def vectorize_loops : Flag<["-"], "vectorize-loops">,
- HelpText<"Run the Loop vectorization passes">;
-def vectorize_slp : Flag<["-"], "vectorize-slp">,
- HelpText<"Run the SLP vectorization passes">;
-def vectorize_slp_aggressive : Flag<["-"], "vectorize-slp-aggressive">,
- HelpText<"Run the BB vectorization passes">;
-def dependent_lib : Joined<["--"], "dependent-lib=">,
- HelpText<"Add dependent library">;
-def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">,
- HelpText<"Sanitizer coverage type">;
-def fsanitize_coverage_indirect_calls
- : Flag<["-"], "fsanitize-coverage-indirect-calls">,
- HelpText<"Enable sanitizer coverage for indirect calls">;
-def fsanitize_coverage_trace_bb
- : Flag<["-"], "fsanitize-coverage-trace-bb">,
- HelpText<"Enable basic block tracing in sanitizer coverage">;
-def fsanitize_coverage_trace_cmp
- : Flag<["-"], "fsanitize-coverage-trace-cmp">,
- HelpText<"Enable cmp instruction tracing in sanitizer coverage">;
-def fsanitize_coverage_8bit_counters
- : Flag<["-"], "fsanitize-coverage-8bit-counters">,
- HelpText<"Enable frequency counters in sanitizer coverage">;
-
-//===----------------------------------------------------------------------===//
-// Dependency Output Options
-//===----------------------------------------------------------------------===//
-
-def sys_header_deps : Flag<["-"], "sys-header-deps">,
- HelpText<"Include system headers in dependency output">;
-def module_file_deps : Flag<["-"], "module-file-deps">,
- HelpText<"Include module files in dependency output">;
-def header_include_file : Separate<["-"], "header-include-file">,
- HelpText<"Filename (or -) to write header include output to">;
-def show_includes : Flag<["--"], "show-includes">,
- HelpText<"Print cl.exe style /showIncludes to stdout">;
-
-//===----------------------------------------------------------------------===//
-// Diagnostic Options
-//===----------------------------------------------------------------------===//
-
-def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">,
- HelpText<"Filename (or -) to log diagnostics to">;
-def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">,
- MetaVarName<"<filename>">,
- HelpText<"File for serializing diagnostics in a binary format">;
-
-def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">,
- HelpText<"Change diagnostic formatting to match IDE and command line tools">;
-def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">,
- HelpText<"Print diagnostic category">;
-def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">,
- HelpText<"Ignore #line directives when displaying diagnostic locations">;
-def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"<N>">,
- HelpText<"Set the tab stop distance.">;
-def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">;
-def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">;
-def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">;
-def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">;
-def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit).">;
-def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">,
- HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
-def verify : Flag<["-"], "verify">,
- HelpText<"Verify diagnostic output using comment directives">;
-def verify_ignore_unexpected : Flag<["-"], "verify-ignore-unexpected">,
- HelpText<"Ignore unexpected diagnostic messages">;
-def verify_ignore_unexpected_EQ : CommaJoined<["-"], "verify-ignore-unexpected=">,
- HelpText<"Ignore unexpected diagnostic messages">;
-def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">,
- HelpText<"Silence ObjC rewriting warnings">;
-
-//===----------------------------------------------------------------------===//
-// Frontend Options
-//===----------------------------------------------------------------------===//
-
-// This isn't normally used, it is just here so we can parse a
-// CompilerInvocation out of a driver-derived argument vector.
-def cc1 : Flag<["-"], "cc1">;
-def cc1as : Flag<["-"], "cc1as">;
-
-def ast_merge : Separate<["-"], "ast-merge">,
- MetaVarName<"<ast file>">,
- HelpText<"Merge the given AST file into the translation unit being compiled.">;
-def aux_triple : Separate<["-"], "aux-triple">,
- HelpText<"Auxiliary target triple.">;
-def code_completion_at : Separate<["-"], "code-completion-at">,
- MetaVarName<"<file>:<line>:<column>">,
- HelpText<"Dump code-completion information at a location">;
-def remap_file : Separate<["-"], "remap-file">,
- MetaVarName<"<from>;<to>">,
- HelpText<"Replace the contents of the <from> file with the contents of the <to> file">;
-def code_completion_at_EQ : Joined<["-"], "code-completion-at=">,
- Alias<code_completion_at>;
-def code_completion_macros : Flag<["-"], "code-completion-macros">,
- HelpText<"Include macros in code-completion results">;
-def code_completion_patterns : Flag<["-"], "code-completion-patterns">,
- HelpText<"Include code patterns in code-completion results">;
-def no_code_completion_globals : Flag<["-"], "no-code-completion-globals">,
- HelpText<"Do not include global declarations in code-completion results.">;
-def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">,
- HelpText<"Include brief documentation comments in code-completion results.">;
-def disable_free : Flag<["-"], "disable-free">,
- HelpText<"Disable freeing of memory on exit">;
-def load : Separate<["-"], "load">, MetaVarName<"<dsopath>">,
- HelpText<"Load the named plugin (dynamic shared object)">;
-def plugin : Separate<["-"], "plugin">, MetaVarName<"<name>">,
- HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">;
-def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">,
- MetaVarName<"<name> <arg>">,
- HelpText<"Pass <arg> to plugin <name>">;
-def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"<name>">,
- HelpText<"Use the named plugin action in addition to the default action">;
-def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
- MetaVarName<"<dump_filter>">,
- HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
- " nodes having a certain substring in a qualified name. Use"
- " -ast-list to list all filterable declaration node names.">;
-def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
- HelpText<"Do not automatically generate or update the global module index">;
-def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">,
- HelpText<"Do not automatically import modules for error recovery">;
-def fmodule_implementation_of : Separate<["-"], "fmodule-implementation-of">,
- MetaVarName<"<name>">,
- HelpText<"Specify the name of the module whose implementation file this is">;
-def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">,
- HelpText<"Use the current working directory as the home directory of "
- "module maps specified by -fmodule-map-file=<FILE>">;
-def fmodule_feature : Separate<["-"], "fmodule-feature">,
- MetaVarName<"<feature>">,
- HelpText<"Enable <feature> in module map requires declarations">;
-def fmodules_embed_file_EQ : Joined<["-"], "fmodules-embed-file=">,
- MetaVarName<"<file>">,
- HelpText<"Embed the contents of the specified file into the module file "
- "being compiled.">;
-def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">,
- HelpText<"Embed the contents of all files read by this compilation into "
- "the produced module file.">;
-def fmodules_local_submodule_visibility :
- Flag<["-"], "fmodules-local-submodule-visibility">,
- HelpText<"Enforce name visibility rules across submodules of the same "
- "top-level module.">;
-def fmodule_format_EQ : Joined<["-"], "fmodule-format=">,
- HelpText<"Select the container format for clang modules and PCH. "
- "Supported options are 'raw' and 'obj'.">;
-def ftest_module_file_extension_EQ :
- Joined<["-"], "ftest-module-file-extension=">,
- HelpText<"introduce a module file extension for testing purposes. "
- "The argument is parsed as blockname:major:minor:hashed:user info">;
-def fconcepts_ts : Flag<["-"], "fconcepts-ts">,
- HelpText<"Enable C++ Extensions for Concepts.">;
-
-let Group = Action_Group in {
-
-def Eonly : Flag<["-"], "Eonly">,
- HelpText<"Just run preprocessor, no output (for timings)">;
-def dump_raw_tokens : Flag<["-"], "dump-raw-tokens">,
- HelpText<"Lex file in raw mode and dump raw tokens">;
-def analyze : Flag<["-"], "analyze">,
- HelpText<"Run static analysis engine">;
-def dump_tokens : Flag<["-"], "dump-tokens">,
- HelpText<"Run preprocessor, dump internal rep of tokens">;
-def init_only : Flag<["-"], "init-only">,
- HelpText<"Only execute frontend initialization">;
-def fixit : Flag<["-"], "fixit">,
- HelpText<"Apply fix-it advice to the input source">;
-def fixit_EQ : Joined<["-"], "fixit=">,
- HelpText<"Apply fix-it advice creating a file with the given suffix">;
-def print_preamble : Flag<["-"], "print-preamble">,
- HelpText<"Print the \"preamble\" of a file, which is a candidate for implicit"
- " precompiled headers.">;
-def emit_html : Flag<["-"], "emit-html">,
- HelpText<"Output input source as HTML">;
-def ast_print : Flag<["-"], "ast-print">,
- HelpText<"Build ASTs and then pretty-print them">;
-def ast_list : Flag<["-"], "ast-list">,
- HelpText<"Build ASTs and print the list of declaration node qualified names">;
-def ast_dump : Flag<["-"], "ast-dump">,
- HelpText<"Build ASTs and then debug dump them">;
-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">,
- HelpText<"Build ASTs and view them with GraphViz">;
-def print_decl_contexts : Flag<["-"], "print-decl-contexts">,
- HelpText<"Print DeclContexts and their Decls">;
-def emit_module : Flag<["-"], "emit-module">,
- HelpText<"Generate pre-compiled module file from a module map">;
-def emit_pth : Flag<["-"], "emit-pth">,
- HelpText<"Generate pre-tokenized header file">;
-def emit_pch : Flag<["-"], "emit-pch">,
- HelpText<"Generate pre-compiled header file">;
-def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">,
- HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
-def emit_llvm_only : Flag<["-"], "emit-llvm-only">,
- HelpText<"Build ASTs and convert to LLVM, discarding output">;
-def emit_codegen_only : Flag<["-"], "emit-codegen-only">,
- HelpText<"Generate machine code, but discard output">;
-def emit_obj : Flag<["-"], "emit-obj">,
- HelpText<"Emit native object files">;
-def rewrite_test : Flag<["-"], "rewrite-test">,
- HelpText<"Rewriter playground">;
-def rewrite_macros : Flag<["-"], "rewrite-macros">,
- HelpText<"Expand macros without full preprocessing">;
-def migrate : Flag<["-"], "migrate">,
- HelpText<"Migrate source code">;
-}
-
-def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">,
- HelpText<"Preserve order of LLVM use-lists when serializing">;
-def no_emit_llvm_uselists : Flag<["-"], "no-emit-llvm-uselists">,
- HelpText<"Don't preserve order of LLVM use-lists when serializing">;
-
-def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">,
- HelpText<"Directory for temporary files produced during ARC or ObjC migration">;
-def arcmt_check : Flag<["-"], "arcmt-check">,
- HelpText<"Check for ARC migration issues that need manual handling">;
-def arcmt_modify : Flag<["-"], "arcmt-modify">,
- HelpText<"Apply modifications to files to conform to ARC">;
-def arcmt_migrate : Flag<["-"], "arcmt-migrate">,
- HelpText<"Apply modifications and produces temporary files that conform to ARC">;
-
-def print_stats : Flag<["-"], "print-stats">,
- HelpText<"Print performance metrics and statistics">;
-def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">,
- HelpText<"Dump record layout information">;
-def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">,
- HelpText<"Dump record layout information in a simple form used for testing">;
-def fix_what_you_can : Flag<["-"], "fix-what-you-can">,
- HelpText<"Apply fix-it advice even in the presence of unfixable errors">;
-def fix_only_warnings : Flag<["-"], "fix-only-warnings">,
- HelpText<"Apply fix-it advice only for warnings, not errors">;
-def fixit_recompile : Flag<["-"], "fixit-recompile">,
- HelpText<"Apply fix-it changes and recompile">;
-def fixit_to_temp : Flag<["-"], "fixit-to-temporary">,
- HelpText<"Apply fix-it changes to temporary files">;
-
-def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">,
- HelpText<"Override record layouts with those in the given file">;
-
-//===----------------------------------------------------------------------===//
-// Language Options
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
-
-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 fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">,
- HelpText<"Weakly link in the blocks runtime">;
-def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">,
- HelpText<"Use SjLj style exceptions">;
-def fnew_ms_eh: Flag<["-"], "fnew-ms-eh">,
- HelpText<"Use the new IR representation for MS exceptions">;
-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">,
- MetaVarName<"<class name>">,
- HelpText<"Specify the class to use for constant Objective-C string objects.">;
-def fobjc_arc_cxxlib_EQ : Joined<["-"], "fobjc-arc-cxxlib=">,
- HelpText<"Objective-C++ Automatic Reference Counting standard library kind">;
-def fobjc_runtime_has_weak : Flag<["-"], "fobjc-runtime-has-weak">,
- HelpText<"The target Objective-C runtime supports ARC weak operations">;
-def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">,
- HelpText<"Objective-C dispatch method to use">;
-def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-default-synthesize-properties">,
- 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 pic_level : Separate<["-"], "pic-level">,
- HelpText<"Value for __PIC__">;
-def pie_level : Separate<["-"], "pie-level">,
- HelpText<"Value for __PIE__">;
-def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
- HelpText<"Disable validation of precompiled headers">;
-def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">,
- HelpText<"Dump declarations that are deserialized from PCH, for testing">;
-def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">,
- HelpText<"Emit error if a specific declaration is deserialized from PCH, for testing">;
-def error_on_deserialized_pch_decl_EQ : Joined<["-"], "error-on-deserialized-decl=">,
- Alias<error_on_deserialized_pch_decl>;
-def static_define : Flag<["-"], "static-define">,
- HelpText<"Should __STATIC__ be defined">;
-def stack_protector : Separate<["-"], "stack-protector">,
- HelpText<"Enable stack protectors">;
-def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">,
- HelpText<"Lower bound for a buffer to be considered for stack protection">;
-def fvisibility : Separate<["-"], "fvisibility">,
- HelpText<"Default type and symbol visibility">;
-def ftype_visibility : Separate<["-"], "ftype-visibility">,
- HelpText<"Default type visibility">;
-def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
- HelpText<"Maximum depth of recursive template instantiation">;
-def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">,
- HelpText<"Maximum number of 'operator->'s to call for a member access">;
-def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">,
- HelpText<"Maximum depth of recursive constexpr function calls">;
-def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">,
- HelpText<"Maximum number of steps in constexpr function evaluation">;
-def fbracket_depth : Separate<["-"], "fbracket-depth">,
- HelpText<"Maximum nesting level for parentheses, brackets, and braces">;
-def fconst_strings : Flag<["-"], "fconst-strings">,
- HelpText<"Use a const qualified type for string literals in C and ObjC">;
-def fno_const_strings : Flag<["-"], "fno-const-strings">,
- HelpText<"Don't use a const qualified type for string literals in C and ObjC">;
-def fno_bitfield_type_align : Flag<["-"], "fno-bitfield-type-align">,
- HelpText<"Ignore bit-field types when aligning structures">;
-def ffake_address_space_map : Flag<["-"], "ffake-address-space-map">,
- HelpText<"Use a fake address space map; OpenCL testing purposes only">;
-def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">, MetaVarName<"<yes|no|target>">,
- HelpText<"Set the mode for address space map based mangling; OpenCL testing purposes only">;
-def funknown_anytype : Flag<["-"], "funknown-anytype">,
- HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">;
-def fdebugger_support : Flag<["-"], "fdebugger-support">,
- HelpText<"Enable special debugger support behavior">;
-def fdebugger_cast_result_to_id : Flag<["-"], "fdebugger-cast-result-to-id">,
- HelpText<"Enable casting unknown expression results to id">;
-def fdebugger_objc_literal : Flag<["-"], "fdebugger-objc-literal">,
- HelpText<"Enable special debugger support for Objective-C subscripting and literals">;
-def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">,
- HelpText<"Defines the __DEPRECATED macro">;
-def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">,
- HelpText<"Undefines the __DEPRECATED macro">;
-def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">,
- 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 fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
- HelpText<"Allow function arguments and returns of type half">;
-
-// C++ TSes.
-def fcoroutines : Flag<["-"], "fcoroutines">,
- HelpText<"Enable support for the C++ Coroutines TS">;
-
-//===----------------------------------------------------------------------===//
-// Header Search Options
-//===----------------------------------------------------------------------===//
-
-def nostdsysteminc : Flag<["-"], "nostdsysteminc">,
- HelpText<"Disable standard system #include directories">;
-def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">,
- HelpText<"Disable the module hash">;
-def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
- HelpText<"Add directory to the C SYSTEM include search path">;
-def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
- MetaVarName<"<directory>">,
- HelpText<"Add directory to the ObjC SYSTEM include search path">;
-def objcxx_isystem : JoinedOrSeparate<["-"], "objcxx-isystem">,
- MetaVarName<"<directory>">,
- HelpText<"Add directory to the ObjC++ SYSTEM include search path">;
-def internal_isystem : JoinedOrSeparate<["-"], "internal-isystem">,
- MetaVarName<"<directory>">,
- HelpText<"Add directory to the internal system include search path; these "
- "are assumed to not be user-provided and are used to model system "
- "and standard headers' paths.">;
-def internal_externc_isystem : JoinedOrSeparate<["-"], "internal-externc-isystem">,
- MetaVarName<"<directory>">,
- HelpText<"Add directory to the internal system include search path with "
- "implicit extern \"C\" semantics; these are assumed to not be "
- "user-provided and are used to model system and standard headers' "
- "paths.">;
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Options
-//===----------------------------------------------------------------------===//
-
-def include_pth : Separate<["-"], "include-pth">, MetaVarName<"<file>">,
- HelpText<"Include file before parsing">;
-def chain_include : Separate<["-"], "chain-include">, MetaVarName<"<file>">,
- HelpText<"Include and chain a header file after turning it into PCH">;
-def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">,
- HelpText<"Assume that the precompiled header is a precompiled preamble "
- "covering the first N bytes of the main file">;
-def token_cache : Separate<["-"], "token-cache">, MetaVarName<"<path>">,
- HelpText<"Use specified token cache file">;
-def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">,
- HelpText<"include a detailed record of preprocessing actions">;
-
-//===----------------------------------------------------------------------===//
-// OpenCL Options
-//===----------------------------------------------------------------------===//
-
-def cl_opt_disable : Flag<["-"], "cl-opt-disable">,
- HelpText<"OpenCL only. This option disables all optimizations. The default is optimizations are enabled.">;
-def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">,
- HelpText<"OpenCL only. This option does nothing and is for compatibility with OpenCL 1.0">;
-def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">,
- HelpText<"OpenCL only. Treat double precision floating-point constant as single precision constant.">;
-def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">,
- HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">;
-def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">,
- HelpText<"OpenCL only. Generate kernel argument metadata.">;
-def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">,
- HelpText<"OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable">;
-def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">,
- HelpText<"OpenCL only. Sets -cl-finite-math-only and -cl-unsafe-math-optimizations, and defines __FAST_RELAXED_MATH__">;
-def cl_mad_enable : Flag<["-"], "cl-mad-enable">,
- HelpText<"OpenCL only. Enable less precise MAD instructions to be generated.">;
-def cl_std_EQ : Joined<["-"], "cl-std=">,
- HelpText<"OpenCL language standard to compile for">;
-def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">,
- HelpText<"OpenCL only. Allow denormals to be flushed to zero">;
-
-//===----------------------------------------------------------------------===//
-// CUDA Options
-//===----------------------------------------------------------------------===//
-
-def fcuda_is_device : Flag<["-"], "fcuda-is-device">,
- HelpText<"Generate code for CUDA device">;
-def fcuda_allow_host_calls_from_host_device : Flag<["-"],
- "fcuda-allow-host-calls-from-host-device">,
- HelpText<"Allow host device functions to call host functions">;
-def fcuda_disable_target_call_checks : Flag<["-"],
- "fcuda-disable-target-call-checks">,
- HelpText<"Disable all cross-target (host, device, etc.) call checks in CUDA">;
-def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">,
- HelpText<"Incorporate CUDA device-side binary into host object file.">;
-def fcuda_target_overloads : Flag<["-"], "fcuda-target-overloads">,
- HelpText<"Enable function overloads based on CUDA target attributes.">;
-
-//===----------------------------------------------------------------------===//
-// OpenMP Options
-//===----------------------------------------------------------------------===//
-
-def fopenmp_is_device : Flag<["-"], "fopenmp-is-device">,
- HelpText<"Generate code only for an OpenMP target device.">;
-def omp_host_ir_file_path : Separate<["-"], "omp-host-ir-file-path">,
- HelpText<"Path to the IR file produced by the frontend for the host.">;
-
-} // let Flags = [CC1Option]
-
-
-//===----------------------------------------------------------------------===//
-// cc1as-only Options
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1AsOption, NoDriverOption] in {
-
-// Language Options
-def n : Flag<["-"], "n">,
- HelpText<"Don't automatically start assembly file with a text section">;
-
-// Frontend Options
-def filetype : Separate<["-"], "filetype">,
- HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
-
-// Transliterate Options
-def output_asm_variant : Separate<["-"], "output-asm-variant">,
- HelpText<"Select the asm variant index to use for output">;
-def show_encoding : Flag<["-"], "show-encoding">,
- HelpText<"Show instruction encoding information in transliterate mode">;
-def show_inst : Flag<["-"], "show-inst">,
- HelpText<"Show internal instruction representation in transliterate mode">;
-
-// Assemble Options
-def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
- HelpText<"The string to embed in the Dwarf debug AT_producer record.">;
-
-} // let Flags = [CC1AsOption]
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
deleted file mode 100644
index 16a5b72..0000000
--- a/include/clang/Driver/CLCompatOptions.td
+++ /dev/null
@@ -1,342 +0,0 @@
-//===--- CLCompatOptions.td - Options for clang-cl ------------------------===//
-//
-// 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 options accepted by clang-cl.
-//
-//===----------------------------------------------------------------------===//
-
-def cl_Group : OptionGroup<"<clang-cl options>">,
- HelpText<"CL.EXE COMPATIBILITY OPTIONS">;
-
-def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">,
- Group<cl_Group>;
-
-def cl_ignored_Group : OptionGroup<"<clang-cl ignored options>">,
- Group<cl_Group>;
-
-class CLFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
- Group<cl_Group>, Flags<[CLOption, DriverOption]>;
-
-class CLCompileFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
- Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>;
-
-class CLIgnoredFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
- Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>;
-
-class CLJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
- Group<cl_Group>, Flags<[CLOption, DriverOption]>;
-
-class CLCompileJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
- Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>;
-
-class CLIgnoredJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
- Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>;
-
-class CLJoinedOrSeparate<string name> : Option<["/", "-"], name,
- KIND_JOINED_OR_SEPARATE>, Group<cl_Group>, Flags<[CLOption, DriverOption]>;
-
-class CLCompileJoinedOrSeparate<string name> : Option<["/", "-"], name,
- KIND_JOINED_OR_SEPARATE>, Group<cl_compile_Group>,
- Flags<[CLOption, DriverOption]>;
-
-class CLRemainingArgs<string name> : Option<["/", "-"], name,
- KIND_REMAINING_ARGS>, Group<cl_Group>, Flags<[CLOption, DriverOption]>;
-
-// Aliases:
-// (We don't put any of these in cl_compile_Group as the options they alias are
-// already in the right group.)
-
-def _SLASH_Brepro : CLFlag<"Brepro">,
- HelpText<"Emit an object file which can be reproduced over time">,
- Alias<mincremental_linker_compatible>;
-def _SLASH_Brepro_ : CLFlag<"Brepro-">,
- HelpText<"Emit an object file which cannot be reproduced over time">,
- Alias<mno_incremental_linker_compatible>;
-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_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">,
- MetaVarName<"<macro[=value]>">, Alias<D>;
-def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>;
-def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias<ftrapping_math>;
-def _SLASH_fp_except_ : CLFlag<"fp:except-">,
- HelpText<"">, Alias<fno_trapping_math>;
-def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias<ffast_math>;
-def _SLASH_fp_precise : CLFlag<"fp:precise">,
- HelpText<"">, Alias<fno_fast_math>;
-def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias<fno_fast_math>;
-def _SLASH_GA : CLFlag<"GA">, Alias<ftlsmodel_EQ>, AliasArgs<["local-exec"]>,
- HelpText<"Assume thread-local variables are defined in the executable">;
-def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable emission of RTTI data">;
-def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">;
-def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">,
- Alias<fwritable_strings>;
-def _SLASH_Gs : CLJoined<"Gs">, HelpText<"Set stack probe size">,
- Alias<mstack_probe_size>;
-def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">,
- Alias<ffunction_sections>;
-def _SLASH_Gy_ : CLFlag<"Gy-">,
- HelpText<"Don't put each function in its own section">,
- Alias<fno_function_sections>;
-def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">,
- Alias<fdata_sections>;
-def _SLASH_Gw_ : CLFlag<"Gw-">,
- HelpText<"Don't put each data item in its own section">,
- Alias<fno_data_sections>;
-def _SLASH_help : CLFlag<"help">, Alias<help>,
- HelpText<"Display available options">;
-def _SLASH_HELP : CLFlag<"HELP">, Alias<help>;
-def _SLASH_I : CLJoinedOrSeparate<"I">,
- HelpText<"Add directory to include search path">, MetaVarName<"<dir>">,
- Alias<I>;
-def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">,
- Alias<funsigned_char>;
-def _SLASH_O0 : CLFlag<"O0">, Alias<O0>;
-def _SLASH_O : CLJoined<"O">, HelpText<"Optimization level">;
-def _SLASH_Ob0 : CLFlag<"Ob0">, HelpText<"Disable inlining">,
- Alias<fno_inline>;
-def _SLASH_Od : CLFlag<"Od">, HelpText<"Disable optimization">, Alias<O0>;
-def _SLASH_Oi : CLFlag<"Oi">, HelpText<"Enable use of builtin functions">,
- Alias<fbuiltin>;
-def _SLASH_Oi_ : CLFlag<"Oi-">, HelpText<"Disable use of builtin functions">,
- Alias<fno_builtin>;
-def _SLASH_Os : CLFlag<"Os">, HelpText<"Optimize for size">, Alias<O>,
- AliasArgs<["s"]>;
-def _SLASH_Ot : CLFlag<"Ot">, HelpText<"Optimize for speed">, Alias<O>,
- AliasArgs<["2"]>;
-def _SLASH_QUESTION : CLFlag<"?">, Alias<help>,
- HelpText<"Display available options">;
-def _SLASH_Qvec : CLFlag<"Qvec">,
- HelpText<"Enable the loop vectorization passes">, Alias<fvectorize>;
-def _SLASH_Qvec_ : CLFlag<"Qvec-">,
- HelpText<"Disable the loop vectorization passes">, Alias<fno_vectorize>;
-def _SLASH_showIncludes : CLFlag<"showIncludes">,
- HelpText<"Print info about included files to stderr">,
- Alias<show_includes>;
-def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">,
- MetaVarName<"<macro>">, Alias<U>;
-def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>;
-def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>;
-def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>;
-def _SLASH_W3 : CLFlag<"W3">, HelpText<"Enable -Wall">, Alias<Wall>;
-def _SLASH_W4 : CLFlag<"W4">, HelpText<"Enable -Wall and -Wextra">, Alias<WCL4>;
-def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Wall and -Wextra">, Alias<WCL4>;
-def _SLASH_WX : CLFlag<"WX">, HelpText<"Treat warnings as errors">,
- Alias<W_Joined>, AliasArgs<["error"]>;
-def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">,
- Alias<W_Joined>, AliasArgs<["no-error"]>;
-def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>;
-def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>,
- AliasArgs<["no-macro-redefined"]>;
-def _SLASH_wd4100 : CLFlag<"wd4100">, Alias<W_Joined>,
- AliasArgs<["no-unused-parameter"]>;
-def _SLASH_wd4910 : CLFlag<"wd4910">, Alias<W_Joined>,
- AliasArgs<["no-dllexport-explicit-instantiation-decl"]>;
-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_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">,
- HelpText<"Enable C++14 sized global deallocation functions">,
- Alias<fsized_deallocation>;
-def _SLASH_Zc_sizedDealloc_ : CLFlag<"Zc:sizedDealloc-">,
- HelpText<"Disable C++14 sized global deallocation functions">,
- Alias<fno_sized_deallocation>;
-def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">,
- HelpText<"Treat string literals as const">, Alias<W_Joined>,
- AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>;
-def _SLASH_Zc_threadSafeInit : CLFlag<"Zc:threadSafeInit">,
- HelpText<"Enable thread-safe initialization of static variables">,
- Alias<fthreadsafe_statics>;
-def _SLASH_Zc_threadSafeInit_ : CLFlag<"Zc:threadSafeInit-">,
- HelpText<"Disable thread-safe initialization of static variables">,
- Alias<fno_threadsafe_statics>;
-def _SLASH_Zc_trigraphs : CLFlag<"Zc:trigraphs">,
- HelpText<"Enable trigraphs">, Alias<ftrigraphs>;
-def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">,
- HelpText<"Disable trigraphs (default)">, Alias<fno_trigraphs>;
-def _SLASH_Z7 : CLFlag<"Z7">,
- HelpText<"Enable CodeView debug information in object files">;
-def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>,
- HelpText<"Alias for /Z7. Does not produce PDBs.">;
-def _SLASH_Zp : CLJoined<"Zp">,
- HelpText<"Specify the default maximum struct packing alignment">,
- Alias<fpack_struct_EQ>;
-def _SLASH_Zp_flag : CLFlag<"Zp">,
- HelpText<"Set the default maximum struct packing alignment to 1">,
- Alias<fpack_struct_EQ>, AliasArgs<["1"]>;
-def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">,
- Alias<fsyntax_only>;
-
-
-// Non-aliases:
-
-def _SLASH_arch : CLCompileJoined<"arch:">,
- HelpText<"Set architecture for code generation">;
-
-def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>;
-def _SLASH_volatile_Group : OptionGroup<"</volatile group>">,
- Group<cl_compile_Group>;
-
-def _SLASH_EH : CLJoined<"EH">, HelpText<"Exception handling model">;
-def _SLASH_EP : CLFlag<"EP">,
- HelpText<"Disable linemarker output and preprocess to stdout">;
-def _SLASH_FA : CLFlag<"FA">,
- HelpText<"Output assembly code file during compilation">;
-def _SLASH_Fa : CLJoined<"Fa">,
- HelpText<"Output assembly code to this file during compilation (with /FA)">,
- MetaVarName<"<file or directory>">;
-def _SLASH_fallback : CLCompileFlag<"fallback">,
- HelpText<"Fall back to cl.exe if clang-cl fails to compile">;
-def _SLASH_FI : CLJoinedOrSeparate<"FI">,
- HelpText<"Include file before parsing">, Alias<include_>;
-def _SLASH_Fe : CLJoined<"Fe">,
- HelpText<"Set output executable file or directory (ends in / or \\)">,
- MetaVarName<"<file or directory>">;
-def _SLASH_Fi : CLCompileJoined<"Fi">,
- HelpText<"Set preprocess output file name (with /P)">,
- MetaVarName<"<file>">;
-def _SLASH_Fo : CLCompileJoined<"Fo">,
- HelpText<"Set output object file, or directory (ends in / or \\) (with /c)">,
- MetaVarName<"<file or directory>">;
-def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">;
-def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">;
-def _SLASH_link : CLRemainingArgs<"link">,
- HelpText<"Forward options to the linker">, MetaVarName<"<options>">;
-def _SLASH_MD : Option<["/", "-"], "MD", KIND_FLAG>, Group<_SLASH_M_Group>,
- Flags<[CLOption, DriverOption]>, HelpText<"Use DLL run-time">;
-def _SLASH_MDd : Option<["/", "-"], "MDd", KIND_FLAG>, Group<_SLASH_M_Group>,
- Flags<[CLOption, DriverOption]>, HelpText<"Use DLL debug run-time">;
-def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>,
- Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">;
-def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>,
- Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">;
-def _SLASH_o : CLJoinedOrSeparate<"o">,
- HelpText<"Set output file or directory (ends in / or \\)">,
- MetaVarName<"<file or directory>">;
-def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">;
-def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">,
- HelpText<"Specify a C source file">, MetaVarName<"<filename>">;
-def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">;
-def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">,
- HelpText<"Specify a C++ source file">, MetaVarName<"<filename>">;
-def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">;
-def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>,
- Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>,
- HelpText<"Volatile loads and stores have standard semantics">;
-def _SLASH_vmb : CLFlag<"vmb">,
- HelpText<"Use a best-case representation method for member pointers">;
-def _SLASH_vmg : CLFlag<"vmg">,
- HelpText<"Use a most-general representation for member pointers">;
-def _SLASH_vms : CLFlag<"vms">,
- HelpText<"Set the default most-general representation to single inheritance">;
-def _SLASH_vmm : CLFlag<"vmm">,
- HelpText<"Set the default most-general representation to "
- "multiple inheritance">;
-def _SLASH_vmv : CLFlag<"vmv">,
- HelpText<"Set the default most-general representation to "
- "virtual inheritance">;
-def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>,
- Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>,
- HelpText<"Volatile loads and stores have acquire and release semantics">;
-def _SLASH_Zl : CLFlag<"Zl">,
- HelpText<"Don't mention any default libraries in the object file">;
-
-// Ignored:
-
-def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">;
-def _SLASH_bigobj : CLIgnoredFlag<"bigobj">;
-def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">;
-def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">;
-def _SLASH_errorReport : CLIgnoredJoined<"errorReport">;
-def _SLASH_Fd : CLIgnoredJoined<"Fd">;
-def _SLASH_FS : CLIgnoredFlag<"FS">, HelpText<"Force synchronous PDB writes">;
-def _SLASH_Gd : CLIgnoredFlag<"Gd">;
-def _SLASH_GF : CLIgnoredFlag<"GF">;
-def _SLASH_GS_ : CLIgnoredFlag<"GS-">;
-def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
-def _SLASH_nologo : CLIgnoredFlag<"nologo">;
-def _SLASH_Ob1 : CLIgnoredFlag<"Ob1">;
-def _SLASH_Ob2 : CLIgnoredFlag<"Ob2">;
-def _SLASH_Og : CLIgnoredFlag<"Og">;
-def _SLASH_openmp_ : CLIgnoredFlag<"openmp-">;
-def _SLASH_RTC : CLIgnoredJoined<"RTC">;
-def _SLASH_sdl : CLIgnoredFlag<"sdl">;
-def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
-def _SLASH_w : CLIgnoredJoined<"w">;
-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_Zm : CLIgnoredJoined<"Zm">;
-def _SLASH_Zo : CLIgnoredFlag<"Zo">;
-def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">;
-
-
-// Unsupported:
-
-def _SLASH_AI : CLJoined<"AI">;
-def _SLASH_clr : CLJoined<"clr">;
-def _SLASH_doc : CLJoined<"doc">;
-def _SLASH_FA_joined : CLJoined<"FA">;
-def _SLASH_favor : CLJoined<"favor">;
-def _SLASH_FC : CLFlag<"FC">;
-def _SLASH_F : CLFlag<"F">;
-def _SLASH_Fm : CLJoined<"Fm">;
-def _SLASH_Fp : CLJoined<"Fp">;
-def _SLASH_Fr : CLJoined<"Fr">;
-def _SLASH_FR : CLJoined<"FR">;
-def _SLASH_FU : CLJoinedOrSeparate<"FU">;
-def _SLASH_Fx : CLFlag<"Fx">;
-def _SLASH_G1 : CLFlag<"G1">;
-def _SLASH_G2 : CLFlag<"G2">;
-def _SLASH_Ge : CLFlag<"Ge">;
-def _SLASH_Gh : CLFlag<"Gh">;
-def _SLASH_GH : CLFlag<"GH">;
-def _SLASH_GL : CLFlag<"GL">;
-def _SLASH_GL_ : CLFlag<"GL-">;
-def _SLASH_Gm : CLFlag<"Gm">;
-def _SLASH_Gm_ : CLFlag<"Gm-">;
-def _SLASH_Gr : CLFlag<"Gr">;
-def _SLASH_GS : CLFlag<"GS">;
-def _SLASH_GT : CLFlag<"GT">;
-def _SLASH_Guard : CLJoined<"guard:">;
-def _SLASH_GX : CLFlag<"GX">;
-def _SLASH_Gv : CLFlag<"Gv">;
-def _SLASH_Gz : CLFlag<"Gz">;
-def _SLASH_GZ : CLFlag<"GZ">;
-def _SLASH_H : CLFlag<"H">;
-def _SLASH_homeparams : CLFlag<"homeparams">;
-def _SLASH_hotpatch : CLFlag<"hotpatch">;
-def _SLASH_kernel : CLFlag<"kernel">;
-def _SLASH_LN : CLFlag<"LN">;
-def _SLASH_MP : CLJoined<"MP">;
-def _SLASH_openmp : CLFlag<"openmp">;
-def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">;
-def _SLASH_QIfist : CLFlag<"QIfist">;
-def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">;
-def _SLASH_Qpar : CLFlag<"Qpar">;
-def _SLASH_Qvec_report : CLJoined<"Qvec-report">;
-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_Yc : CLJoined<"Yc">;
-def _SLASH_Y_ : CLFlag<"Y-">;
-def _SLASH_Yd : CLFlag<"Yd">;
-def _SLASH_Yl : CLJoined<"Yl">;
-def _SLASH_Yu : CLJoined<"Yu">;
-def _SLASH_Za : CLFlag<"Za">;
-def _SLASH_Zc : CLJoined<"Zc:">;
-def _SLASH_Ze : CLFlag<"Ze">;
-def _SLASH_Zg : CLFlag<"Zg">;
-def _SLASH_ZI : CLFlag<"ZI">;
-def _SLASH_ZW : CLJoined<"ZW">;
diff --git a/include/clang/Driver/CMakeLists.txt b/include/clang/Driver/CMakeLists.txt
deleted file mode 100644
index a9d98804..0000000
--- a/include/clang/Driver/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-set(LLVM_TARGET_DEFINITIONS Options.td)
-tablegen(LLVM Options.inc -gen-opt-parser-defs)
-add_public_tablegen_target(ClangDriverOptions)
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
deleted file mode 100644
index 12ff068..0000000
--- a/include/clang/Driver/Compilation.h
+++ /dev/null
@@ -1,202 +0,0 @@
-//===--- Compilation.h - Compilation Task Data Structure --------*- 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_DRIVER_COMPILATION_H
-#define LLVM_CLANG_DRIVER_COMPILATION_H
-
-#include "clang/Driver/Action.h"
-#include "clang/Driver/Job.h"
-#include "clang/Driver/Util.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/Path.h"
-
-namespace llvm {
-namespace opt {
- class DerivedArgList;
- class InputArgList;
-}
-}
-
-namespace clang {
-namespace driver {
- class Driver;
- class JobList;
- class ToolChain;
-
-/// Compilation - A set of tasks to perform for a single driver
-/// invocation.
-class Compilation {
- /// The driver we were created by.
- const Driver &TheDriver;
-
- /// The default tool chain.
- const ToolChain &DefaultToolChain;
-
- const ToolChain *CudaHostToolChain;
- const ToolChain *CudaDeviceToolChain;
-
- /// The original (untranslated) input argument list.
- llvm::opt::InputArgList *Args;
-
- /// The driver translated arguments. Note that toolchains may perform their
- /// own argument translation.
- llvm::opt::DerivedArgList *TranslatedArgs;
-
- /// The list of actions.
- ActionList Actions;
-
- /// The root list of jobs.
- JobList Jobs;
-
- /// Cache of translated arguments for a particular tool chain and bound
- /// architecture.
- llvm::DenseMap<std::pair<const ToolChain *, const char *>,
- llvm::opt::DerivedArgList *> TCArgs;
-
- /// Temporary files which should be removed on exit.
- llvm::opt::ArgStringList TempFiles;
-
- /// Result files which should be removed on failure.
- ArgStringMap ResultFiles;
-
- /// Result files which are generated correctly on failure, and which should
- /// only be removed if we crash.
- ArgStringMap FailureResultFiles;
-
- /// Redirection for stdout, stderr, etc.
- const StringRef **Redirects;
-
- /// Whether we're compiling for diagnostic purposes.
- bool ForDiagnostics;
-
-public:
- Compilation(const Driver &D, const ToolChain &DefaultToolChain,
- llvm::opt::InputArgList *Args,
- llvm::opt::DerivedArgList *TranslatedArgs);
- ~Compilation();
-
- const Driver &getDriver() const { return TheDriver; }
-
- const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
- const ToolChain *getCudaHostToolChain() const { return CudaHostToolChain; }
- const ToolChain *getCudaDeviceToolChain() const {
- return CudaDeviceToolChain;
- }
-
- void setCudaHostToolChain(const ToolChain *HostToolChain) {
- CudaHostToolChain = HostToolChain;
- }
- void setCudaDeviceToolChain(const ToolChain *DeviceToolChain) {
- CudaDeviceToolChain = DeviceToolChain;
- }
-
- const llvm::opt::InputArgList &getInputArgs() const { return *Args; }
-
- const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; }
-
- llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; }
-
- ActionList &getActions() { return Actions; }
- const ActionList &getActions() const { return Actions; }
-
- JobList &getJobs() { return Jobs; }
- const JobList &getJobs() const { return Jobs; }
-
- void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); }
-
- const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }
-
- const ArgStringMap &getResultFiles() const { return ResultFiles; }
-
- const ArgStringMap &getFailureResultFiles() const {
- return FailureResultFiles;
- }
-
- /// Returns the sysroot path.
- StringRef getSysRoot() const;
-
- /// getArgsForToolChain - Return the derived argument list for the
- /// tool chain \p TC (or the default tool chain, if TC is not specified).
- ///
- /// \param BoundArch - The bound architecture name, or 0.
- const llvm::opt::DerivedArgList &getArgsForToolChain(const ToolChain *TC,
- const char *BoundArch);
-
- /// addTempFile - Add a file to remove on exit, and returns its
- /// argument.
- const char *addTempFile(const char *Name) {
- TempFiles.push_back(Name);
- return Name;
- }
-
- /// addResultFile - Add a file to remove on failure, and returns its
- /// argument.
- const char *addResultFile(const char *Name, const JobAction *JA) {
- ResultFiles[JA] = Name;
- return Name;
- }
-
- /// addFailureResultFile - Add a file to remove if we crash, and returns its
- /// argument.
- const char *addFailureResultFile(const char *Name, const JobAction *JA) {
- FailureResultFiles[JA] = Name;
- return Name;
- }
-
- /// CleanupFile - Delete a given file.
- ///
- /// \param IssueErrors - Report failures as errors.
- /// \return Whether the file was removed successfully.
- bool CleanupFile(const char *File, bool IssueErrors = false) const;
-
- /// CleanupFileList - Remove the files in the given list.
- ///
- /// \param IssueErrors - Report failures as errors.
- /// \return Whether all files were removed successfully.
- bool CleanupFileList(const llvm::opt::ArgStringList &Files,
- bool IssueErrors = false) const;
-
- /// CleanupFileMap - Remove the files in the given map.
- ///
- /// \param JA - If specified, only delete the files associated with this
- /// JobAction. Otherwise, delete all files in the map.
- /// \param IssueErrors - Report failures as errors.
- /// \return Whether all files were removed successfully.
- bool CleanupFileMap(const ArgStringMap &Files,
- const JobAction *JA,
- bool IssueErrors = false) const;
-
- /// ExecuteCommand - Execute an actual command.
- ///
- /// \param FailingCommand - For non-zero results, this will be set to the
- /// Command which failed, if any.
- /// \return The result code of the subprocess.
- int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
-
- /// ExecuteJob - Execute a single job.
- ///
- /// \param FailingCommands - For non-zero results, this will be a vector of
- /// failing commands and their associated result code.
- void ExecuteJobs(
- const JobList &Jobs,
- SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const;
-
- /// initCompilationForDiagnostics - Remove stale state and suppress output
- /// so compilation can be reexecuted to generate additional diagnostic
- /// information (e.g., preprocessed source(s)).
- void initCompilationForDiagnostics();
-
- /// Return true if we're compiling for diagnostics.
- bool isForDiagnostics() const { return ForDiagnostics; }
-};
-
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
deleted file mode 100644
index c9940ba..0000000
--- a/include/clang/Driver/Driver.h
+++ /dev/null
@@ -1,468 +0,0 @@
-//===--- Driver.h - Clang GCC Compatible Driver -----------------*- 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_DRIVER_DRIVER_H
-#define LLVM_CLANG_DRIVER_DRIVER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Driver/Phases.h"
-#include "clang/Driver/Types.h"
-#include "clang/Driver/Util.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/Path.h" // FIXME: Kill when CompilationInfo
-#include <memory>
- // lands.
-#include <list>
-#include <set>
-#include <string>
-
-namespace llvm {
-namespace opt {
- class Arg;
- class ArgList;
- class DerivedArgList;
- class InputArgList;
- class OptTable;
-}
-}
-
-namespace clang {
-
-namespace vfs {
-class FileSystem;
-}
-
-namespace driver {
-
- class Action;
- class Command;
- class Compilation;
- class InputInfo;
- class JobList;
- class JobAction;
- class SanitizerArgs;
- class ToolChain;
-
-/// Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
-enum LTOKind {
- LTOK_None,
- LTOK_Full,
- LTOK_Thin,
- LTOK_Unknown
-};
-
-/// Driver - Encapsulate logic for constructing compilation processes
-/// from a set of gcc-driver-like command line arguments.
-class Driver {
- llvm::opt::OptTable *Opts;
-
- DiagnosticsEngine &Diags;
-
- IntrusiveRefCntPtr<vfs::FileSystem> VFS;
-
- enum DriverMode {
- GCCMode,
- GXXMode,
- CPPMode,
- CLMode
- } Mode;
-
- enum SaveTempsMode {
- SaveTempsNone,
- SaveTempsCwd,
- SaveTempsObj
- } SaveTemps;
-
- /// LTO mode selected via -f(no-)?lto(=.*)? options.
- LTOKind LTOMode;
-
-public:
- // Diag - Forwarding function for diagnostics.
- DiagnosticBuilder Diag(unsigned DiagID) const {
- return Diags.Report(DiagID);
- }
-
- // FIXME: Privatize once interface is stable.
-public:
- /// The name the driver was invoked as.
- std::string Name;
-
- /// The path the driver executable was in, as invoked from the
- /// command line.
- std::string Dir;
-
- /// The original path to the clang executable.
- std::string ClangExecutable;
-
- /// The path to the installed clang directory, if any.
- std::string InstalledDir;
-
- /// The path to the compiler resource directory.
- std::string ResourceDir;
-
- /// 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
- /// universal driver when it is ready.
- typedef SmallVector<std::string, 4> prefix_list;
- prefix_list PrefixDirs;
-
- /// sysroot, if present
- std::string SysRoot;
-
- /// Dynamic loader prefix, if present
- std::string DyldPrefix;
-
- /// If the standard library is used
- bool UseStdLib;
-
- /// Default target triple.
- std::string DefaultTargetTriple;
-
- /// Driver title to use with help.
- std::string DriverTitle;
-
- /// Information about the host which can be overridden by the user.
- std::string HostBits, HostMachine, HostSystem, HostRelease;
-
- /// The file to log CC_PRINT_OPTIONS output to, if enabled.
- const char *CCPrintOptionsFilename;
-
- /// The file to log CC_PRINT_HEADERS output to, if enabled.
- const char *CCPrintHeadersFilename;
-
- /// The file to log CC_LOG_DIAGNOSTICS output to, if enabled.
- const char *CCLogDiagnosticsFilename;
-
- /// A list of inputs and their types for the given arguments.
- typedef SmallVector<std::pair<types::ID, const llvm::opt::Arg *>, 16>
- InputList;
-
- /// Whether the driver should follow g++ like behavior.
- bool CCCIsCXX() const { return Mode == GXXMode; }
-
- /// Whether the driver is just the preprocessor.
- bool CCCIsCPP() const { return Mode == CPPMode; }
-
- /// Whether the driver should follow cl.exe like behavior.
- bool IsCLMode() const { return Mode == CLMode; }
-
- /// Only print tool bindings, don't build any jobs.
- unsigned CCCPrintBindings : 1;
-
- /// Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to
- /// CCPrintOptionsFilename or to stderr.
- unsigned CCPrintOptions : 1;
-
- /// Set CC_PRINT_HEADERS mode, which causes the frontend to log header include
- /// information to CCPrintHeadersFilename or to stderr.
- unsigned CCPrintHeaders : 1;
-
- /// Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics
- /// to CCLogDiagnosticsFilename or to stderr, in a stable machine readable
- /// format.
- unsigned CCLogDiagnostics : 1;
-
- /// Whether the driver is generating diagnostics for debugging purposes.
- unsigned CCGenDiagnostics : 1;
-
-private:
- /// Name to use when invoking gcc/g++.
- std::string CCCGenericGCCName;
-
- /// Whether to check that input files exist when constructing compilation
- /// jobs.
- unsigned CheckInputsExist : 1;
-
-public:
- /// Use lazy precompiled headers for PCH support.
- unsigned CCCUsePCH : 1;
-
-private:
- /// Certain options suppress the 'no input files' warning.
- bool SuppressMissingInputWarning : 1;
-
- std::list<std::string> TempFiles;
- std::list<std::string> ResultFiles;
-
- /// \brief 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
- /// stored in it, and will clean them up when torn down.
- mutable llvm::StringMap<ToolChain *> ToolChains;
-
-private:
- /// TranslateInputArgs - Create a new derived argument list from the input
- /// arguments, after applying the standard argument translations.
- llvm::opt::DerivedArgList *
- TranslateInputArgs(const llvm::opt::InputArgList &Args) const;
-
- // getFinalPhase - Determine which compilation mode we are in and record
- // which option we used to determine the final phase.
- phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
- llvm::opt::Arg **FinalPhaseArg = nullptr) const;
-
- // Before executing jobs, sets up response files for commands that need them.
- void setUpResponseFiles(Compilation &C, Command &Cmd);
-
- void generatePrefixedToolNames(const char *Tool, const ToolChain &TC,
- SmallVectorImpl<std::string> &Names) const;
-
-public:
- Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
- DiagnosticsEngine &Diags,
- IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
- ~Driver();
-
- /// @name Accessors
- /// @{
-
- /// Name to use when invoking gcc/g++.
- const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; }
-
- const llvm::opt::OptTable &getOpts() const { return *Opts; }
-
- const DiagnosticsEngine &getDiags() const { return Diags; }
-
- vfs::FileSystem &getVFS() const { return *VFS; }
-
- bool getCheckInputsExist() const { return CheckInputsExist; }
-
- void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
-
- const std::string &getTitle() { return DriverTitle; }
- void setTitle(std::string Value) { DriverTitle = Value; }
-
- /// \brief 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.
- const char *getInstalledDir() const {
- if (!InstalledDir.empty())
- return InstalledDir.c_str();
- return Dir.c_str();
- }
- void setInstalledDir(StringRef Value) {
- InstalledDir = Value;
- }
-
- bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; }
- bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
-
- /// @}
- /// @name Primary Functionality
- /// @{
-
- /// BuildCompilation - Construct a compilation object for a command
- /// line argument vector.
- ///
- /// \return A compilation, or 0 if none was built for the given
- /// argument vector. A null return value does not necessarily
- /// indicate an error condition, the diagnostics should be queried
- /// to determine if an error occurred.
- Compilation *BuildCompilation(ArrayRef<const char *> Args);
-
- /// @name Driver Steps
- /// @{
-
- /// ParseDriverMode - Look for and handle the driver mode option in Args.
- void ParseDriverMode(ArrayRef<const char *> Args);
-
- /// ParseArgStrings - Parse the given list of strings into an
- /// ArgList.
- llvm::opt::InputArgList ParseArgStrings(ArrayRef<const char *> Args);
-
- /// BuildInputs - Construct the list of inputs and their types from
- /// the given arguments.
- ///
- /// \param TC - The default host tool chain.
- /// \param Args - The input arguments.
- /// \param Inputs - The list to store the resulting compilation
- /// inputs onto.
- void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args,
- InputList &Inputs) const;
-
- /// BuildActions - Construct the list of actions to perform for the
- /// given arguments, which are only done for a single architecture.
- ///
- /// \param C - The compilation that is being built.
- /// \param TC - The default host tool chain.
- /// \param Args - The input arguments.
- /// \param Actions - The list to store the resulting actions onto.
- void BuildActions(Compilation &C, const ToolChain &TC,
- llvm::opt::DerivedArgList &Args, const InputList &Inputs,
- ActionList &Actions) const;
-
- /// BuildUniversalActions - Construct the list of actions to perform
- /// for the given arguments, which may require a universal build.
- ///
- /// \param C - The compilation that is being built.
- /// \param TC - The default host tool chain.
- void BuildUniversalActions(Compilation &C, const ToolChain &TC,
- const InputList &BAInputs) const;
-
- /// BuildJobs - Bind actions to concrete tools and translate
- /// arguments to form the list of jobs to run.
- ///
- /// \param C - The compilation that is being built.
- void BuildJobs(Compilation &C) const;
-
- /// ExecuteCompilation - Execute the compilation according to the command line
- /// arguments and return an appropriate exit code.
- ///
- /// This routine handles additional processing that must be done in addition
- /// to just running the subprocesses, for example reporting errors, setting
- /// up response files, removing temporary files, etc.
- int ExecuteCompilation(Compilation &C,
- SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands);
-
- /// generateCompilationDiagnostics - Generate diagnostics information
- /// including preprocessed source file(s).
- ///
- void generateCompilationDiagnostics(Compilation &C,
- const Command &FailingCommand);
-
- /// @}
- /// @name Helper Methods
- /// @{
-
- /// PrintActions - Print the list of actions.
- void PrintActions(const Compilation &C) const;
-
- /// PrintHelp - Print the help text.
- ///
- /// \param ShowHidden - Show hidden options.
- void PrintHelp(bool ShowHidden) const;
-
- /// PrintVersion - Print the driver version.
- void PrintVersion(const Compilation &C, raw_ostream &OS) const;
-
- /// GetFilePath - Lookup \p Name in the list of file search paths.
- ///
- /// \param TC - The tool chain for additional information on
- /// directories to search.
- //
- // FIXME: This should be in CompilationInfo.
- std::string GetFilePath(const char *Name, const ToolChain &TC) const;
-
- /// GetProgramPath - Lookup \p Name in the list of program search paths.
- ///
- /// \param TC - The provided tool chain for additional information on
- /// directories to search.
- //
- // FIXME: This should be in CompilationInfo.
- std::string GetProgramPath(const char *Name, const ToolChain &TC) const;
-
- /// HandleImmediateArgs - Handle any arguments which should be
- /// treated before building actions or binding tools.
- ///
- /// \return Whether any compilation should be built for this
- /// invocation.
- bool HandleImmediateArgs(const Compilation &C);
-
- /// ConstructAction - Construct the appropriate action to do for
- /// \p Phase on the \p Input, taking in to account arguments
- /// like -fsyntax-only or --analyze.
- std::unique_ptr<Action>
- ConstructPhaseAction(const ToolChain &TC, const llvm::opt::ArgList &Args,
- phases::ID Phase, std::unique_ptr<Action> Input) const;
-
- /// BuildJobsForAction - Construct the jobs to perform for the
- /// action \p A.
- void BuildJobsForAction(Compilation &C,
- const Action *A,
- const ToolChain *TC,
- const char *BoundArch,
- bool AtTopLevel,
- bool MultipleArchs,
- const char *LinkingOutput,
- InputInfo &Result) const;
-
- /// Returns the default name for linked images (e.g., "a.out").
- const char *getDefaultImageName() const;
-
- /// GetNamedOutputPath - Return the name to use for the output of
- /// the action \p JA. The result is appended to the compilation's
- /// list of temporary or result files, as appropriate.
- ///
- /// \param C - The compilation.
- /// \param JA - The action of interest.
- /// \param BaseInput - The original input file that this action was
- /// triggered by.
- /// \param BoundArch - The bound architecture.
- /// \param AtTopLevel - Whether this is a "top-level" action.
- /// \param MultipleArchs - Whether multiple -arch options were supplied.
- const char *GetNamedOutputPath(Compilation &C,
- const JobAction &JA,
- const char *BaseInput,
- const char *BoundArch,
- bool AtTopLevel,
- bool MultipleArchs) const;
-
- /// GetTemporaryPath - Return the pathname of a temporary file to use
- /// as part of compilation; the file will have the given prefix and suffix.
- ///
- /// GCC goes to extra lengths here to be a bit more robust.
- std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const;
-
- /// ShouldUseClangCompiler - Should the clang compiler be used to
- /// handle this action.
- bool ShouldUseClangCompiler(const JobAction &JA) const;
-
- /// Returns true if we are performing any kind of LTO.
- bool isUsingLTO() const { return LTOMode != LTOK_None; }
-
- /// Get the specific kind of LTO being performed.
- LTOKind getLTOMode() const { return LTOMode; }
-
-private:
- /// Parse the \p Args list for LTO options and record the type of LTO
- /// 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.
- ///
- /// Will cache ToolChains for the life of the driver object, and create them
- /// on-demand.
- const ToolChain &getToolChain(const llvm::opt::ArgList &Args,
- const llvm::Triple &Target) const;
-
- /// @}
-
- /// \brief Get bitmasks for which option flags to include and exclude based on
- /// the driver mode.
- std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks() const;
-
-public:
- /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
- /// return the grouped values as integers. Numbers which are not
- /// provided are set to 0.
- ///
- /// \return True if the entire string was parsed (9.2), or all
- /// groups were parsed (10.3.5extrastuff). HadExtra is true if all
- /// groups were parsed but extra characters remain at the end.
- static bool GetReleaseVersion(const char *Str, unsigned &Major,
- unsigned &Minor, unsigned &Micro,
- bool &HadExtra);
-};
-
-/// \return True if the last defined optimization level is -Ofast.
-/// And False otherwise.
-bool isOptimizationLevelFast(const llvm::opt::ArgList &Args);
-
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h
deleted file mode 100644
index 680338a..0000000
--- a/include/clang/Driver/DriverDiagnostic.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- 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_DRIVER_DRIVERDIAGNOSTIC_H
-#define LLVM_CLANG_DRIVER_DRIVERDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define DRIVERSTART
-#include "clang/Basic/DiagnosticDriverKinds.inc"
-#undef DIAG
- NUM_BUILTIN_DRIVER_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
deleted file mode 100644
index 263356f..0000000
--- a/include/clang/Driver/Job.h
+++ /dev/null
@@ -1,174 +0,0 @@
-//===--- Job.h - Commands to Execute ----------------------------*- 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_DRIVER_JOB_H
-#define LLVM_CLANG_DRIVER_JOB_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Option/Option.h"
-#include <memory>
-
-namespace llvm {
- class raw_ostream;
-}
-
-namespace clang {
-namespace driver {
-class Action;
-class Command;
-class Tool;
-class InputInfo;
-
-// Re-export this as clang::driver::ArgStringList.
-using llvm::opt::ArgStringList;
-
-struct CrashReportInfo {
- StringRef Filename;
- StringRef VFSPath;
-
- CrashReportInfo(StringRef Filename, StringRef VFSPath)
- : Filename(Filename), VFSPath(VFSPath) {}
-};
-
-/// Command - An executable path/name and argument vector to
-/// execute.
-class Command {
- /// Source - The action which caused the creation of this job.
- const Action &Source;
-
- /// Tool - The tool which caused the creation of this job.
- const Tool &Creator;
-
- /// The executable to run.
- const char *Executable;
-
- /// The list of program arguments (not including the implicit first
- /// argument, which will be the executable).
- llvm::opt::ArgStringList Arguments;
-
- /// The list of program arguments which are inputs.
- llvm::opt::ArgStringList InputFilenames;
-
- /// Response file name, if this command is set to use one, or nullptr
- /// otherwise
- const char *ResponseFile;
-
- /// The input file list in case we need to emit a file list instead of a
- /// proper response file
- llvm::opt::ArgStringList InputFileList;
-
- /// String storage if we need to create a new argument to specify a response
- /// file
- std::string ResponseFileFlag;
-
- /// When a response file is needed, we try to put most arguments in an
- /// exclusive file, while others remains as regular command line arguments.
- /// This functions fills a vector with the regular command line arguments,
- /// argv, excluding the ones passed in a response file.
- void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
-
- /// Encodes an array of C strings into a single string separated by whitespace.
- /// This function will also put in quotes arguments that have whitespaces and
- /// will escape the regular backslashes (used in Windows paths) and quotes.
- /// The results are the contents of a response file, written into a raw_ostream.
- void writeResponseFile(raw_ostream &OS) const;
-
-public:
- Command(const Action &Source, const Tool &Creator, const char *Executable,
- const llvm::opt::ArgStringList &Arguments,
- ArrayRef<InputInfo> Inputs);
- // 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 void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
- CrashReportInfo *CrashInfo = nullptr) const;
-
- virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
- bool *ExecutionFailed) const;
-
- /// getSource - Return the Action which caused the creation of this job.
- const Action &getSource() const { return Source; }
-
- /// getCreator - Return the Tool which caused the creation of this job.
- const Tool &getCreator() const { return Creator; }
-
- /// Set to pass arguments via a response file when launching the command
- void setResponseFile(const char *FileName);
-
- /// Set an input file list, necessary if we need to use a response file but
- /// the tool being called only supports input files lists.
- void setInputFileList(llvm::opt::ArgStringList List) {
- InputFileList = std::move(List);
- }
-
- const char *getExecutable() const { return Executable; }
-
- const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
-
- /// Print a command argument, and optionally quote it.
- static void printArg(llvm::raw_ostream &OS, const char *Arg, bool Quote);
-};
-
-/// Like Command, but with a fallback which is executed in case
-/// the primary command crashes.
-class FallbackCommand : public Command {
-public:
- FallbackCommand(const Action &Source_, const Tool &Creator_,
- const char *Executable_, const ArgStringList &Arguments_,
- ArrayRef<InputInfo> Inputs,
- std::unique_ptr<Command> Fallback_);
-
- void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
- CrashReportInfo *CrashInfo = nullptr) const override;
-
- int Execute(const StringRef **Redirects, std::string *ErrMsg,
- bool *ExecutionFailed) const override;
-
-private:
- std::unique_ptr<Command> Fallback;
-};
-
-/// 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;
-
-private:
- list_type Jobs;
-
-public:
- void Print(llvm::raw_ostream &OS, const char *Terminator,
- bool Quote, CrashReportInfo *CrashInfo = nullptr) const;
-
- /// Add a job to the list (taking ownership).
- void addJob(std::unique_ptr<Command> J) { Jobs.push_back(std::move(J)); }
-
- /// Clear the job list.
- void clear();
-
- const list_type &getJobs() const { return Jobs; }
-
- size_type size() const { return Jobs.size(); }
- iterator begin() { return Jobs.begin(); }
- const_iterator begin() const { return Jobs.begin(); }
- iterator end() { return Jobs.end(); }
- const_iterator end() const { return Jobs.end(); }
-};
-
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile
deleted file mode 100644
index 8309330..0000000
--- a/include/clang/Driver/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-CLANG_LEVEL := ../../..
-BUILT_SOURCES = Options.inc
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/Options.inc.tmp : Options.td CC1Options.td CLCompatOptions.td $(LLVM_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang Driver Option tables with tblgen"
- $(Verb) $(LLVMTableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h
deleted file mode 100644
index 20bb80d..0000000
--- a/include/clang/Driver/Multilib.h
+++ /dev/null
@@ -1,175 +0,0 @@
-//===--- Multilib.h ---------------------------------------------*- 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_DRIVER_MULTILIB_H
-#define LLVM_CLANG_DRIVER_MULTILIB_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Option/Option.h"
-#include <functional>
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace driver {
-
-/// This corresponds to a single GCC Multilib, or a segment of one controlled
-/// by a command line flag
-class Multilib {
-public:
- typedef std::vector<std::string> flags_list;
-
-private:
- std::string GCCSuffix;
- std::string OSSuffix;
- std::string IncludeSuffix;
- flags_list Flags;
-
-public:
- Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "",
- StringRef IncludeSuffix = "");
-
- /// \brief 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
- /// 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
- /// 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
- /// All elements begin with either '+' or '-'
- const flags_list &flags() const { return Flags; }
- flags_list &flags() { return Flags; }
- /// Add a flag to the flags list
- Multilib &flag(StringRef F) {
- assert(F.front() == '+' || F.front() == '-');
- Flags.push_back(F);
- return *this;
- }
-
- /// \brief print summary of the Multilib
- void print(raw_ostream &OS) const;
-
- /// Check whether any of the 'against' flags contradict the 'for' flags.
- bool isValid() const;
-
- /// Check whether the default is selected
- bool isDefault() const
- { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
-
- bool operator==(const Multilib &Other) const;
-};
-
-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>(
- StringRef InstallDir, StringRef Triple, const Multilib &M)>
- IncludeDirsFunc;
-
- typedef llvm::function_ref<bool(const Multilib &)> FilterCallback;
-
-private:
- multilib_list Multilibs;
- IncludeDirsFunc IncludeCallback;
-
-public:
- MultilibSet() {}
-
- /// Add an optional Multilib segment
- MultilibSet &Maybe(const Multilib &M);
-
- /// Add a set of mutually incompatible Multilib segments
- MultilibSet &Either(const Multilib &M1, const Multilib &M2);
- MultilibSet &Either(const Multilib &M1, const Multilib &M2,
- const Multilib &M3);
- MultilibSet &Either(const Multilib &M1, const Multilib &M2,
- const Multilib &M3, const Multilib &M4);
- MultilibSet &Either(const Multilib &M1, const Multilib &M2,
- const Multilib &M3, const Multilib &M4,
- const Multilib &M5);
- MultilibSet &Either(ArrayRef<Multilib> Ms);
-
- /// 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);
-
- /// Add a completed Multilib to the set
- void push_back(const Multilib &M);
-
- /// Union this set of multilibs with another
- void combineWith(const MultilibSet &MS);
-
- /// Remove all of thie multilibs from the set
- void clear() { Multilibs.clear(); }
-
- iterator begin() { return Multilibs.begin(); }
- const_iterator begin() const { return Multilibs.begin(); }
-
- iterator end() { return Multilibs.end(); }
- const_iterator end() const { return Multilibs.end(); }
-
- /// Pick the best multilib in the set, \returns false if none are compatible
- bool select(const Multilib::flags_list &Flags, Multilib &M) const;
-
- unsigned size() const { return Multilibs.size(); }
-
- void print(raw_ostream &OS) const;
-
- MultilibSet &setIncludeDirsCallback(IncludeDirsFunc F) {
- IncludeCallback = std::move(F);
- return *this;
- }
- const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; }
-
-private:
- /// Apply the filter to Multilibs and return the subset that remains
- static multilib_list filterCopy(FilterCallback F, const multilib_list &Ms);
-
- /// Apply the filter to the multilib_list, removing those that don't match
- static void filterInPlace(FilterCallback F, multilib_list &Ms);
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
-}
-}
-
-#endif
-
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
deleted file mode 100644
index 2716fa9..0000000
--- a/include/clang/Driver/Options.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===--- Options.h - Option info & table ------------------------*- 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_DRIVER_OPTIONS_H
-#define LLVM_CLANG_DRIVER_OPTIONS_H
-
-namespace llvm {
-namespace opt {
-class OptTable;
-}
-}
-
-namespace clang {
-namespace driver {
-
-namespace options {
-/// Flags specifically for clang options. Must not overlap with
-/// llvm::opt::DriverFlag.
-enum ClangFlags {
- DriverOption = (1 << 4),
- LinkerInput = (1 << 5),
- NoArgumentUnused = (1 << 6),
- Unsupported = (1 << 7),
- CoreOption = (1 << 8),
- CLOption = (1 << 9),
- CC1Option = (1 << 10),
- CC1AsOption = (1 << 11),
- NoDriverOption = (1 << 12)
-};
-
-enum ID {
- OPT_INVALID = 0, // This is not an option ID.
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) OPT_##ID,
-#include "clang/Driver/Options.inc"
- LastOption
-#undef OPTION
- };
-}
-
-llvm::opt::OptTable *createDriverOptTable();
-}
-}
-
-#endif
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
deleted file mode 100644
index e219a9b..0000000
--- a/include/clang/Driver/Options.td
+++ /dev/null
@@ -1,2133 +0,0 @@
-//===--- Options.td - Options for clang -----------------------------------===//
-//
-// 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 options accepted by clang.
-//
-//===----------------------------------------------------------------------===//
-
-// Include the common option parsing interfaces.
-include "llvm/Option/OptParser.td"
-
-/////////
-// Flags
-
-// DriverOption - The option is a "driver" option, and should not be forwarded
-// to other tools.
-def DriverOption : OptionFlag;
-
-// LinkerInput - The option is a linker input.
-def LinkerInput : OptionFlag;
-
-// NoArgumentUnused - Don't report argument unused warnings for this option; this
-// is useful for options like -static or -dynamic which a user may always end up
-// passing, even if the platform defaults to (or only supports) that option.
-def NoArgumentUnused : OptionFlag;
-
-// Unsupported - The option is unsupported, and the driver will reject command
-// lines that use it.
-def Unsupported : OptionFlag;
-
-// CoreOption - This is considered a "core" Clang option, available in both
-// clang and clang-cl modes.
-def CoreOption : OptionFlag;
-
-// CLOption - This is a cl.exe compatibility option. Options with this flag
-// are made available when the driver is running in CL compatibility mode.
-def CLOption : OptionFlag;
-
-// CC1Option - This option should be accepted by clang -cc1.
-def CC1Option : OptionFlag;
-
-// CC1AsOption - This option should be accepted by clang -cc1as.
-def CC1AsOption : OptionFlag;
-
-// NoDriverOption - This option should not be accepted by the driver.
-def NoDriverOption : OptionFlag;
-
-/////////
-// Groups
-
-// Meta-group for options which are only used for compilation,
-// and not linking etc.
-def CompileOnly_Group : OptionGroup<"<CompileOnly group>">;
-
-def Action_Group : OptionGroup<"<action group>">;
-
-def I_Group : OptionGroup<"<I group>">, Group<CompileOnly_Group>;
-def M_Group : OptionGroup<"<M group>">, Group<CompileOnly_Group>;
-def T_Group : OptionGroup<"<T group>">;
-def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
-def R_Group : OptionGroup<"<R group>">, Group<CompileOnly_Group>;
-def R_value_Group : OptionGroup<"<R (with value) group>">, Group<R_Group>;
-def W_Group : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
-def W_value_Group : OptionGroup<"<W (with value) group>">, Group<W_Group>;
-def d_Group : OptionGroup<"<d group>">;
-def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
-def f_clang_Group : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>;
-def g_Group : OptionGroup<"<g group>">;
-def gN_Group : OptionGroup<"<gN group>">, Group<g_Group>;
-def ggdbN_Group : OptionGroup<"<ggdbN group>">, Group<gN_Group>;
-def gTune_Group : OptionGroup<"<gTune group>">, Group<g_Group>;
-def g_flags_Group : OptionGroup<"<g flags group>">;
-def i_Group : OptionGroup<"<i group>">, Group<CompileOnly_Group>;
-def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>;
-def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>;
-
-// Feature groups - these take command line options that correspond directly to
-// target specific features and can be translated directly from command line
-// options.
-def m_x86_Features_Group : OptionGroup<"<x86 features group>">,
- Group<m_Group>,
- Flags<[CoreOption]>;
-def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">,
- Group<m_Group>;
-def m_arm_Features_Group : OptionGroup<"<arm features group>">,
- Group<m_Group>;
-def m_aarch64_Features_Group : OptionGroup<"<aarch64 features group>">,
- Group<m_Group>;
-def m_ppc_Features_Group : OptionGroup<"<ppc features group>">,
- Group<m_Group>;
-def m_wasm_Features_Group : OptionGroup<"<wasm features group>">,
- Group<m_Group>;
-
-def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>;
-def u_Group : OptionGroup<"<u group>">;
-
-def pedantic_Group : OptionGroup<"<pedantic group>">,
- Group<CompileOnly_Group>;
-def reserved_lib_Group : OptionGroup<"<reserved libs group>">;
-
-// Temporary groups for clang options which we know we don't support,
-// but don't want to verbosely warn the user about.
-def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">,
- Group<f_Group>;
-def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
- Group<m_Group>;
-
-// Group that ignores all gcc optimizations that won't be implemented
-def clang_ignored_gcc_optimization_f_Group : OptionGroup<
- "<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>;
-
-/////////
-// Options
-
-// The internal option ID must be a valid C++ identifier and results in a
-// clang::driver::options::OPT_XX enum constant for XX.
-//
-// We want to unambiguously be able to refer to options from the driver source
-// code, for this reason the option name is mangled into an ID. This mangling
-// isn't guaranteed to have an inverse, but for practical purposes it does.
-//
-// The mangling scheme is to ignore the leading '-', and perform the following
-// substitutions:
-// _ => __
-// - => _
-// / => _SLASH
-// # => _HASH
-// ? => _QUESTION
-// , => _COMMA
-// = => _EQ
-// C++ => CXX
-// . => _
-
-// Developer Driver Options
-
-def internal_Group : OptionGroup<"<clang internal options>">;
-def internal_driver_Group : OptionGroup<"<clang driver internal options>">,
- Group<internal_Group>, HelpText<"DRIVER OPTIONS">;
-def internal_debug_Group :
- OptionGroup<"<clang debug/development internal options>">,
- Group<internal_Group>, HelpText<"DEBUG/DEVELOPMENT OPTIONS">;
-
-class InternalDriverOpt : Group<internal_driver_Group>,
- Flags<[DriverOption, HelpHidden]>;
-def driver_mode : Joined<["--"], "driver-mode=">, Group<internal_driver_Group>,
- Flags<[CoreOption, DriverOption, HelpHidden]>,
- HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">;
-def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, InternalDriverOpt,
- HelpText<"Name for native GCC compiler">,
- MetaVarName<"<gcc-path>">;
-def ccc_pch_is_pch : Flag<["-"], "ccc-pch-is-pch">, InternalDriverOpt,
- HelpText<"Use lazy PCH for precompiled headers">;
-def ccc_pch_is_pth : Flag<["-"], "ccc-pch-is-pth">, InternalDriverOpt,
- HelpText<"Use pretokenized headers for precompiled headers">;
-
-class InternalDebugOpt : Group<internal_debug_Group>,
- Flags<[DriverOption, HelpHidden, CoreOption]>;
-def ccc_install_dir : Separate<["-"], "ccc-install-dir">, InternalDebugOpt,
- HelpText<"Simulate installation in the given directory">;
-def ccc_print_phases : Flag<["-"], "ccc-print-phases">, InternalDebugOpt,
- HelpText<"Dump list of actions to perform">;
-def ccc_print_bindings : Flag<["-"], "ccc-print-bindings">, InternalDebugOpt,
- HelpText<"Show bindings of tools to actions">;
-
-def ccc_arcmt_check : Flag<["-"], "ccc-arcmt-check">, InternalDriverOpt,
- HelpText<"Check for ARC migration issues that need manual handling">;
-def ccc_arcmt_modify : Flag<["-"], "ccc-arcmt-modify">, InternalDriverOpt,
- HelpText<"Apply modifications to files to conform to ARC">;
-def ccc_arcmt_migrate : Separate<["-"], "ccc-arcmt-migrate">, InternalDriverOpt,
- HelpText<"Apply modifications and produces temporary files that conform to ARC">;
-def arcmt_migrate_report_output : Separate<["-"], "arcmt-migrate-report-output">,
- HelpText<"Output path for the plist report">, Flags<[CC1Option]>;
-def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">,
- HelpText<"Emit ARC errors even if the migrator can fix them">,
- Flags<[CC1Option]>;
-
-def _migrate : Flag<["--"], "migrate">, Flags<[DriverOption]>,
- HelpText<"Run the migrator">;
-def ccc_objcmt_migrate : Separate<["-"], "ccc-objcmt-migrate">,
- InternalDriverOpt,
- HelpText<"Apply modifications and produces temporary files to migrate to "
- "modern ObjC syntax">;
-def objcmt_migrate_literals : Flag<["-"], "objcmt-migrate-literals">, Flags<[CC1Option]>,
- HelpText<"Enable migration to modern ObjC literals">;
-def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">, Flags<[CC1Option]>,
- HelpText<"Enable migration to modern ObjC subscripting">;
-def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">, Flags<[CC1Option]>,
- HelpText<"Enable migration to modern ObjC property">;
-def objcmt_migrate_all : Flag<["-"], "objcmt-migrate-all">, Flags<[CC1Option]>,
- HelpText<"Enable migration to modern ObjC">;
-def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">, Flags<[CC1Option]>,
- HelpText<"Enable migration to modern ObjC readonly property">;
-def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">, Flags<[CC1Option]>,
- HelpText<"Enable migration to modern ObjC readwrite property">;
-def objcmt_migrate_property_dot_syntax : Flag<["-"], "objcmt-migrate-property-dot-syntax">, Flags<[CC1Option]>,
- HelpText<"Enable migration of setter/getter messages to property-dot syntax">;
-def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">, Flags<[CC1Option]>,
- HelpText<"Enable migration to property and method annotations">;
-def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">, Flags<[CC1Option]>,
- HelpText<"Enable migration to infer instancetype for method result type">;
-def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">, Flags<[CC1Option]>,
- HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">;
-def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">, Flags<[CC1Option]>,
- HelpText<"Enable migration to add protocol conformance on classes">;
-def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, Flags<[CC1Option]>,
- HelpText<"Make migration to 'atomic' properties">;
-def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">, Flags<[CC1Option]>,
- HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">;
-def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>,
- HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">;
-def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, Flags<[CC1Option]>,
- HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">;
-def objcmt_whitelist_dir_path: Joined<["-"], "objcmt-whitelist-dir-path=">, Flags<[CC1Option]>,
- HelpText<"Only modify files with a filename contained in the provided directory path">;
-// The misspelt "white-list" [sic] alias is due for removal.
-def : Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>,
- Alias<objcmt_whitelist_dir_path>;
-
-// Make sure all other -ccc- options are rejected.
-def ccc_ : Joined<["-"], "ccc-">, Group<internal_Group>, Flags<[Unsupported]>;
-
-// Standard Options
-
-def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[DriverOption, CoreOption]>,
- HelpText<"Print (but do not run) the commands to run for this compilation">;
-def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>,
- Flags<[DriverOption, CoreOption]>;
-def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>;
-def B : JoinedOrSeparate<["-"], "B">;
-def CC : Flag<["-"], "CC">, Flags<[CC1Option]>;
-def C : Flag<["-"], "C">, Flags<[CC1Option]>;
-def D : JoinedOrSeparate<["-"], "D">, Group<CompileOnly_Group>, Flags<[CC1Option]>;
-def E : Flag<["-"], "E">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
- HelpText<"Only run the preprocessor">;
-def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined,CC1Option]>,
- HelpText<"Add directory to framework include search path">;
-def G : JoinedOrSeparate<["-"], "G">, Flags<[DriverOption]>;
-def G_EQ : Joined<["-"], "G=">, Flags<[DriverOption]>;
-def H : Flag<["-"], "H">, Flags<[CC1Option]>,
- HelpText<"Show header includes and nesting depth">;
-def I_ : Flag<["-"], "I-">, Group<I_Group>;
-def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option,CC1AsOption]>,
- HelpText<"Add directory to include search path">;
-def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>;
-def MD : Flag<["-"], "MD">, Group<M_Group>,
- HelpText<"Write a depfile containing user and system headers">;
-def MMD : Flag<["-"], "MMD">, Group<M_Group>,
- HelpText<"Write a depfile containing user headers">;
-def M : Flag<["-"], "M">, Group<M_Group>,
- HelpText<"Like -MD, but also implies -E and writes to stdout by default">;
-def MM : Flag<["-"], "MM">, Group<M_Group>,
- HelpText<"Like -MMD, but also implies -E and writes to stdout by default">;
-def MF : JoinedOrSeparate<["-"], "MF">, Group<M_Group>,
- HelpText<"Write depfile output from -MMD, -MD, -MM, or -M to <file>">,
- MetaVarName<"<file>">;
-def MG : Flag<["-"], "MG">, Group<M_Group>, Flags<[CC1Option]>,
- HelpText<"Add missing headers to depfile">;
-def MP : Flag<["-"], "MP">, Group<M_Group>, Flags<[CC1Option]>,
- HelpText<"Create phony target for each dependency (other than main file)">;
-def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>, Flags<[CC1Option]>,
- HelpText<"Specify name of main file output to quote in depfile">;
-def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>,
- HelpText<"Specify name of main file output in depfile">;
-def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>,
- HelpText<"Use NMake/Jom format for the depfile">;
-def Mach : Flag<["-"], "Mach">;
-def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>;
-def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>;
-def ObjCXX : Flag<["-"], "ObjC++">, Flags<[DriverOption]>,
- HelpText<"Treat source input files as Objective-C++ inputs">;
-def ObjC : Flag<["-"], "ObjC">, Flags<[DriverOption]>,
- HelpText<"Treat source input files as Objective-C inputs">;
-def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>;
-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]>,
- HelpText<"Disable linemarker output in -E mode">;
-def Qn : Flag<["-"], "Qn">;
-def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>,
- HelpText<"Don't emit warning for unused driver arguments">;
-def Q : Flag<["-"], "Q">;
-def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_value_Group>, Flags<[CC1Option]>,
- HelpText<"Report transformations performed by optimization passes whose "
- "name matches the given POSIX regular expression">;
-def Rpass_missed_EQ : Joined<["-"], "Rpass-missed=">, Group<R_value_Group>,
- Flags<[CC1Option]>,
- HelpText<"Report missed transformations by optimization passes whose "
- "name matches the given POSIX regular expression">;
-def Rpass_analysis_EQ : Joined<["-"], "Rpass-analysis=">, Group<R_value_Group>,
- Flags<[CC1Option]>,
- HelpText<"Report transformation analysis from optimization passes whose "
- "name matches the given POSIX regular expression">;
-def R_Joined : Joined<["-"], "R">, Group<R_Group>, Flags<[CC1Option, CoreOption]>,
- MetaVarName<"<remark>">, HelpText<"Enable the specified remark">;
-def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
- HelpText<"Only run preprocess and compilation steps">;
-def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>;
-def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group<T_Group>;
-def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group<T_Group>;
-def T : JoinedOrSeparate<["-"], "T">, Group<T_Group>;
-def U : JoinedOrSeparate<["-"], "U">, Group<CompileOnly_Group>, Flags<[CC1Option]>;
-def V : JoinedOrSeparate<["-"], "V">, Flags<[DriverOption, Unsupported]>;
-def Wa_COMMA : CommaJoined<["-"], "Wa,">,
- HelpText<"Pass the comma separated arguments in <arg> to the assembler">,
- MetaVarName<"<arg>">;
-def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CC1Option]>;
-def WCL4 : Flag<["-"], "WCL4">, Group<W_Group>, Flags<[CC1Option]>;
-def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>;
-def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>, Flags<[CC1Option]>;
-def Wextra : Flag<["-"], "Wextra">, Group<W_Group>, Flags<[CC1Option]>;
-def Wl_COMMA : CommaJoined<["-"], "Wl,">, Flags<[LinkerInput, RenderAsInput]>,
- HelpText<"Pass the comma separated arguments in <arg> to the linker">,
- MetaVarName<"<arg>">;
-// FIXME: This is broken; these should not be Joined arguments.
-def Wno_nonportable_cfstrings : Joined<["-"], "Wno-nonportable-cfstrings">, Group<W_Group>,
- Flags<[CC1Option]>;
-def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Group>,
- Flags<[CC1Option]>;
-def Wp_COMMA : CommaJoined<["-"], "Wp,">,
- HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
- MetaVarName<"<arg>">;
-def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option]>;
-def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option]>;
-def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
- MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
-def Xanalyzer : Separate<["-"], "Xanalyzer">,
- HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">;
-def Xarch__ : JoinedAndSeparate<["-"], "Xarch_">, Flags<[DriverOption]>;
-def Xassembler : Separate<["-"], "Xassembler">,
- HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">;
-def Xclang : Separate<["-"], "Xclang">,
- HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">,
- Flags<[DriverOption, CoreOption]>;
-def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
- HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">;
-def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
- HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
-def Xpreprocessor : Separate<["-"], "Xpreprocessor">,
- HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
-def X_Flag : Flag<["-"], "X">;
-def X_Joined : Joined<["-"], "X">;
-def Z_Flag : Flag<["-"], "Z">;
-def Z_Joined : Joined<["-"], "Z">;
-def all__load : Flag<["-"], "all_load">;
-def allowable__client : Separate<["-"], "allowable_client">;
-def ansi : Flag<["-", "--"], "ansi">;
-def arch__errors__fatal : Flag<["-"], "arch_errors_fatal">;
-def arch : Separate<["-"], "arch">, Flags<[DriverOption]>;
-def arch__only : Separate<["-"], "arch_only">;
-def a : Joined<["-"], "a">;
-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 client__name : JoinedOrSeparate<["-"], "client_name">;
-def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>;
-def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
-def coverage : Flag<["-", "--"], "coverage">;
-def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>;
-def current__version : JoinedOrSeparate<["-"], "current_version">;
-def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
- HelpText<"Add directory to the C++ SYSTEM include search path">, Flags<[CC1Option]>,
- MetaVarName<"<directory>">;
-def c : Flag<["-"], "c">, Flags<[DriverOption]>,
- HelpText<"Only run preprocess, compile, and assemble steps">;
-def cuda_device_only : Flag<["--"], "cuda-device-only">,
- HelpText<"Do device-side CUDA compilation only">;
-def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">,
- Flags<[DriverOption, HelpHidden]>, HelpText<"CUDA GPU architecture">;
-def cuda_host_only : Flag<["--"], "cuda-host-only">,
- HelpText<"Do host-side CUDA compilation only">;
-def cuda_path_EQ : Joined<["--"], "cuda-path=">, Group<i_Group>,
- HelpText<"CUDA installation path">;
-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">;
-def dM : Flag<["-"], "dM">, Group<d_Group>, Flags<[CC1Option]>,
- HelpText<"Print macro definitions in -E mode instead of normal output">;
-def dead__strip : Flag<["-"], "dead_strip">;
-def dependency_file : Separate<["-"], "dependency-file">, Flags<[CC1Option]>,
- HelpText<"Filename (or -) to write dependency output to">;
-def dependency_dot : Separate<["-"], "dependency-dot">, Flags<[CC1Option]>,
- HelpText<"Filename to write DOT-formatted header dependencies to">;
-def module_dependency_dir : Separate<["-"], "module-dependency-dir">,
- Flags<[CC1Option]>, HelpText<"Directory to dump module dependencies to">;
-def dumpmachine : Flag<["-"], "dumpmachine">;
-def dumpspecs : Flag<["-"], "dumpspecs">, Flags<[Unsupported]>;
-def dumpversion : Flag<["-"], "dumpversion">;
-def dylib__file : Separate<["-"], "dylib_file">;
-def dylinker__install__name : JoinedOrSeparate<["-"], "dylinker_install_name">;
-def dylinker : Flag<["-"], "dylinker">;
-def dynamiclib : Flag<["-"], "dynamiclib">;
-def dynamic : Flag<["-"], "dynamic">, Flags<[NoArgumentUnused]>;
-def d_Flag : Flag<["-"], "d">, Group<d_Group>;
-def d_Joined : Joined<["-"], "d">, Group<d_Group>;
-def emit_ast : Flag<["-"], "emit-ast">,
- HelpText<"Emit Clang AST files for source inputs">;
-def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option]>, Group<Action_Group>,
- HelpText<"Use the LLVM representation for assembler and object files">;
-def exported__symbols__list : Separate<["-"], "exported_symbols_list">;
-def e : JoinedOrSeparate<["-"], "e">;
-def fPIC : Flag<["-"], "fPIC">, Group<f_Group>;
-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 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">;
-def fapple_pragma_pack : Flag<["-"], "fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable Apple gcc-compatible #pragma pack handling">;
-def shared_libasan : Flag<["-"], "shared-libasan">;
-def fasm : Flag<["-"], "fasm">, Group<f_Group>;
-
-def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]>;
-def fno_asm_blocks : Flag<["-"], "fno-asm-blocks">, Group<f_Group>;
-
-def fassume_sane_operator_new : Flag<["-"], "fassume-sane-operator-new">, Group<f_Group>;
-def fastcp : Flag<["-"], "fastcp">, Group<f_Group>;
-def fastf : Flag<["-"], "fastf">, Group<f_Group>;
-def fast : Flag<["-"], "fast">, Group<f_Group>;
-def fasynchronous_unwind_tables : Flag<["-"], "fasynchronous-unwind-tables">, Group<f_Group>;
-
-def fautolink : Flag <["-"], "fautolink">, Group<f_Group>;
-def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>,
- Flags<[DriverOption, CC1Option]>,
- HelpText<"Disable generation of linker directives for automatic library linking">;
-
-def fgnu_inline_asm : Flag<["-"], "fgnu-inline-asm">, Group<f_Group>, Flags<[DriverOption]>;
-def fno_gnu_inline_asm : Flag<["-"], "fno-gnu-inline-asm">, Group<f_Group>,
- Flags<[DriverOption, CC1Option]>,
- HelpText<"Disable GNU style inline asm">;
-
-def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">,
- Group<f_Group>, Flags<[DriverOption, CC1Option]>,
- HelpText<"Enable sample-based profile guided optimizations">;
-def fauto_profile_EQ : Joined<["-"], "fauto-profile=">,
- Alias<fprofile_sample_use_EQ>;
-def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
- Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overriden by '=' form of option or LLVM_PROFILE_FILE env var)">;
-def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">,
- Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<file>">,
- HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">;
-def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
- Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Use instrumentation data for profile-guided optimization">;
-def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">,
- Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Generate coverage mapping to enable code coverage analysis">;
-def fno_coverage_mapping : Flag<["-"], "fno-coverage-mapping">,
- Group<f_Group>, Flags<[DriverOption]>,
- HelpText<"Disable code coverage analysis">;
-def fprofile_generate : Flag<["-"], "fprofile-generate">,
- Alias<fprofile_instr_generate>;
-def fprofile_generate_EQ : Joined<["-"], "fprofile-generate=">,
- Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<directory>">,
- HelpText<"Generate instrumented code to collect execution counts into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
-def fprofile_use : Flag<["-"], "fprofile-use">, Group<f_Group>,
- Alias<fprofile_instr_use>;
-def fprofile_use_EQ : Joined<["-"], "fprofile-use=">,
- Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<pathname>">,
- HelpText<"Use instrumentation data for profile-guided optimization. If pathname is a directory, it reads from <pathname>/default.profdata. Otherwise, it reads from file <pathname>.">;
-def fno_profile_instr_generate : Flag<["-"], "fno-profile-instr-generate">,
- Group<f_Group>, Flags<[DriverOption]>,
- HelpText<"Disable generation of profile instrumentation.">;
-def fno_profile_generate : Flag<["-"], "fno-profile-generate">,
- Alias<fno_profile_instr_generate>;
-def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">,
- Group<f_Group>, Flags<[DriverOption]>,
- HelpText<"Disable using instrumentation data for profile-guided optimization">;
-def fno_profile_use : Flag<["-"], "fno-profile-use">,
- Alias<fno_profile_instr_use>;
-
-def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[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 fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
-def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
-def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
- Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">;
-def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>,
- Flags<[CoreOption, DriverOption]>;
-def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group<f_Group>;
-def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group<f_Group>,
- Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">;
-def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">,
- MetaVarName<"<arg>">;
-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 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>;
-def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
-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]>;
-def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
-def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group<f_Group>,
- HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>;
-def fcxx_modules : Flag <["-"], "fcxx-modules">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fdebug_pass_arguments : Flag<["-"], "fdebug-pass-arguments">, Group<f_Group>;
-def fdebug_pass_structure : Flag<["-"], "fdebug-pass-structure">, Group<f_Group>;
-def fdepfile_entry : Joined<["-"], "fdepfile-entry=">,
- Group<f_clang_Group>, Flags<[CC1Option]>;
-def fdiagnostics_fixit_info : Flag<["-"], "fdiagnostics-fixit-info">, Group<f_clang_Group>;
-def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">, Group<f_clang_Group>,
- Flags<[CoreOption, CC1Option]>, HelpText<"Print fix-its in machine parseable form">;
-def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-source-range-info">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Print source range spans in numeric form">;
-def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">;
-def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">,
- Group<f_Group>, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">;
-def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group<f_clang_Group>;
-def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<f_clang_Group>;
-def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">,
- Group<f_Group>, Flags<[CC1Option]>,
- 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 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>;
-def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
-def fdwarf_directory_asm : Flag<["-"], "fdwarf-directory-asm">, Group<f_Group>;
-def fno_dwarf_directory_asm : Flag<["-"], "fno-dwarf-directory-asm">, Group<f_Group>, Flags<[CC1Option]>;
-def felide_constructors : Flag<["-"], "felide-constructors">, Group<f_Group>;
-def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>,
- Flags<[CC1Option]>,
- HelpText<"Do not elide types when printing diagnostics">;
-def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>;
-def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>,
- 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 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]>,
- HelpText<"Enable support for exception handling">;
-def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
-def : Flag<["-"], "fno-expensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
-def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>;
-def : Flag<["-"], "fdefer-pop">, Group<clang_ignored_gcc_optimization_f_Group>;
-def : Flag<["-"], "fno-defer-pop">, Group<clang_ignored_gcc_optimization_f_Group>;
-def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
-def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
-def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
-def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable the *frontend*'s 'fast-math' mode. This has no effect on "
- "optimizations, but provides a preprocessor macro __FAST_MATH__ the "
- "same as GCC's -ffast-math flag">;
-def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>;
-def fmath_errno : Flag<["-"], "fmath-errno">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Require math functions to indicate errors by setting errno">;
-def fno_math_errno : Flag<["-"], "fno-math-errno">, Group<f_Group>;
-def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>;
-def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>;
-def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>;
-def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
- Flags<[CC1Option, CoreOption]>, MetaVarName<"<check>">,
- HelpText<"Turn on runtime checks for various forms of undefined "
- "or suspicious behavior. See user manual for available checks">;
-def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>,
- Flags<[CoreOption]>;
-def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
- Group<f_clang_Group>, Flags<[CC1Option, CoreOption]>,
- HelpText<"Path to blacklist file for sanitizers">;
-def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
- Group<f_clang_Group>,
- HelpText<"Don't use blacklist file for sanitizers">;
-def fsanitize_coverage
- : CommaJoined<["-"], "fsanitize-coverage=">,
- Group<f_clang_Group>, Flags<[CoreOption]>,
- HelpText<"Specify the type of coverage instrumentation for Sanitizers">;
-def fno_sanitize_coverage
- : CommaJoined<["-"], "fno-sanitize-coverage=">,
- Group<f_clang_Group>, Flags<[CoreOption]>,
- HelpText<"Disable specified features of coverage instrumentation for "
- "Sanitizers">;
-def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Enable origins tracking in MemorySanitizer">;
-def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Enable origins tracking in MemorySanitizer">;
-def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Disable origins tracking in MemorySanitizer">;
-def fsanitize_memory_use_after_dtor : Flag<["-"], "fsanitize-memory-use-after-dtor">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Enable use-after-destroy detection in MemorySanitizer">;
-def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Level of field padding for AddressSanitizer">;
-def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>,
- Flags<[CoreOption]>;
-def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
- Group<f_clang_Group>, Flags<[CoreOption]>;
-def fsanitize_recover_EQ : CommaJoined<["-"], "fsanitize-recover=">,
- Group<f_clang_Group>,
- Flags<[CC1Option, CoreOption]>,
- HelpText<"Enable recovery for specified sanitizers">;
-def fno_sanitize_recover_EQ
- : CommaJoined<["-"], "fno-sanitize-recover=">,
- Group<f_clang_Group>, Flags<[CoreOption]>,
- HelpText<"Disable recovery for specified sanitizers">;
-def fsanitize_trap_EQ : CommaJoined<["-"], "fsanitize-trap=">, Group<f_clang_Group>,
- Flags<[CC1Option, CoreOption]>,
- HelpText<"Enable trapping for specified sanitizers">;
-def fno_sanitize_trap_EQ : CommaJoined<["-"], "fno-sanitize-trap=">, Group<f_clang_Group>,
- Flags<[CoreOption]>,
- HelpText<"Disable trapping for specified sanitizers">;
-def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on-error">,
- Group<f_clang_Group>;
-def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">,
- Group<f_clang_Group>;
-def fsanitize_link_cxx_runtime : Flag<["-"], "fsanitize-link-c++-runtime">,
- Group<f_clang_Group>;
-def fsanitize_cfi_cross_dso : Flag<["-"], "fsanitize-cfi-cross-dso">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Enable control flow integrity (CFI) checks for cross-DSO calls.">;
-def fno_sanitize_cfi_cross_dso : Flag<["-"], "fno-sanitize-cfi-cross-dso">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Disable control flow integrity (CFI) checks for cross-DSO calls.">;
-def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">,
- Group<f_Group>;
-def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">,
- Group<f_Group>;
-def fassociative_math : Flag<["-"], "fassociative-math">, Group<f_Group>;
-def fno_associative_math : Flag<["-"], "fno-associative-math">, Group<f_Group>;
-def freciprocal_math :
- Flag<["-"], "freciprocal-math">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Allow division operations to be reassociated">;
-def fno_reciprocal_math : Flag<["-"], "fno-reciprocal-math">, Group<f_Group>;
-def ffinite_math_only : Flag<["-"], "ffinite-math-only">, Group<f_Group>, Flags<[CC1Option]>;
-def fno_finite_math_only : Flag<["-"], "fno-finite-math-only">, Group<f_Group>;
-def fsigned_zeros : Flag<["-"], "fsigned-zeros">, Group<f_Group>;
-def fno_signed_zeros :
- Flag<["-"], "fno-signed-zeros">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Allow optimizations that ignore the sign of floating point zeros">;
-def fhonor_nans : Flag<["-"], "fhonor-nans">, Group<f_Group>;
-def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Group<f_Group>;
-def fhonor_infinities : Flag<["-"], "fhonor-infinities">, Group<f_Group>;
-def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<f_Group>;
-// This option was originally misspelt "infinites" [sic].
-def : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>;
-def : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>;
-def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>;
-def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>;
-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)">;
-
-def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>;
-def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;
-
-def frewrite_includes : Flag<["-"], "frewrite-includes">, Group<f_Group>,
- Flags<[CC1Option]>;
-def fno_rewrite_includes : Flag<["-"], "fno-rewrite-includes">, Group<f_Group>;
-
-def frewrite_map_file : Separate<["-"], "frewrite-map-file">,
- Group<f_Group>,
- Flags<[ DriverOption, CC1Option ]>;
-def frewrite_map_file_EQ : Joined<["-"], "frewrite-map-file=">,
- Group<f_Group>,
- Flags<[DriverOption]>;
-
-def fuse_line_directives : Flag<["-"], "fuse-line-directives">, Group<f_Group>,
- Flags<[CC1Option]>;
-def fno_use_line_directives : Flag<["-"], "fno-use-line-directives">, Group<f_Group>;
-
-def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Assert that the compilation takes place in a freestanding environment">;
-def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Allow GNU-extension keywords regardless of language standard">;
-def fgnu89_inline : Flag<["-"], "fgnu89-inline">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Use the gnu89 inline semantics">;
-def fno_gnu89_inline : Flag<["-"], "fno-gnu89-inline">, Group<f_Group>;
-def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>,
- HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
-def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>;
-def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>;
-def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
-def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
-def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
-def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
-def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
-def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Generate calls to instrument function entry and exit">;
-def flat__namespace : Flag<["-"], "flat_namespace">;
-def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
-def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
-def flto_EQ : Joined<["-"], "flto=">, Flags<[CC1Option]>, Group<f_Group>,
- HelpText<"Set LTO mode to either 'full' or 'thin'">;
-def flto : Flag<["-"], "flto">, Flags<[CC1Option]>, Group<f_Group>,
- HelpText<"Enable LTO in 'full' mode">;
-def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>,
- HelpText<"Disable LTO mode (default)">;
-def fthinlto_index_EQ : Joined<["-"], "fthinlto-index=">,
- Flags<[CC1Option]>, Group<f_Group>,
- 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 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">;
-def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
- HelpText<"Enable full Microsoft Visual C++ compatibility">;
-def fms_volatile : Joined<["-"], "fms-volatile">, Group<f_Group>, Flags<[CC1Option]>;
-def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[DriverOption, CoreOption]>,
- HelpText<"Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))">;
-def fms_compatibility_version
- : Joined<["-"], "fms-compatibility-version=">,
- Group<f_Group>,
- Flags<[ CC1Option, CoreOption ]>,
- HelpText<"Dot-separated value representing the Microsoft compiler "
- "version number to report in _MSC_VER (0 = don't define it "
- "(default))">;
-def fdelayed_template_parsing : Flag<["-"], "fdelayed-template-parsing">, Group<f_Group>,
- HelpText<"Parse templated function definitions at the end of the "
- "translation unit">, Flags<[CC1Option]>;
-def fms_memptr_rep_EQ : Joined<["-"], "fms-memptr-rep=">, Group<f_Group>, Flags<[CC1Option]>;
-def fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group<i_Group>,
- Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
- HelpText<"Specify the module cache path">;
-def fmodules_user_build_path : Separate<["-"], "fmodules-user-build-path">, Group<i_Group>,
- Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
- HelpText<"Specify the module user build path">;
-def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
- Flags<[CC1Option]>, MetaVarName<"<seconds>">,
- HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">;
-def fmodules_prune_after : Joined<["-"], "fmodules-prune-after=">, Group<i_Group>,
- Flags<[CC1Option]>, MetaVarName<"<seconds>">,
- HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">;
-def fmodules_search_all : Flag <["-"], "fmodules-search-all">, Group<f_Group>,
- Flags<[DriverOption, CC1Option]>,
- HelpText<"Search even non-imported modules to resolve references">;
-def fbuild_session_timestamp : Joined<["-"], "fbuild-session-timestamp=">,
- Group<i_Group>, Flags<[CC1Option]>, MetaVarName<"<time since Epoch in seconds>">,
- HelpText<"Time when the current build session started">;
-def fbuild_session_file : Joined<["-"], "fbuild-session-file=">,
- Group<i_Group>, MetaVarName<"<file>">,
- HelpText<"Use the last modification time of <file> as the build session timestamp">;
-def fmodules_validate_once_per_build_session : Flag<["-"], "fmodules-validate-once-per-build-session">,
- Group<i_Group>, Flags<[CC1Option]>,
- HelpText<"Don't verify input files for the modules if the module has been "
- "successfully validated or loaded during this build session">;
-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 fmodules : Flag <["-"], "fmodules">, Group<f_Group>,
- Flags<[DriverOption, CC1Option]>,
- HelpText<"Enable the 'modules' language feature">;
-def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group>,
- Flags<[DriverOption, CC1Option]>,
- HelpText<"Implicitly search the file system for module map files.">;
-def fmodule_maps : Flag <["-"], "fmodule-maps">, Alias<fimplicit_module_maps>;
-def fmodule_name : JoinedOrSeparate<["-"], "fmodule-name=">, Group<f_Group>,
- Flags<[DriverOption,CC1Option]>, MetaVarName<"<name>">,
- HelpText<"Specify the name of the module to build">;
-def fmodule_map_file : Joined<["-"], "fmodule-map-file=">,
- Group<f_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"<file>">,
- HelpText<"Load this module map file">;
-def fmodule_file : Joined<["-"], "fmodule-file=">,
- Group<f_Group>, Flags<[DriverOption,CC1Option]>,
- HelpText<"Load this precompiled module file">, MetaVarName<"<file>">;
-def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Ignore the definition of the given macro when building and loading modules">;
-def fmodules_decluse : Flag <["-"], "fmodules-decluse">, Group<f_Group>,
- Flags<[DriverOption,CC1Option]>,
- HelpText<"Require declaration of modules used within a module">;
-def fmodules_strict_decluse : Flag <["-"], "fmodules-strict-decluse">, Group<f_Group>,
- Flags<[DriverOption,CC1Option]>,
- HelpText<"Like -fmodules-decluse but requires all headers to be in modules">;
-def fno_modules_search_all : Flag <["-"], "fno-modules-search-all">, Group<f_Group>,
- Flags<[DriverOption, CC1Option]>;
-def fno_implicit_modules :
- Flag <["-"], "fno-implicit-modules">,
- Group<f_Group>, Flags<[DriverOption, CC1Option]>;
-def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>;
-
-def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>;
-def fmudflap : Flag<["-"], "fmudflap">, Group<f_Group>;
-def fnested_functions : Flag<["-"], "fnested-functions">, Group<f_Group>;
-def fnext_runtime : Flag<["-"], "fnext-runtime">, Group<f_Group>;
-def fno_access_control : Flag<["-"], "fno-access-control">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Disable C++ access control">;
-def fno_apple_pragma_pack : Flag<["-"], "fno-apple-pragma-pack">, Group<f_Group>;
-def fno_asm : Flag<["-"], "fno-asm">, Group<f_Group>;
-def fno_asynchronous_unwind_tables : Flag<["-"], "fno-asynchronous-unwind-tables">, Group<f_Group>;
-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_borland_extensions : Flag<["-"], "fno-borland-extensions">, Group<f_Group>;
-def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Disable implicit builtin knowledge of functions">;
-def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Disable implicit builtin knowledge of a specific function">;
-def fno_math_builtin : Flag<["-"], "fno-math-builtin">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Disable implicit builtin knowledge of math functions">;
-def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<f_Group>,
- Flags<[CC1Option]>;
-def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>,
- Flags<[CoreOption, CC1Option]>;
-def fno_diagnostics_color : Flag<["-"], "fno-diagnostics-color">, Group<f_Group>,
- Flags<[CoreOption, DriverOption]>;
-def fno_common : Flag<["-"], "fno-common">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Compile common globals like normal definitions">;
-def fno_constant_cfstrings : Flag<["-"], "fno-constant-cfstrings">, Group<f_Group>,
- Flags<[CC1Option]>,
- HelpText<"Disable creation of CodeFoundation-type constant strings">;
-def fno_cxx_exceptions: Flag<["-"], "fno-cxx-exceptions">, Group<f_Group>;
-def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">;
-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 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>,
- HelpText<"Disallow '$' in identifiers">, Flags<[CC1Option]>;
-def fno_elide_constructors : Flag<["-"], "fno-elide-constructors">, Group<f_Group>,
- HelpText<"Disable C++ copy constructor elision">, Flags<[CC1Option]>;
-def fno_eliminate_unused_debug_symbols : Flag<["-"], "fno-eliminate-unused-debug-symbols">, Group<f_Group>;
-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 fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Use the given vector functions library">;
-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">;
-def fno_modules : Flag <["-"], "fno-modules">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fno_implicit_module_maps : Flag <["-"], "fno-implicit-module-maps">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fno_module_maps : Flag <["-"], "fno-module-maps">, Alias<fno_implicit_module_maps>;
-def fno_modules_decluse : Flag <["-"], "fno-modules-decluse">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fimplicit_modules : Flag <["-"], "fimplicit-modules">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fmodule_file_deps : Flag <["-"], "fmodule-file-deps">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fno_module_file_deps : Flag <["-"], "fno-module-file-deps">, Group<f_Group>,
- Flags<[DriverOption]>;
-def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>,
- Flags<[CoreOption]>;
-def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>,
- Flags<[CoreOption]>;
-def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>;
-def fno_objc_exceptions: Flag<["-"], "fno-objc-exceptions">, Group<f_Group>;
-def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>;
-def fno_objc_weak : Flag<["-"], "fno-objc-weak">, Group<f_Group>, Flags<[CC1Option]>;
-def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>;
-def fno_operator_names : Flag<["-"], "fno-operator-names">, Group<f_Group>,
- HelpText<"Do not treat C++ operator name keywords as synonyms for operators">,
- Flags<[CC1Option]>;
-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_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">;
-def fno_show_source_location : Flag<["-"], "fno-show-source-location">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Do not include source location information with diagnostics">;
-def fno_spell_checking : Flag<["-"], "fno-spell-checking">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Disable spell-checking">;
-def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>,
- HelpText<"Disable the use of stack protectors">;
-def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
- Flags<[DriverOption, CoreOption]>;
-def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
-def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
-def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
-def fno_strict_vtable_pointers: Flag<["-"], "fno-strict-vtable-pointers">,
- Group<f_Group>;
-def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
-def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>,
- 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_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>;
-def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group<f_Group>;
-def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>;
-def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>;
-def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>;
-def fno_zero_initialized_in_bss : Flag<["-"], "fno-zero-initialized-in-bss">, Group<f_Group>;
-def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Synthesize retain and release calls for Objective-C pointers">;
-def fno_objc_arc : Flag<["-"], "fno-objc-arc">, Group<f_Group>;
-def fobjc_arc_exceptions : Flag<["-"], "fobjc-arc-exceptions">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Use EH-safe code when synthesizing retains and releases in -fobjc-arc">;
-def fno_objc_arc_exceptions : Flag<["-"], "fno-objc-arc-exceptions">, Group<f_Group>;
-def fobjc_atdefs : Flag<["-"], "fobjc-atdefs">, Group<clang_ignored_f_Group>;
-def fobjc_call_cxx_cdtors : Flag<["-"], "fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
-def fobjc_exceptions: Flag<["-"], "fobjc-exceptions">, Group<f_Group>,
- HelpText<"Enable Objective-C exceptions">, Flags<[CC1Option]>;
-def fapplication_extension : Flag<["-"], "fapplication-extension">,
- Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Restrict code to those available for App Extensions">;
-def fno_application_extension : Flag<["-"], "fno-application-extension">,
- Group<f_Group>;
-def fsized_deallocation : Flag<["-"], "fsized-deallocation">, Flags<[CC1Option]>,
- HelpText<"Enable C++14 sized global deallocation functions">, Group<f_Group>;
-def fno_sized_deallocation: Flag<["-"], "fno-sized-deallocation">, Group<f_Group>;
-
-def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Use GC exclusively for Objective-C related memory management">;
-def fobjc_gc : Flag<["-"], "fobjc-gc">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable Objective-C garbage collection">;
-def fobjc_legacy_dispatch : Flag<["-"], "fobjc-legacy-dispatch">, Group<f_Group>;
-def fobjc_new_property : Flag<["-"], "fobjc-new-property">, Group<clang_ignored_f_Group>;
-def fobjc_infer_related_result_type : Flag<["-"], "fobjc-infer-related-result-type">,
- Group<f_Group>;
-def fno_objc_infer_related_result_type : Flag<["-"],
- "fno-objc-infer-related-result-type">, Group<f_Group>,
- HelpText<
- "do not infer Objective-C related result type based on method family">,
- Flags<[CC1Option]>;
-def fobjc_link_runtime: Flag<["-"], "fobjc-link-runtime">, Group<f_Group>;
-def fobjc_weak : Flag<["-"], "fobjc-weak">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable ARC-style weak references in Objective-C">;
-
-// Objective-C ABI options.
-def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Specify the target Objective-C runtime kind and version">;
-def fobjc_abi_version_EQ : Joined<["-"], "fobjc-abi-version=">, Group<f_Group>;
-def fobjc_nonfragile_abi_version_EQ : Joined<["-"], "fobjc-nonfragile-abi-version=">, Group<f_Group>;
-def fobjc_nonfragile_abi : Flag<["-"], "fobjc-nonfragile-abi">, Group<f_Group>;
-def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Group>;
-
-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 fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[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 fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
-def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-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">;
-def force_addr : Joined<["-"], "fforce-addr">, Group<clang_ignored_f_Group>;
-def foutput_class_dir_EQ : Joined<["-"], "foutput-class-dir=">, Group<f_Group>;
-def fpack_struct : Flag<["-"], "fpack-struct">, Group<f_Group>;
-def fno_pack_struct : Flag<["-"], "fno-pack-struct">, Group<f_Group>;
-def fpack_struct_EQ : Joined<["-"], "fpack-struct=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Specify the default maximum struct packing alignment">;
-def fmax_type_align_EQ : Joined<["-"], "fmax-type-align=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Specify the maximum alignment to enforce on pointers lacking an explicit alignment">;
-def fno_max_type_align : Flag<["-"], "fno-max-type-align">, Group<f_Group>;
-def fpascal_strings : Flag<["-"], "fpascal-strings">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Recognize and construct Pascal-style string literals">;
-def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Override the default ABI to return all structs on the stack">;
-def fpch_preprocess : Flag<["-"], "fpch-preprocess">, Group<f_Group>;
-def fpic : Flag<["-"], "fpic">, Group<f_Group>;
-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 fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<dsopath>">,
- HelpText<"Load the named plugin (dynamic shared object)">;
-def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>;
-def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group<f_Group>;
-def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>;
-def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group<clang_ignored_f_Group>;
-def freg_struct_return : Flag<["-"], "freg-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Override the default ABI to return small structs in registers">;
-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 fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Force wchar_t to be a short unsigned int">;
-def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Force wchar_t to be an unsigned int">;
-def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Which overload candidates to show when overload resolution fails: "
- "best|all; defaults to all">;
-def fshow_column : Flag<["-"], "fshow-column">, Group<f_Group>, Flags<[CC1Option]>;
-def fshow_source_location : Flag<["-"], "fshow-source-location">, Group<f_Group>;
-def fspell_checking : Flag<["-"], "fspell-checking">, Group<f_Group>;
-def fspell_checking_limit_EQ : Joined<["-"], "fspell-checking-limit=">, Group<f_Group>;
-def fsigned_bitfields : Flag<["-"], "fsigned-bitfields">, Group<f_Group>;
-def fsigned_char : Flag<["-"], "fsigned-char">, Group<f_Group>;
-def fno_signed_char : Flag<["-"], "fno-signed-char">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Char is unsigned">;
-def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>;
-def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>,
- HelpText<"Force the usage of stack protectors for all functions">;
-def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group<f_Group>,
- HelpText<"Use a strong heuristic to apply stack protectors to functions">;
-def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>,
- HelpText<"Enable stack protectors for functions potentially vulnerable to stack smashing">;
-def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>,
- HelpText<"Emit full debug info for all types used by the program">;
-def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>,
- HelpText<"Limit debug information produced to reduce size of debug binary">;
-def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Alias<fno_standalone_debug>;
-def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Alias<fstandalone_debug>;
-def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>,
- Flags<[DriverOption, CoreOption]>;
-def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable optimizations based on the strict definition of an enum's "
- "value range">;
-def fstrict_vtable_pointers: Flag<["-"], "fstrict-vtable-pointers">,
- Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable optimizations based on the strict rules for overwriting "
- "polymorphic C++ objects">;
-def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
-def fsyntax_only : Flag<["-"], "fsyntax-only">,
- Flags<[DriverOption,CoreOption,CC1Option]>, Group<Action_Group>;
-def ftabstop_EQ : Joined<["-"], "ftabstop=">, Group<f_Group>;
-def ftemplate_depth_EQ : Joined<["-"], "ftemplate-depth=">, Group<f_Group>;
-def ftemplate_depth_ : Joined<["-"], "ftemplate-depth-">, Group<f_Group>;
-def ftemplate_backtrace_limit_EQ : Joined<["-"], "ftemplate-backtrace-limit=">,
- Group<f_Group>;
-def foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">,
- Group<f_Group>;
-def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>;
-def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
- HelpText<"Enable the loop vectorization passes">;
-def fno_vectorize : Flag<["-"], "fno-vectorize">, Group<f_Group>;
-def : Flag<["-"], "ftree-vectorize">, Alias<fvectorize>;
-def : Flag<["-"], "fno-tree-vectorize">, Alias<fno_vectorize>;
-def fslp_vectorize : Flag<["-"], "fslp-vectorize">, Group<f_Group>,
- HelpText<"Enable the superword-level parallelism vectorization passes">;
-def fno_slp_vectorize : Flag<["-"], "fno-slp-vectorize">, Group<f_Group>;
-def fslp_vectorize_aggressive : Flag<["-"], "fslp-vectorize-aggressive">, Group<f_Group>,
- HelpText<"Enable the BB vectorization passes">;
-def fno_slp_vectorize_aggressive : Flag<["-"], "fno-slp-vectorize-aggressive">, Group<f_Group>;
-def : Flag<["-"], "ftree-slp-vectorize">, Alias<fslp_vectorize>;
-def : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>;
-def Wlarge_by_value_copy_def : Flag<["-"], "Wlarge-by-value-copy">,
- HelpText<"Warn if a function definition returns or accepts an object larger "
- "in bytes than a given value">, Flags<[HelpHidden]>;
-def Wlarge_by_value_copy_EQ : Joined<["-"], "Wlarge-by-value-copy=">, Flags<[CC1Option]>;
-
-// These "special" warning flags are effectively processed as f_Group flags by the driver:
-// Just silence warnings about -Wlarger-than for now.
-def Wlarger_than_EQ : Joined<["-"], "Wlarger-than=">, Group<clang_ignored_f_Group>;
-def Wlarger_than_ : Joined<["-"], "Wlarger-than-">, Alias<Wlarger_than_EQ>;
-def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Group<f_Group>, Flags<[DriverOption]>;
-
-def : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>;
-def fthreadsafe_statics : Flag<["-"], "fthreadsafe-statics">, Group<f_Group>;
-def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>, Flags<[CC1Option]>;
-def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group<f_Group>, Flags<[CC1Option]>;
-def ftrapv : Flag<["-"], "ftrapv">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Trap on integer overflow">;
-def ftrapv_handler_EQ : Joined<["-"], "ftrapv-handler=">, Group<f_Group>,
- MetaVarName<"<function name>">,
- HelpText<"Specify the function to be called on overflow">;
-def ftrapv_handler : Separate<["-"], "ftrapv-handler">, Group<f_Group>, Flags<[CC1Option]>;
-def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Issue call to specified function rather than a trap instruction">;
-def funit_at_a_time : Flag<["-"], "funit-at-a-time">, Group<f_Group>;
-def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
- HelpText<"Turn on loop unroller">, Flags<[CC1Option]>;
-def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,
- HelpText<"Turn off loop unroller">, Flags<[CC1Option]>;
-def freroll_loops : Flag<["-"], "freroll-loops">, Group<f_Group>,
- HelpText<"Turn on loop reroller">, Flags<[CC1Option]>;
-def fno_reroll_loops : Flag<["-"], "fno-reroll-loops">, Group<f_Group>,
- HelpText<"Turn off loop reroller">;
-def ftrigraphs : Flag<["-"], "ftrigraphs">, Group<f_Group>,
- HelpText<"Process trigraph sequences">, Flags<[CC1Option]>;
-def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>,
- HelpText<"Do not process trigraph sequences">, Flags<[CC1Option]>;
-def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
-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 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>;
-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">;
-def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group<f_Group>,
- HelpText<"Give inline C++ member functions default 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 "
- "variables 'hidden' visibility by default">;
-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]>,
- HelpText<"Store string literals as writable data">;
-def fzero_initialized_in_bss : Flag<["-"], "fzero-initialized-in-bss">, Group<f_Group>;
-def ffunction_sections : Flag<["-"], "ffunction-sections">, Group<f_Group>,
- Flags<[CC1Option]>,
- HelpText<"Place each function in its own section (ELF Only)">;
-def fno_function_sections : Flag<["-"], "fno-function-sections">,
- Group<f_Group>, Flags<[CC1Option]>;
-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 funique_section_names : Flag <["-"], "funique-section-names">,
- Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Use unique names for text and data sections (ELF Only)">;
-def fno_unique_section_names : Flag <["-"], "fno-unique-section-names">,
- Group<f_Group>, Flags<[CC1Option]>;
-
-
-def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
-def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
- Flags<[CC1Option]>;
-def fdebug_prefix_map_EQ
- : Joined<["-"], "fdebug-prefix-map=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"remap file source paths in debug info">;
-def g_Flag : Flag<["-"], "g">, Group<g_Group>,
- HelpText<"Generate source-level debug information">;
-def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,
- HelpText<"Emit debug line number tables only">;
-def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>;
-def g0 : Flag<["-"], "g0">, Group<gN_Group>;
-def g1 : Flag<["-"], "g1">, Group<gN_Group>, Alias<gline_tables_only>;
-def g2 : Flag<["-"], "g2">, Group<gN_Group>;
-def g3 : Flag<["-"], "g3">, Group<gN_Group>;
-def ggdb : Flag<["-"], "ggdb">, Group<gTune_Group>;
-def ggdb0 : Flag<["-"], "ggdb0">, Group<ggdbN_Group>;
-def ggdb1 : Flag<["-"], "ggdb1">, Group<ggdbN_Group>;
-def ggdb2 : Flag<["-"], "ggdb2">, Group<ggdbN_Group>;
-def ggdb3 : Flag<["-"], "ggdb3">, Group<ggdbN_Group>;
-def glldb : Flag<["-"], "glldb">, Group<gTune_Group>;
-def gsce : Flag<["-"], "gsce">, Group<gTune_Group>;
-def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>,
- HelpText<"Generate source-level debug information with dwarf version 2">;
-def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group<g_Group>,
- HelpText<"Generate source-level debug information with dwarf version 3">;
-def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>,
- HelpText<"Generate source-level debug information with dwarf version 4">;
-def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group<g_Group>,
- HelpText<"Generate source-level debug information with dwarf version 5">;
-def gcodeview : Flag<["-"], "gcodeview">,
- HelpText<"Generate CodeView debug information">,
- Flags<[CC1Option, CC1AsOption, CoreOption]>;
-// Equivalent to our default dwarf version. Forces usual dwarf emission when
-// CodeView is enabled.
-def gdwarf : Flag<["-"], "gdwarf">, Alias<gdwarf_4>, Flags<[CoreOption]>;
-
-def gfull : Flag<["-"], "gfull">, Group<g_Group>;
-def gused : Flag<["-"], "gused">, Group<g_Group>;
-def gstabs : Joined<["-"], "gstabs">, Group<g_Group>, Flags<[Unsupported]>;
-def gcoff : Joined<["-"], "gcoff">, Group<g_Group>, Flags<[Unsupported]>;
-def gxcoff : Joined<["-"], "gxcoff">, Group<g_Group>, Flags<[Unsupported]>;
-def gvms : Joined<["-"], "gvms">, Group<g_Group>, Flags<[Unsupported]>;
-def gtoggle : Flag<["-"], "gtoggle">, Group<g_flags_Group>, Flags<[Unsupported]>;
-def grecord_gcc_switches : Flag<["-"], "grecord-gcc-switches">, Group<g_flags_Group>;
-def gno_record_gcc_switches : Flag<["-"], "gno-record-gcc-switches">,
- Group<g_flags_Group>;
-def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>;
-def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>;
-def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>;
-def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>;
-def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
-def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>;
-def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
-def gmodules : Flag <["-"], "gmodules">, Group<f_Group>,
- HelpText<"Generate debug info with external references to clang modules"
- " or precompiled headers">;
-def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
-def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption]>,
- HelpText<"Display available options">;
-def index_header_map : Flag<["-"], "index-header-map">, Flags<[CC1Option]>,
- HelpText<"Make the next included directory (-I or -F) an indexer header map">;
-def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Add directory to AFTER include search path">;
-def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Add directory to SYSTEM framework search path">;
-def imacros : JoinedOrSeparate<["-", "--"], "imacros">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Include macros from file before parsing">, MetaVarName<"<file>">;
-def image__base : Separate<["-"], "image_base">;
-def include_ : JoinedOrSeparate<["-", "--"], "include">, Group<clang_i_Group>, EnumName<"include">,
- MetaVarName<"<file>">, HelpText<"Include file before parsing">, Flags<[CC1Option]>;
-def include_pch : Separate<["-"], "include-pch">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Include precompiled header file">, MetaVarName<"<file>">;
-def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, Flags<[CC1Option]>,
- HelpText<"Whether to build a relocatable precompiled header">;
-def verify_pch : Flag<["-"], "verify-pch">, Group<Action_Group>, Flags<[CC1Option]>,
- HelpText<"Load and verify that a pre-compiled header file is not stale">;
-def init : Separate<["-"], "init">;
-def install__name : Separate<["-"], "install_name">;
-def iprefix : JoinedOrSeparate<["-"], "iprefix">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">, MetaVarName<"<dir>">;
-def iquote : JoinedOrSeparate<["-"], "iquote">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Add directory to QUOTE include search path">, MetaVarName<"<directory>">;
-def isysroot : JoinedOrSeparate<["-"], "isysroot">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Set the system root directory (usually /)">, MetaVarName<"<dir>">;
-def isystem : JoinedOrSeparate<["-"], "isystem">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Add directory to SYSTEM include search path">, MetaVarName<"<directory>">;
-def iwithprefixbefore : JoinedOrSeparate<["-"], "iwithprefixbefore">, Group<clang_i_Group>,
- HelpText<"Set directory to include search path with prefix">, MetaVarName<"<dir>">,
- Flags<[CC1Option]>;
-def iwithprefix : JoinedOrSeparate<["-"], "iwithprefix">, Group<clang_i_Group>, Flags<[CC1Option]>,
- HelpText<"Set directory to SYSTEM include search path with prefix">, MetaVarName<"<dir>">;
-def iwithsysroot : JoinedOrSeparate<["-"], "iwithsysroot">, Group<clang_i_Group>,
- HelpText<"Add directory to SYSTEM include search path, "
- "absolute paths are relative to -isysroot">, MetaVarName<"<directory>">,
- 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 keep__private__externs : Flag<["-"], "keep_private_externs">;
-def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>;
-def lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>;
-def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>;
-def mlittle_endian : Flag<["-"], "mlittle-endian">, Flags<[DriverOption]>;
-def EL : Flag<["-"], "EL">, Alias<mlittle_endian>;
-def mbig_endian : Flag<["-"], "mbig-endian">, Flags<[DriverOption]>;
-def EB : Flag<["-"], "EB">, Alias<mbig_endian>;
-def m16 : Flag<["-"], "m16">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
-def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
-def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[DriverOption,CC1Option]>,
- HelpText<"Enable hexagon-qdsp6 backward compatibility">;
-def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>;
-def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>;
-def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
-def mx32 : Flag<["-"], "mx32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
-def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
-def malign_functions_EQ : Joined<["-"], "malign-functions=">, Group<clang_ignored_m_Group>;
-def malign_loops_EQ : Joined<["-"], "malign-loops=">, Group<clang_ignored_m_Group>;
-def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group<clang_ignored_m_Group>;
-def mfancy_math_387 : Flag<["-"], "mfancy-math-387">, Group<clang_ignored_m_Group>;
-def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>;
-def mappletvos_version_min_EQ : Joined<["-"], "mappletvos-version-min=">, Alias<mtvos_version_min_EQ>;
-def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">, Alias<mtvos_version_min_EQ>;
-def mappletvsimulator_version_min_EQ : Joined<["-"], "mappletvsimulator-version-min=">, Alias<mtvos_version_min_EQ>;
-def mwatchos_version_min_EQ : Joined<["-"], "mwatchos-version-min=">, Group<m_Group>;
-def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">, Alias<mwatchos_version_min_EQ>;
-def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_version_min_EQ>;
-def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
-def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
-def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
-def mconstant_cfstrings : Flag<["-"], "mconstant-cfstrings">, Group<clang_ignored_m_Group>;
-def mconsole : Joined<["-"], "mconsole">, Group<m_Group>, Flags<[DriverOption]>;
-def mwindows : Joined<["-"], "mwindows">, Group<m_Group>, Flags<[DriverOption]>;
-def mdll : Joined<["-"], "mdll">, Group<m_Group>, Flags<[DriverOption]>;
-def municode : Joined<["-"], "municode">, Group<m_Group>, Flags<[DriverOption]>;
-def mthreads : Joined<["-"], "mthreads">, Group<m_Group>, Flags<[DriverOption]>;
-def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>;
-def mdynamic_no_pic : Joined<["-"], "mdynamic-no-pic">, Group<m_Group>;
-def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group<clang_ignored_m_Group>;
-def mieee_fp : Flag<["-"], "mieee-fp">, Group<clang_ignored_m_Group>;
-def minline_all_stringops : Flag<["-"], "minline-all-stringops">, Group<clang_ignored_m_Group>;
-def mno_inline_all_stringops : Flag<["-"], "mno-inline-all-stringops">, Group<clang_ignored_m_Group>;
-def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>;
-def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group<m_Group>;
-def mfpu_EQ : Joined<["-"], "mfpu=">, Group<m_Group>;
-def mhwdiv_EQ : Joined<["-"], "mhwdiv=">, Group<m_Group>;
-def mglobal_merge : Flag<["-"], "mglobal-merge">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Enable merging of globals">;
-def mhard_float : Flag<["-"], "mhard-float">, Group<m_Group>;
-def miphoneos_version_min_EQ : Joined<["-"], "miphoneos-version-min=">, Group<m_Group>;
-def mios_version_min_EQ : Joined<["-"], "mios-version-min=">,
- Alias<miphoneos_version_min_EQ>, HelpText<"Set iOS deployment target">;
-def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">, Alias<miphoneos_version_min_EQ>;
-def miphonesimulator_version_min_EQ : Joined<["-"], "miphonesimulator-version-min=">, Alias<miphoneos_version_min_EQ>;
-def mkernel : Flag<["-"], "mkernel">, Group<m_Group>;
-def mlinker_version_EQ : Joined<["-"], "mlinker-version=">,
- Flags<[DriverOption]>;
-def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option,CC1AsOption,CoreOption]>,
- HelpText<"Additional arguments to forward to LLVM's option processing">;
-def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">,
- Group<m_Group>, HelpText<"Set Mac OS X deployment target">;
-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 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]>,
- HelpText<"Force realign the stack at entry to every function">;
-def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>, Flags<[CC1Option]>,
- 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 mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"The thread model to use, e.g. posix, single (posix by default)">;
-def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Set EABI type, e.g. 4, 5 or gnu (default depends on triple)">;
-
-def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>;
-def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>;
-def mno_3dnow : Flag<["-"], "mno-3dnow">, Group<m_x86_Features_Group>;
-def mno_constant_cfstrings : Flag<["-"], "mno-constant-cfstrings">, Group<m_Group>;
-def mno_global_merge : Flag<["-"], "mno-global-merge">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Disable merging of globals">;
-def mno_mmx : Flag<["-"], "mno-mmx">, Group<m_x86_Features_Group>;
-def mno_pascal_strings : Flag<["-"], "mno-pascal-strings">,
- Alias<fno_pascal_strings>;
-def mno_red_zone : Flag<["-"], "mno-red-zone">, Group<m_Group>;
-def mno_relax_all : Flag<["-"], "mno-relax-all">, Group<m_Group>;
-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 mno_sse2 : Flag<["-"], "mno-sse2">, Group<m_x86_Features_Group>;
-def mno_sse3 : Flag<["-"], "mno-sse3">, Group<m_x86_Features_Group>;
-def mno_sse4a : Flag<["-"], "mno-sse4a">, Group<m_x86_Features_Group>;
-def mno_sse4_1 : Flag<["-"], "mno-sse4.1">, Group<m_x86_Features_Group>;
-def mno_sse4_2 : Flag<["-"], "mno-sse4.2">, Group<m_x86_Features_Group>;
-// -mno-sse4 turns off sse4.1 which has the effect of turning off everything
-// later than 4.1. -msse4 turns on 4.2 which has the effect of turning on
-// everything earlier than 4.2.
-def mno_sse4 : Flag<["-"], "mno-sse4">, Alias<mno_sse4_1>;
-def mno_sse : Flag<["-"], "mno-sse">, Group<m_x86_Features_Group>;
-def mno_ssse3 : Flag<["-"], "mno-ssse3">, Group<m_x86_Features_Group>;
-def mno_aes : Flag<["-"], "mno-aes">, Group<m_x86_Features_Group>;
-def mno_avx : Flag<["-"], "mno-avx">, Group<m_x86_Features_Group>;
-def mno_avx2 : Flag<["-"], "mno-avx2">, Group<m_x86_Features_Group>;
-def mno_avx512f : Flag<["-"], "mno-avx512f">, Group<m_x86_Features_Group>;
-def mno_avx512cd : Flag<["-"], "mno-avx512cd">, Group<m_x86_Features_Group>;
-def mno_avx512er : Flag<["-"], "mno-avx512er">, Group<m_x86_Features_Group>;
-def mno_avx512pf : Flag<["-"], "mno-avx512pf">, Group<m_x86_Features_Group>;
-def mno_avx512dq : Flag<["-"], "mno-avx512dq">, Group<m_x86_Features_Group>;
-def mno_avx512bw : Flag<["-"], "mno-avx512bw">, Group<m_x86_Features_Group>;
-def mno_avx512vl : Flag<["-"], "mno-avx512vl">, Group<m_x86_Features_Group>;
-def mno_pclmul : Flag<["-"], "mno-pclmul">, Group<m_x86_Features_Group>;
-def mno_lzcnt : Flag<["-"], "mno-lzcnt">, Group<m_x86_Features_Group>;
-def mno_rdrnd : Flag<["-"], "mno-rdrnd">, Group<m_x86_Features_Group>;
-def mno_fsgsbase : Flag<["-"], "mno-fsgsbase">, Group<m_x86_Features_Group>;
-def mno_bmi : Flag<["-"], "mno-bmi">, Group<m_x86_Features_Group>;
-def mno_bmi2 : Flag<["-"], "mno-bmi2">, Group<m_x86_Features_Group>;
-def mno_popcnt : Flag<["-"], "mno-popcnt">, Group<m_x86_Features_Group>;
-def mno_tbm : Flag<["-"], "mno-tbm">, Group<m_x86_Features_Group>;
-def mno_fma4 : Flag<["-"], "mno-fma4">, Group<m_x86_Features_Group>;
-def mno_fma : Flag<["-"], "mno-fma">, Group<m_x86_Features_Group>;
-def mno_xop : Flag<["-"], "mno-xop">, Group<m_x86_Features_Group>;
-def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>;
-def mno_rtm : Flag<["-"], "mno-rtm">, Group<m_x86_Features_Group>;
-def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>;
-def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>;
-def mno_adx : Flag<["-"], "mno-adx">, Group<m_x86_Features_Group>;
-def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>;
-def mno_fxsr : Flag<["-"], "mno-fxsr">, Group<m_x86_Features_Group>;
-def mno_xsave : Flag<["-"], "mno-xsave">, Group<m_x86_Features_Group>;
-def mno_xsaveopt : Flag<["-"], "mno-xsaveopt">, Group<m_x86_Features_Group>;
-def mno_xsavec : Flag<["-"], "mno-xsavec">, Group<m_x86_Features_Group>;
-def mno_xsaves : Flag<["-"], "mno-xsaves">, Group<m_x86_Features_Group>;
-def mno_pku : Flag<["-"], "mno-pku">, Group<m_x86_Features_Group>;
-
-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>,
- HelpText<"Force all memory accesses to be aligned (AArch32/AArch64 only)">;
-def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>, Flags<[CC1Option,HelpHidden]>,
- HelpText<"Force all memory accesses to be aligned (same as mno-unaligned-access)">;
-def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>;
-def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>,
- HelpText<"Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.">;
-def mno_restrict_it: Flag<["-"], "mno-restrict-it">, Group<m_arm_Features_Group>,
- HelpText<"Allow generation of deprecated IT blocks for ARMv8. It is off by default for ARMv8 Thumb mode">;
-def marm : Flag<["-"], "marm">, Alias<mno_thumb>;
-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 mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
- HelpText<"Disallow use of CRC instructions (ARM only)">;
-def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_arm_Features_Group>,
- HelpText<"Generate an indirect jump to enable jumps further than 64M">;
-def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_arm_Features_Group>,
- HelpText<"Restore the default behaviour of not generating long calls">;
-
-def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
- HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
-
-def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
- Group<m_aarch64_Features_Group>,
- HelpText<"Workaround Cortex-A53 erratum 835769 (AArch64 only)">;
-def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
- Group<m_aarch64_Features_Group>,
- 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 msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
-def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
-
-def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
-def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
-def mpower8_vector : Flag<["-"], "mpower8-vector">,
- Group<m_ppc_Features_Group>;
-def mno_power8_vector : Flag<["-"], "mno-power8-vector">,
- Group<m_ppc_Features_Group>;
-def mpower8_crypto : Flag<["-"], "mcrypto">,
- Group<m_ppc_Features_Group>;
-def mnopower8_crypto : Flag<["-"], "mno-crypto">,
- Group<m_ppc_Features_Group>;
-def mdirect_move : Flag<["-"], "mdirect-move">,
- Group<m_ppc_Features_Group>;
-def mnodirect_move : Flag<["-"], "mno-direct-move">,
- Group<m_ppc_Features_Group>;
-def mhtm : Flag<["-"], "mhtm">, Group<m_ppc_Features_Group>;
-def mno_htm : Flag<["-"], "mno-htm">, Group<m_ppc_Features_Group>;
-def mfprnd : Flag<["-"], "mfprnd">, Group<m_ppc_Features_Group>;
-def mno_fprnd : Flag<["-"], "mno-fprnd">, Group<m_ppc_Features_Group>;
-def mcmpb : Flag<["-"], "mcmpb">, Group<m_ppc_Features_Group>;
-def mno_cmpb : Flag<["-"], "mno-cmpb">, Group<m_ppc_Features_Group>;
-def misel : Flag<["-"], "misel">, Group<m_ppc_Features_Group>;
-def mno_isel : Flag<["-"], "mno-isel">, Group<m_ppc_Features_Group>;
-def mmfocrf : Flag<["-"], "mmfocrf">, Group<m_ppc_Features_Group>;
-def mmfcrf : Flag<["-"], "mmfcrf">, Alias<mmfocrf>;
-def mno_mfocrf : Flag<["-"], "mno-mfocrf">, Group<m_ppc_Features_Group>;
-def mno_mfcrf : Flag<["-"], "mno-mfcrf">, Alias<mno_mfocrf>;
-def mpopcntd : Flag<["-"], "mpopcntd">, Group<m_ppc_Features_Group>;
-def mno_popcntd : Flag<["-"], "mno-popcntd">, Group<m_ppc_Features_Group>;
-def mqpx : Flag<["-"], "mqpx">, Group<m_ppc_Features_Group>;
-def mno_qpx : Flag<["-"], "mno-qpx">, Group<m_ppc_Features_Group>;
-def mcrbits : Flag<["-"], "mcrbits">, Group<m_ppc_Features_Group>;
-def mno_crbits : Flag<["-"], "mno-crbits">, Group<m_ppc_Features_Group>;
-def minvariant_function_descriptors :
- Flag<["-"], "minvariant-function-descriptors">, Group<m_ppc_Features_Group>;
-def mno_invariant_function_descriptors :
- Flag<["-"], "mno-invariant-function-descriptors">,
- Group<m_ppc_Features_Group>;
-
-def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable AltiVec vector initializer syntax">;
-def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[CC1Option]>;
-def maltivec : Flag<["-"], "maltivec">, Alias<faltivec>;
-def mno_altivec : Flag<["-"], "mno-altivec">, Alias<fno_altivec>;
-
-def mvx : Flag<["-"], "mvx">, Group<m_Group>;
-def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
-
-def fzvector : Flag<["-"], "fzvector">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable System z vector language extension">;
-def fno_zvector : Flag<["-"], "fno-zvector">, Group<f_Group>,
- Flags<[CC1Option]>;
-def mzvector : Flag<["-"], "mzvector">, Alias<fzvector>;
-def mno_zvector : Flag<["-"], "mno-zvector">, Alias<fno_zvector>;
-
-def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>;
-def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>;
-def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>,
- HelpText<"Omit frame pointer setup for leaf functions">, Flags<[CC1Option]>;
-def moslib_EQ : Joined<["-"], "moslib=">, Group<m_Group>;
-def mpascal_strings : Flag<["-"], "mpascal-strings">, Alias<fpascal_strings>;
-def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>;
-def mregparm_EQ : Joined<["-"], "mregparm=">, Group<m_Group>;
-def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option,CC1AsOption]>,
- HelpText<"(integrated-as) Relax all machine instructions">;
-def mincremental_linker_compatible : Flag<["-"], "mincremental-linker-compatible">, Group<m_Group>,
- Flags<[CC1Option,CC1AsOption]>,
- HelpText<"(integrated-as) Emit an object file which can be used with an incremental linker">;
-def mno_incremental_linker_compatible : Flag<["-"], "mno-incremental-linker-compatible">, Group<m_Group>,
- HelpText<"(integrated-as) Emit an object file which cannot be used with an incremental linker">;
-def mrtd : Flag<["-"], "mrtd">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Make StdCall calling convention the default">;
-def msmall_data_threshold_EQ : Joined <["-"], "msmall-data-threshold=">, Group<m_Group>;
-def msoft_float : Flag<["-"], "msoft-float">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Use software floating point">;
-def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>,
- HelpText<"Don't generate implicit floating point instructions">;
-def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>;
-def mrecip : Flag<["-"], "mrecip">, Group<m_Group>;
-def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>, Flags<[CC1Option]>;
-def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>;
-def msse3 : Flag<["-"], "msse3">, Group<m_x86_Features_Group>;
-def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>;
-def msse4_1 : Flag<["-"], "msse4.1">, Group<m_x86_Features_Group>;
-def msse4_2 : Flag<["-"], "msse4.2">, Group<m_x86_Features_Group>;
-def msse4 : Flag<["-"], "msse4">, Alias<msse4_2>;
-def msse : Flag<["-"], "msse">, Group<m_x86_Features_Group>;
-def mssse3 : Flag<["-"], "mssse3">, Group<m_x86_Features_Group>;
-def maes : Flag<["-"], "maes">, Group<m_x86_Features_Group>;
-def mavx : Flag<["-"], "mavx">, Group<m_x86_Features_Group>;
-def mavx2 : Flag<["-"], "mavx2">, Group<m_x86_Features_Group>;
-def mavx512f : Flag<["-"], "mavx512f">, Group<m_x86_Features_Group>;
-def mavx512cd : Flag<["-"], "mavx512cd">, Group<m_x86_Features_Group>;
-def mavx512er : Flag<["-"], "mavx512er">, Group<m_x86_Features_Group>;
-def mavx512pf : Flag<["-"], "mavx512pf">, Group<m_x86_Features_Group>;
-def mavx512dq : Flag<["-"], "mavx512dq">, Group<m_x86_Features_Group>;
-def mavx512bw : Flag<["-"], "mavx512bw">, Group<m_x86_Features_Group>;
-def mavx512vl : Flag<["-"], "mavx512vl">, Group<m_x86_Features_Group>;
-def mpclmul : Flag<["-"], "mpclmul">, Group<m_x86_Features_Group>;
-def mlzcnt : Flag<["-"], "mlzcnt">, Group<m_x86_Features_Group>;
-def mrdrnd : Flag<["-"], "mrdrnd">, Group<m_x86_Features_Group>;
-def mfsgsbase : Flag<["-"], "mfsgsbase">, Group<m_x86_Features_Group>;
-def mbmi : Flag<["-"], "mbmi">, Group<m_x86_Features_Group>;
-def mbmi2 : Flag<["-"], "mbmi2">, Group<m_x86_Features_Group>;
-def mpopcnt : Flag<["-"], "mpopcnt">, Group<m_x86_Features_Group>;
-def mtbm : Flag<["-"], "mtbm">, Group<m_x86_Features_Group>;
-def mfma4 : Flag<["-"], "mfma4">, Group<m_x86_Features_Group>;
-def mfma : Flag<["-"], "mfma">, Group<m_x86_Features_Group>;
-def mxop : Flag<["-"], "mxop">, Group<m_x86_Features_Group>;
-def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>;
-def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>;
-def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>;
-def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>;
-def mpku : Flag<["-"], "mpku">, Group<m_x86_Features_Group>;
-def madx : Flag<["-"], "madx">, Group<m_x86_Features_Group>;
-def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>;
-def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>;
-def mfxsr : Flag<["-"], "mfxsr">, Group<m_x86_Features_Group>;
-def mxsave : Flag<["-"], "mxsave">, Group<m_x86_Features_Group>;
-def mxsaveopt : Flag<["-"], "mxsaveopt">, Group<m_x86_Features_Group>;
-def mxsavec : Flag<["-"], "mxsavec">, Group<m_x86_Features_Group>;
-def mxsaves : Flag<["-"], "mxsaves">, Group<m_x86_Features_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 mno_check_zero_division : Flag<["-"], "mno-check-zero-division">,
- Group<m_Group>;
-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 mmsa : Flag<["-"], "mmsa">, Group<m_Group>,
- HelpText<"Enable MSA ASE (MIPS only)">;
-def mno_msa : Flag<["-"], "mno-msa">, Group<m_Group>,
- HelpText<"Disable MSA ASE (MIPS only)">;
-def mfp64 : Flag<["-"], "mfp64">, Group<m_Group>,
- HelpText<"Use 64-bit floating point registers (MIPS only)">;
-def mfp32 : Flag<["-"], "mfp32">, Group<m_Group>,
- HelpText<"Use 32-bit floating point registers (MIPS only)">;
-def mnan_EQ : Joined<["-"], "mnan=">, Group<m_Group>;
-def mabicalls : Flag<["-"], "mabicalls">, Group<m_Group>,
- HelpText<"Enable SVR4-style position-independent code (Mips only)">;
-def mno_abicalls : Flag<["-"], "mno-abicalls">, Group<m_Group>,
- HelpText<"Disable SVR4-style position-independent code (Mips only)">;
-def mips1 : Flag<["-"], "mips1">,
- Alias<march_EQ>, AliasArgs<["mips1"]>,
- HelpText<"Equivalent to -march=mips1">, Flags<[HelpHidden]>;
-def mips2 : Flag<["-"], "mips2">,
- Alias<march_EQ>, AliasArgs<["mips2"]>,
- HelpText<"Equivalent to -march=mips2">, Flags<[HelpHidden]>;
-def mips3 : Flag<["-"], "mips3">,
- Alias<march_EQ>, AliasArgs<["mips3"]>,
- HelpText<"Equivalent to -march=mips3">, Flags<[HelpHidden]>;
-def mips4 : Flag<["-"], "mips4">,
- Alias<march_EQ>, AliasArgs<["mips4"]>,
- HelpText<"Equivalent to -march=mips4">, Flags<[HelpHidden]>;
-def mips5 : Flag<["-"], "mips5">,
- Alias<march_EQ>, AliasArgs<["mips5"]>,
- HelpText<"Equivalent to -march=mips5">, Flags<[HelpHidden]>;
-def mips32 : Flag<["-"], "mips32">,
- Alias<march_EQ>, AliasArgs<["mips32"]>,
- HelpText<"Equivalent to -march=mips32">, Flags<[HelpHidden]>;
-def mips32r2 : Flag<["-"], "mips32r2">,
- Alias<march_EQ>, AliasArgs<["mips32r2"]>,
- HelpText<"Equivalent to -march=mips32r2">, Flags<[HelpHidden]>;
-def mips32r3 : Flag<["-"], "mips32r3">,
- Alias<march_EQ>, AliasArgs<["mips32r3"]>,
- HelpText<"Equivalent to -march=mips32r3">, Flags<[HelpHidden]>;
-def mips32r5 : Flag<["-"], "mips32r5">,
- Alias<march_EQ>, AliasArgs<["mips32r5"]>,
- HelpText<"Equivalent to -march=mips32r5">, Flags<[HelpHidden]>;
-def mips32r6 : Flag<["-"], "mips32r6">,
- Alias<march_EQ>, AliasArgs<["mips32r6"]>,
- HelpText<"Equivalent to -march=mips32r6">, Flags<[HelpHidden]>;
-def mips64 : Flag<["-"], "mips64">,
- Alias<march_EQ>, AliasArgs<["mips64"]>,
- HelpText<"Equivalent to -march=mips64">, Flags<[HelpHidden]>;
-def mips64r2 : Flag<["-"], "mips64r2">,
- Alias<march_EQ>, AliasArgs<["mips64r2"]>,
- HelpText<"Equivalent to -march=mips64r2">, Flags<[HelpHidden]>;
-def mips64r3 : Flag<["-"], "mips64r3">,
- Alias<march_EQ>, AliasArgs<["mips64r3"]>,
- HelpText<"Equivalent to -march=mips64r3">, Flags<[HelpHidden]>;
-def mips64r5 : Flag<["-"], "mips64r5">,
- Alias<march_EQ>, AliasArgs<["mips64r5"]>,
- HelpText<"Equivalent to -march=mips64r5">, Flags<[HelpHidden]>;
-def mips64r6 : Flag<["-"], "mips64r6">,
- Alias<march_EQ>, AliasArgs<["mips64r6"]>,
- HelpText<"Equivalent to -march=mips64r6">, Flags<[HelpHidden]>;
-def mfpxx : Flag<["-"], "mfpxx">, Group<m_Group>,
- HelpText<"Avoid FPU mode dependent operations when used with the O32 ABI">,
- Flags<[HelpHidden]>;
-def modd_spreg : Flag<["-"], "modd-spreg">, Group<m_Group>,
- HelpText<"Enable odd single-precision floating point registers">,
- Flags<[HelpHidden]>;
-def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_Group>,
- HelpText<"Disable odd single-precision floating point registers">,
- Flags<[HelpHidden]>;
-def mglibc : Flag<["-"], "mglibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
-def muclibc : Flag<["-"], "muclibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
-def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>;
-def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
-def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>;
-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]>,
- 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]>;
-def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>;
-def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">;
-def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option]>,
- HelpText<"Disable builtin #include directories">;
-def nocudainc : Flag<["-"], "nocudainc">;
-def nocudalib : Flag<["-"], "nocudalib">;
-def nodefaultlibs : Flag<["-"], "nodefaultlibs">;
-def nofixprebinding : Flag<["-"], "nofixprebinding">;
-def nolibc : Flag<["-"], "nolibc">;
-def nomultidefs : Flag<["-"], "nomultidefs">;
-def nopie : Flag<["-"], "nopie">;
-def noprebind : Flag<["-"], "noprebind">;
-def noseglinkedit : Flag<["-"], "noseglinkedit">;
-def nostartfiles : Flag<["-"], "nostartfiles">;
-def nostdinc : Flag<["-"], "nostdinc">;
-def nostdlibinc : Flag<["-"], "nostdlibinc">;
-def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
- HelpText<"Disable standard #include directories for the C++ standard library">;
-def nostdlib : Flag<["-"], "nostdlib">;
-def object : Flag<["-"], "object">;
-def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>,
- HelpText<"Write output to <file>">, MetaVarName<"<file>">;
-def omptargets_EQ : CommaJoined<["-"], "omptargets=">, Flags<[DriverOption, CC1Option]>,
- HelpText<"Specify comma-separated list of triples OpenMP offloading targets to be supported">;
-def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">;
-def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>;
-def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group<pedantic_Group>, Flags<[CC1Option]>;
-def pedantic : Flag<["-", "--"], "pedantic">, Group<pedantic_Group>, Flags<[CC1Option]>;
-def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">, Flags<[CC1Option]>;
-def pipe : Flag<["-", "--"], "pipe">,
- HelpText<"Use pipes between commands, when possible">;
-def prebind__all__twolevel__modules : Flag<["-"], "prebind_all_twolevel_modules">;
-def prebind : Flag<["-"], "prebind">;
-def preload : Flag<["-"], "preload">;
-def print_file_name_EQ : Joined<["-", "--"], "print-file-name=">,
- HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">;
-def print_ivar_layout : Flag<["-"], "print-ivar-layout">, Flags<[CC1Option]>,
- HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
-def print_libgcc_file_name : Flag<["-", "--"], "print-libgcc-file-name">,
- HelpText<"Print the library path for \"libgcc.a\"">;
-def print_multi_directory : Flag<["-", "--"], "print-multi-directory">;
-def print_multi_lib : Flag<["-", "--"], "print-multi-lib">;
-def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">,
- Flags<[Unsupported]>;
-def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">,
- HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">;
-def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
- HelpText<"Print the paths used for finding libraries and programs">;
-def private__bundle : Flag<["-"], "private_bundle">;
-def pthreads : Flag<["-"], "pthreads">;
-def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>,
- HelpText<"Support POSIX threads in generated code">;
-def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>;
-def p : Flag<["-"], "p">;
-def pie : Flag<["-"], "pie">;
-def read__only__relocs : Separate<["-"], "read_only_relocs">;
-def remap : Flag<["-"], "remap">;
-def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>,
- HelpText<"Rewrite Objective-C source to C++">, Group<Action_Group>;
-def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[DriverOption]>,
- HelpText<"Rewrite Legacy Objective-C source to C++">;
-def rdynamic : Flag<["-"], "rdynamic">;
-def resource_dir : Separate<["-"], "resource-dir">,
- Flags<[DriverOption, CC1Option, HelpHidden]>,
- HelpText<"The directory which holds the compiler resource files">;
-def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption]>,
- Alias<resource_dir>;
-def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>;
-def rtlib_EQ : Joined<["-", "--"], "rtlib=">;
-def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>;
-def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[DriverOption]>,
- HelpText<"Save intermediate compilation results.">;
-def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>,
- Alias<save_temps_EQ>, AliasArgs<["cwd"]>,
- HelpText<"Save intermediate compilation results">;
-def via_file_asm : Flag<["-", "--"], "via-file-asm">, InternalDebugOpt,
- HelpText<"Write assembly to file for input to assemble jobs">;
-def sectalign : MultiArg<["-"], "sectalign", 3>;
-def sectcreate : MultiArg<["-"], "sectcreate", 3>;
-def sectobjectsymbols : MultiArg<["-"], "sectobjectsymbols", 2>;
-def sectorder : MultiArg<["-"], "sectorder", 3>;
-def seg1addr : JoinedOrSeparate<["-"], "seg1addr">;
-def seg__addr__table__filename : Separate<["-"], "seg_addr_table_filename">;
-def seg__addr__table : Separate<["-"], "seg_addr_table">;
-def segaddr : MultiArg<["-"], "segaddr", 2>;
-def segcreate : MultiArg<["-"], "segcreate", 3>;
-def seglinkedit : Flag<["-"], "seglinkedit">;
-def segprot : MultiArg<["-"], "segprot", 3>;
-def segs__read__only__addr : Separate<["-"], "segs_read_only_addr">;
-def segs__read__write__addr : Separate<["-"], "segs_read_write_addr">;
-def segs__read__ : Joined<["-"], "segs_read_">;
-def shared_libgcc : Flag<["-"], "shared-libgcc">;
-def shared : Flag<["-", "--"], "shared">;
-def single__module : Flag<["-"], "single_module">;
-def specs_EQ : Joined<["-", "--"], "specs=">;
-def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>;
-def static_libgcc : Flag<["-"], "static-libgcc">;
-def static_libstdcxx : Flag<["-"], "static-libstdc++">;
-def static : Flag<["-", "--"], "static">, Flags<[NoArgumentUnused]>;
-def std_default_EQ : Joined<["-"], "std-default=">;
-def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
- Group<CompileOnly_Group>, HelpText<"Language standard to compile for">;
-def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
- HelpText<"C++ standard library to use">;
-def sub__library : JoinedOrSeparate<["-"], "sub_library">;
-def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
-def system_header_prefix : Joined<["--"], "system-header-prefix=">,
- Group<clang_i_Group>, Flags<[CC1Option]>, MetaVarName<"<prefix>">,
- HelpText<"Treat all #include paths starting with <prefix> as including a "
- "system header.">;
-def : Separate<["--"], "system-header-prefix">, Alias<system_header_prefix>;
-def no_system_header_prefix : Joined<["--"], "no-system-header-prefix=">,
- Group<clang_i_Group>, Flags<[CC1Option]>, MetaVarName<"<prefix>">,
- HelpText<"Treat all #include paths starting with <prefix> as not including a "
- "system header.">;
-def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix>;
-def s : Flag<["-"], "s">;
-def target : Joined<["--"], "target=">, Flags<[DriverOption, CoreOption]>,
- HelpText<"Generate code for the given target">;
-def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[DriverOption]>,
- HelpText<"Use the gcc toolchain at the given directory">;
-def time : Flag<["-"], "time">,
- HelpText<"Time individual commands">;
-def traditional_cpp : Flag<["-", "--"], "traditional-cpp">, Flags<[CC1Option]>,
- HelpText<"Enable some traditional CPP emulation">;
-def traditional : Flag<["-", "--"], "traditional">;
-def trigraphs : Flag<["-", "--"], "trigraphs">, Alias<ftrigraphs>,
- HelpText<"Process trigraph sequences">;
-def twolevel__namespace__hints : Flag<["-"], "twolevel_namespace_hints">;
-def twolevel__namespace : Flag<["-"], "twolevel_namespace">;
-def t : Flag<["-"], "t">;
-def umbrella : Separate<["-"], "umbrella">;
-def undefined : JoinedOrSeparate<["-"], "undefined">, Group<u_Group>;
-def undef : Flag<["-"], "undef">, Group<u_Group>, Flags<[CC1Option]>,
- HelpText<"undef all system defines">;
-def unexported__symbols__list : Separate<["-"], "unexported_symbols_list">;
-def u : JoinedOrSeparate<["-"], "u">, Group<u_Group>;
-def v : Flag<["-"], "v">, Flags<[CC1Option, CoreOption]>,
- HelpText<"Show commands to run and use verbose output">;
-def verify_debug_info : Flag<["--"], "verify-debug-info">, Flags<[DriverOption]>,
- HelpText<"Verify the binary representation of debug output">;
-def weak_l : Joined<["-"], "weak-l">, Flags<[LinkerInput]>;
-def weak__framework : Separate<["-"], "weak_framework">, Flags<[LinkerInput]>;
-def weak__library : Separate<["-"], "weak_library">, Flags<[LinkerInput]>;
-def weak__reference__mismatches : Separate<["-"], "weak_reference_mismatches">;
-def whatsloaded : Flag<["-"], "whatsloaded">;
-def whyload : Flag<["-"], "whyload">;
-def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>;
-def x : JoinedOrSeparate<["-"], "x">, Flags<[DriverOption,CC1Option]>,
- HelpText<"Treat subsequent input files as having type <language>">,
- MetaVarName<"<language>">;
-def y : Joined<["-"], "y">;
-
-def fintegrated_as : Flag<["-"], "fintegrated-as">, Flags<[DriverOption]>,
- Group<f_Group>, HelpText<"Enable the integrated assembler">;
-def fno_integrated_as : Flag<["-"], "fno-integrated-as">,
- Flags<[CC1Option, DriverOption]>, Group<f_Group>,
- HelpText<"Disable the integrated assembler">;
-def : Flag<["-"], "integrated-as">, Alias<fintegrated_as>, Flags<[DriverOption]>;
-def : Flag<["-"], "no-integrated-as">, Alias<fno_integrated_as>,
- Flags<[CC1Option, DriverOption]>;
-
-def working_directory : JoinedOrSeparate<["-"], "working-directory">, Flags<[CC1Option]>,
- HelpText<"Resolve file paths relative to the specified directory">;
-def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option]>,
- Alias<working_directory>;
-
-// Double dash options, which are usually an alias for one of the previous
-// options.
-
-def _mhwdiv_EQ : Joined<["--"], "mhwdiv=">, Alias<mhwdiv_EQ>;
-def _mhwdiv : Separate<["--"], "mhwdiv">, Alias<mhwdiv_EQ>;
-def _CLASSPATH_EQ : Joined<["--"], "CLASSPATH=">, Alias<fclasspath_EQ>;
-def _CLASSPATH : Separate<["--"], "CLASSPATH">, Alias<fclasspath_EQ>;
-def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>;
-def _analyze_auto : Flag<["--"], "analyze-auto">, Flags<[DriverOption]>;
-def _analyzer_no_default_checks : Flag<["--"], "analyzer-no-default-checks">, Flags<[DriverOption]>;
-def _analyzer_output : JoinedOrSeparate<["--"], "analyzer-output">, Flags<[DriverOption]>;
-def _analyze : Flag<["--"], "analyze">, Flags<[DriverOption, CoreOption]>,
- HelpText<"Run the static analyzer">;
-def _assemble : Flag<["--"], "assemble">, Alias<S>;
-def _assert_EQ : Joined<["--"], "assert=">, Alias<A>;
-def _assert : Separate<["--"], "assert">, Alias<A>;
-def _bootclasspath_EQ : Joined<["--"], "bootclasspath=">, Alias<fbootclasspath_EQ>;
-def _bootclasspath : Separate<["--"], "bootclasspath">, Alias<fbootclasspath_EQ>;
-def _classpath_EQ : Joined<["--"], "classpath=">, Alias<fclasspath_EQ>;
-def _classpath : Separate<["--"], "classpath">, Alias<fclasspath_EQ>;
-def _comments_in_macros : Flag<["--"], "comments-in-macros">, Alias<CC>;
-def _comments : Flag<["--"], "comments">, Alias<C>;
-def _compile : Flag<["--"], "compile">, Alias<c>;
-def _constant_cfstrings : Flag<["--"], "constant-cfstrings">;
-def _debug_EQ : Joined<["--"], "debug=">, Alias<g_Flag>;
-def _debug : Flag<["--"], "debug">, Alias<g_Flag>;
-def _define_macro_EQ : Joined<["--"], "define-macro=">, Alias<D>;
-def _define_macro : Separate<["--"], "define-macro">, Alias<D>;
-def _dependencies : Flag<["--"], "dependencies">, Alias<M>;
-def _dyld_prefix_EQ : Joined<["--"], "dyld-prefix=">;
-def _dyld_prefix : Separate<["--"], "dyld-prefix">, Alias<_dyld_prefix_EQ>;
-def _encoding_EQ : Joined<["--"], "encoding=">, Alias<fencoding_EQ>;
-def _encoding : Separate<["--"], "encoding">, Alias<fencoding_EQ>;
-def _entry : Flag<["--"], "entry">, Alias<e>;
-def _extdirs_EQ : Joined<["--"], "extdirs=">, Alias<fextdirs_EQ>;
-def _extdirs : Separate<["--"], "extdirs">, Alias<fextdirs_EQ>;
-def _extra_warnings : Flag<["--"], "extra-warnings">, Alias<W_Joined>;
-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 _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>;
-def _include_directory_after : Separate<["--"], "include-directory-after">, Alias<idirafter>;
-def _include_directory_EQ : Joined<["--"], "include-directory=">, Alias<I>;
-def _include_directory : Separate<["--"], "include-directory">, Alias<I>;
-def _include_prefix_EQ : Joined<["--"], "include-prefix=">, Alias<iprefix>;
-def _include_prefix : Separate<["--"], "include-prefix">, Alias<iprefix>;
-def _include_with_prefix_after_EQ : Joined<["--"], "include-with-prefix-after=">, Alias<iwithprefix>;
-def _include_with_prefix_after : Separate<["--"], "include-with-prefix-after">, Alias<iwithprefix>;
-def _include_with_prefix_before_EQ : Joined<["--"], "include-with-prefix-before=">, Alias<iwithprefixbefore>;
-def _include_with_prefix_before : Separate<["--"], "include-with-prefix-before">, Alias<iwithprefixbefore>;
-def _include_with_prefix_EQ : Joined<["--"], "include-with-prefix=">, Alias<iwithprefix>;
-def _include_with_prefix : Separate<["--"], "include-with-prefix">, Alias<iwithprefix>;
-def _include_EQ : Joined<["--"], "include=">, Alias<include_>;
-def _language_EQ : Joined<["--"], "language=">, Alias<x>;
-def _language : Separate<["--"], "language">, Alias<x>;
-def _library_directory_EQ : Joined<["--"], "library-directory=">, Alias<L>;
-def _library_directory : Separate<["--"], "library-directory">, Alias<L>;
-def _no_line_commands : Flag<["--"], "no-line-commands">, Alias<P>;
-def _no_standard_includes : Flag<["--"], "no-standard-includes">, Alias<nostdinc>;
-def _no_standard_libraries : Flag<["--"], "no-standard-libraries">, Alias<nostdlib>;
-def _no_undefined : Flag<["--"], "no-undefined">, Flags<[LinkerInput]>;
-def _no_warnings : Flag<["--"], "no-warnings">, Alias<w>;
-def _optimize_EQ : Joined<["--"], "optimize=">, Alias<O>;
-def _optimize : Flag<["--"], "optimize">, Alias<O>;
-def _output_class_directory_EQ : Joined<["--"], "output-class-directory=">, Alias<foutput_class_dir_EQ>;
-def _output_class_directory : Separate<["--"], "output-class-directory">, Alias<foutput_class_dir_EQ>;
-def _output_EQ : Joined<["--"], "output=">, Alias<o>;
-def _output : Separate<["--"], "output">, Alias<o>;
-def _param : Separate<["--"], "param">, Group<CompileOnly_Group>;
-def _param_EQ : Joined<["--"], "param=">, Alias<_param>;
-def _prefix_EQ : Joined<["--"], "prefix=">, Alias<B>;
-def _prefix : Separate<["--"], "prefix">, Alias<B>;
-def _preprocess : Flag<["--"], "preprocess">, Alias<E>;
-def _print_diagnostic_categories : Flag<["--"], "print-diagnostic-categories">;
-def _print_file_name : Separate<["--"], "print-file-name">, Alias<print_file_name_EQ>;
-def _print_missing_file_dependencies : Flag<["--"], "print-missing-file-dependencies">, Alias<MG>;
-def _print_prog_name : Separate<["--"], "print-prog-name">, Alias<print_prog_name_EQ>;
-def _profile_blocks : Flag<["--"], "profile-blocks">, Alias<a>;
-def _profile : Flag<["--"], "profile">, Alias<p>;
-def _resource_EQ : Joined<["--"], "resource=">, Alias<fcompile_resource_EQ>;
-def _resource : Separate<["--"], "resource">, Alias<fcompile_resource_EQ>;
-def _rtlib : Separate<["--"], "rtlib">, Alias<rtlib_EQ>;
-def _serialize_diags : Separate<["-", "--"], "serialize-diagnostics">, Flags<[DriverOption]>,
- HelpText<"Serialize compiler diagnostics to a file">;
-// We give --version different semantics from -version.
-def _version : Flag<["--"], "version">, Flags<[CC1Option]>;
-def _signed_char : Flag<["--"], "signed-char">, Alias<fsigned_char>;
-def _std : Separate<["--"], "std">, Alias<std_EQ>;
-def _stdlib : Separate<["--"], "stdlib">, Alias<stdlib_EQ>;
-def _sysroot_EQ : Joined<["--"], "sysroot=">;
-def _sysroot : Separate<["--"], "sysroot">, Alias<_sysroot_EQ>;
-def _target_help : Flag<["--"], "target-help">;
-def _trace_includes : Flag<["--"], "trace-includes">, Alias<H>;
-def _undefine_macro_EQ : Joined<["--"], "undefine-macro=">, Alias<U>;
-def _undefine_macro : Separate<["--"], "undefine-macro">, Alias<U>;
-def _unsigned_char : Flag<["--"], "unsigned-char">, Alias<funsigned_char>;
-def _user_dependencies : Flag<["--"], "user-dependencies">, Alias<MM>;
-def _verbose : Flag<["--"], "verbose">, Alias<v>;
-def _warn__EQ : Joined<["--"], "warn-=">, Alias<W_Joined>;
-def _warn_ : Joined<["--"], "warn-">, Alias<W_Joined>;
-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>;
-def mv4 : Flag<["-"], "mv4">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["v4"]>;
-def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<mcpu_EQ>,
- AliasArgs<["v5"]>;
-def mv55 : Flag<["-"], "mv55">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["v55"]>;
-def mv60 : Flag<["-"], "mv60">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["v60"]>;
-def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Enable Hexagon Vector eXtensions">;
-def mno_hexagon_hvx : Flag<["-"], "mno-hvx">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Disable Hexagon Vector eXtensions">;
-def mhexagon_hvx_double : Flag<["-"], "mhvx-double">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Enable Hexagon Double Vector eXtensions">;
-def mno_hexagon_hvx_double : Flag<["-"], "mno-hvx-double">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Disable Hexagon Double Vector eXtensions">;
-
-// 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
-// style of double-dash and equals-joined flags.
-def gcc_toolchain_legacy_spelling : Separate<["-"], "gcc-toolchain">, Alias<gcc_toolchain>;
-def target_legacy_spelling : Separate<["-"], "target">, Alias<target>;
-
-// Special internal option to handle -Xlinker --no-demangle.
-def Z_Xlinker__no_demangle : Flag<["-"], "Z-Xlinker-no-demangle">,
- Flags<[Unsupported, NoArgumentUnused]>;
-
-// Special internal option to allow forwarding arbitrary arguments to linker.
-def Zlinker_input : Separate<["-"], "Zlinker-input">,
- Flags<[Unsupported, NoArgumentUnused]>;
-
-// Reserved library options.
-def Z_reserved_lib_stdcxx : Flag<["-"], "Z-reserved-lib-stdc++">,
- Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>;
-def Z_reserved_lib_cckext : Flag<["-"], "Z-reserved-lib-cckext">,
- Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>;
-
-// Ignored options
-// FIXME: multiclasess produce suffixes, not prefixes. This is fine for now
-// since it is only used in ignored options.
-multiclass BooleanFFlag<string name> {
- def _f : Flag<["-"], "f"#name>;
- def _fno : Flag<["-"], "fno-"#name>;
-}
-
-defm : BooleanFFlag<"keep-inline-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
-
-def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_gcc_optimization_f_Group>;
-
-def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
-
-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>;
-def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm align_jumps : BooleanFFlag<"align-jumps">, Group<clang_ignored_gcc_optimization_f_Group>;
-def falign_jumps_EQ : Joined<["-"], "falign-jumps=">, Group<clang_ignored_gcc_optimization_f_Group>;
-
-// FIXME: This option should be supported and wired up to our diognostics, but
-// ignore it for now to avoid breaking builds that use it.
-def fdiagnostics_show_location_EQ : Joined<["-"], "fdiagnostics-show-location=">, Group<clang_ignored_f_Group>;
-
-defm fcheck_new : BooleanFFlag<"check-new">, Group<clang_ignored_f_Group>;
-defm caller_saves : BooleanFFlag<"caller-saves">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm reorder_blocks : BooleanFFlag<"reorder-blocks">, Group<clang_ignored_gcc_optimization_f_Group>;
-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>;
-defm function_attribute_list : BooleanFFlag<"function-attribute-list">, Group<clang_ignored_f_Group>;
-defm gcse : BooleanFFlag<"gcse">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm gcse_after_reload: BooleanFFlag<"gcse-after-reload">, Group<clang_ignored_gcc_optimization_f_Group>;
-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>;
-defm modulo_sched : BooleanFFlag<"modulo-sched">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm modulo_sched_allow_regmoves : BooleanFFlag<"modulo-sched-allow-regmoves">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-defm inline_functions_called_once : BooleanFFlag<"inline-functions-called-once">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-def finline_limit_EQ : Joined<["-"], "finline-limit=">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm finline_limit : BooleanFFlag<"inline-limit">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm inline_small_functions : BooleanFFlag<"inline-small-functions">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-defm ipa_cp : BooleanFFlag<"ipa-cp">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>;
-defm peel_loops : BooleanFFlag<"peel-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>;
-defm prefetch_loop_arrays : BooleanFFlag<"prefetch-loop-arrays">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm printf : BooleanFFlag<"printf">, Group<clang_ignored_f_Group>;
-defm profile : BooleanFFlag<"profile">, Group<clang_ignored_f_Group>;
-defm profile_correction : BooleanFFlag<"profile-correction">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm profile_generate_sampling : BooleanFFlag<"profile-generate-sampling">, Group<clang_ignored_f_Group>;
-defm profile_reusedist : BooleanFFlag<"profile-reusedist">, Group<clang_ignored_f_Group>;
-defm profile_values : BooleanFFlag<"profile-values">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm regs_graph : BooleanFFlag<"regs-graph">, Group<clang_ignored_f_Group>;
-defm rename_registers : BooleanFFlag<"rename-registers">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm ripa : BooleanFFlag<"ripa">, Group<clang_ignored_f_Group>;
-defm rounding_math : BooleanFFlag<"rounding-math">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm schedule_insns : BooleanFFlag<"schedule-insns">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm schedule_insns2 : BooleanFFlag<"schedule-insns2">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm see : BooleanFFlag<"see">, Group<clang_ignored_f_Group>;
-defm signaling_nans : BooleanFFlag<"signaling-nans">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm single_precision_constant : BooleanFFlag<"single-precision-constant">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-defm spec_constr_count : BooleanFFlag<"spec-constr-count">, Group<clang_ignored_f_Group>;
-defm stack_check : BooleanFFlag<"stack-check">, Group<clang_ignored_f_Group>;
-defm strength_reduce :
- BooleanFFlag<"strength-reduce">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm tls_model : BooleanFFlag<"tls-model">, Group<clang_ignored_f_Group>;
-defm tracer : BooleanFFlag<"tracer">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm tree_dce : BooleanFFlag<"tree-dce">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm tree_loop_im : BooleanFFlag<"tree_loop_im">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm tree_loop_ivcanon : BooleanFFlag<"tree_loop_ivcanon">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm tree_loop_linear : BooleanFFlag<"tree_loop_linear">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm tree_salias : BooleanFFlag<"tree-salias">, Group<clang_ignored_f_Group>;
-defm tree_ter : BooleanFFlag<"tree-ter">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm tree_vectorizer_verbose : BooleanFFlag<"tree-vectorizer-verbose">, Group<clang_ignored_f_Group>;
-defm tree_vrp : BooleanFFlag<"tree-vrp">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm unroll_all_loops : BooleanFFlag<"unroll-all-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm unsafe_loop_optimizations : BooleanFFlag<"unsafe-loop-optimizations">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-defm unswitch_loops : BooleanFFlag<"unswitch-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm use_linker_plugin : BooleanFFlag<"use-linker-plugin">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm vect_cost_model : BooleanFFlag<"vect-cost-model">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm variable_expansion_in_unroller : BooleanFFlag<"variable-expansion-in-unroller">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-defm web : BooleanFFlag<"web">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm whole_program : BooleanFFlag<"whole-program">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm devirtualize : BooleanFFlag<"devirtualize">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm devirtualize_speculatively : BooleanFFlag<"devirtualize-speculatively">,
- Group<clang_ignored_gcc_optimization_f_Group>;
-
-// gfortran options that we recognize in the driver and pass along when
-// invoking GCC to compile Fortran code.
-def gfortran_Group : OptionGroup<"gfortran Group">;
-
-// Generic gfortran options.
-def A_DASH : Joined<["-"], "A-">, Group<gfortran_Group>;
-def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined]>, Group<gfortran_Group>;
-def cpp : Flag<["-"], "cpp">, Group<gfortran_Group>;
-def nocpp : Flag<["-"], "nocpp">, Group<gfortran_Group>;
-def static_libgfortran : Flag<["-"], "static-libgfortran">, Group<gfortran_Group>;
-
-// "f" options with values for gfortran.
-def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran_Group>;
-def fcheck_EQ : Joined<["-"], "fcheck=">, Group<gfortran_Group>;
-def fcoarray_EQ : Joined<["-"], "fcoarray=">, Group<gfortran_Group>;
-def fconvert_EQ : Joined<["-"], "fconvert=">, Group<gfortran_Group>;
-def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<gfortran_Group>;
-def ffpe_trap_EQ : Joined<["-"], "ffpe-trap=">, Group<gfortran_Group>;
-def ffree_line_length_VALUE : Joined<["-"], "ffree-line-length-">, Group<gfortran_Group>;
-def finit_character_EQ : Joined<["-"], "finit-character=">, Group<gfortran_Group>;
-def finit_integer_EQ : Joined<["-"], "finit-integer=">, Group<gfortran_Group>;
-def finit_logical_EQ : Joined<["-"], "finit-logical=">, Group<gfortran_Group>;
-def finit_real_EQ : Joined<["-"], "finit-real=">, Group<gfortran_Group>;
-def fmax_array_constructor_EQ : Joined<["-"], "fmax-array-constructor=">, Group<gfortran_Group>;
-def fmax_errors_EQ : Joined<["-"], "fmax-errors=">, Group<gfortran_Group>;
-def fmax_stack_var_size_EQ : Joined<["-"], "fmax-stack-var-size=">, Group<gfortran_Group>;
-def fmax_subrecord_length_EQ : Joined<["-"], "fmax-subrecord-length=">, Group<gfortran_Group>;
-def frecord_marker_EQ : Joined<["-"], "frecord-marker=">, Group<gfortran_Group>;
-
-// "f" flags for gfortran.
-defm aggressive_function_elimination : BooleanFFlag<"aggressive-function-elimination">, Group<gfortran_Group>;
-defm align_commons : BooleanFFlag<"align-commons">, Group<gfortran_Group>;
-defm all_intrinsics : BooleanFFlag<"all-intrinsics">, Group<gfortran_Group>;
-defm automatic : BooleanFFlag<"automatic">, Group<gfortran_Group>;
-defm backslash : BooleanFFlag<"backslash">, Group<gfortran_Group>;
-defm backtrace : BooleanFFlag<"backtrace">, Group<gfortran_Group>;
-defm bounds_check : BooleanFFlag<"bounds-check">, Group<gfortran_Group>;
-defm check_array_temporaries : BooleanFFlag<"check-array-temporaries">, Group<gfortran_Group>;
-defm cray_pointer : BooleanFFlag<"cray-pointer">, Group<gfortran_Group>;
-defm d_lines_as_code : BooleanFFlag<"d-lines-as-code">, Group<gfortran_Group>;
-defm d_lines_as_comments : BooleanFFlag<"d-lines-as-comments">, Group<gfortran_Group>;
-defm default_double_8 : BooleanFFlag<"default-double-8">, Group<gfortran_Group>;
-defm default_integer_8 : BooleanFFlag<"default-integer-8">, Group<gfortran_Group>;
-defm default_real_8 : BooleanFFlag<"default-real-8">, Group<gfortran_Group>;
-defm dollar_ok : BooleanFFlag<"dollar-ok">, Group<gfortran_Group>;
-defm dump_fortran_optimized : BooleanFFlag<"dump-fortran-optimized">, Group<gfortran_Group>;
-defm dump_fortran_original : BooleanFFlag<"dump-fortran-original">, Group<gfortran_Group>;
-defm dump_parse_tree : BooleanFFlag<"dump-parse-tree">, Group<gfortran_Group>;
-defm external_blas : BooleanFFlag<"external-blas">, Group<gfortran_Group>;
-defm f2c : BooleanFFlag<"f2c">, Group<gfortran_Group>;
-defm fixed_form : BooleanFFlag<"fixed-form">, Group<gfortran_Group>;
-defm free_form : BooleanFFlag<"free-form">, Group<gfortran_Group>;
-defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group<gfortran_Group>;
-defm implicit_none : BooleanFFlag<"implicit-none">, Group<gfortran_Group>;
-defm init_local_zero : BooleanFFlag<"init-local-zero">, Group<gfortran_Group>;
-defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group<gfortran_Group>;
-defm intrinsic_modules_path : BooleanFFlag<"intrinsic-modules-path">, Group<gfortran_Group>;
-defm max_identifier_length : BooleanFFlag<"max-identifier-length">, Group<gfortran_Group>;
-defm module_private : BooleanFFlag<"module-private">, Group<gfortran_Group>;
-defm pack_derived : BooleanFFlag<"pack-derived">, Group<gfortran_Group>;
-defm protect_parens : BooleanFFlag<"protect-parens">, Group<gfortran_Group>;
-defm range_check : BooleanFFlag<"range-check">, Group<gfortran_Group>;
-defm real_4_real_10 : BooleanFFlag<"real-4-real-10">, Group<gfortran_Group>;
-defm real_4_real_16 : BooleanFFlag<"real-4-real-16">, Group<gfortran_Group>;
-defm real_4_real_8 : BooleanFFlag<"real-4-real-8">, Group<gfortran_Group>;
-defm real_8_real_10 : BooleanFFlag<"real-8-real-10">, Group<gfortran_Group>;
-defm real_8_real_16 : BooleanFFlag<"real-8-real-16">, Group<gfortran_Group>;
-defm real_8_real_4 : BooleanFFlag<"real-8-real-4">, Group<gfortran_Group>;
-defm realloc_lhs : BooleanFFlag<"realloc-lhs">, Group<gfortran_Group>;
-defm recursive : BooleanFFlag<"recursive">, Group<gfortran_Group>;
-defm repack_arrays : BooleanFFlag<"repack-arrays">, Group<gfortran_Group>;
-defm second_underscore : BooleanFFlag<"second-underscore">, Group<gfortran_Group>;
-defm sign_zero : BooleanFFlag<"sign-zero">, Group<gfortran_Group>;
-defm stack_arrays : BooleanFFlag<"stack-arrays">, Group<gfortran_Group>;
-defm underscoring : BooleanFFlag<"underscoring">, Group<gfortran_Group>;
-defm whole_file : BooleanFFlag<"whole-file">, Group<gfortran_Group>;
-
-
-include "CC1Options.td"
-
-include "CLCompatOptions.td"
diff --git a/include/clang/Driver/Phases.h b/include/clang/Driver/Phases.h
deleted file mode 100644
index cd6b5b5..0000000
--- a/include/clang/Driver/Phases.h
+++ /dev/null
@@ -1,37 +0,0 @@
-//===--- Phases.h - Transformations on Driver Types -------------*- 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_DRIVER_PHASES_H
-#define LLVM_CLANG_DRIVER_PHASES_H
-
-namespace clang {
-namespace driver {
-namespace phases {
- /// ID - Ordered values for successive stages in the
- /// compilation process which interact with user options.
- enum ID {
- Preprocess,
- Precompile,
- Compile,
- Backend,
- Assemble,
- Link
- };
-
- enum {
- MaxNumberOfPhases = Link + 1
- };
-
- const char *getPhaseName(ID Id);
-
-} // end namespace phases
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
deleted file mode 100644
index c2611b5..0000000
--- a/include/clang/Driver/SanitizerArgs.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//===--- SanitizerArgs.h - Arguments for sanitizer tools -------*- 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_DRIVER_SANITIZERARGS_H
-#define LLVM_CLANG_DRIVER_SANITIZERARGS_H
-
-#include "clang/Basic/Sanitizers.h"
-#include "clang/Driver/Types.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace driver {
-
-class ToolChain;
-
-class SanitizerArgs {
- SanitizerSet Sanitizers;
- SanitizerSet RecoverableSanitizers;
- SanitizerSet TrapSanitizers;
-
- std::vector<std::string> BlacklistFiles;
- std::vector<std::string> ExtraDeps;
- int CoverageFeatures;
- int MsanTrackOrigins;
- bool MsanUseAfterDtor;
- bool CfiCrossDso;
- int AsanFieldPadding;
- bool AsanSharedRuntime;
- bool LinkCXXRuntimes;
- bool NeedPIE;
-
- public:
- /// Parses the sanitizer arguments from an argument list.
- SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
-
- bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
- bool needsSharedAsanRt() const { return AsanSharedRuntime; }
- bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
- bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
- bool needsLsanRt() const {
- return Sanitizers.has(SanitizerKind::Leak) &&
- !Sanitizers.has(SanitizerKind::Address);
- }
- bool needsUbsanRt() const;
- bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
- bool needsSafeStackRt() const {
- return Sanitizers.has(SanitizerKind::SafeStack);
- }
- bool needsCfiRt() const;
- bool needsCfiDiagRt() const;
-
- bool requiresPIE() const;
- bool needsUnwindTables() const;
- bool linkCXXRuntimes() const { return LinkCXXRuntimes; }
- void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;
-
- private:
- void clear();
-};
-
-} // namespace driver
-} // namespace clang
-
-#endif
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
deleted file mode 100644
index b9eac1c..0000000
--- a/include/clang/Driver/Tool.h
+++ /dev/null
@@ -1,137 +0,0 @@
-//===--- Tool.h - Compilation Tools -----------------------------*- 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_DRIVER_TOOL_H
-#define LLVM_CLANG_DRIVER_TOOL_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/Support/Program.h"
-
-namespace llvm {
-namespace opt {
- class ArgList;
-}
-}
-
-namespace clang {
-namespace driver {
-
- class Compilation;
- class InputInfo;
- class Job;
- class JobAction;
- class ToolChain;
-
- typedef SmallVector<InputInfo, 4> InputInfoList;
-
-/// Tool - Information on a specific compilation tool.
-class Tool {
-public:
- // Documents the level of support for response files in this tool.
- // Response files are necessary if the command line gets too large,
- // requiring the arguments to be transfered to a file.
- enum ResponseFileSupport {
- // Provides full support for response files, which means we can transfer
- // all tool input arguments to a file. E.g.: clang, gcc, binutils and MSVC
- // tools.
- RF_Full,
- // Input file names can live in a file, but flags can't. E.g.: ld64 (Mac
- // OS X linker).
- RF_FileList,
- // Does not support response files: all arguments must be passed via
- // command line.
- RF_None
- };
-
-private:
- /// The tool name (for debugging).
- const char *Name;
-
- /// The human readable name for the tool, for use in diagnostics.
- const char *ShortName;
-
- /// The tool chain this tool is a part of.
- const ToolChain &TheToolChain;
-
- /// The level of support for response files seen in this tool
- const ResponseFileSupport ResponseSupport;
-
- /// The encoding to use when writing response files for this tool on Windows
- const llvm::sys::WindowsEncodingMethod ResponseEncoding;
-
- /// The flag used to pass a response file via command line to this tool
- const char *const ResponseFlag;
-
-public:
- Tool(const char *Name, const char *ShortName, const ToolChain &TC,
- ResponseFileSupport ResponseSupport = RF_None,
- llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
- const char *ResponseFlag = "@");
-
-public:
- virtual ~Tool();
-
- const char *getName() const { return Name; }
-
- const char *getShortName() const { return ShortName; }
-
- const ToolChain &getToolChain() const { return TheToolChain; }
-
- virtual bool hasIntegratedAssembler() const { return false; }
- virtual bool canEmitIR() const { return false; }
- 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,
- /// 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
- /// relevant on Windows platforms where there are different encodings being
- /// accepted for different tools. On UNIX, UTF8 is universal.
- ///
- /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response
- /// files encoded with the system current code page.
- /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows.
- /// - Clang accepts both UTF8 and UTF16.
- ///
- /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should
- /// always use UTF16 for Windows, which is the Windows official encoding for
- /// international characters.
- llvm::sys::WindowsEncodingMethod getResponseFileEncoding() const {
- return ResponseEncoding;
- }
- /// \brief 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
- /// driver add an additional "command failed" diagnostic on failures.
- virtual bool hasGoodDiagnostics() const { return false; }
-
- /// ConstructJob - Construct jobs to perform the action \p JA,
- /// writing to \p Output and with \p Inputs, and add the jobs to
- /// \p C.
- ///
- /// \param TCArgs - The argument list for this toolchain, with any
- /// tool chain specific translations applied.
- /// \param LinkingOutput - If this output will eventually feed the
- /// linker, then this is the final output name of the linked image.
- virtual void ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const llvm::opt::ArgList &TCArgs,
- const char *LinkingOutput) const = 0;
-};
-
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
deleted file mode 100644
index ed73107..0000000
--- a/include/clang/Driver/ToolChain.h
+++ /dev/null
@@ -1,418 +0,0 @@
-//===--- ToolChain.h - Collections of tools for one platform ----*- 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_DRIVER_TOOLCHAIN_H
-#define LLVM_CLANG_DRIVER_TOOLCHAIN_H
-
-#include "clang/Basic/Sanitizers.h"
-#include "clang/Driver/Action.h"
-#include "clang/Driver/Multilib.h"
-#include "clang/Driver/Types.h"
-#include "clang/Driver/Util.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Target/TargetOptions.h"
-#include <memory>
-#include <string>
-
-namespace llvm {
-namespace opt {
- class ArgList;
- class DerivedArgList;
- class InputArgList;
-}
-}
-
-namespace clang {
-class ObjCRuntime;
-namespace vfs {
-class FileSystem;
-}
-
-namespace driver {
- class Compilation;
- class Driver;
- class JobAction;
- class SanitizerArgs;
- class Tool;
-
-/// ToolChain - Access to tools for a single platform.
-class ToolChain {
-public:
- typedef SmallVector<std::string, 16> path_list;
-
- enum CXXStdlibType {
- CST_Libcxx,
- CST_Libstdcxx
- };
-
- enum RuntimeLibType {
- RLT_CompilerRT,
- RLT_Libgcc
- };
-
- enum RTTIMode {
- RM_EnabledExplicitly,
- RM_EnabledImplicitly,
- RM_DisabledExplicitly,
- RM_DisabledImplicitly
- };
-
-private:
- const Driver &D;
- const 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.
- path_list FilePaths;
-
- /// 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;
- Tool *getClang() const;
- Tool *getAssemble() const;
- Tool *getLink() const;
- Tool *getClangAs() const;
-
- mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
-
-protected:
- MultilibSet Multilibs;
- const char *DefaultLinker = "ld";
-
- ToolChain(const Driver &D, const llvm::Triple &T,
- const llvm::opt::ArgList &Args);
-
- virtual Tool *buildAssembler() const;
- virtual Tool *buildLinker() const;
- virtual Tool *getTool(Action::ActionClass AC) const;
-
- /// \name Utilities for implementing subclasses.
- ///@{
- static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args,
- const Twine &Path);
- static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args,
- const Twine &Path);
- static void
- addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args,
- const Twine &Path);
- static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args,
- ArrayRef<StringRef> Paths);
- ///@}
-
-public:
- virtual ~ToolChain();
-
- // Accessors
-
- const Driver &getDriver() const { return D; }
- vfs::FileSystem &getVFS() const;
- const llvm::Triple &getTriple() const { return Triple; }
-
- llvm::Triple::ArchType getArch() const { return Triple.getArch(); }
- StringRef getArchName() const { return Triple.getArchName(); }
- StringRef getPlatform() const { return Triple.getVendorName(); }
- StringRef getOS() const { return Triple.getOSName(); }
-
- /// \brief Provide the default architecture name (as expected by -arch) for
- /// this toolchain. Note t
- StringRef getDefaultUniversalArchName() const;
-
- std::string getTripleString() const {
- return Triple.getTriple();
- }
-
- path_list &getFilePaths() { return FilePaths; }
- const path_list &getFilePaths() const { return FilePaths; }
-
- path_list &getProgramPaths() { return ProgramPaths; }
- const path_list &getProgramPaths() const { return ProgramPaths; }
-
- const MultilibSet &getMultilibs() const { return Multilibs; }
-
- const SanitizerArgs& getSanitizerArgs() const;
-
- // Returns the Arg * that explicitly turned on/off rtti, or nullptr.
- const llvm::opt::Arg *getRTTIArg() const { return CachedRTTIArg; }
-
- // 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
- /// the compiler driver as `ProgName`.
- ///
- /// For example, when called with i686-linux-android-g++, the first element
- /// of the return value will be set to `"i686-linux-android"` and the second
- /// will be set to "--driver-mode=g++"`.
- ///
- /// \pre `llvm::InitializeAllTargets()` has been called.
- /// \param ProgName The name the Clang driver was invoked with (from,
- /// e.g., argv[0])
- /// \return A pair of (`target`, `mode-flag`), where one or both may be empty.
- static std::pair<std::string, std::string>
- getTargetAndModeFromProgramName(StringRef ProgName);
-
- // Tool access.
-
- /// TranslateArgs - Create a new derived argument list for any argument
- /// translations this ToolChain may wish to perform, or 0 if no tool chain
- /// specific translations are needed.
- ///
- /// \param BoundArch - The bound architecture name, or 0.
- virtual llvm::opt::DerivedArgList *
- TranslateArgs(const llvm::opt::DerivedArgList &Args,
- const char *BoundArch) const {
- return nullptr;
- }
-
- /// Choose a tool to use to handle the action \p JA.
- ///
- /// This can be overridden when a particular ToolChain needs to use
- /// a compiler other than Clang.
- virtual Tool *SelectTool(const JobAction &JA) const;
-
- // Helper methods
-
- std::string GetFilePath(const char *Name) const;
- std::string GetProgramPath(const char *Name) const;
-
- /// Returns the linker path, respecting the -fuse-ld= argument to determine
- /// the linker suffix or name.
- std::string GetLinkerPath() const;
-
- /// \brief 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
- /// the driver on a specific platform.
- virtual void printVerboseInfo(raw_ostream &OS) const {}
-
- // Platform defaults information
-
- /// \brief Returns true if the toolchain is targeting a non-native
- /// architecture.
- virtual bool isCrossCompiling() const;
-
- /// HasNativeLTOLinker - Check whether the linker and related tools have
- /// native LLVM support.
- virtual bool HasNativeLLVMSupport() const;
-
- /// LookupTypeForExtension - Return the default language type to use for the
- /// given extension.
- virtual types::ID LookupTypeForExtension(const char *Ext) const;
-
- /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
- virtual bool IsBlocksDefault() const { return false; }
-
- /// IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as
- /// by default.
- virtual bool IsIntegratedAssemblerDefault() const { return false; }
-
- /// \brief Check if the toolchain should use the integrated assembler.
- bool useIntegratedAs() const;
-
- /// IsMathErrnoDefault - Does this tool chain use -fmath-errno by default.
- virtual bool IsMathErrnoDefault() const { return true; }
-
- /// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable
- /// -fencode-extended-block-signature by default.
- virtual bool IsEncodeExtendedBlockSignatureDefault() const { return false; }
-
- /// IsObjCNonFragileABIDefault - Does this tool chain set
- /// -fobjc-nonfragile-abi by default.
- virtual bool IsObjCNonFragileABIDefault() const { return false; }
-
- /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the
- /// mixed dispatch method be used?
- virtual bool UseObjCMixedDispatch() const { return false; }
-
- /// GetDefaultStackProtectorLevel - Get the default stack protector level for
- /// this tool chain (0=off, 1=on, 2=strong, 3=all).
- virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
- return 0;
- }
-
- /// GetDefaultRuntimeLibType - Get the default runtime library variant to use.
- virtual RuntimeLibType GetDefaultRuntimeLibType() const {
- return ToolChain::RLT_Libgcc;
- }
-
- virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
- StringRef Component,
- bool Shared = false) const;
-
- const char *getCompilerRTArgString(const llvm::opt::ArgList &Args,
- StringRef Component,
- bool Shared = false) const;
- /// needsProfileRT - returns true if instrumentation profile is on.
- static bool needsProfileRT(const llvm::opt::ArgList &Args);
-
- /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
- /// by default.
- virtual bool IsUnwindTablesDefault() const;
-
- /// \brief Test whether this toolchain defaults to PIC.
- virtual bool isPICDefault() const = 0;
-
- /// \brief Test whether this toolchain defaults to PIE.
- virtual bool isPIEDefault() const = 0;
-
- /// \brief 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.
- virtual bool isPICDefaultForced() const = 0;
-
- /// SupportsProfiling - Does this tool chain support -pg.
- virtual bool SupportsProfiling() const { return true; }
-
- /// Does this tool chain support Objective-C garbage collection.
- virtual bool SupportsObjCGC() const { return true; }
-
- /// Complain if this tool chain doesn't support Objective-C ARC.
- virtual void CheckObjCARC() const {}
-
- /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
- /// compile unit information.
- virtual bool UseDwarfDebugFlags() const { return false; }
-
- // Return the DWARF version to emit, in the absence of arguments
- // to the contrary.
- virtual unsigned GetDefaultDwarfVersion() const { return 4; }
-
- // True if the driver should assume "-fstandalone-debug"
- // in the absence of an option specifying otherwise,
- // provided that debugging was requested in the first place.
- // i.e. a value of 'true' does not imply that debugging is wanted.
- virtual bool GetDefaultStandaloneDebug() const { return false; }
-
- // Return the default debugger "tuning."
- virtual llvm::DebuggerKind getDefaultDebuggerTuning() const {
- return llvm::DebuggerKind::GDB;
- }
-
- /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
- virtual bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const {
- return false;
- }
-
- /// getThreadModel() - Which thread model does this target use?
- virtual std::string getThreadModel() const { return "posix"; }
-
- /// isThreadModelSupported() - Does this target support a thread model?
- virtual bool isThreadModelSupported(const StringRef Model) const;
-
- /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking
- /// command line arguments into account.
- virtual std::string
- ComputeLLVMTriple(const llvm::opt::ArgList &Args,
- types::ID InputType = types::TY_INVALID) const;
-
- /// ComputeEffectiveClangTriple - Return the Clang triple to use for this
- /// target, which may take into account the command line arguments. For
- /// example, on Darwin the -mmacosx-version-min= command line argument (which
- /// sets the deployment target) determines the version in the triple passed to
- /// Clang.
- virtual std::string ComputeEffectiveClangTriple(
- const llvm::opt::ArgList &Args,
- types::ID InputType = types::TY_INVALID) const;
-
- /// getDefaultObjCRuntime - Return the default Objective-C runtime
- /// for this platform.
- ///
- /// FIXME: this really belongs on some sort of DeploymentTarget abstraction
- virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const;
-
- /// hasBlocksRuntime - Given that the user is compiling with
- /// -fblocks, does this tool chain guarantee the existence of a
- /// blocks runtime?
- ///
- /// 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.
- ///
- /// This routine is responsible for adding the necessary cc1 arguments to
- /// include headers from standard system header directories.
- virtual void
- AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const;
-
- /// \brief Add options that need to be passed to cc1 for this target.
- virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const;
-
- /// \brief 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
- // given compilation arguments.
- virtual RuntimeLibType
- GetRuntimeLibType(const llvm::opt::ArgList &Args) const;
-
- // GetCXXStdlibType - Determine the C++ standard library type to use with the
- // given compilation arguments.
- virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
-
- /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
- /// the include paths to use for the given C++ standard library type.
- virtual void
- AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const;
-
- /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
- /// for the given C++ standard library type.
- virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CmdArgs) const;
-
- /// AddFilePathLibArgs - Add each thing in getFilePaths() as a "-L" option.
- void AddFilePathLibArgs(const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CmdArgs) const;
-
- /// AddCCKextLibArgs - Add the system specific linker arguments to use
- /// for kernel extensions (Darwin-specific).
- virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CmdArgs) const;
-
- /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets
- /// global flags for unsafe floating point math, add it and return true.
- ///
- /// 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.
- virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const;
-
- /// \brief Return sanitizers which are available in this toolchain.
- virtual SanitizerMask getSupportedSanitizers() const;
-};
-
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
deleted file mode 100644
index d1b6915..0000000
--- a/include/clang/Driver/Types.def
+++ /dev/null
@@ -1,96 +0,0 @@
-//===--- Types.def - Driver Type info ---------------------------*- 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 driver type information. Users of this file
-// must define the TYPE macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TYPE
-#error "Define TYPE prior to including this file!"
-#endif
-
-// TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS)
-
-// The first value is the type name as a string; for types which can
-// be user specified this should be the equivalent -x option.
-
-// The second value is the type id, which will result in a
-// clang::driver::types::TY_XX enum constant.
-
-// The third value is that id of the type for preprocessed inputs of
-// this type, or INVALID if this type is not preprocessed.
-
-// The fourth value is the suffix to use when creating temporary files
-// of this type, or null if unspecified.
-
-// The fifth value is a string containing option flags. Valid values:
-// a - The type should only be assembled.
-// p - The type should only be precompiled.
-// u - The type can be user specified (with -x).
-// A - The type's temporary suffix should be appended when generating
-// outputs of this type.
-
-
-// C family source language (with and without preprocessing).
-TYPE("cpp-output", PP_C, INVALID, "i", "u")
-TYPE("c", C, PP_C, "c", "u")
-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("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")
-TYPE("c++-cpp-output", PP_CXX, INVALID, "ii", "u")
-TYPE("c++", CXX, PP_CXX, "cpp", "u")
-TYPE("objective-c++-cpp-output", PP_ObjCXX, INVALID, "mii", "u")
-TYPE("objc++-cpp-output", PP_ObjCXX_Alias, INVALID, "mii", "u")
-TYPE("objective-c++", ObjCXX, PP_ObjCXX, "mm", "u")
-
-// C family input files to precompile.
-TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", "p")
-TYPE("c-header", CHeader, PP_CHeader, "h", "pu")
-TYPE("cl-header", CLHeader, PP_CHeader, "h", "pu")
-TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID, "mi", "p")
-TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, "h", "pu")
-TYPE("c++-header-cpp-output", PP_CXXHeader, INVALID, "ii", "p")
-TYPE("c++-header", CXXHeader, PP_CXXHeader, "hh", "pu")
-TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
-TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, "h", "pu")
-
-// Other languages.
-TYPE("ada", Ada, INVALID, nullptr, "u")
-TYPE("assembler", PP_Asm, INVALID, "s", "au")
-TYPE("assembler-with-cpp", Asm, PP_Asm, "S", "au")
-TYPE("f95", PP_Fortran, INVALID, nullptr, "u")
-TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, "u")
-TYPE("java", Java, INVALID, nullptr, "u")
-
-// LLVM IR/LTO types. We define separate types for IR and LTO because LTO
-// outputs should use the standard suffixes.
-TYPE("ir", LLVM_IR, INVALID, "ll", "u")
-TYPE("ir", LLVM_BC, INVALID, "bc", "u")
-TYPE("lto-ir", LTO_IR, INVALID, "s", "")
-TYPE("lto-bc", LTO_BC, INVALID, "o", "")
-
-// Misc.
-TYPE("ast", AST, INVALID, "ast", "u")
-TYPE("pcm", ModuleFile, INVALID, "pcm", "u")
-TYPE("plist", Plist, INVALID, "plist", "")
-TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", "")
-TYPE("rewritten-legacy-objc", RewrittenLegacyObjC,INVALID, "cpp", "")
-TYPE("remap", Remap, INVALID, "remap", "")
-TYPE("precompiled-header", PCH, INVALID, "gch", "A")
-TYPE("object", Object, INVALID, "o", "")
-TYPE("treelang", Treelang, INVALID, nullptr, "u")
-TYPE("image", Image, INVALID, "out", "")
-TYPE("dSYM", dSYM, INVALID, "dSYM", "A")
-TYPE("dependencies", Dependencies, INVALID, "d", "")
-TYPE("none", Nothing, INVALID, nullptr, "u")
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
deleted file mode 100644
index 22122c7..0000000
--- a/include/clang/Driver/Types.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//===--- Types.h - Input & Temporary Driver Types ---------------*- 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_DRIVER_TYPES_H
-#define LLVM_CLANG_DRIVER_TYPES_H
-
-#include "clang/Driver/Phases.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-namespace driver {
-namespace types {
- enum ID {
- TY_INVALID,
-#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) TY_##ID,
-#include "clang/Driver/Types.def"
-#undef TYPE
- TY_LAST
- };
-
- /// getTypeName - Return the name of the type for \p Id.
- const char *getTypeName(ID Id);
-
- /// getPreprocessedType - Get the ID of the type for this input when
- /// it has been preprocessed, or INVALID if this input is not
- /// preprocessed.
- ID getPreprocessedType(ID Id);
-
- /// getTypeTempSuffix - Return the suffix to use when creating a
- /// temp file of this type, or null if unspecified.
- const char *getTypeTempSuffix(ID Id, bool CLMode = false);
-
- /// onlyAssembleType - Should this type only be assembled.
- bool onlyAssembleType(ID Id);
-
- /// onlyPrecompileType - Should this type only be precompiled.
- bool onlyPrecompileType(ID Id);
-
- /// canTypeBeUserSpecified - Can this type be specified on the
- /// command line (by the type name); this is used when forwarding
- /// commands to gcc.
- bool canTypeBeUserSpecified(ID Id);
-
- /// appendSuffixForType - When generating outputs of this type,
- /// should the suffix be appended (instead of replacing the existing
- /// suffix).
- bool appendSuffixForType(ID Id);
-
- /// canLipoType - Is this type acceptable as the output of a
- /// universal build (currently, just the Nothing, Image, and Object
- /// types).
- bool canLipoType(ID Id);
-
- /// isAcceptedByClang - Can clang handle this input type.
- bool isAcceptedByClang(ID Id);
-
- /// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
- bool isCXX(ID Id);
-
- /// Is this LLVM IR.
- bool isLLVMIR(ID Id);
-
- /// isCuda - Is this a CUDA input.
- bool isCuda(ID Id);
-
- /// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
- bool isObjC(ID Id);
-
- /// lookupTypeForExtension - Lookup the type to use for the file
- /// extension \p Ext.
- ID lookupTypeForExtension(const char *Ext);
-
- /// lookupTypeForTypSpecifier - Lookup the type to use for a user
- /// specified type name.
- ID lookupTypeForTypeSpecifier(const char *Name);
-
- /// getCompilationPhases - Get the list of compilation phases ('Phases') to be
- /// done for type 'Id'.
- void getCompilationPhases(
- ID Id,
- llvm::SmallVectorImpl<phases::ID> &Phases);
-
- /// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given
- /// C type (used for clang++ emulation of g++ behaviour)
- ID lookupCXXTypeForCType(ID Id);
-
-} // end namespace types
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Driver/Util.h b/include/clang/Driver/Util.h
deleted file mode 100644
index 07495a1..0000000
--- a/include/clang/Driver/Util.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===--- Util.h - Common Driver Utilities -----------------------*- 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_DRIVER_UTIL_H
-#define LLVM_CLANG_DRIVER_UTIL_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-class DiagnosticsEngine;
-
-namespace driver {
- class Action;
- class JobAction;
-
- /// ArgStringMap - Type used to map a JobAction to its result file.
- typedef llvm::DenseMap<const JobAction*, const char*> ArgStringMap;
-
- /// ActionList - Type used for lists of actions.
- typedef SmallVector<Action*, 3> ActionList;
-
-} // end namespace driver
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
deleted file mode 100644
index ac4bb47..0000000
--- a/include/clang/Edit/Commit.h
+++ /dev/null
@@ -1,143 +0,0 @@
-//===----- Commit.h - A unit of edits ---------------------------*- 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_EDIT_COMMIT_H
-#define LLVM_CLANG_EDIT_COMMIT_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;
-
-namespace edit {
- class EditedSource;
-
-class Commit {
-public:
- enum EditKind {
- Act_Insert,
- Act_InsertFromRange,
- Act_Remove
- };
-
- struct Edit {
- EditKind Kind;
- StringRef Text;
- SourceLocation OrigLoc;
- FileOffset Offset;
- FileOffset InsertFromRangeOffs;
- unsigned Length;
- bool BeforePrev;
-
- SourceLocation getFileLocation(SourceManager &SM) const;
- CharSourceRange getFileRange(SourceManager &SM) const;
- CharSourceRange getInsertFromRange(SourceManager &SM) const;
- };
-
-private:
- const SourceManager &SourceMgr;
- const LangOptions &LangOpts;
- const PPConditionalDirectiveRecord *PPRec;
- EditedSource *Editor;
-
- bool IsCommitable;
- SmallVector<Edit, 8> CachedEdits;
-
- llvm::BumpPtrAllocator StrAlloc;
-
-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) { }
-
- 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);
- bool insertWrap(StringRef before, CharSourceRange range, StringRef after);
-
- bool remove(CharSourceRange range);
-
- bool replace(CharSourceRange range, StringRef text);
- bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange);
- bool replaceText(SourceLocation loc, StringRef text,
- StringRef replacementText);
-
- bool insertFromRange(SourceLocation loc, SourceRange TokenRange,
- bool afterToken = false,
- bool beforePreviousInsertions = false) {
- 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;
- edit_iterator edit_begin() const { return CachedEdits.begin(); }
- edit_iterator edit_end() const { return CachedEdits.end(); }
-
-private:
- void addInsert(SourceLocation OrigLoc,
- FileOffset Offs, StringRef text, bool beforePreviousInsertions);
- void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
- FileOffset RangeOffs, unsigned RangeLen,
- bool beforePreviousInsertions);
- void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len);
-
- bool canInsert(SourceLocation loc, FileOffset &Offset);
- bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset,
- SourceLocation &AfterLoc);
- bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
- bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len);
- bool canReplaceText(SourceLocation loc, StringRef text,
- FileOffset &Offs, unsigned &Len);
-
- void commitInsert(FileOffset offset, StringRef text,
- bool beforePreviousInsertions);
- void commitRemove(FileOffset offset, unsigned length);
-
- bool isAtStartOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroBegin = nullptr) const;
- bool isAtEndOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroEnd = nullptr) const;
-};
-
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
deleted file mode 100644
index b6ec8b8..0000000
--- a/include/clang/Edit/EditedSource.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//===----- EditedSource.h - Collection of source edits ----------*- 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_EDIT_EDITEDSOURCE_H
-#define LLVM_CLANG_EDIT_EDITEDSOURCE_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Edit/FileOffset.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Support/Allocator.h"
-#include <map>
-
-namespace clang {
- class LangOptions;
- class PPConditionalDirectiveRecord;
-
-namespace edit {
- class Commit;
- class EditsReceiver;
-
-class EditedSource {
- const SourceManager &SourceMgr;
- const LangOptions &LangOpts;
- const PPConditionalDirectiveRecord *PPRec;
-
- struct FileEdit {
- StringRef Text;
- unsigned RemoveLen;
-
- FileEdit() : RemoveLen(0) {}
- };
-
- typedef std::map<FileOffset, FileEdit> FileEditsTy;
- FileEditsTy FileEdits;
-
- llvm::DenseMap<unsigned, llvm::TinyPtrVector<IdentifierInfo*>>
- ExpansionToArgMap;
- SmallVector<std::pair<SourceLocation, IdentifierInfo*>, 2>
- CurrCommitMacroArgExps;
-
- IdentifierTable IdentTable;
- llvm::BumpPtrAllocator StrAlloc;
-
-public:
- EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
- const PPConditionalDirectiveRecord *PPRec = nullptr)
- : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts),
- StrAlloc() { }
-
- const SourceManager &getSourceManager() const { return SourceMgr; }
- const LangOptions &getLangOpts() const { return LangOpts; }
- const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const {
- return PPRec;
- }
-
- bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
-
- bool commit(const Commit &commit);
-
- void applyRewrites(EditsReceiver &receiver);
- void clearRewrites();
-
- StringRef copyString(StringRef str) { return str.copy(StrAlloc); }
- StringRef copyString(const Twine &twine);
-
-private:
- bool commitInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text,
- bool beforePreviousInsertions);
- bool commitInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
- FileOffset InsertFromRangeOffs, unsigned Len,
- bool beforePreviousInsertions);
- void commitRemove(SourceLocation OrigLoc, FileOffset BeginOffs, unsigned Len);
-
- StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs,
- bool &Invalid);
- FileEditsTy::iterator getActionForOffset(FileOffset Offs);
- void deconstructMacroArgLoc(SourceLocation Loc,
- SourceLocation &ExpansionLoc,
- IdentifierInfo *&II);
-
- void startingCommit();
- void finishedCommit();
-};
-
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Edit/EditsReceiver.h b/include/clang/Edit/EditsReceiver.h
deleted file mode 100644
index 600ac28..0000000
--- a/include/clang/Edit/EditsReceiver.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===----- EditedSource.h - Collection of source edits ----------*- 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_EDIT_EDITSRECEIVER_H
-#define LLVM_CLANG_EDIT_EDITSRECEIVER_H
-
-#include "clang/Basic/LLVM.h"
-
-namespace clang {
- class SourceLocation;
- class CharSourceRange;
-
-namespace edit {
-
-class EditsReceiver {
-public:
- virtual ~EditsReceiver() { }
-
- 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.
- virtual void remove(CharSourceRange range);
-};
-
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Edit/FileOffset.h b/include/clang/Edit/FileOffset.h
deleted file mode 100644
index 0c1e72b..0000000
--- a/include/clang/Edit/FileOffset.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//===----- FileOffset.h - Offset in a file ----------------------*- 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_EDIT_FILEOFFSET_H
-#define LLVM_CLANG_EDIT_FILEOFFSET_H
-
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-namespace edit {
-
-class FileOffset {
- FileID FID;
- unsigned Offs;
-public:
- FileOffset() : Offs(0) { }
- FileOffset(FileID fid, unsigned offs) : FID(fid), Offs(offs) { }
-
- bool isInvalid() const { return FID.isInvalid(); }
-
- FileID getFID() const { return FID; }
- unsigned getOffset() const { return Offs; }
-
- FileOffset getWithOffset(unsigned offset) const {
- FileOffset NewOffs = *this;
- NewOffs.Offs += offset;
- return NewOffs;
- }
-
- 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
-
-#endif
diff --git a/include/clang/Edit/Rewriters.h b/include/clang/Edit/Rewriters.h
deleted file mode 100644
index 5e3425f..0000000
--- a/include/clang/Edit/Rewriters.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//===--- Rewriters.h - Rewritings ---------------------------*- 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_EDIT_REWRITERS_H
-#define LLVM_CLANG_EDIT_REWRITERS_H
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- class ObjCMessageExpr;
- class ObjCMethodDecl;
- class ObjCInterfaceDecl;
- class ObjCProtocolDecl;
- class NSAPI;
- class EnumDecl;
- class TypedefDecl;
- class ParentMap;
-
-namespace edit {
- class Commit;
-
-bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg,
- const NSAPI &NS, Commit &commit);
-
-bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
- const NSAPI &NS, Commit &commit,
- const ParentMap *PMap);
-
-bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg,
- const NSAPI &NS, Commit &commit);
-
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
deleted file mode 100644
index 6d051e0..0000000
--- a/include/clang/Format/Format.h
+++ /dev/null
@@ -1,792 +0,0 @@
-//===--- Format.h - Format C++ code -----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Various functions to configurably format source code.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FORMAT_FORMAT_H
-#define LLVM_CLANG_FORMAT_FORMAT_H
-
-#include "clang/Basic/LangOptions.h"
-#include "clang/Tooling/Core/Replacement.h"
-#include "llvm/ADT/ArrayRef.h"
-#include <system_error>
-
-namespace clang {
-
-class Lexer;
-class SourceManager;
-class DiagnosticConsumer;
-
-namespace format {
-
-enum class ParseError { Success = 0, Error, Unsuitable };
-class ParseErrorCategory final : public std::error_category {
-public:
- const char *name() const LLVM_NOEXCEPT override;
- std::string message(int EV) const override;
-};
-const std::error_category &getParseCategory();
-std::error_code make_error_code(ParseError e);
-
-/// \brief The \c FormatStyle is used to configure the formatting to follow
-/// specific guidelines.
-struct FormatStyle {
- /// \brief The extra indent or outdent of access modifiers, e.g. \c public:.
- int AccessModifierOffset;
-
- /// \brief Different styles for aligning after open brackets.
- enum BracketAlignmentStyle {
- /// \brief Align parameters on the open bracket, e.g.:
- /// \code
- /// someLongFunction(argument1,
- /// argument2);
- /// \endcode
- BAS_Align,
- /// \brief Don't align, instead use \c ContinuationIndentWidth, e.g.:
- /// \code
- /// someLongFunction(argument1,
- /// argument2);
- /// \endcode
- BAS_DontAlign,
- /// \brief Always break after an open bracket, if the parameters don't fit
- /// on a single line, e.g.:
- /// \code
- /// someLongFunction(
- /// argument1, argument2);
- /// \endcode
- BAS_AlwaysBreak,
- };
-
- /// \brief If \c true, horizontally aligns arguments after an open bracket.
- ///
- /// This applies to round brackets (parentheses), angle brackets and square
- /// brackets.
- BracketAlignmentStyle AlignAfterOpenBracket;
-
- /// \brief If \c true, aligns consecutive assignments.
- ///
- /// This will align the assignment operators of consecutive lines. This
- /// will result in formattings like
- /// \code
- /// int aaaa = 12;
- /// int b = 23;
- /// int ccc = 23;
- /// \endcode
- bool AlignConsecutiveAssignments;
-
- /// \brief If \c true, aligns consecutive declarations.
- ///
- /// This will align the declaration names of consecutive lines. This
- /// will result in formattings like
- /// \code
- /// int aaaa = 12;
- /// float b = 23;
- /// std::string ccc = 23;
- /// \endcode
- bool AlignConsecutiveDeclarations;
-
- /// \brief If \c true, aligns escaped newlines as far left as possible.
- /// Otherwise puts them into the right-most column.
- bool AlignEscapedNewlinesLeft;
-
- /// \brief If \c true, horizontally align operands of binary and ternary
- /// expressions.
- ///
- /// Specifically, this aligns operands of a single expression that needs to be
- /// split over multiple lines, e.g.:
- /// \code
- /// int aaa = bbbbbbbbbbbbbbb +
- /// ccccccccccccccc;
- /// \endcode
- bool AlignOperands;
-
- /// \brief If \c true, aligns trailing comments.
- bool AlignTrailingComments;
-
- /// \brief Allow putting all parameters of a function declaration onto
- /// the next line even if \c BinPackParameters is \c false.
- bool AllowAllParametersOfDeclarationOnNextLine;
-
- /// \brief Allows contracting simple braced statements to a single line.
- ///
- /// E.g., this allows <tt>if (a) { return; }</tt> to be put on a single line.
- bool AllowShortBlocksOnASingleLine;
-
- /// \brief If \c true, short case labels will be contracted to a single line.
- bool AllowShortCaseLabelsOnASingleLine;
-
- /// \brief Different styles for merging short functions containing at most one
- /// statement.
- enum ShortFunctionStyle {
- /// \brief Never merge functions into a single line.
- SFS_None,
- /// \brief Only merge empty functions.
- SFS_Empty,
- /// \brief Only merge functions defined inside a class. Implies "empty".
- SFS_Inline,
- /// \brief Merge all functions fitting on a single line.
- SFS_All,
- };
-
- /// \brief Dependent on the value, <tt>int f() { return 0; }</tt> can be put
- /// on a single line.
- ShortFunctionStyle AllowShortFunctionsOnASingleLine;
-
- /// \brief If \c true, <tt>if (a) return;</tt> can be put on a single
- /// line.
- bool AllowShortIfStatementsOnASingleLine;
-
- /// \brief If \c true, <tt>while (true) continue;</tt> can be put on a
- /// single line.
- bool AllowShortLoopsOnASingleLine;
-
- /// \brief Different ways to break after the function definition return type.
- enum DefinitionReturnTypeBreakingStyle {
- /// Break after return type automatically.
- /// \c PenaltyReturnTypeOnItsOwnLine is taken into account.
- DRTBS_None,
- /// Always break after the return type.
- DRTBS_All,
- /// Always break after the return types of top-level functions.
- DRTBS_TopLevel,
- };
-
- /// \brief Different ways to break after the function definition or
- /// declaration return type.
- enum ReturnTypeBreakingStyle {
- /// Break after return type automatically.
- /// \c PenaltyReturnTypeOnItsOwnLine is taken into account.
- RTBS_None,
- /// Always break after the return type.
- RTBS_All,
- /// Always break after the return types of top-level functions.
- RTBS_TopLevel,
- /// Always break after the return type of function definitions.
- RTBS_AllDefinitions,
- /// Always break after the return type of top-level definitions.
- RTBS_TopLevelDefinitions,
- };
-
- /// \brief 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.
- ReturnTypeBreakingStyle AlwaysBreakAfterReturnType;
-
- /// \brief If \c 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
- /// the string at that point leads to it being indented
- /// \c ContinuationIndentWidth spaces from the start of the line.
- bool AlwaysBreakBeforeMultilineStrings;
-
- /// \brief If \c true, always break after the <tt>template<...></tt> of a
- /// template declaration.
- bool AlwaysBreakTemplateDeclarations;
-
- /// \brief If \c false, a function call's arguments will either be all on the
- /// same line or will have one line each.
- bool BinPackArguments;
-
- /// \brief If \c false, a function declaration's or function definition's
- /// parameters will either all be on the same line or will have one line each.
- bool BinPackParameters;
-
- /// \brief The style of breaking before or after binary operators.
- enum BinaryOperatorStyle {
- /// Break after operators.
- BOS_None,
- /// Break before operators that aren't assignments.
- BOS_NonAssignment,
- /// Break before operators.
- BOS_All,
- };
-
- /// \brief The way to wrap binary operators.
- BinaryOperatorStyle BreakBeforeBinaryOperators;
-
- /// \brief Different ways to attach braces to their surrounding context.
- enum BraceBreakingStyle {
- /// Always attach braces to surrounding context.
- BS_Attach,
- /// Like \c Attach, but break before braces on function, namespace and
- /// class definitions.
- BS_Linux,
- /// Like ``Attach``, but break before braces on enum, function, and record
- /// definitions.
- BS_Mozilla,
- /// Like \c Attach, but break before function definitions, 'catch', and 'else'.
- BS_Stroustrup,
- /// Always break before braces.
- BS_Allman,
- /// Always break before braces and add an extra level of indentation to
- /// braces of control statements, not to those of class, function
- /// or other definitions.
- BS_GNU,
- /// Like ``Attach``, but break before functions.
- BS_WebKit,
- /// Configure each individual brace in \c BraceWrapping.
- BS_Custom
- };
-
- /// \brief The brace breaking style to use.
- BraceBreakingStyle BreakBeforeBraces;
-
- /// \brief Precise control over the wrapping of braces.
- struct BraceWrappingFlags {
- /// \brief Wrap class definitions.
- bool AfterClass;
- /// \brief Wrap control statements (if/for/while/switch/..).
- bool AfterControlStatement;
- /// \brief Wrap enum definitions.
- bool AfterEnum;
- /// \brief Wrap function definitions.
- bool AfterFunction;
- /// \brief Wrap namespace definitions.
- bool AfterNamespace;
- /// \brief Wrap ObjC definitions (@autoreleasepool, interfaces, ..).
- bool AfterObjCDeclaration;
- /// \brief Wrap struct definitions.
- bool AfterStruct;
- /// \brief Wrap union definitions.
- bool AfterUnion;
- /// \brief Wrap before \c catch.
- bool BeforeCatch;
- /// \brief Wrap before \c else.
- bool BeforeElse;
- /// \brief Indent the wrapped braces themselves.
- bool IndentBraces;
- };
-
- /// \brief Control of individual brace wrapping cases.
- ///
- /// If \c BreakBeforeBraces is set to \c custom, use this to specify how each
- /// individual brace case should be handled. Otherwise, this is ignored.
- BraceWrappingFlags BraceWrapping;
-
- /// \brief If \c true, ternary operators will be placed after line breaks.
- bool BreakBeforeTernaryOperators;
-
- /// \brief Always break constructor initializers before commas and align
- /// the commas with the colon.
- bool BreakConstructorInitializersBeforeComma;
-
- /// \brief Break after each annotation on a field in Java files.
- bool BreakAfterJavaFieldAnnotations;
-
- /// \brief The column limit.
- ///
- /// A column limit of \c 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,
- /// which should not be split into lines or otherwise changed.
- std::string CommentPragmas;
-
- /// \brief If the constructor initializers don't fit on a line, put each
- /// initializer on its own line.
- bool ConstructorInitializerAllOnOneLineOrOnePerLine;
-
- /// \brief The number of characters to use for indentation of constructor
- /// initializer lists.
- unsigned ConstructorInitializerIndentWidth;
-
- /// \brief Indent width for line continuations.
- unsigned ContinuationIndentWidth;
-
- /// \brief If \c true, format braced lists as best suited for C++11 braced
- /// lists.
- ///
- /// Important differences:
- /// - No spaces inside the braced list.
- /// - No line break before the closing brace.
- /// - Indentation with the continuation indent, not with the block indent.
- ///
- /// Fundamentally, C++11 braced lists are formatted exactly like function
- /// calls would be formatted in their place. If the braced list follows a name
- /// (e.g. a type or variable name), clang-format formats as if the \c {} were
- /// the parentheses of a function call with that name. If there is no name,
- /// a zero-length name is assumed.
- bool Cpp11BracedListStyle;
-
- /// \brief If \c true, analyze the formatted file for the most common
- /// alignment of & and *. \c PointerAlignment is then used only as fallback.
- bool DerivePointerAlignment;
-
- /// \brief Disables formatting completely.
- bool DisableFormat;
-
- /// \brief If \c 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
- /// inconclusive, e.g. completely on one line, but a decision needs to be
- /// made, clang-format analyzes whether there are other bin-packed cases in
- /// the input file and act accordingly.
- ///
- /// NOTE: This is an experimental flag, that might go away or be renamed. Do
- /// not use this in config files, etc. Use at your own risk.
- bool ExperimentalAutoDetectBinPacking;
-
- /// \brief 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:
- /// \code
- /// FOREACH(<variable-declaration>, ...)
- /// <loop-body>
- /// \endcode
- ///
- /// In the .clang-format configuration file, this can be configured like:
- /// \code
- /// ForEachMacros: ['RANGES_FOR', 'FOREACH']
- /// \endcode
- ///
- /// For example: BOOST_FOREACH.
- std::vector<std::string> ForEachMacros;
-
- /// \brief See documentation of \c 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;
- }
- };
-
- /// \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
- /// IncludeCategories:
- /// - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
- /// Priority: 2
- /// - Regex: '^(<|"(gtest|isl|json)/)'
- /// Priority: 3
- /// - Regex: '.*'
- /// Priority: 1
- /// \endcode
- std::vector<IncludeCategory> IncludeCategories;
-
- /// \brief Indent case labels one level from the switch statement.
- ///
- /// When \c false, use the same indentation level as for the switch statement.
- /// Switch statement body is always indented one level more than case labels.
- bool IndentCaseLabels;
-
- /// \brief The number of columns to use for indentation.
- unsigned IndentWidth;
-
- /// \brief Indent if a function definition or declaration is wrapped after the
- /// type.
- bool IndentWrappedFunctionNames;
-
- /// \brief If true, empty lines at the start of blocks are kept.
- bool KeepEmptyLinesAtTheStartOfBlocks;
-
- /// \brief Supported languages. When stored in a configuration file, specifies
- /// the language, that the configuration targets. When passed to the
- /// reformat() function, enables syntax features specific to the language.
- enum LanguageKind {
- /// Do not use.
- LK_None,
- /// Should be used for C, C++, ObjectiveC, ObjectiveC++.
- LK_Cpp,
- /// Should be used for Java.
- LK_Java,
- /// Should be used for JavaScript.
- LK_JavaScript,
- /// Should be used for Protocol Buffers
- /// (https://developers.google.com/protocol-buffers/).
- LK_Proto,
- /// Should be used for TableGen code.
- LK_TableGen
- };
-
- /// \brief Language, this format style is targeted at.
- LanguageKind Language;
-
- /// \brief A regular expression matching macros that start a block.
- std::string MacroBlockBegin;
-
- /// \brief A regular expression matching macros that end a block.
- std::string MacroBlockEnd;
-
- /// \brief The maximum number of consecutive empty lines to keep.
- unsigned MaxEmptyLinesToKeep;
-
- /// \brief Different ways to indent namespace contents.
- enum NamespaceIndentationKind {
- /// Don't indent in namespaces.
- NI_None,
- /// Indent only in inner namespaces (nested in other namespaces).
- NI_Inner,
- /// Indent in all namespaces.
- NI_All
- };
-
- /// \brief The indentation used for namespaces.
- NamespaceIndentationKind NamespaceIndentation;
-
- /// \brief The number of characters to use for indentation of ObjC blocks.
- unsigned ObjCBlockIndentWidth;
-
- /// \brief Add a space after \c @property in Objective-C, i.e. use
- /// <tt>\@property (readonly)</tt> instead of <tt>\@property(readonly)</tt>.
- bool ObjCSpaceAfterProperty;
-
- /// \brief Add a space in front of an Objective-C protocol list, i.e. use
- /// <tt>Foo <Protocol></tt> instead of \c Foo<Protocol>.
- bool ObjCSpaceBeforeProtocolList;
-
- /// \brief The penalty for breaking a function call after "call(".
- unsigned PenaltyBreakBeforeFirstCallParameter;
-
- /// \brief The penalty for each line break introduced inside a comment.
- unsigned PenaltyBreakComment;
-
- /// \brief The penalty for breaking before the first \c <<.
- unsigned PenaltyBreakFirstLessLess;
-
- /// \brief The penalty for each line break introduced inside a string literal.
- unsigned PenaltyBreakString;
-
- /// \brief 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
- /// line.
- unsigned PenaltyReturnTypeOnItsOwnLine;
-
- /// \brief The & and * alignment style.
- enum PointerAlignmentStyle {
- /// Align pointer to the left.
- PAS_Left,
- /// Align pointer to the right.
- PAS_Right,
- /// Align pointer in the middle.
- PAS_Middle
- };
-
- /// \brief Pointer and reference alignment style.
- PointerAlignmentStyle PointerAlignment;
-
- /// \brief If true, clang-format will attempt to re-flow comments.
- bool ReflowComments;
-
- /// \brief If true, clang-format will sort #includes.
- bool SortIncludes;
-
- /// \brief If \c true, a space may be inserted after C style casts.
- bool SpaceAfterCStyleCast;
-
- /// \brief If \c false, spaces will be removed before assignment operators.
- bool SpaceBeforeAssignmentOperators;
-
- /// \brief Different ways to put a space before opening parentheses.
- enum SpaceBeforeParensOptions {
- /// Never put a space before opening parentheses.
- SBPO_Never,
- /// Put a space before opening parentheses only after control statement
- /// keywords (<tt>for/if/while...</tt>).
- SBPO_ControlStatements,
- /// Always put a space before opening parentheses, except when it's
- /// prohibited by the syntax rules (in function-like macro definitions) or
- /// when determined by other style rules (after unary operators, opening
- /// parentheses, etc.)
- SBPO_Always
- };
-
- /// \brief Defines in which cases to put a space before opening parentheses.
- SpaceBeforeParensOptions SpaceBeforeParens;
-
- /// \brief If \c true, spaces may be inserted into '()'.
- bool SpaceInEmptyParentheses;
-
- /// \brief The number of spaces before trailing line comments
- /// (\c // - comments).
- ///
- /// This does not affect trailing block comments (\c /**/ - comments) as those
- /// commonly have different usage patterns and a number of special cases.
- unsigned SpacesBeforeTrailingComments;
-
- /// \brief If \c true, spaces will be inserted after '<' and before '>' in
- /// template argument lists
- bool SpacesInAngles;
-
- /// \brief If \c true, spaces are inserted inside container literals (e.g.
- /// ObjC and Javascript array and dict literals).
- bool SpacesInContainerLiterals;
-
- /// \brief If \c true, spaces may be inserted into C style casts.
- bool SpacesInCStyleCastParentheses;
-
- /// \brief If \c true, spaces will be inserted after '(' and before ')'.
- bool SpacesInParentheses;
-
- /// \brief If \c true, spaces will be inserted after '[' and before ']'.
- bool SpacesInSquareBrackets;
-
- /// \brief Supported language standards.
- enum LanguageStandard {
- /// Use C++03-compatible syntax.
- LS_Cpp03,
- /// Use features of C++11 (e.g. \c A<A<int>> instead of
- /// <tt>A<A<int> ></tt>).
- LS_Cpp11,
- /// Automatic detection based on the input.
- LS_Auto
- };
-
- /// \brief Format compatible with this standard, e.g. use
- /// <tt>A<A<int> ></tt> instead of \c A<A<int>> for LS_Cpp03.
- LanguageStandard Standard;
-
- /// \brief The number of columns used for tab stops.
- unsigned TabWidth;
-
- /// \brief Different ways to use tab in formatting.
- enum UseTabStyle {
- /// Never use tab.
- UT_Never,
- /// Use tabs only for indentation.
- UT_ForIndentation,
- /// Use tabs whenever we need to fill whitespace that spans at least from
- /// one tab stop to the next one.
- UT_Always
- };
-
- /// \brief The way to use tab characters in the resulting file.
- UseTabStyle UseTab;
-
- bool operator==(const FormatStyle &R) const {
- return AccessModifierOffset == R.AccessModifierOffset &&
- AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
- AlignConsecutiveAssignments == R.AlignConsecutiveAssignments &&
- AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations &&
- AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
- AlignOperands == R.AlignOperands &&
- AlignTrailingComments == R.AlignTrailingComments &&
- AllowAllParametersOfDeclarationOnNextLine ==
- R.AllowAllParametersOfDeclarationOnNextLine &&
- AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine &&
- AllowShortCaseLabelsOnASingleLine ==
- R.AllowShortCaseLabelsOnASingleLine &&
- AllowShortFunctionsOnASingleLine ==
- R.AllowShortFunctionsOnASingleLine &&
- AllowShortIfStatementsOnASingleLine ==
- R.AllowShortIfStatementsOnASingleLine &&
- AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
- AlwaysBreakAfterReturnType == R.AlwaysBreakAfterReturnType &&
- AlwaysBreakBeforeMultilineStrings ==
- R.AlwaysBreakBeforeMultilineStrings &&
- AlwaysBreakTemplateDeclarations ==
- R.AlwaysBreakTemplateDeclarations &&
- BinPackArguments == R.BinPackArguments &&
- BinPackParameters == R.BinPackParameters &&
- BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
- BreakBeforeBraces == R.BreakBeforeBraces &&
- BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
- BreakConstructorInitializersBeforeComma ==
- R.BreakConstructorInitializersBeforeComma &&
- BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations &&
- ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas &&
- ConstructorInitializerAllOnOneLineOrOnePerLine ==
- R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
- ConstructorInitializerIndentWidth ==
- R.ConstructorInitializerIndentWidth &&
- ContinuationIndentWidth == R.ContinuationIndentWidth &&
- Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
- DerivePointerAlignment == R.DerivePointerAlignment &&
- DisableFormat == R.DisableFormat &&
- ExperimentalAutoDetectBinPacking ==
- R.ExperimentalAutoDetectBinPacking &&
- ForEachMacros == R.ForEachMacros &&
- IncludeCategories == R.IncludeCategories &&
- IndentCaseLabels == R.IndentCaseLabels &&
- IndentWidth == R.IndentWidth && Language == R.Language &&
- IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
- KeepEmptyLinesAtTheStartOfBlocks ==
- R.KeepEmptyLinesAtTheStartOfBlocks &&
- MacroBlockBegin == R.MacroBlockBegin &&
- MacroBlockEnd == R.MacroBlockEnd &&
- MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
- NamespaceIndentation == R.NamespaceIndentation &&
- ObjCBlockIndentWidth == R.ObjCBlockIndentWidth &&
- ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
- ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
- PenaltyBreakBeforeFirstCallParameter ==
- R.PenaltyBreakBeforeFirstCallParameter &&
- PenaltyBreakComment == R.PenaltyBreakComment &&
- PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess &&
- PenaltyBreakString == R.PenaltyBreakString &&
- PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
- PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
- PointerAlignment == R.PointerAlignment &&
- SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
- SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
- SpaceBeforeParens == R.SpaceBeforeParens &&
- SpaceInEmptyParentheses == R.SpaceInEmptyParentheses &&
- SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
- SpacesInAngles == R.SpacesInAngles &&
- SpacesInContainerLiterals == R.SpacesInContainerLiterals &&
- SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
- SpacesInParentheses == R.SpacesInParentheses &&
- SpacesInSquareBrackets == R.SpacesInSquareBrackets &&
- Standard == R.Standard && TabWidth == R.TabWidth &&
- UseTab == R.UseTab;
- }
-};
-
-/// \brief 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:
-/// 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:
-/// http://www.chromium.org/developers/coding-style.
-FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language);
-
-/// \brief 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:
-/// http://www.webkit.org/coding/coding-style.html
-FormatStyle getWebKitStyle();
-
-/// \brief 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.
-FormatStyle getNoStyle();
-
-/// \brief Gets a predefined style for the specified language by name.
-///
-/// Currently supported names: LLVM, Google, Chromium, Mozilla. Names are
-/// compared case-insensitively.
-///
-/// Returns \c true if the Style has been set.
-bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
- FormatStyle *Style);
-
-/// \brief Parse configuration from YAML-formatted text.
-///
-/// Style->Language is used to get the base style, if the \c BasedOnStyle
-/// option is present.
-///
-/// When \c 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.
-std::string configurationAsText(const FormatStyle &Style);
-
-/// \brief 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 Reformats the given \p Ranges in the file \p ID.
-///
-/// 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
-/// formatting.
-///
-/// Returns the \c Replacements necessary to make all \p Ranges comply with
-/// \p Style.
-///
-/// If \c 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,
- SourceManager &SourceMgr, FileID ID,
- ArrayRef<CharSourceRange> Ranges,
- bool *IncompleteFormat = nullptr);
-
-/// \brief Reformats the given \p Ranges in \p Code.
-///
-/// Otherwise identical to the reformat() function using a file ID.
-tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
- ArrayRef<tooling::Range> Ranges,
- StringRef FileName = "<stdin>",
- bool *IncompleteFormat = nullptr);
-
-/// \brief Returns the \c 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
-/// specifying format style. The description is closely related to the operation
-/// of getStyle().
-extern const char *StyleOptionHelpDescription;
-
-/// \brief Construct a FormatStyle based on \c StyleName.
-///
-/// \c StyleName can take several forms:
-/// \li "{<key>: <value>, ...}" - Set specic style parameters.
-/// \li "<style name>" - One of the style names supported by
-/// getPredefinedStyle().
-/// \li "file" - Load style configuration from a file called '.clang-format'
-/// located in one of the parent directories of \c FileName or the current
-/// directory if \c FileName is empty.
-///
-/// \param[in] StyleName Style name to interpret according to the description
-/// above.
-/// \param[in] FileName Path to start search for .clang-format if \c StyleName
-/// == "file".
-/// \param[in] FallbackStyle The name of a predefined style used to fallback to
-/// in case the style can't be determined from \p StyleName.
-///
-/// \returns FormatStyle as specified by \c StyleName. If no style could be
-/// determined, the default is LLVM Style (see getLLVMStyle()).
-FormatStyle getStyle(StringRef StyleName, StringRef FileName,
- StringRef FallbackStyle);
-
-} // end namespace format
-} // end namespace clang
-
-namespace std {
-template <>
-struct is_error_code_enum<clang::format::ParseError> : std::true_type {};
-}
-
-#endif // LLVM_CLANG_FORMAT_FORMAT_H
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
deleted file mode 100644
index 757fcae..0000000
--- a/include/clang/Frontend/ASTConsumers.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// AST Consumers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_ASTCONSUMERS_H
-#define LLVM_CLANG_FRONTEND_ASTCONSUMERS_H
-
-#include "clang/Basic/LLVM.h"
-#include <memory>
-
-namespace clang {
-
-class ASTConsumer;
-class CodeGenOptions;
-class DiagnosticsEngine;
-class FileManager;
-class LangOptions;
-class Preprocessor;
-class TargetOptions;
-
-// AST pretty-printer: prints out the AST in a format that is close to the
-// original C code. The output is intended to be in a format such that
-// clang could re-parse the output back into the same AST, but the
-// implementation is still incomplete.
-std::unique_ptr<ASTConsumer> CreateASTPrinter(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,
- bool DumpDecls,
- bool DumpLookups);
-
-// AST Decl node lister: prints qualified names of all filterable AST Decl
-// nodes.
-std::unique_ptr<ASTConsumer> CreateASTDeclNodeLister();
-
-// Graphical AST viewer: for each function definition, creates a graph of
-// the AST and displays it with the graph viewer "dotty". Also outputs
-// function declarations to stderr.
-std::unique_ptr<ASTConsumer> CreateASTViewer();
-
-// DeclContext printer: prints out the DeclContext tree in human-readable form
-// to stderr; this is intended for debugging.
-std::unique_ptr<ASTConsumer> CreateDeclContextPrinter();
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
deleted file mode 100644
index a5f7af5..0000000
--- a/include/clang/Frontend/ASTUnit.h
+++ /dev/null
@@ -1,924 +0,0 @@
-//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// ASTUnit utility class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H
-#define LLVM_CLANG_FRONTEND_ASTUNIT_H
-
-#include "clang-c/Index.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetOptions.h"
-#include "clang/Lex/HeaderSearchOptions.h"
-#include "clang/Lex/ModuleLoader.h"
-#include "clang/Lex/PreprocessingRecord.h"
-#include "clang/Sema/CodeCompleteConsumer.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/MD5.h"
-#include "llvm/Support/Path.h"
-#include <cassert>
-#include <map>
-#include <memory>
-#include <string>
-#include <sys/types.h>
-#include <utility>
-#include <vector>
-
-namespace llvm {
- class MemoryBuffer;
-}
-
-namespace clang {
-class Sema;
-class ASTContext;
-class ASTReader;
-class CodeCompleteConsumer;
-class CompilerInvocation;
-class CompilerInstance;
-class Decl;
-class DiagnosticsEngine;
-class FileEntry;
-class FileManager;
-class HeaderSearch;
-class Preprocessor;
-class PCHContainerOperations;
-class PCHContainerReader;
-class SourceManager;
-class TargetInfo;
-class ASTFrontendAction;
-class ASTDeserializationListener;
-
-/// \brief Utility class for loading a ASTContext from an AST file.
-///
-class ASTUnit : public ModuleLoader {
-public:
- struct StandaloneFixIt {
- std::pair<unsigned, unsigned> RemoveRange;
- std::pair<unsigned, unsigned> InsertFromRange;
- std::string CodeToInsert;
- bool BeforePreviousInsertions;
- };
-
- struct StandaloneDiagnostic {
- unsigned ID;
- DiagnosticsEngine::Level Level;
- std::string Message;
- std::string Filename;
- unsigned LocOffset;
- std::vector<std::pair<unsigned, unsigned> > Ranges;
- std::vector<StandaloneFixIt> FixIts;
- };
-
-private:
- std::shared_ptr<LangOptions> LangOpts;
- IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
- IntrusiveRefCntPtr<FileManager> FileMgr;
- IntrusiveRefCntPtr<SourceManager> SourceMgr;
- std::unique_ptr<HeaderSearch> HeaderInfo;
- IntrusiveRefCntPtr<TargetInfo> Target;
- IntrusiveRefCntPtr<Preprocessor> PP;
- IntrusiveRefCntPtr<ASTContext> Ctx;
- std::shared_ptr<TargetOptions> TargetOpts;
- IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
- IntrusiveRefCntPtr<ASTReader> Reader;
- bool HadModuleLoaderFatalFailure;
-
- struct ASTWriterData;
- std::unique_ptr<ASTWriterData> WriterData;
-
- FileSystemOptions FileSystemOpts;
-
- /// \brief 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
- /// unit.
- std::unique_ptr<Sema> TheSema;
-
- /// Optional owned invocation, just used to make the invocation used in
- /// LoadFromCommandLine available.
- IntrusiveRefCntPtr<CompilerInvocation> Invocation;
-
- // 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;
-
- /// \brief Whether to capture any diagnostics produced.
- bool CaptureDiagnostics;
-
- /// \brief 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;
-
- /// \brief Whether we should time each operation.
- bool WantTiming;
-
- /// \brief Whether the ASTUnit should delete the remapped buffers.
- bool OwnsRemappedFileBuffers;
-
- /// Track the top-level decls which appeared in an ASTUnit which was loaded
- /// from a source file.
- //
- // FIXME: This is just an optimization hack to avoid deserializing large parts
- // of a PCH file when using the Index library on an ASTUnit loaded from
- // source. In the long term we should make the Index library use efficient and
- // 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;
-
- /// \brief 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.
- SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics;
-
- /// \brief 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
- /// to failure to load the PCH.
- SmallVector<StoredDiagnostic, 4> FailedParseDiagnostics;
-
- /// \brief 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;
-
- /// \brief Counter that determines when we want to try building a
- /// precompiled preamble.
- ///
- /// If zero, we will never build a precompiled preamble. Otherwise,
- /// it's treated as a counter that decrements each time we reparse
- /// without the benefit of a precompiled preamble. When it hits 1,
- /// 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;
-
-public:
- class PreambleData {
- const FileEntry *File;
- std::vector<char> Buffer;
- mutable unsigned NumLines;
-
- public:
- PreambleData() : File(nullptr), NumLines(0) { }
-
- void assign(const FileEntry *F, const char *begin, const char *end) {
- File = F;
- Buffer.assign(begin, end);
- NumLines = 0;
- }
-
- void clear() { Buffer.clear(); File = nullptr; NumLines = 0; }
-
- size_t size() const { return Buffer.size(); }
- bool empty() const { return Buffer.empty(); }
-
- const char *getBufferStart() const { return &Buffer[0]; }
-
- unsigned getNumLines() const {
- if (NumLines)
- return NumLines;
- countLines();
- return NumLines;
- }
-
- SourceRange getSourceRange(const SourceManager &SM) const {
- SourceLocation FileLoc = SM.getLocForStartOfFile(SM.getPreambleFileID());
- return SourceRange(FileLoc, FileLoc.getLocWithOffset(size()-1));
- }
-
- private:
- void countLines() const;
- };
-
- const PreambleData &getPreambleData() const {
- return Preamble;
- }
-
- /// Data used to determine if a file used in the preamble has been changed.
- struct PreambleFileHash {
- /// All files have size set.
- off_t Size;
-
- /// Modification time is set for files that are on disk. For memory
- /// buffers it is zero.
- time_t ModTime;
-
- /// Memory buffers have MD5 instead of modification time. We don't
- /// compute MD5 for on-disk files because we hope that modification time is
- /// enough to tell if the file was changed.
- llvm::MD5::MD5Result MD5;
-
- static PreambleFileHash createForFile(off_t Size, time_t ModTime);
- static PreambleFileHash
- createForMemoryBuffer(const llvm::MemoryBuffer *Buffer);
-
- friend bool operator==(const PreambleFileHash &LHS,
- const PreambleFileHash &RHS);
-
- friend bool operator!=(const PreambleFileHash &LHS,
- const PreambleFileHash &RHS) {
- return !(LHS == RHS);
- }
- };
-
-private:
- /// \brief The contents of the preamble that has been precompiled to
- /// \c PreambleFile.
- PreambleData Preamble;
-
- /// \brief 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.
- bool PreambleEndsAtStartOfLine;
-
- /// \brief Keeps track of the files that were used when computing the
- /// preamble, with both their buffer size and their modification time.
- ///
- /// If any of the files have changed from one compile to the next,
- /// the preamble must be thrown away.
- llvm::StringMap<PreambleFileHash> FilesInPreamble;
-
- /// \brief 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 When non-NULL, this is the buffer used to store the
- /// contents of the preamble when it has been padded to build the
- /// precompiled preamble.
- std::unique_ptr<llvm::MemoryBuffer> PreambleBuffer;
-
- /// \brief 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;
-
- /// \brief 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.
- bool ShouldCacheCodeCompletionResults : 1;
-
- /// \brief 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
- /// (likely to change while trying to use them).
- bool UserFilesAreVolatile : 1;
-
- /// \brief The language options used when we load an AST file.
- LangOptions ASTFileLangOpts;
-
- static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- ASTUnit &AST, bool CaptureDiagnostics);
-
- void TranslateStoredDiagnostics(FileManager &FileMgr,
- SourceManager &SrcMan,
- const SmallVectorImpl<StandaloneDiagnostic> &Diags,
- SmallVectorImpl<StoredDiagnostic> &Out);
-
- void clearFileLevelDecls();
-
-public:
- /// \brief 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
- /// result.
- CodeCompletionString *Completion;
-
- /// \brief A bitmask that indicates which code-completion contexts should
- /// contain this completion result.
- ///
- /// The bits in the bitmask correspond to the values of
- /// CodeCompleteContext::Kind. To map from a completion context kind to a
- /// bit, shift 1 by that number of bits. Many completions can occur in
- /// several different contexts.
- uint64_t ShowInContexts;
-
- /// \brief The priority given to this code-completion result.
- unsigned Priority;
-
- /// \brief The libclang cursor kind corresponding to this code-completion
- /// result.
- CXCursorKind Kind;
-
- /// \brief The availability of this code-completion result.
- CXAvailabilityKind Availability;
-
- /// \brief 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
- /// 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
- /// determined by the formatted type string. Se \c CachedCompletionTypes
- /// for more information.
- unsigned Type;
- };
-
- /// \brief Retrieve the mapping from formatted type names to unique type
- /// identifiers.
- llvm::StringMap<unsigned> &getCachedCompletionTypes() {
- return CachedCompletionTypes;
- }
-
- /// \brief Retrieve the allocator used to cache global code completions.
- IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
- getCachedCompletionAllocator() {
- return CachedCompletionAllocator;
- }
-
- CodeCompletionTUInfo &getCodeCompletionTUInfo() {
- if (!CCTUInfo)
- CCTUInfo.reset(new CodeCompletionTUInfo(
- new GlobalCodeCompletionAllocator));
- return *CCTUInfo;
- }
-
-private:
- /// \brief Allocator used to store cached code completions.
- IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
- CachedCompletionAllocator;
-
- std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
-
- /// \brief 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
- /// type, which is used for type equality comparisons.
- llvm::StringMap<unsigned> CachedCompletionTypes;
-
- /// \brief 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;
-
- /// \brief 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;
-
- /// \brief The current hash value for the top-level declaration and macro
- /// definition names
- unsigned CurrentTopLevelHashValue;
-
- /// \brief 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
- /// recomputing them with each completion.
- void CacheCodeCompletionResults();
-
- /// \brief Clear out and deallocate
- void ClearCachedCompletionResults();
-
- ASTUnit(const ASTUnit &) = delete;
- void operator=(const ASTUnit &) = delete;
-
- explicit ASTUnit(bool MainFileIsAST);
-
- void CleanTemporaryFiles();
- bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer);
-
- struct ComputedPreamble {
- llvm::MemoryBuffer *Buffer;
- std::unique_ptr<llvm::MemoryBuffer> Owner;
- unsigned Size;
- bool PreambleEndsAtStartOfLine;
- ComputedPreamble(llvm::MemoryBuffer *Buffer,
- std::unique_ptr<llvm::MemoryBuffer> Owner, unsigned Size,
- bool PreambleEndsAtStartOfLine)
- : Buffer(Buffer), Owner(std::move(Owner)), Size(Size),
- PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {}
- ComputedPreamble(ComputedPreamble &&C)
- : Buffer(C.Buffer), Owner(std::move(C.Owner)), Size(C.Size),
- PreambleEndsAtStartOfLine(C.PreambleEndsAtStartOfLine) {}
- };
- ComputedPreamble ComputePreamble(CompilerInvocation &Invocation,
- unsigned MaxLines);
-
- std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild = true,
- unsigned MaxLines = 0);
- void RealizeTopLevelDeclsFromPreamble();
-
- /// \brief 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,
- /// which is not supported.
- ///
- /// Clients should create instances of the ConcurrencyCheck class whenever
- /// using the ASTUnit in a way that isn't intended to be concurrent, which is
- /// just about any usage.
- /// Becomes a noop in release mode; only useful for debug mode checking.
- class ConcurrencyState {
- void *Mutex; // a llvm::sys::MutexImpl in debug;
-
- public:
- ConcurrencyState();
- ~ConcurrencyState();
-
- void start();
- void finish();
- };
- ConcurrencyState ConcurrencyCheckValue;
-
-public:
- class ConcurrencyCheck {
- ASTUnit &Self;
-
- public:
- explicit ConcurrencyCheck(ASTUnit &Self)
- : Self(Self)
- {
- Self.ConcurrencyCheckValue.start();
- }
- ~ConcurrencyCheck() {
- Self.ConcurrencyCheckValue.finish();
- }
- };
- friend class ConcurrencyCheck;
-
- ~ASTUnit() override;
-
- bool isMainFileAST() const { return MainFileIsAST; }
-
- bool isUnsafeToFree() const { return UnsafeToFree; }
- void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
-
- const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; }
- DiagnosticsEngine &getDiagnostics() { return *Diagnostics; }
-
- const SourceManager &getSourceManager() const { return *SourceMgr; }
- SourceManager &getSourceManager() { return *SourceMgr; }
-
- const Preprocessor &getPreprocessor() const { return *PP; }
- Preprocessor &getPreprocessor() { return *PP; }
-
- const ASTContext &getASTContext() const { return *Ctx; }
- ASTContext &getASTContext() { return *Ctx; }
-
- void setASTContext(ASTContext *ctx) { Ctx = ctx; }
- void setPreprocessor(Preprocessor *pp);
-
- bool hasSema() const { return (bool)TheSema; }
- Sema &getSema() const {
- assert(TheSema && "ASTUnit does not have a Sema object!");
- return *TheSema;
- }
-
- const LangOptions &getLangOpts() const {
- assert(LangOpts && " ASTUnit does not have language options");
- return *LangOpts;
- }
-
- const FileManager &getFileManager() const { return *FileMgr; }
- FileManager &getFileManager() { return *FileMgr; }
-
- const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
-
- StringRef getOriginalSourceFileName() {
- return OriginalSourceFile;
- }
-
- ASTMutationListener *getASTMutationListener();
- ASTDeserializationListener *getDeserializationListener();
-
- /// \brief Add a temporary file that the ASTUnit depends on.
- ///
- /// This file will be erased when the ASTUnit is destroyed.
- void addTemporaryFile(StringRef TempFile);
-
- bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
-
- bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; }
- void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; }
-
- StringRef getMainFileName() const;
-
- /// \brief If this ASTUnit came from an AST file, returns the filename for it.
- StringRef getASTFileName() const;
-
- typedef std::vector<Decl *>::iterator top_level_iterator;
-
- top_level_iterator top_level_begin() {
- assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
- if (!TopLevelDeclsInPreamble.empty())
- RealizeTopLevelDeclsFromPreamble();
- return TopLevelDecls.begin();
- }
-
- top_level_iterator top_level_end() {
- assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
- if (!TopLevelDeclsInPreamble.empty())
- RealizeTopLevelDeclsFromPreamble();
- return TopLevelDecls.end();
- }
-
- std::size_t top_level_size() const {
- assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
- return TopLevelDeclsInPreamble.size() + TopLevelDecls.size();
- }
-
- bool top_level_empty() const {
- assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
- return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty();
- }
-
- /// \brief Add a new top-level declaration.
- void addTopLevelDecl(Decl *D) {
- TopLevelDecls.push_back(D);
- }
-
- /// \brief 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
- /// 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 Add a new top-level declaration, identified by its ID in
- /// the precompiled preamble.
- void addTopLevelDeclFromPreamble(serialization::DeclID D) {
- TopLevelDeclsInPreamble.push_back(D);
- }
-
- /// \brief 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.
- ///
- /// The difference with SourceManager::getLocation is that this method checks
- /// whether the requested location points inside the precompiled preamble
- /// in which case the returned source location will be a "loaded" one.
- SourceLocation getLocation(const FileEntry *File,
- unsigned Line, unsigned Col) const;
-
- /// \brief 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
- /// the corresponding local location of the main file, otherwise it returns
- /// \p Loc.
- SourceLocation mapLocationFromPreamble(SourceLocation Loc);
-
- /// \brief 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);
-
- bool isInPreambleFileID(SourceLocation Loc);
- bool isInMainFileID(SourceLocation Loc);
- SourceLocation getStartOfMainFileID();
- SourceLocation getEndOfPreambleFileID();
-
- /// \see mapLocationFromPreamble.
- SourceRange mapRangeFromPreamble(SourceRange R) {
- return SourceRange(mapLocationFromPreamble(R.getBegin()),
- mapLocationFromPreamble(R.getEnd()));
- }
-
- /// \see mapLocationToPreamble.
- SourceRange mapRangeToPreamble(SourceRange R) {
- return SourceRange(mapLocationToPreamble(R.getBegin()),
- mapLocationToPreamble(R.getEnd()));
- }
-
- // Retrieve the diagnostics associated with this AST
- typedef StoredDiagnostic *stored_diag_iterator;
- typedef const StoredDiagnostic *stored_diag_const_iterator;
- 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() {
- if (NumStoredDiagnosticsFromDriver > StoredDiagnostics.size())
- NumStoredDiagnosticsFromDriver = 0;
- return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver;
- }
-
- typedef std::vector<CachedCodeCompletionResult>::iterator
- cached_completion_iterator;
-
- cached_completion_iterator cached_completion_begin() {
- return CachedCompletionResults.begin();
- }
-
- cached_completion_iterator cached_completion_end() {
- return CachedCompletionResults.end();
- }
-
- unsigned cached_completion_size() const {
- return CachedCompletionResults.size();
- }
-
- /// \brief 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.
- /// \returns true to continue iteration and false to abort.
- typedef bool (*DeclVisitorFn)(void *context, const Decl *D);
-
- /// \brief 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.
- const FileEntry *getPCHFile();
-
- /// \brief Returns true if the ASTUnit was constructed from a serialized
- /// module file.
- bool isModuleFile();
-
- std::unique_ptr<llvm::MemoryBuffer>
- getBufferForFile(StringRef Filename, std::string *ErrorStr = nullptr);
-
- /// \brief Determine what kind of translation unit this AST represents.
- TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
-
- /// \brief 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;
-
- /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
- static ASTUnit *create(CompilerInvocation *CI,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- bool CaptureDiagnostics,
- bool UserFilesAreVolatile);
-
- /// \brief Create a ASTUnit from an AST file.
- ///
- /// \param Filename - The AST file to load.
- ///
- /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and
- /// creating modules.
- /// \param Diags - The diagnostics engine to use for reporting errors; its
- /// lifetime is expected to extend past that of the returned ASTUnit.
- ///
- /// \returns - The initialized ASTUnit or null if the AST failed to load.
- static std::unique_ptr<ASTUnit> LoadFromASTFile(
- const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- const FileSystemOptions &FileSystemOpts, bool UseDebugInfo = false,
- bool OnlyLocalDecls = false, ArrayRef<RemappedFile> RemappedFiles = None,
- bool CaptureDiagnostics = false, bool AllowPCHWithCompilerErrors = false,
- bool UserFilesAreVolatile = false);
-
-private:
- /// \brief Helper function for \c LoadFromCompilerInvocation() and
- /// \c LoadFromCommandLine(), which loads an AST from a compiler invocation.
- ///
- /// \param PrecompilePreambleAfterNParses After how many parses the preamble
- /// of this translation unit should be precompiled, to improve the performance
- /// of reparsing. Set to zero to disable preambles.
- ///
- /// \returns \c true if a catastrophic failure occurred (which means that the
- /// \c ASTUnit itself is invalid), or \c false otherwise.
- bool LoadFromCompilerInvocation(
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- unsigned PrecompilePreambleAfterNParses);
-
-public:
-
- /// \brief 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
- /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
- ///
- /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
- /// creating modules.
- ///
- /// \param Diags - The diagnostics engine to use for reporting errors; its
- /// lifetime is expected to extend past that of the returned ASTUnit.
- ///
- /// \param Action - The ASTFrontendAction to invoke. Its ownership is not
- /// transferred.
- ///
- /// \param Unit - optionally an already created ASTUnit. Its ownership is not
- /// transferred.
- ///
- /// \param Persistent - if true the returned ASTUnit will be complete.
- /// false means the caller is only interested in getting info through the
- /// provided \see Action.
- ///
- /// \param ErrAST - If non-null and parsing failed without any AST to return
- /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
- /// mainly to allow the caller to see the diagnostics.
- /// This will only receive an ASTUnit if a new one was created. If an already
- /// created ASTUnit was passed in \p Unit then the caller can check that.
- ///
- static ASTUnit *LoadFromCompilerInvocationAction(
- CompilerInvocation *CI,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
- bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
- bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
- unsigned PrecompilePreambleAfterNParses = 0,
- bool CacheCodeCompletionResults = false,
- bool IncludeBriefCommentsInCodeCompletion = false,
- bool UserFilesAreVolatile = false,
- std::unique_ptr<ASTUnit> *ErrAST = nullptr);
-
- /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
- /// CompilerInvocation object.
- ///
- /// \param CI - The compiler invocation to use; it must have exactly one input
- /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
- ///
- /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
- /// creating modules.
- ///
- /// \param Diags - The diagnostics engine to use for reporting errors; its
- /// lifetime is expected to extend past that of the returned ASTUnit.
- //
- // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
- // shouldn't need to specify them at construction time.
- static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
- CompilerInvocation *CI,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
- bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
- unsigned PrecompilePreambleAfterNParses = 0,
- TranslationUnitKind TUKind = TU_Complete,
- bool CacheCodeCompletionResults = false,
- bool IncludeBriefCommentsInCodeCompletion = false,
- bool UserFilesAreVolatile = false);
-
- /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
- /// arguments, which must specify exactly one source file.
- ///
- /// \param ArgBegin - The beginning of the argument vector.
- ///
- /// \param ArgEnd - The end of the argument vector.
- ///
- /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
- /// creating modules.
- ///
- /// \param Diags - The diagnostics engine to use for reporting errors; its
- /// lifetime is expected to extend past that of the returned ASTUnit.
- ///
- /// \param ResourceFilesPath - The path to the compiler resource files.
- ///
- /// \param ModuleFormat - If provided, uses the specific module format.
- ///
- /// \param ErrAST - If non-null and parsing failed without any AST to return
- /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
- /// mainly to allow the caller to see the diagnostics.
- ///
- // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
- // shouldn't need to specify them at construction time.
- static ASTUnit *LoadFromCommandLine(
- const char **ArgBegin, const char **ArgEnd,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
- bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
- ArrayRef<RemappedFile> RemappedFiles = None,
- bool RemappedFilesKeepOriginalName = true,
- unsigned PrecompilePreambleAfterNParses = 0,
- TranslationUnitKind TUKind = TU_Complete,
- bool CacheCodeCompletionResults = false,
- bool IncludeBriefCommentsInCodeCompletion = false,
- bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false,
- bool UserFilesAreVolatile = false, bool ForSerialization = false,
- llvm::Optional<StringRef> ModuleFormat = llvm::None,
- std::unique_ptr<ASTUnit> *ErrAST = nullptr);
-
- /// \brief Reparse the source files using the same command-line options that
- /// were originally used to produce this translation unit.
- ///
- /// \returns True if a failure occurred that causes the ASTUnit not to
- /// contain any translation-unit information, false otherwise.
- bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- ArrayRef<RemappedFile> RemappedFiles = None);
-
- /// \brief Perform code completion at the given file, line, and
- /// column within this translation unit.
- ///
- /// \param File The file in which code completion will occur.
- ///
- /// \param Line The line at which code completion will occur.
- ///
- /// \param Column The column at which code completion will occur.
- ///
- /// \param IncludeMacros Whether to include macros in the code-completion
- /// results.
- ///
- /// \param IncludeCodePatterns Whether to include code patterns (such as a
- /// for loop) in the code-completion results.
- ///
- /// \param IncludeBriefComments Whether to include brief documentation within
- /// the set of code completions returned.
- ///
- /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
- /// OwnedBuffers parameters are all disgusting hacks. They will go away.
- void CodeComplete(StringRef File, unsigned Line, unsigned Column,
- ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
- bool IncludeCodePatterns, bool IncludeBriefComments,
- CodeCompleteConsumer &Consumer,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- DiagnosticsEngine &Diag, LangOptions &LangOpts,
- SourceManager &SourceMgr, FileManager &FileMgr,
- SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
- SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers);
-
- /// \brief 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.
- ///
- /// \returns True if an error occurred, false otherwise.
- bool serialize(raw_ostream &OS);
-
- ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) override {
- // ASTUnit doesn't know how to load modules (not that this matters).
- return ModuleLoadResult();
- }
-
- void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc) override {}
-
- GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
- { return nullptr; }
- bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
- { return 0; }
-};
-
-} // namespace clang
-
-#endif
diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h
deleted file mode 100644
index eb33273..0000000
--- a/include/clang/Frontend/ChainedDiagnosticConsumer.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===- ChainedDiagnosticConsumer.h - Chain Diagnostic Clients ---*- 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_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H
-#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include <memory>
-
-namespace clang {
-class LangOptions;
-
-/// ChainedDiagnosticConsumer - Chain two diagnostic clients so that diagnostics
-/// go to the first client and then the second. The first diagnostic client
-/// should be the "primary" client, and will be used for computing whether the
-/// diagnostics should be included in counts.
-class ChainedDiagnosticConsumer : public DiagnosticConsumer {
- virtual void anchor();
- std::unique_ptr<DiagnosticConsumer> OwningPrimary;
- DiagnosticConsumer *Primary;
- std::unique_ptr<DiagnosticConsumer> Secondary;
-
-public:
- ChainedDiagnosticConsumer(std::unique_ptr<DiagnosticConsumer> Primary,
- std::unique_ptr<DiagnosticConsumer> Secondary)
- : OwningPrimary(std::move(Primary)), Primary(OwningPrimary.get()),
- Secondary(std::move(Secondary)) {}
-
- /// \brief Construct without taking ownership of \c Primary.
- ChainedDiagnosticConsumer(DiagnosticConsumer *Primary,
- std::unique_ptr<DiagnosticConsumer> Secondary)
- : Primary(Primary), Secondary(std::move(Secondary)) {}
-
- void BeginSourceFile(const LangOptions &LO,
- const Preprocessor *PP) override {
- Primary->BeginSourceFile(LO, PP);
- Secondary->BeginSourceFile(LO, PP);
- }
-
- void EndSourceFile() override {
- Secondary->EndSourceFile();
- Primary->EndSourceFile();
- }
-
- void finish() override {
- Secondary->finish();
- Primary->finish();
- }
-
- bool IncludeInDiagnosticCounts() const override {
- return Primary->IncludeInDiagnosticCounts();
- }
-
- void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) override {
- // Default implementation (Warnings/errors count).
- DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
-
- Primary->HandleDiagnostic(DiagLevel, Info);
- Secondary->HandleDiagnostic(DiagLevel, Info);
- }
-};
-
-} // end namspace clang
-
-#endif
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
deleted file mode 100644
index d9f6ab7..0000000
--- a/include/clang/Frontend/CodeGenOptions.def
+++ /dev/null
@@ -1,212 +0,0 @@
-//===--- CodeGenOptions.def - Code generation option 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 the code generation options. Users of this file
-// must define the CODEGENOPT macro to make use of this information.
-// Optionally, the user may also define ENUM_CODEGENOPT (for options
-// that have enumeration type and VALUE_CODEGENOPT is a code
-// generation option that describes a value rather than a flag.
-//
-//===----------------------------------------------------------------------===//
-#ifndef CODEGENOPT
-# error Define the CODEGENOPT macro to handle language options
-#endif
-
-#ifndef VALUE_CODEGENOPT
-# define VALUE_CODEGENOPT(Name, Bits, Default) \
-CODEGENOPT(Name, Bits, Default)
-#endif
-
-#ifndef ENUM_CODEGENOPT
-# define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
-CODEGENOPT(Name, Bits, Default)
-#endif
-
-CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
-CODEGENOPT(CompressDebugSections, 1, 0) ///< -Wa,-compress-debug-sections
-CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
-CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
-CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
-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(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.
-CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names.
-CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled.
-CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory.
-CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing.
-CODEGENOPT(DisableLLVMOpts , 1, 0) ///< Don't run any optimizations, for use in
- ///< getting .bc files that correspond to the
- ///< internal state before optimizations are
- ///< done.
-CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
- ///< the pristine IR generated by the
- ///< frontend.
-CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
-CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
-CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
- ///< Decl* various IR entities came from.
- ///< Only useful when running CodeGen as a
- ///< subroutine.
-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 FP_CONTRACT mode (on/off/fast).
-ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On)
-CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
- ///< are required.
-CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
-CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
- ///< enabled.
-CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
-CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to
- ///< be generated.
-CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the
- ///< compile step.
-CODEGENOPT(EmitFunctionSummary, 1, 0) ///< Set when -flto=thin is enabled on the
- ///< compile step.
-CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
- ///< be used with an incremental
- ///< linker.
-CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
-CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled.
-CODEGENOPT(MSVolatile , 1, 0) ///< Set when /volatile:ms is enabled.
-CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled.
-CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is
- ///< enabled.
-CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
-CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is
- ///< enabled.
-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(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated.
-CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled.
- ///< Disables use of the inline keyword.
-CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN.
-CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
-/// \brief 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.
-VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
-VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
-
-CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate
- ///< execution counts to use with PGO.
-CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to
- ///< enable code coverage analysis.
-CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping
- ///< regions.
-
- /// If -fpcc-struct-return or -freg-struct-return is specified.
-ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
-
-CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions.
-CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
-CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA.
-CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
-CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
- ///< offset in AddressSanitizer.
-CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
- ///< MemorySanitizer
-CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
- ///< in MemorySanitizer
-CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI.
-CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
- ///< instrumentation.
-CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage
- ///< for indirect calls.
-CODEGENOPT(SanitizeCoverageTraceBB, 1, 0) ///< Enable basic block tracing in
- ///< in sanitizer coverage.
-CODEGENOPT(SanitizeCoverageTraceCmp, 1, 0) ///< Enable cmp instruction tracing
- ///< in sanitizer coverage.
-CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters
- ///< in sanitizer coverage.
-CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
-CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
-CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
-CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers
-CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled.
-CODEGENOPT(UnitAtATime , 1, 1) ///< Unused. For mirroring GCC optimization
- ///< selection.
-CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled.
-CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled.
-CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns.
-CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables.
-CODEGENOPT(VectorizeBB , 1, 0) ///< Run basic block vectorizer.
-CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer.
-CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer.
-
- /// Attempt to use register sized accesses to bit-fields in structures, when
- /// possible.
-CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0)
-
-CODEGENOPT(VerifyModule , 1, 1) ///< Control whether the module should be run
- ///< through the LLVM Verifier.
-
-CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to force stack
- ///< realignment.
-CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or
- ///< .ctors.
-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(DebugColumnInfo, 1, 0) ///< Whether or not to use column information
- ///< in debug info.
-
-CODEGENOPT(DebugTypeExtRefs, 1, 0) ///< Whether or not debug info should contain
- ///< external references to a PCH or module.
-
-CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should
- ///< contain explicit imports for
- ///< anonymous namespaces
-
-CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
-
-/// The user specified number of registers to be used for integral arguments,
-/// or 0 if unspecified.
-VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)
-
-/// The lower bound for a buffer to be considered for stack protection.
-VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
-
-/// The kind of generated debug info.
-ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo)
-
-/// Tune the debug info for this debugger.
-ENUM_CODEGENOPT(DebuggerTuning, DebuggerKind, 2, DebuggerKindDefault)
-
-/// Dwarf version. Version zero indicates to LLVM that no DWARF should be
-/// emitted.
-VALUE_CODEGENOPT(DwarfVersion, 3, 0)
-
-/// Whether we should emit CodeView debug information. It's possible to emit
-/// CodeView and DWARF into the same object.
-CODEGENOPT(EmitCodeView, 1, 0)
-
-/// The kind of inlining to perform.
-ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining)
-
-// Vector functions library to use.
-ENUM_CODEGENOPT(VecLib, VectorLibrary, 1, NoLibrary)
-
-/// The default TLS model to use.
-ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
-
-#undef CODEGENOPT
-#undef ENUM_CODEGENOPT
-#undef VALUE_CODEGENOPT
-
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
deleted file mode 100644
index 7550e6f..0000000
--- a/include/clang/Frontend/CodeGenOptions.h
+++ /dev/null
@@ -1,245 +0,0 @@
-//===--- CodeGenOptions.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 the CodeGenOptions interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
-#define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
-
-#include "clang/Basic/Sanitizers.h"
-#include "llvm/Support/Regex.h"
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace clang {
-
-/// \brief Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
-/// that this large collection of bitfields is a trivial class type.
-class CodeGenOptionsBase {
-public:
-#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits;
-#define ENUM_CODEGENOPT(Name, Type, Bits, Default)
-#include "clang/Frontend/CodeGenOptions.def"
-
-protected:
-#define CODEGENOPT(Name, Bits, Default)
-#define ENUM_CODEGENOPT(Name, Type, Bits, Default) unsigned Name : Bits;
-#include "clang/Frontend/CodeGenOptions.def"
-};
-
-/// CodeGenOptions - Track various options which control how the code
-/// is optimized and passed to the backend.
-class CodeGenOptions : public CodeGenOptionsBase {
-public:
- enum InliningMethod {
- NoInlining, // Perform no inlining whatsoever.
- NormalInlining, // Use the standard function inlining pass.
- OnlyAlwaysInlining // Only run the always inlining pass.
- };
-
- enum VectorLibrary {
- NoLibrary, // Don't use any vector library.
- Accelerate // Use the Accelerate framework.
- };
-
- enum ObjCDispatchMethodKind {
- Legacy = 0,
- NonLegacy = 1,
- Mixed = 2
- };
-
- enum DebugInfoKind {
- NoDebugInfo, /// Don't generate debug info.
-
- LocTrackingOnly, /// Emit location information but do not generate
- /// debug info in the output. This is useful in
- /// cases where the backend wants to track source
- /// locations for instructions without actually
- /// emitting debug info for them (e.g., when -Rpass
- /// is used).
-
- DebugLineTablesOnly, /// Emit only debug info necessary for generating
- /// line number tables (-gline-tables-only).
-
- LimitedDebugInfo, /// Limit generated debug info to reduce size
- /// (-fno-standalone-debug). This emits
- /// 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
- /// contains the classe's vtable.
-
- FullDebugInfo /// Generate complete debug info.
- };
-
- enum DebuggerKind {
- DebuggerKindDefault,
- DebuggerKindGDB,
- DebuggerKindLLDB,
- DebuggerKindSCE
- };
-
- enum TLSModel {
- GeneralDynamicTLSModel,
- LocalDynamicTLSModel,
- InitialExecTLSModel,
- LocalExecTLSModel
- };
-
- 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).
- };
-
- enum StructReturnConventionKind {
- SRCK_Default, // No special option was passed.
- SRCK_OnStack, // Small structs on the stack (-fpcc-struct-return).
- SRCK_InRegs // Small structs in registers (-freg-struct-return).
- };
-
- /// The code model to use (-mcmodel).
- std::string CodeModel;
-
- /// The filename with path we use for coverage files. The extension will be
- /// replaced.
- std::string CoverageFile;
-
- /// The version string to put into coverage files.
- char CoverageVersion[4];
-
- /// Enable additional debugging information.
- std::string DebugPass;
-
- /// The string to embed in debug information as the current working directory.
- std::string DebugCompilationDir;
-
- /// The string to embed in the debug information for the compile unit, if
- /// non-empty.
- std::string DwarfDebugFlags;
-
- std::map<std::string, std::string> DebugPrefixMap;
-
- /// The ABI to use for passing floating point arguments.
- std::string FloatABI;
-
- /// The float precision limit to use, if non-empty.
- std::string LimitFloatPrecision;
-
- /// The name of the bitcode file to link before optzns.
- std::vector<std::pair<unsigned, std::string>> LinkBitcodeFiles;
-
- /// The user provided name for the "main file", if non-empty. This is useful
- /// in situations where the input file name does not match the original input
- /// file, for example with -save-temps.
- std::string MainFileName;
-
- /// The name for the split debug info file that we'll break out. This is used
- /// in the backend for setting the name in the skeleton cu.
- std::string SplitDwarfFile;
-
- /// The name of the relocation model to use.
- std::string RelocationModel;
-
- /// The thread model to use
- std::string ThreadModel;
-
- /// If not an empty string, trap intrinsics are lowered to calls to this
- /// 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;
-
- /// Name of the profile file to use as output for -fprofile-instr-generate
- /// and -fprofile-generate.
- std::string InstrProfileOutput;
-
- /// Name of the profile file to use with -fprofile-sample-use.
- std::string SampleProfileFile;
-
- /// Name of the profile file to use as input for -fprofile-instr-use
- std::string InstrProfileInput;
-
- /// Name of the function summary index file to use for ThinLTO function
- /// importing.
- std::string ThinLTOIndexFile;
-
- /// The EABI version to use
- std::string EABIVersion;
-
- /// 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;
-
- /// Regular expression to select optimizations for which we should enable
- /// optimization remarks. Transformation passes whose name matches this
- /// expression (and support this feature), will emit a diagnostic
- /// whenever they perform a transformation. This is enabled by the
- /// -Rpass=regexp flag.
- std::shared_ptr<llvm::Regex> OptimizationRemarkPattern;
-
- /// Regular expression to select optimizations for which we should enable
- /// missed optimization remarks. Transformation passes whose name matches this
- /// expression (and support this feature), will emit a diagnostic
- /// whenever they tried but failed to perform a transformation. This is
- /// enabled by the -Rpass-missed=regexp flag.
- std::shared_ptr<llvm::Regex> OptimizationRemarkMissedPattern;
-
- /// Regular expression to select optimizations for which we should enable
- /// optimization analyses. Transformation passes whose name matches this
- /// expression (and support this feature), will emit a diagnostic
- /// whenever they want to explain why they decided to apply or not apply
- /// a given transformation. This is enabled by the -Rpass-analysis=regexp
- /// flag.
- std::shared_ptr<llvm::Regex> OptimizationRemarkAnalysisPattern;
-
- /// Set of files definining the rules for the symbol rewriting.
- std::vector<std::string> RewriteMapFiles;
-
- /// Set of sanitizer checks that are non-fatal (i.e. execution should be
- /// continued when possible).
- SanitizerSet SanitizeRecover;
-
- /// Set of sanitizer checks that trap rather than diagnose.
- SanitizerSet SanitizeTrap;
-
- /// \brief A list of all -fno-builtin-* function names (e.g., memset).
- std::vector<std::string> NoBuiltinFuncs;
-
-public:
- // Define accessors/mutators for code generation options of enumeration type.
-#define CODEGENOPT(Name, Bits, Default)
-#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
- Type get##Name() const { return static_cast<Type>(Name); } \
- void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
-#include "clang/Frontend/CodeGenOptions.def"
-
- CodeGenOptions();
-
- /// \brief 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;
-
- const std::vector<std::string> &getNoBuiltinFuncs() const {
- return NoBuiltinFuncs;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
deleted file mode 100644
index a78c96d..0000000
--- a/include/clang/Frontend/CommandLineSourceLoc.h
+++ /dev/null
@@ -1,87 +0,0 @@
-
-//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Command line parsing for source locations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
-#define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-
-/// \brief A source location that has been parsed on the command line.
-struct ParsedSourceLocation {
- std::string FileName;
- unsigned Line;
- unsigned Column;
-
-public:
- /// Construct a parsed source location from a string; the Filename is empty on
- /// error.
- static ParsedSourceLocation FromString(StringRef Str) {
- ParsedSourceLocation PSL;
- std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':');
- std::pair<StringRef, StringRef> LineSplit =
- ColSplit.first.rsplit(':');
-
- // If both tail splits were valid integers, return success.
- if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
- !LineSplit.second.getAsInteger(10, PSL.Line)) {
- PSL.FileName = LineSplit.first;
-
- // On the command-line, stdin may be specified via "-". Inside the
- // compiler, stdin is called "<stdin>".
- if (PSL.FileName == "-")
- PSL.FileName = "<stdin>";
- }
-
- return PSL;
- }
-};
-
-}
-
-namespace llvm {
- namespace cl {
- /// \brief Command-line option parser that parses source locations.
- ///
- /// Source locations are of the form filename:line:column.
- template<>
- class parser<clang::ParsedSourceLocation> final
- : public basic_parser<clang::ParsedSourceLocation> {
- public:
- inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
- clang::ParsedSourceLocation &Val);
- };
-
- bool
- parser<clang::ParsedSourceLocation>::
- parse(Option &O, StringRef ArgName, StringRef ArgValue,
- clang::ParsedSourceLocation &Val) {
- using namespace clang;
-
- Val = ParsedSourceLocation::FromString(ArgValue);
- if (Val.FileName.empty()) {
- errs() << "error: "
- << "source location must be of the form filename:line:column\n";
- return true;
- }
-
- return false;
- }
- }
-}
-
-#endif
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
deleted file mode 100644
index 83eed2c..0000000
--- a/include/clang/Frontend/CompilerInstance.h
+++ /dev/null
@@ -1,785 +0,0 @@
-//===-- CompilerInstance.h - Clang Compiler Instance ------------*- 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_FRONTEND_COMPILERINSTANCE_H_
-#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
-
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Frontend/PCHContainerOperations.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/Utils.h"
-#include "clang/Lex/ModuleLoader.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringRef.h"
-#include <cassert>
-#include <list>
-#include <memory>
-#include <string>
-#include <utility>
-
-namespace llvm {
-class raw_fd_ostream;
-class Timer;
-class TimerGroup;
-}
-
-namespace clang {
-class ASTContext;
-class ASTConsumer;
-class ASTReader;
-class CodeCompleteConsumer;
-class DiagnosticsEngine;
-class DiagnosticConsumer;
-class ExternalASTSource;
-class FileEntry;
-class FileManager;
-class FrontendAction;
-class Module;
-class Preprocessor;
-class Sema;
-class SourceManager;
-class TargetInfo;
-
-/// CompilerInstance - Helper class for managing a single instance of the Clang
-/// compiler.
-///
-/// The CompilerInstance serves two purposes:
-/// (1) It manages the various objects which are necessary to run the compiler,
-/// for example the preprocessor, the target information, and the AST
-/// context.
-/// (2) It provides utility routines for constructing and manipulating the
-/// common Clang objects.
-///
-/// The compiler instance generally owns the instance of all the objects that it
-/// manages. However, clients can still share objects by manually setting the
-/// object and retaking ownership prior to destroying the CompilerInstance.
-///
-/// The compiler instance is intended to simplify clients, but not to lock them
-/// in to the compiler instance for everything. When possible, utility functions
-/// come in two forms; a short form that reuses the CompilerInstance objects,
-/// and a long form that takes explicit instances of any required objects.
-class CompilerInstance : public ModuleLoader {
- /// The options used in this compiler instance.
- IntrusiveRefCntPtr<CompilerInvocation> Invocation;
-
- /// The diagnostics engine instance.
- IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
-
- /// The target being compiled for.
- IntrusiveRefCntPtr<TargetInfo> Target;
-
- /// Auxiliary Target info.
- IntrusiveRefCntPtr<TargetInfo> AuxTarget;
-
- /// The virtual file system.
- IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem;
-
- /// The file manager.
- IntrusiveRefCntPtr<FileManager> FileMgr;
-
- /// The source manager.
- IntrusiveRefCntPtr<SourceManager> SourceMgr;
-
- /// The preprocessor.
- IntrusiveRefCntPtr<Preprocessor> PP;
-
- /// The AST context.
- IntrusiveRefCntPtr<ASTContext> Context;
-
- /// The AST consumer.
- std::unique_ptr<ASTConsumer> Consumer;
-
- /// The code completion consumer.
- std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
-
- /// \brief The semantic analysis object.
- std::unique_ptr<Sema> TheSema;
-
- /// \brief The frontend timer group.
- std::unique_ptr<llvm::TimerGroup> FrontendTimerGroup;
-
- /// \brief The frontend timer.
- std::unique_ptr<llvm::Timer> FrontendTimer;
-
- /// \brief The ASTReader, if one exists.
- IntrusiveRefCntPtr<ASTReader> ModuleManager;
-
- /// \brief The module dependency collector for crashdumps
- std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
-
- /// \brief The module provider.
- std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations;
-
- /// \brief 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,
- /// along with the module map
- llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
-
- /// \brief The location of the module-import keyword for the last module
- /// import.
- SourceLocation LastModuleImportLoc;
-
- /// \brief The result of the last module import.
- ///
- ModuleLoadResult LastModuleImportResult;
-
- /// \brief Whether we should (re)build the global module index once we
- /// have finished with this translation unit.
- bool BuildGlobalModuleIndex;
-
- /// \brief We have a full global module index, with all modules.
- bool HaveFullGlobalModuleIndex;
-
- /// \brief One or more modules failed to build.
- bool ModuleBuildFailed;
-
- /// \brief 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
- /// failed.
- struct OutputFile {
- std::string Filename;
- std::string TempFilename;
- std::unique_ptr<raw_ostream> OS;
-
- OutputFile(std::string filename, std::string tempFilename,
- std::unique_ptr<raw_ostream> OS)
- : Filename(std::move(filename)), TempFilename(std::move(tempFilename)),
- OS(std::move(OS)) {}
- OutputFile(OutputFile &&O)
- : Filename(std::move(O.Filename)),
- TempFilename(std::move(O.TempFilename)), OS(std::move(O.OS)) {}
- };
-
- /// If the output doesn't support seeking (terminal, pipe). we switch
- /// the stream to a buffer_ostream. These are the buffer and the original
- /// stream.
- std::unique_ptr<llvm::raw_fd_ostream> NonSeekStream;
-
- /// The list of active output files.
- std::list<OutputFile> OutputFiles;
-
- CompilerInstance(const CompilerInstance &) = delete;
- void operator=(const CompilerInstance &) = delete;
-public:
- explicit CompilerInstance(
- std::shared_ptr<PCHContainerOperations> PCHContainerOps =
- std::make_shared<PCHContainerOperations>(),
- bool BuildingModule = false);
- ~CompilerInstance() override;
-
- /// @name High-Level Operations
- /// {
-
- /// ExecuteAction - Execute the provided action against the compiler's
- /// CompilerInvocation object.
- ///
- /// This function makes the following assumptions:
- ///
- /// - The invocation options should be initialized. This function does not
- /// handle the '-help' or '-version' options, clients should handle those
- /// directly.
- ///
- /// - The diagnostics engine should have already been created by the client.
- ///
- /// - No other CompilerInstance state should have been initialized (this is
- /// an unchecked error).
- ///
- /// - Clients should have initialized any LLVM target features that may be
- /// required.
- ///
- /// - Clients should eventually call llvm_shutdown() upon the completion of
- /// this routine to ensure that any managed objects are properly destroyed.
- ///
- /// Note that this routine may write output to 'stderr'.
- ///
- /// \param Act - The action to execute.
- /// \return - True on success.
- //
- // FIXME: This function should take the stream to write any debugging /
- // verbose output to as an argument.
- //
- // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
- // of the context or else not CompilerInstance specific.
- bool ExecuteAction(FrontendAction &Act);
-
- /// }
- /// @name Compiler Invocation and Options
- /// {
-
- bool hasInvocation() const { return Invocation != nullptr; }
-
- CompilerInvocation &getInvocation() {
- assert(Invocation && "Compiler instance has no invocation!");
- return *Invocation;
- }
-
- /// setInvocation - Replace the current invocation.
- void setInvocation(CompilerInvocation *Value);
-
- /// \brief 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
- /// module index.
- void setBuildGlobalModuleIndex(bool Build) {
- BuildGlobalModuleIndex = Build;
- }
-
- /// }
- /// @name Forwarding Methods
- /// {
-
- AnalyzerOptionsRef getAnalyzerOpts() {
- return Invocation->getAnalyzerOpts();
- }
-
- CodeGenOptions &getCodeGenOpts() {
- return Invocation->getCodeGenOpts();
- }
- const CodeGenOptions &getCodeGenOpts() const {
- return Invocation->getCodeGenOpts();
- }
-
- DependencyOutputOptions &getDependencyOutputOpts() {
- return Invocation->getDependencyOutputOpts();
- }
- const DependencyOutputOptions &getDependencyOutputOpts() const {
- return Invocation->getDependencyOutputOpts();
- }
-
- DiagnosticOptions &getDiagnosticOpts() {
- return Invocation->getDiagnosticOpts();
- }
- const DiagnosticOptions &getDiagnosticOpts() const {
- return Invocation->getDiagnosticOpts();
- }
-
- FileSystemOptions &getFileSystemOpts() {
- return Invocation->getFileSystemOpts();
- }
- const FileSystemOptions &getFileSystemOpts() const {
- return Invocation->getFileSystemOpts();
- }
-
- FrontendOptions &getFrontendOpts() {
- return Invocation->getFrontendOpts();
- }
- const FrontendOptions &getFrontendOpts() const {
- return Invocation->getFrontendOpts();
- }
-
- HeaderSearchOptions &getHeaderSearchOpts() {
- return Invocation->getHeaderSearchOpts();
- }
- const HeaderSearchOptions &getHeaderSearchOpts() const {
- return Invocation->getHeaderSearchOpts();
- }
-
- LangOptions &getLangOpts() {
- return *Invocation->getLangOpts();
- }
- const LangOptions &getLangOpts() const {
- return *Invocation->getLangOpts();
- }
-
- PreprocessorOptions &getPreprocessorOpts() {
- return Invocation->getPreprocessorOpts();
- }
- const PreprocessorOptions &getPreprocessorOpts() const {
- return Invocation->getPreprocessorOpts();
- }
-
- PreprocessorOutputOptions &getPreprocessorOutputOpts() {
- return Invocation->getPreprocessorOutputOpts();
- }
- const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
- return Invocation->getPreprocessorOutputOpts();
- }
-
- TargetOptions &getTargetOpts() {
- return Invocation->getTargetOpts();
- }
- const TargetOptions &getTargetOpts() const {
- return Invocation->getTargetOpts();
- }
-
- /// }
- /// @name Diagnostics Engine
- /// {
-
- bool hasDiagnostics() const { return Diagnostics != nullptr; }
-
- /// Get the current diagnostics engine.
- DiagnosticsEngine &getDiagnostics() const {
- assert(Diagnostics && "Compiler instance has no diagnostics!");
- return *Diagnostics;
- }
-
- /// setDiagnostics - Replace the current diagnostics engine.
- void setDiagnostics(DiagnosticsEngine *Value);
-
- DiagnosticConsumer &getDiagnosticClient() const {
- assert(Diagnostics && Diagnostics->getClient() &&
- "Compiler instance has no diagnostic client!");
- return *Diagnostics->getClient();
- }
-
- /// }
- /// @name Target Info
- /// {
-
- bool hasTarget() const { return Target != nullptr; }
-
- TargetInfo &getTarget() const {
- assert(Target && "Compiler instance has no target!");
- return *Target;
- }
-
- /// Replace the current Target.
- void setTarget(TargetInfo *Value);
-
- /// }
- /// @name AuxTarget Info
- /// {
-
- TargetInfo *getAuxTarget() const { return AuxTarget.get(); }
-
- /// Replace the current AuxTarget.
- void setAuxTarget(TargetInfo *Value);
-
- /// }
- /// @name Virtual File System
- /// {
-
- bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; }
-
- vfs::FileSystem &getVirtualFileSystem() const {
- assert(hasVirtualFileSystem() &&
- "Compiler instance has no virtual file system");
- return *VirtualFileSystem;
- }
-
- /// \brief 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.
- void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) {
- VirtualFileSystem = FS;
- }
-
- /// }
- /// @name File Manager
- /// {
-
- bool hasFileManager() const { return FileMgr != nullptr; }
-
- /// Return the current file manager to the caller.
- FileManager &getFileManager() const {
- assert(FileMgr && "Compiler instance has no file manager!");
- return *FileMgr;
- }
-
- void resetAndLeakFileManager() {
- BuryPointer(FileMgr.get());
- FileMgr.resetWithoutRelease();
- }
-
- /// \brief Replace the current file manager and virtual file system.
- void setFileManager(FileManager *Value);
-
- /// }
- /// @name Source Manager
- /// {
-
- bool hasSourceManager() const { return SourceMgr != nullptr; }
-
- /// Return the current source manager.
- SourceManager &getSourceManager() const {
- assert(SourceMgr && "Compiler instance has no source manager!");
- return *SourceMgr;
- }
-
- void resetAndLeakSourceManager() {
- BuryPointer(SourceMgr.get());
- SourceMgr.resetWithoutRelease();
- }
-
- /// setSourceManager - Replace the current source manager.
- void setSourceManager(SourceManager *Value);
-
- /// }
- /// @name Preprocessor
- /// {
-
- bool hasPreprocessor() const { return PP != nullptr; }
-
- /// Return the current preprocessor.
- Preprocessor &getPreprocessor() const {
- assert(PP && "Compiler instance has no preprocessor!");
- return *PP;
- }
-
- void resetAndLeakPreprocessor() {
- BuryPointer(PP.get());
- PP.resetWithoutRelease();
- }
-
- /// Replace the current preprocessor.
- void setPreprocessor(Preprocessor *Value);
-
- /// }
- /// @name ASTContext
- /// {
-
- bool hasASTContext() const { return Context != nullptr; }
-
- ASTContext &getASTContext() const {
- assert(Context && "Compiler instance has no AST context!");
- return *Context;
- }
-
- void resetAndLeakASTContext() {
- BuryPointer(Context.get());
- Context.resetWithoutRelease();
- }
-
- /// setASTContext - Replace the current AST context.
- void setASTContext(ASTContext *Value);
-
- /// \brief Replace the current Sema; the compiler instance takes ownership
- /// of S.
- void setSema(Sema *S);
-
- /// }
- /// @name ASTConsumer
- /// {
-
- bool hasASTConsumer() const { return (bool)Consumer; }
-
- ASTConsumer &getASTConsumer() const {
- assert(Consumer && "Compiler instance has no AST consumer!");
- return *Consumer;
- }
-
- /// takeASTConsumer - Remove the current AST consumer and give ownership to
- /// the caller.
- std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); }
-
- /// setASTConsumer - Replace the current AST consumer; the compiler instance
- /// takes ownership of \p Value.
- void setASTConsumer(std::unique_ptr<ASTConsumer> Value);
-
- /// }
- /// @name Semantic analysis
- /// {
- bool hasSema() const { return (bool)TheSema; }
-
- Sema &getSema() const {
- assert(TheSema && "Compiler instance has no Sema object!");
- return *TheSema;
- }
-
- std::unique_ptr<Sema> takeSema();
- void resetAndLeakSema();
-
- /// }
- /// @name Module Management
- /// {
-
- IntrusiveRefCntPtr<ASTReader> getModuleManager() const;
- void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader);
-
- std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
- void setModuleDepCollector(
- std::shared_ptr<ModuleDependencyCollector> Collector);
-
- std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
- return ThePCHContainerOperations;
- }
-
- /// Return the appropriate PCHContainerWriter depending on the
- /// current CodeGenOptions.
- const PCHContainerWriter &getPCHContainerWriter() const {
- assert(Invocation && "cannot determine module format without invocation");
- StringRef Format = getHeaderSearchOpts().ModuleFormat;
- auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format);
- if (!Writer) {
- if (Diagnostics)
- Diagnostics->Report(diag::err_module_format_unhandled) << Format;
- llvm::report_fatal_error("unknown module format");
- }
- return *Writer;
- }
-
- /// Return the appropriate PCHContainerReader depending on the
- /// current CodeGenOptions.
- const PCHContainerReader &getPCHContainerReader() const {
- assert(Invocation && "cannot determine module format without invocation");
- StringRef Format = getHeaderSearchOpts().ModuleFormat;
- auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format);
- if (!Reader) {
- if (Diagnostics)
- Diagnostics->Report(diag::err_module_format_unhandled) << Format;
- llvm::report_fatal_error("unknown module format");
- }
- return *Reader;
- }
-
- /// }
- /// @name Code Completion
- /// {
-
- bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
-
- CodeCompleteConsumer &getCodeCompletionConsumer() const {
- assert(CompletionConsumer &&
- "Compiler instance has no code completion consumer!");
- return *CompletionConsumer;
- }
-
- /// setCodeCompletionConsumer - Replace the current code completion consumer;
- /// the compiler instance takes ownership of \p Value.
- void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
-
- /// }
- /// @name Frontend timer
- /// {
-
- bool hasFrontendTimer() const { return (bool)FrontendTimer; }
-
- llvm::Timer &getFrontendTimer() const {
- assert(FrontendTimer && "Compiler instance has no frontend timer!");
- return *FrontendTimer;
- }
-
- /// }
- /// @name Output Files
- /// {
-
- /// addOutputFile - Add an output file onto the list of tracked output files.
- ///
- /// \param OutFile - The output file info.
- void addOutputFile(OutputFile &&OutFile);
-
- /// clearOutputFiles - Clear the output file list, destroying the contained
- /// output streams.
- ///
- /// \param EraseFiles - If true, attempt to erase the files from disk.
- void clearOutputFiles(bool EraseFiles);
-
- /// }
- /// @name Construction Utility Methods
- /// {
-
- /// Create the diagnostics engine using the invocation's diagnostic options
- /// and replace any existing one with it.
- ///
- /// Note that this routine also replaces the diagnostic client,
- /// allocating one if one is not provided.
- ///
- /// \param Client If non-NULL, a diagnostic client that will be
- /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
- /// unit.
- ///
- /// \param ShouldOwnClient If Client is non-NULL, specifies whether
- /// the diagnostic object should take ownership of the client.
- void createDiagnostics(DiagnosticConsumer *Client = nullptr,
- bool ShouldOwnClient = true);
-
- /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
- ///
- /// If no diagnostic client is provided, this creates a
- /// DiagnosticConsumer that is owned by the returned diagnostic
- /// object, if using directly the caller is responsible for
- /// releasing the returned DiagnosticsEngine's client eventually.
- ///
- /// \param Opts - The diagnostic options; note that the created text
- /// diagnostic object contains a reference to these options.
- ///
- /// \param Client If non-NULL, a diagnostic client that will be
- /// attached to (and, then, owned by) the returned DiagnosticsEngine
- /// object.
- ///
- /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
- /// used by some diagnostics printers (for logging purposes only).
- ///
- /// \return The new object on success, or null on failure.
- static IntrusiveRefCntPtr<DiagnosticsEngine>
- createDiagnostics(DiagnosticOptions *Opts,
- DiagnosticConsumer *Client = nullptr,
- bool ShouldOwnClient = true,
- const CodeGenOptions *CodeGenOpts = nullptr);
-
- /// Create the file manager and replace any existing one with it.
- void createFileManager();
-
- /// Create the source manager and replace any existing one with it.
- void createSourceManager(FileManager &FileMgr);
-
- /// Create the preprocessor, using the invocation, file, and source managers,
- /// and replace any existing one with it.
- void createPreprocessor(TranslationUnitKind TUKind);
-
- std::string getSpecificModuleCachePath();
-
- /// Create the AST context.
- void createASTContext();
-
- /// Create an external AST source to read a PCH file and attach it to the AST
- /// context.
- void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation,
- bool AllowPCHWithCompilerErrors,
- void *DeserializationListener,
- bool OwnDeserializationListener);
-
- /// Create an external AST source to read a PCH file.
- ///
- /// \return - The new object on success, or null on failure.
- static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
- StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
- bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
- const PCHContainerReader &PCHContainerRdr,
- ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
- void *DeserializationListener, bool OwnDeserializationListener,
- bool Preamble, bool UseGlobalModuleIndex);
-
- /// Create a code completion consumer using the invocation; note that this
- /// will cause the source manager to truncate the input source file at the
- /// completion point.
- void createCodeCompletionConsumer();
-
- /// Create a code completion consumer to print code completion results, at
- /// \p Filename, \p Line, and \p Column, to the given output stream \p OS.
- static CodeCompleteConsumer *createCodeCompletionConsumer(
- Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column,
- const CodeCompleteOptions &Opts, raw_ostream &OS);
-
- /// \brief Create the Sema object to be used for parsing.
- void createSema(TranslationUnitKind TUKind,
- CodeCompleteConsumer *CompletionConsumer);
-
- /// Create the frontend timer and replace any existing one with it.
- void createFrontendTimer();
-
- /// Create the default output file (from the invocation's options) and add it
- /// to the list of tracked output files.
- ///
- /// The files created by this function always use temporary files to write to
- /// their result (that is, the data is written to a temporary file which will
- /// atomically replace the target output on success).
- ///
- /// \return - Null on error.
- raw_pwrite_stream *createDefaultOutputFile(bool Binary = true,
- StringRef BaseInput = "",
- StringRef Extension = "");
-
- /// Create a new output file and add it to the list of tracked output files,
- /// optionally deriving the output path name.
- ///
- /// \return - Null on error.
- raw_pwrite_stream *createOutputFile(StringRef OutputPath, bool Binary,
- bool RemoveFileOnSignal,
- StringRef BaseInput, StringRef Extension,
- bool UseTemporary,
- bool CreateMissingDirectories = false);
-
- /// Create a new output file, optionally deriving the output path name.
- ///
- /// If \p OutputPath is empty, then createOutputFile will derive an output
- /// path location as \p BaseInput, with any suffix removed, and \p Extension
- /// appended. If \p OutputPath is not stdout and \p UseTemporary
- /// is true, createOutputFile will create a new temporary file that must be
- /// renamed to \p OutputPath in the end.
- ///
- /// \param OutputPath - If given, the path to the output file.
- /// \param Error [out] - On failure, the error.
- /// \param BaseInput - If \p OutputPath is empty, the input path name to use
- /// for deriving the output path.
- /// \param Extension - The extension to use for derived output names.
- /// \param Binary - The mode to open the file in.
- /// \param RemoveFileOnSignal - Whether the file should be registered with
- /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
- /// multithreaded use, as the underlying signal mechanism is not reentrant
- /// \param UseTemporary - Create a new temporary file that must be renamed to
- /// OutputPath in the end.
- /// \param CreateMissingDirectories - When \p UseTemporary is true, create
- /// missing directories in the output path.
- /// \param ResultPathName [out] - If given, the result path name will be
- /// stored here on success.
- /// \param TempPathName [out] - If given, the temporary file path name
- /// will be stored here on success.
- std::unique_ptr<raw_pwrite_stream>
- createOutputFile(StringRef OutputPath, std::error_code &Error, bool Binary,
- bool RemoveFileOnSignal, StringRef BaseInput,
- StringRef Extension, bool UseTemporary,
- bool CreateMissingDirectories, std::string *ResultPathName,
- std::string *TempPathName);
-
- llvm::raw_null_ostream *createNullOutputFile();
-
- /// }
- /// @name Initialization Utility Methods
- /// {
-
- /// InitializeSourceManager - Initialize the source manager to set InputFile
- /// as the main file.
- ///
- /// \return True on success.
- bool InitializeSourceManager(const FrontendInputFile &Input);
-
- /// InitializeSourceManager - Initialize the source manager to set InputFile
- /// as the main file.
- ///
- /// \return True on success.
- static bool InitializeSourceManager(const FrontendInputFile &Input,
- DiagnosticsEngine &Diags,
- FileManager &FileMgr,
- SourceManager &SourceMgr,
- const FrontendOptions &Opts);
-
- /// }
-
- // Create module manager.
- void createModuleManager();
-
- bool loadModuleFile(StringRef FileName);
-
- ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) override;
-
- void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc) override;
-
- bool hadModuleLoaderFatalFailure() const {
- return ModuleLoader::HadFatalFailure;
- }
-
- GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
-
- bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
-
- void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
- DependencyCollectors.push_back(std::move(Listener));
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
deleted file mode 100644
index 0b4a1e5..0000000
--- a/include/clang/Frontend/CompilerInvocation.h
+++ /dev/null
@@ -1,219 +0,0 @@
-//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- 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_FRONTEND_COMPILERINVOCATION_H_
-#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
-
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/TargetOptions.h"
-#include "clang/Frontend/CodeGenOptions.h"
-#include "clang/Frontend/DependencyOutputOptions.h"
-#include "clang/Frontend/FrontendOptions.h"
-#include "clang/Frontend/LangStandard.h"
-#include "clang/Frontend/MigratorOptions.h"
-#include "clang/Frontend/PreprocessorOutputOptions.h"
-#include "clang/Lex/HeaderSearchOptions.h"
-#include "clang/Lex/PreprocessorOptions.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-namespace opt {
-class ArgList;
-}
-}
-
-namespace clang {
-class CompilerInvocation;
-class DiagnosticsEngine;
-
-/// \brief Fill out Opts based on the options given in Args.
-///
-/// Args must have been created from the OptTable returned by
-/// createCC1OptTable().
-///
-/// When errors are encountered, return false and, if Diags is non-null,
-/// report the error(s).
-bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
- DiagnosticsEngine *Diags = nullptr);
-
-class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
- void operator=(const CompilerInvocationBase &) = delete;
-
-public:
- /// Options controlling the language variant.
- std::shared_ptr<LangOptions> LangOpts;
-
- /// Options controlling the target.
- std::shared_ptr<TargetOptions> TargetOpts;
-
- /// Options controlling the diagnostic engine.
- IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;
-
- /// Options controlling the \#include directive.
- IntrusiveRefCntPtr<HeaderSearchOptions> HeaderSearchOpts;
-
- /// Options controlling the preprocessor (aside from \#include handling).
- IntrusiveRefCntPtr<PreprocessorOptions> PreprocessorOpts;
-
- CompilerInvocationBase();
- ~CompilerInvocationBase();
-
- CompilerInvocationBase(const CompilerInvocationBase &X);
-
- LangOptions *getLangOpts() { return LangOpts.get(); }
- const LangOptions *getLangOpts() const { return LangOpts.get(); }
-
- TargetOptions &getTargetOpts() { 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;
- }
-
- PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; }
- const PreprocessorOptions &getPreprocessorOpts() const {
- return *PreprocessorOpts;
- }
-};
-
-/// \brief 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
-/// options, the warning flags, and so on.
-class CompilerInvocation : public CompilerInvocationBase {
- /// Options controlling the static analyzer.
- AnalyzerOptionsRef AnalyzerOpts;
-
- MigratorOptions MigratorOpts;
-
- /// Options controlling IRgen and the backend.
- CodeGenOptions CodeGenOpts;
-
- /// Options controlling dependency output.
- DependencyOutputOptions DependencyOutputOpts;
-
- /// Options controlling file system operations.
- FileSystemOptions FileSystemOpts;
-
- /// Options controlling the frontend itself.
- FrontendOptions FrontendOpts;
-
- /// Options controlling preprocessed output.
- PreprocessorOutputOptions PreprocessorOutputOpts;
-
-public:
- CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {}
-
- /// @name Utility Methods
- /// @{
-
- /// \brief Create a compiler invocation from a list of input options.
- /// \returns true on success.
- ///
- /// \param [out] Res - The resulting invocation.
- /// \param ArgBegin - The first element in the argument vector.
- /// \param ArgEnd - The last element in the argument vector.
- /// \param Diags - The diagnostic engine to use for errors.
- static bool CreateFromArgs(CompilerInvocation &Res,
- const char* const *ArgBegin,
- const char* const *ArgEnd,
- DiagnosticsEngine &Diags);
-
- /// \brief Get the directory where the compiler headers
- /// reside, relative to the compiler binary (found by the passed in
- /// arguments).
- ///
- /// \param Argv0 - The program path (from argv[0]), for finding the builtin
- /// compiler path.
- /// \param MainAddr - The address of main (or some other function in the main
- /// 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
- /// language standard in the given LangOptions object.
- ///
- /// \param Opts - The LangOptions object to set up.
- /// \param IK - The input language.
- /// \param LangStd - The input language standard.
- static void setLangDefaults(LangOptions &Opts, InputKind IK,
- LangStandard::Kind LangStd = LangStandard::lang_unspecified);
-
- /// \brief Retrieve a module hash string that is suitable for uniquely
- /// identifying the conditions under which the module was built.
- std::string getModuleHash() const;
-
- /// @}
- /// @name Option Subgroups
- /// @{
-
- AnalyzerOptionsRef getAnalyzerOpts() const {
- return AnalyzerOpts;
- }
-
- MigratorOptions &getMigratorOpts() { return MigratorOpts; }
- const MigratorOptions &getMigratorOpts() const {
- return MigratorOpts;
- }
-
- CodeGenOptions &getCodeGenOpts() { 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;
- }
-
- PreprocessorOutputOptions &getPreprocessorOutputOpts() {
- return PreprocessorOutputOpts;
- }
- const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
- return PreprocessorOutputOpts;
- }
-
- /// @}
-};
-
-namespace vfs {
- class FileSystem;
-}
-
-IntrusiveRefCntPtr<vfs::FileSystem>
-createVFSFromCompilerInvocation(const CompilerInvocation &CI,
- DiagnosticsEngine &Diags);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
deleted file mode 100644
index 129b534..0000000
--- a/include/clang/Frontend/DependencyOutputOptions.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//===--- DependencyOutputOptions.h ------------------------------*- 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_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
-#define LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
-
-#include <string>
-#include <vector>
-
-namespace clang {
-
-/// DependencyOutputFormat - Format for the compiler dependency file.
-enum class DependencyOutputFormat { Make, NMake };
-
-/// DependencyOutputOptions - Options for controlling the compiler dependency
-/// file generation.
-class DependencyOutputOptions {
-public:
- unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies.
- unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H).
- unsigned UsePhonyTargets : 1; ///< Include phony targets for each
- /// 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.
-
- /// The format for the dependency file.
- DependencyOutputFormat OutputFormat;
-
- /// The file to write dependency output to.
- std::string OutputFile;
-
- /// The file to write header include output to. This is orthogonal to
- /// ShowHeaderIncludes (-H) and will include headers mentioned in the
- /// predefines buffer. If the output file is "-", output will be sent to
- /// stderr.
- std::string HeaderIncludeOutputFile;
-
- /// A list of names to use as the targets in the dependency file; this list
- /// must contain at least one entry.
- std::vector<std::string> Targets;
-
- /// A list of filenames to be used as extra dependencies for every target.
- std::vector<std::string> ExtraDeps;
-
- /// \brief The file to write GraphViz-formatted header dependencies to.
- std::string DOTOutputFile;
-
- /// \brief 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;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
deleted file mode 100644
index c372fdd..0000000
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ /dev/null
@@ -1,178 +0,0 @@
-//===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a utility class that provides support for pretty-printing of
-// diagnostics. It is used to implement the different code paths which require
-// such functionality in a consistent way.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
-#define LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerUnion.h"
-
-namespace clang {
-
-class DiagnosticOptions;
-class LangOptions;
-class SourceManager;
-
-typedef llvm::PointerUnion<const Diagnostic *,
- const StoredDiagnostic *> DiagOrStoredDiag;
-
-/// \brief Class to encapsulate the logic for formatting a diagnostic message.
-///
-/// Actual "printing" logic is implemented by subclasses.
-///
-/// This class provides an interface for building and emitting
-/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
-/// Hints, and code snippets. In the presence of macros this involves
-/// a recursive process, synthesizing notes for each macro expansion.
-///
-/// A brief worklist:
-/// FIXME: Sink the recursive printing of template instantiations into this
-/// class.
-class DiagnosticRenderer {
-protected:
- const LangOptions &LangOpts;
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
-
- /// \brief 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.
- ///
- /// 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. Used to detect level changes
- /// which change the amount of information displayed.
- DiagnosticsEngine::Level LastLevel;
-
- DiagnosticRenderer(const LangOptions &LangOpts,
- DiagnosticOptions *DiagOpts);
-
- virtual ~DiagnosticRenderer();
-
- virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
- DiagnosticsEngine::Level Level,
- StringRef Message,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager *SM,
- DiagOrStoredDiag Info) = 0;
-
- virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
- DiagnosticsEngine::Level Level,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager &SM) = 0;
-
- virtual void emitCodeContext(SourceLocation Loc,
- DiagnosticsEngine::Level Level,
- SmallVectorImpl<CharSourceRange>& Ranges,
- ArrayRef<FixItHint> Hints,
- const SourceManager &SM) = 0;
-
- virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
- const SourceManager &SM) = 0;
- virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
- StringRef ModuleName,
- const SourceManager &SM) = 0;
- virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
- StringRef ModuleName,
- const SourceManager &SM) = 0;
-
- virtual void beginDiagnostic(DiagOrStoredDiag D,
- DiagnosticsEngine::Level Level) {}
- virtual void endDiagnostic(DiagOrStoredDiag D,
- DiagnosticsEngine::Level Level) {}
-
-
-private:
- void emitBasicNote(StringRef Message);
- void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc,
- DiagnosticsEngine::Level Level, const SourceManager &SM);
- void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
- void emitImportStack(SourceLocation Loc, const SourceManager &SM);
- void emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName,
- const SourceManager &SM);
- void emitModuleBuildStack(const SourceManager &SM);
- void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
- ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints,
- const SourceManager &SM);
- void emitSingleMacroExpansion(SourceLocation Loc,
- DiagnosticsEngine::Level Level,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager &SM);
- void emitMacroExpansions(SourceLocation Loc,
- DiagnosticsEngine::Level Level,
- ArrayRef<CharSourceRange> Ranges,
- ArrayRef<FixItHint> Hints,
- const SourceManager &SM);
-public:
- /// \brief 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
- /// information needed based on macros whose expansions impact the
- /// diagnostic.
- ///
- /// \param Loc The location for this caret.
- /// \param Level The level of the diagnostic to be emitted.
- /// \param Message The diagnostic message to emit.
- /// \param Ranges The underlined ranges for this code snippet.
- /// \param FixItHints The FixIt hints active for this diagnostic.
- /// \param SM The SourceManager; will be null if the diagnostic came from the
- /// frontend, thus \p Loc will be invalid.
- void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
- StringRef Message, ArrayRef<CharSourceRange> Ranges,
- ArrayRef<FixItHint> FixItHints,
- const SourceManager *SM,
- DiagOrStoredDiag D = (Diagnostic *)nullptr);
-
- void emitStoredDiagnostic(StoredDiagnostic &Diag);
-};
-
-/// Subclass of DiagnosticRender that turns all subdiagostics into explicit
-/// notes. It is up to subclasses to further define the behavior.
-class DiagnosticNoteRenderer : public DiagnosticRenderer {
-public:
- DiagnosticNoteRenderer(const LangOptions &LangOpts,
- DiagnosticOptions *DiagOpts)
- : DiagnosticRenderer(LangOpts, DiagOpts) {}
-
- ~DiagnosticNoteRenderer() override;
-
- void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
- const SourceManager &SM) override;
-
- void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
- StringRef ModuleName,
- const SourceManager &SM) override;
-
- void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
- StringRef ModuleName,
- const SourceManager &SM) override;
-
- virtual void emitNote(SourceLocation Loc, StringRef Message,
- const SourceManager *SM) = 0;
-};
-} // end clang namespace
-#endif
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
deleted file mode 100644
index c407ff8..0000000
--- a/include/clang/Frontend/FrontendAction.h
+++ /dev/null
@@ -1,298 +0,0 @@
-//===-- FrontendAction.h - Generic Frontend Action Interface ----*- 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::FrontendAction interface and various convenience
-/// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
-/// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
-/// derived from it.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
-#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
-
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/FrontendOptions.h"
-#include "llvm/ADT/StringRef.h"
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace clang {
-class ASTMergeAction;
-class CompilerInstance;
-
-/// Abstract base class for actions which can be performed by the frontend.
-class FrontendAction {
- FrontendInputFile CurrentInput;
- std::unique_ptr<ASTUnit> CurrentASTUnit;
- CompilerInstance *Instance;
- friend class ASTMergeAction;
- friend class WrapperFrontendAction;
-
-private:
- std::unique_ptr<ASTConsumer> CreateWrappedASTConsumer(CompilerInstance &CI,
- StringRef InFile);
-
-protected:
- /// @name Implementation Action Interface
- /// @{
-
- /// \brief 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
- /// action has indicated that it only uses the preprocessor.
- ///
- /// \param CI - The current compiler instance, provided as a convenience, see
- /// getCompilerInstance().
- ///
- /// \param InFile - The current input file, provided as a convenience, see
- /// getCurrentFile().
- ///
- /// \return The new AST consumer, or null on failure.
- virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) = 0;
-
- /// \brief Callback before starting processing a single input, giving the
- /// opportunity to modify the CompilerInvocation or do some other action
- /// before BeginSourceFileAction is called.
- ///
- /// \return True on success; on failure BeginSourceFileAction(),
- /// ExecuteAction() and EndSourceFileAction() will not be called.
- virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
-
- /// \brief Callback at the start of processing a single input.
- ///
- /// \return True on success; on failure ExecutionAction() and
- /// EndSourceFileAction() will not be called.
- virtual bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename) {
- return true;
- }
-
- /// \brief 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.
- ///
- /// 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
- /// if the output files should be erased or not.
- ///
- /// By default it returns true if a compiler error occurred.
- /// This is guaranteed to only be called following a successful call to
- /// BeginSourceFileAction (and BeginSourceFile).
- virtual bool shouldEraseOutputFiles();
-
- /// @}
-
-public:
- FrontendAction();
- virtual ~FrontendAction();
-
- /// @name Compiler Instance Access
- /// @{
-
- CompilerInstance &getCompilerInstance() const {
- assert(Instance && "Compiler instance not registered!");
- return *Instance;
- }
-
- void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
-
- /// @}
- /// @name Current File Information
- /// @{
-
- bool isCurrentFileAST() const {
- assert(!CurrentInput.isEmpty() && "No current file!");
- return (bool)CurrentASTUnit;
- }
-
- const FrontendInputFile &getCurrentInput() const {
- return CurrentInput;
- }
-
- const StringRef getCurrentFile() const {
- assert(!CurrentInput.isEmpty() && "No current file!");
- return CurrentInput.getFile();
- }
-
- InputKind getCurrentFileKind() const {
- assert(!CurrentInput.isEmpty() && "No current file!");
- return CurrentInput.getKind();
- }
-
- ASTUnit &getCurrentASTUnit() const {
- assert(CurrentASTUnit && "No current AST unit!");
- return *CurrentASTUnit;
- }
-
- std::unique_ptr<ASTUnit> takeCurrentASTUnit() {
- return std::move(CurrentASTUnit);
- }
-
- void setCurrentInput(const FrontendInputFile &CurrentInput,
- std::unique_ptr<ASTUnit> AST = nullptr);
-
- /// @}
- /// @name Supported Modes
- /// @{
-
- /// \brief 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?
- ///
- /// 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.
- virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
-
- /// \brief Does this action support use with PCH?
- virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
-
- /// \brief Does this action support use with AST files?
- virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
-
- /// \brief Does this action support use with IR files?
- virtual bool hasIRSupport() const { return false; }
-
- /// \brief 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.
- ///
- /// This is run after the options and frontend have been initialized,
- /// but prior to executing any per-file processing.
- ///
- /// \param CI - The compiler instance this action is being run from. The
- /// action may store and use this object up until the matching EndSourceFile
- /// action.
- ///
- /// \param Input - The input filename and kind. Some input kinds are handled
- /// specially, for example AST inputs, since the AST file itself contains
- /// several objects which would normally be owned by the
- /// CompilerInstance. When processing AST input files, these objects should
- /// generally not be initialized in the CompilerInstance -- they will
- /// automatically be shared with the AST file in between
- /// BeginSourceFile() and EndSourceFile().
- ///
- /// \return True on success; on failure the compilation of this file should
- /// 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.
- bool Execute();
-
- /// \brief 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.
-class ASTFrontendAction : public FrontendAction {
-protected:
- /// \brief 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
- /// the user requested it and the action supports it.
- void ExecuteAction() override;
-
-public:
- ASTFrontendAction() {}
- bool usesPreprocessorOnly() const override { return false; }
-};
-
-class PluginASTAction : public ASTFrontendAction {
- virtual void anchor();
-public:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override = 0;
-
- /// \brief 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
- /// destroyed and no action run. The plugin is responsible for using the
- /// CompilerInstance's Diagnostic object to report errors.
- virtual bool ParseArgs(const CompilerInstance &CI,
- const std::vector<std::string> &arg) = 0;
-};
-
-/// \brief Abstract base class to use for preprocessor-based frontend actions.
-class PreprocessorFrontendAction : public FrontendAction {
-protected:
- /// \brief 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;
-
-public:
- bool usesPreprocessorOnly() const override { return true; }
-};
-
-/// \brief A frontend action which simply wraps some other runtime-specified
-/// frontend action.
-///
-/// Deriving from this class allows an action to inject custom logic around
-/// some existing action's behavior. It implements every virtual method in
-/// the FrontendAction interface by forwarding to the wrapped action.
-class WrapperFrontendAction : public FrontendAction {
- std::unique_ptr<FrontendAction> WrappedAction;
-
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
- bool BeginInvocation(CompilerInstance &CI) override;
- bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
- void ExecuteAction() override;
- void EndSourceFileAction() override;
-
-public:
- /// Construct a WrapperFrontendAction from an existing action, taking
- /// ownership of it.
- WrapperFrontendAction(FrontendAction *WrappedAction);
-
- bool usesPreprocessorOnly() const override;
- TranslationUnitKind getTranslationUnitKind() override;
- bool hasPCHSupport() const override;
- bool hasASTFileSupport() const override;
- bool hasIRSupport() const override;
- bool hasCodeCompletionSupport() const override;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
deleted file mode 100644
index f61775f..0000000
--- a/include/clang/Frontend/FrontendActions.h
+++ /dev/null
@@ -1,241 +0,0 @@
-//===-- FrontendActions.h - Useful Frontend Actions -------------*- 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_FRONTEND_FRONTENDACTIONS_H
-#define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
-
-#include "clang/Frontend/FrontendAction.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-
-class Module;
-class FileEntry;
-
-//===----------------------------------------------------------------------===//
-// Custom Consumer Actions
-//===----------------------------------------------------------------------===//
-
-class InitOnlyAction : public FrontendAction {
- void ExecuteAction() override;
-
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
-public:
- // Don't claim to only use the preprocessor, we want to follow the AST path,
- // but do nothing.
- bool usesPreprocessorOnly() const override { return false; }
-};
-
-//===----------------------------------------------------------------------===//
-// AST Consumer Actions
-//===----------------------------------------------------------------------===//
-
-class ASTPrintAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-class ASTDumpAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-class ASTDeclListAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-class ASTViewAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-class DeclContextPrintAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-class GeneratePCHAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
- TranslationUnitKind getTranslationUnitKind() override {
- return TU_Prefix;
- }
-
- bool hasASTFileSupport() const override { return false; }
-
-public:
- /// \brief Compute the AST consumer arguments that will be used to
- /// create the PCHGenerator instance returned by CreateASTConsumer.
- ///
- /// \returns true if an error occurred, false otherwise.
- static raw_pwrite_stream *
- ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
- std::string &Sysroot, std::string &OutputFile);
-};
-
-class GenerateModuleAction : public ASTFrontendAction {
- clang::Module *Module;
- const FileEntry *ModuleMapForUniquing;
- bool IsSystem;
-
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
- TranslationUnitKind getTranslationUnitKind() override {
- return TU_Module;
- }
-
- bool hasASTFileSupport() const override { return false; }
-
-public:
- GenerateModuleAction(const FileEntry *ModuleMap = nullptr,
- bool IsSystem = false)
- : ASTFrontendAction(), ModuleMapForUniquing(ModuleMap), IsSystem(IsSystem)
- { }
-
- bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
-
- /// \brief Compute the AST consumer arguments that will be used to
- /// create the PCHGenerator instance returned by CreateASTConsumer.
- ///
- /// \returns true if an error occurred, false otherwise.
- raw_pwrite_stream *ComputeASTConsumerArguments(CompilerInstance &CI,
- StringRef InFile,
- std::string &Sysroot,
- std::string &OutputFile);
-};
-
-class SyntaxOnlyAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
-public:
- bool hasCodeCompletionSupport() const override { return true; }
-};
-
-/// \brief Dump information about the given module file, to be used for
-/// basic debugging and discovery.
-class DumpModuleInfoAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
- void ExecuteAction() override;
-
-public:
- bool hasPCHSupport() const override { return false; }
- bool hasASTFileSupport() const override { return true; }
- bool hasIRSupport() const override { return false; }
- bool hasCodeCompletionSupport() const override { return false; }
-};
-
-class VerifyPCHAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
- void ExecuteAction() override;
-
-public:
- bool hasCodeCompletionSupport() const override { return false; }
-};
-
-/**
- * \brief 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
- * adaptor, which forwards most of its calls to another action that
- * will consume the merged context.
- */
-class ASTMergeAction : public FrontendAction {
- /// \brief The action that the merge action adapts.
- FrontendAction *AdaptedAction;
-
- /// \brief The set of AST files to merge.
- std::vector<std::string> ASTFiles;
-
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
- bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename) override;
-
- void ExecuteAction() override;
- void EndSourceFileAction() override;
-
-public:
- ASTMergeAction(FrontendAction *AdaptedAction, ArrayRef<std::string> ASTFiles);
- ~ASTMergeAction() override;
-
- bool usesPreprocessorOnly() const override;
- TranslationUnitKind getTranslationUnitKind() override;
- bool hasPCHSupport() const override;
- bool hasASTFileSupport() const override;
- bool hasCodeCompletionSupport() const override;
-};
-
-class PrintPreambleAction : public FrontendAction {
-protected:
- void ExecuteAction() override;
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &,
- StringRef) override {
- return nullptr;
- }
-
- bool usesPreprocessorOnly() const override { return true; }
-};
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Actions
-//===----------------------------------------------------------------------===//
-
-class DumpRawTokensAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-};
-
-class DumpTokensAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-};
-
-class GeneratePTHAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-};
-
-class PreprocessOnlyAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-};
-
-class PrintPreprocessedAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-
- bool hasPCHSupport() const override { return true; }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h
deleted file mode 100644
index 0f37b7e..0000000
--- a/include/clang/Frontend/FrontendDiagnostic.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- 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_FRONTEND_FRONTENDDIAGNOSTIC_H
-#define LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define FRONTENDSTART
-#include "clang/Basic/DiagnosticFrontendKinds.inc"
-#undef DIAG
- NUM_BUILTIN_FRONTEND_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
deleted file mode 100644
index c800a51..0000000
--- a/include/clang/Frontend/FrontendOptions.h
+++ /dev/null
@@ -1,292 +0,0 @@
-//===--- FrontendOptions.h --------------------------------------*- 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_FRONTEND_FRONTENDOPTIONS_H
-#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
-
-#include "clang/Frontend/CommandLineSourceLoc.h"
-#include "clang/Serialization/ModuleFileExtension.h"
-#include "clang/Sema/CodeCompleteOptions.h"
-#include "llvm/ADT/StringRef.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-class MemoryBuffer;
-}
-
-namespace clang {
-
-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.
- 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 InputKind {
- IK_None,
- IK_Asm,
- IK_C,
- IK_CXX,
- IK_ObjC,
- IK_ObjCXX,
- IK_PreprocessedC,
- IK_PreprocessedCXX,
- IK_PreprocessedObjC,
- IK_PreprocessedObjCXX,
- IK_OpenCL,
- IK_CUDA,
- IK_PreprocessedCuda,
- IK_AST,
- IK_LLVM_IR
-};
-
-
-/// \brief An input file for the front end.
-class FrontendInputFile {
- /// \brief The file name, or "-" to read from standard input.
- std::string File;
-
- llvm::MemoryBuffer *Buffer;
-
- /// \brief 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).
- bool IsSystem;
-
-public:
- FrontendInputFile() : Buffer(nullptr), Kind(IK_None), IsSystem(false) { }
- FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
- : File(File.str()), Buffer(nullptr), Kind(Kind), IsSystem(IsSystem) { }
- FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind,
- bool IsSystem = false)
- : Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { }
-
- InputKind getKind() const { return Kind; }
- bool isSystem() const { return IsSystem; }
-
- bool isEmpty() const { return File.empty() && Buffer == nullptr; }
- bool isFile() const { return !isBuffer(); }
- bool isBuffer() const { return Buffer != nullptr; }
-
- StringRef getFile() const {
- assert(isFile());
- return File;
- }
- llvm::MemoryBuffer *getBuffer() const {
- assert(isBuffer());
- return Buffer;
- }
-};
-
-/// 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 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.
-
- CodeCompleteOptions CodeCompleteOpts;
-
- enum {
- ARCMT_None,
- ARCMT_Check,
- ARCMT_Modify,
- ARCMT_Migrate
- } ARCMTAction;
-
- enum {
- ObjCMT_None = 0,
- /// \brief Enable migration to modern ObjC literals.
- ObjCMT_Literals = 0x1,
- /// \brief Enable migration to modern ObjC subscripting.
- ObjCMT_Subscripting = 0x2,
- /// \brief Enable migration to modern ObjC readonly property.
- ObjCMT_ReadonlyProperty = 0x4,
- /// \brief Enable migration to modern ObjC readwrite property.
- ObjCMT_ReadwriteProperty = 0x8,
- /// \brief Enable migration to modern ObjC property.
- ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty),
- /// \brief Enable annotation of ObjCMethods of all kinds.
- ObjCMT_Annotation = 0x10,
- /// \brief Enable migration of ObjC methods to 'instancetype'.
- ObjCMT_Instancetype = 0x20,
- /// \brief Enable migration to NS_ENUM/NS_OPTIONS macros.
- ObjCMT_NsMacros = 0x40,
- /// \brief Enable migration to add conforming protocols.
- ObjCMT_ProtocolConformance = 0x80,
- /// \brief prefer 'atomic' property over 'nonatomic'.
- ObjCMT_AtomicProperty = 0x100,
- /// \brief annotate property with NS_RETURNS_INNER_POINTER
- ObjCMT_ReturnsInnerPointerProperty = 0x200,
- /// \brief use NS_NONATOMIC_IOSONLY for property 'atomic' attribute
- ObjCMT_NsAtomicIOSOnlyProperty = 0x400,
- /// \brief Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
- ObjCMT_DesignatedInitializer = 0x800,
- /// \brief 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 |
- ObjCMT_NsAtomicIOSOnlyProperty |
- ObjCMT_DesignatedInitializer),
- ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting |
- ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax)
- };
- unsigned ObjCMTAction;
- std::string ObjCMTWhiteListPath;
-
- std::string MTMigrateDir;
- std::string ARCMTMigrateReportOut;
-
- /// The input files and their types.
- std::vector<FrontendInputFile> Inputs;
-
- /// The output file, if any.
- std::string OutputFile;
-
- /// If given, the new suffix for fix-it rewritten files.
- std::string FixItSuffix;
-
- /// If given, filter dumped AST Decl nodes by this substring.
- std::string ASTDumpFilter;
-
- /// If given, enable code completion at the provided location.
- ParsedSourceLocation CodeCompletionAt;
-
- /// The frontend action to perform.
- frontend::ActionKind ProgramAction;
-
- /// The name of the action to run when using a plugin action.
- std::string ActionName;
-
- /// Args to pass to the plugin
- std::vector<std::string> PluginArgs;
-
- /// The list of plugin actions to run in addition to the normal action.
- std::vector<std::string> AddPluginActions;
-
- /// Args to pass to the additional plugins
- std::vector<std::vector<std::string> > AddPluginArgs;
-
- /// The list of plugins to load.
- std::vector<std::string> Plugins;
-
- /// The list of module file extensions.
- std::vector<IntrusiveRefCntPtr<ModuleFileExtension>> ModuleFileExtensions;
-
- /// \brief 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
- /// processing the input.
- std::vector<std::string> ModuleFiles;
-
- /// \brief The list of files to embed into the compiled module file.
- std::vector<std::string> ModulesEmbedFiles;
-
- /// \brief 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
- /// 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
- /// (in the format produced by -fdump-record-layouts).
- std::string OverrideRecordLayoutsFile;
-
- /// \brief Auxiliary triple for CUDA compilation.
- std::string AuxTriple;
-
-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),
- ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None),
- ProgramAction(frontend::ParseSyntaxOnly)
- {}
-
- /// getInputKindForExtension - Return the appropriate input kind for a file
- /// extension. For example, "c" would return IK_C.
- ///
- /// \return The input kind for the extension, or IK_None if the extension is
- /// not recognized.
- static InputKind getInputKindForExtension(StringRef Extension);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
deleted file mode 100644
index ecab630..0000000
--- a/include/clang/Frontend/FrontendPluginRegistry.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- 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_FRONTEND_FRONTENDPLUGINREGISTRY_H
-#define LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
-
-#include "clang/Frontend/FrontendAction.h"
-#include "llvm/Support/Registry.h"
-
-// Instantiated in FrontendAction.cpp.
-extern template class llvm::Registry<clang::PluginASTAction>;
-
-namespace clang {
-
-/// The frontend plugin registry.
-typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry;
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
deleted file mode 100644
index 8021d08..0000000
--- a/include/clang/Frontend/LangStandard.h
+++ /dev/null
@@ -1,100 +0,0 @@
-//===--- LangStandard.h -----------------------------------------*- 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_FRONTEND_LANGSTANDARD_H
-#define LLVM_CLANG_FRONTEND_LANGSTANDARD_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-
-namespace frontend {
-
-enum LangFeatures {
- LineComment = (1 << 0),
- C89 = (1 << 1),
- C99 = (1 << 2),
- C11 = (1 << 3),
- CPlusPlus = (1 << 4),
- CPlusPlus11 = (1 << 5),
- CPlusPlus14 = (1 << 6),
- CPlusPlus1z = (1 << 7),
- Digraphs = (1 << 8),
- GNUMode = (1 << 9),
- HexFloat = (1 << 10),
- ImplicitInt = (1 << 11)
-};
-
-}
-
-/// LangStandard - Information about the properties of a particular language
-/// standard.
-struct LangStandard {
- enum Kind {
-#define LANGSTANDARD(id, name, desc, features) \
- lang_##id,
-#include "clang/Frontend/LangStandards.def"
- lang_unspecified
- };
-
- const char *ShortName;
- const char *Description;
- unsigned Flags;
-
-public:
- /// getName - Get the name of this standard.
- const char *getName() const { return ShortName; }
-
- /// getDescription - Get the description of this standard.
- const char *getDescription() const { return Description; }
-
- /// Language supports '//' comments.
- bool hasLineComments() const { return Flags & frontend::LineComment; }
-
- /// isC89 - Language is a superset of C89.
- bool isC89() const { return Flags & frontend::C89; }
-
- /// isC99 - Language is a superset of C99.
- bool isC99() const { return Flags & frontend::C99; }
-
- /// isC11 - Language is a superset of C11.
- bool isC11() const { return Flags & frontend::C11; }
-
- /// isCPlusPlus - Language is a C++ variant.
- bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
-
- /// isCPlusPlus11 - Language is a C++11 variant (or later).
- bool isCPlusPlus11() const { return Flags & frontend::CPlusPlus11; }
-
- /// isCPlusPlus14 - Language is a C++14 variant (or later).
- bool isCPlusPlus14() const { return Flags & frontend::CPlusPlus14; }
-
- /// isCPlusPlus1z - Language is a C++17 variant (or later).
- bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; }
-
- /// hasDigraphs - Language supports digraphs.
- bool hasDigraphs() const { return Flags & frontend::Digraphs; }
-
- /// isGNUMode - Language includes GNU extensions.
- bool isGNUMode() const { return Flags & frontend::GNUMode; }
-
- /// hasHexFloats - Language supports hexadecimal float constants.
- bool hasHexFloats() const { return Flags & frontend::HexFloat; }
-
- /// hasImplicitInt - Language allows variables to be typed as int implicitly.
- bool hasImplicitInt() const { return Flags & frontend::ImplicitInt; }
-
- static const LangStandard &getLangStandardForKind(Kind K);
- static const LangStandard *getLangStandardForName(StringRef Name);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
deleted file mode 100644
index cac9c3c..0000000
--- a/include/clang/Frontend/LangStandards.def
+++ /dev/null
@@ -1,153 +0,0 @@
-//===-- LangStandards.def - Language Standard Data --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LANGSTANDARD
-#error "LANGSTANDARD must be defined before including this file"
-#endif
-
-/// LANGSTANDARD(IDENT, NAME, DESC, FEATURES)
-///
-/// \param IDENT - The name of the standard as a C++ identifier.
-/// \param NAME - The name of the standard.
-/// \param DESC - A short description of the standard.
-/// \param FEATURES - The standard features as flags, these are enums from the
-/// clang::frontend namespace, which is assumed to be be available.
-
-// C89-ish modes.
-LANGSTANDARD(c89, "c89",
- "ISO C 1990",
- C89 | ImplicitInt)
-LANGSTANDARD(c90, "c90",
- "ISO C 1990",
- C89 | ImplicitInt)
-LANGSTANDARD(iso9899_1990, "iso9899:1990",
- "ISO C 1990",
- C89 | ImplicitInt)
-
-LANGSTANDARD(c94, "iso9899:199409",
- "ISO C 1990 with amendment 1",
- C89 | Digraphs | ImplicitInt)
-
-LANGSTANDARD(gnu89, "gnu89",
- "ISO C 1990 with GNU extensions",
- LineComment | C89 | Digraphs | GNUMode | ImplicitInt)
-LANGSTANDARD(gnu90, "gnu90",
- "ISO C 1990 with GNU extensions",
- LineComment | C89 | Digraphs | GNUMode | ImplicitInt)
-
-// C99-ish modes
-LANGSTANDARD(c99, "c99",
- "ISO C 1999",
- LineComment | C99 | Digraphs | HexFloat)
-LANGSTANDARD(c9x, "c9x",
- "ISO C 1999",
- LineComment | C99 | Digraphs | HexFloat)
-LANGSTANDARD(iso9899_1999,
- "iso9899:1999", "ISO C 1999",
- LineComment | C99 | Digraphs | HexFloat)
-LANGSTANDARD(iso9899_199x,
- "iso9899:199x", "ISO C 1999",
- LineComment | C99 | Digraphs | HexFloat)
-
-LANGSTANDARD(gnu99, "gnu99",
- "ISO C 1999 with GNU extensions",
- LineComment | C99 | Digraphs | GNUMode | HexFloat)
-LANGSTANDARD(gnu9x, "gnu9x",
- "ISO C 1999 with GNU extensions",
- LineComment | C99 | Digraphs | GNUMode | HexFloat)
-
-// C11 modes
-LANGSTANDARD(c11, "c11",
- "ISO C 2011",
- LineComment | C99 | C11 | Digraphs | HexFloat)
-LANGSTANDARD(c1x, "c1x",
- "ISO C 2011",
- LineComment | C99 | C11 | Digraphs | HexFloat)
-LANGSTANDARD(iso9899_2011,
- "iso9899:2011", "ISO C 2011",
- LineComment | C99 | C11 | Digraphs | HexFloat)
-LANGSTANDARD(iso9899_201x,
- "iso9899:2011", "ISO C 2011",
- LineComment | C99 | C11 | Digraphs | HexFloat)
-
-LANGSTANDARD(gnu11, "gnu11",
- "ISO C 2011 with GNU extensions",
- LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat)
-LANGSTANDARD(gnu1x, "gnu1x",
- "ISO C 2011 with GNU extensions",
- LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat)
-
-// C++ modes
-LANGSTANDARD(cxx98, "c++98",
- "ISO C++ 1998 with amendments",
- LineComment | CPlusPlus | Digraphs)
-LANGSTANDARD(cxx03, "c++03",
- "ISO C++ 1998 with amendments",
- LineComment | CPlusPlus | Digraphs)
-LANGSTANDARD(gnucxx98, "gnu++98",
- "ISO C++ 1998 with amendments and GNU extensions",
- LineComment | CPlusPlus | Digraphs | GNUMode)
-
-LANGSTANDARD(cxx0x, "c++0x",
- "ISO C++ 2011 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | Digraphs)
-LANGSTANDARD(cxx11, "c++11",
- "ISO C++ 2011 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | Digraphs)
-LANGSTANDARD(gnucxx0x, "gnu++0x",
- "ISO C++ 2011 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
-LANGSTANDARD(gnucxx11, "gnu++11",
- "ISO C++ 2011 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
-
-LANGSTANDARD(cxx1y, "c++1y",
- "ISO C++ 2014 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
-LANGSTANDARD(cxx14, "c++14",
- "ISO C++ 2014 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
-LANGSTANDARD(gnucxx1y, "gnu++1y",
- "ISO C++ 2014 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs |
- GNUMode)
-LANGSTANDARD(gnucxx14, "gnu++14",
- "ISO C++ 2014 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs |
- GNUMode)
-
-LANGSTANDARD(cxx1z, "c++1z",
- "Working draft for ISO C++ 2017",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
- Digraphs)
-LANGSTANDARD(gnucxx1z, "gnu++1z",
- "Working draft for ISO C++ 2017 with GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
- Digraphs | GNUMode)
-
-// OpenCL
-LANGSTANDARD(opencl, "cl",
- "OpenCL 1.0",
- LineComment | C99 | Digraphs | HexFloat)
-LANGSTANDARD(opencl11, "CL1.1",
- "OpenCL 1.1",
- LineComment | C99 | Digraphs | HexFloat)
-LANGSTANDARD(opencl12, "CL1.2",
- "OpenCL 1.2",
- LineComment | C99 | Digraphs | HexFloat)
-LANGSTANDARD(opencl20, "CL2.0",
- "OpenCL 2.0",
- LineComment | C99 | Digraphs | HexFloat)
-
-// CUDA
-LANGSTANDARD(cuda, "cuda",
- "NVIDIA CUDA(tm)",
- LineComment | CPlusPlus | Digraphs)
-
-#undef LANGSTANDARD
diff --git a/include/clang/Frontend/LayoutOverrideSource.h b/include/clang/Frontend/LayoutOverrideSource.h
deleted file mode 100644
index 16d032b..0000000
--- a/include/clang/Frontend/LayoutOverrideSource.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===--- LayoutOverrideSource.h --Override Record Layouts -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H
-#define LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H
-
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
- /// \brief 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.
- struct Layout {
- /// \brief The size of the record.
- uint64_t Size;
-
- /// \brief The alignment of the record.
- uint64_t Align;
-
- /// \brief The offsets of the fields, in source order.
- SmallVector<uint64_t, 8> FieldOffsets;
- };
-
- /// \brief 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
- /// 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,
- /// return that layout.
- bool
- layoutRecordType(const RecordDecl *Record,
- uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
- llvm::DenseMap<const CXXRecordDecl *,
- CharUnits> &VirtualBaseOffsets) override;
-
- /// \brief Dump the overridden layouts.
- void dump();
- };
-}
-
-#endif
diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h
deleted file mode 100644
index 98adf65..0000000
--- a/include/clang/Frontend/LogDiagnosticPrinter.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//===--- LogDiagnosticPrinter.h - Log Diagnostic Client ---------*- 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_FRONTEND_LOGDIAGNOSTICPRINTER_H
-#define LLVM_CLANG_FRONTEND_LOGDIAGNOSTICPRINTER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-class DiagnosticOptions;
-class LangOptions;
-
-class LogDiagnosticPrinter : public DiagnosticConsumer {
- struct DiagEntry {
- /// The primary message line of the diagnostic.
- std::string Message;
-
- /// The source file name, if available.
- std::string Filename;
-
- /// The source file line number, if available.
- unsigned Line;
-
- /// The source file column number, if available.
- unsigned Column;
-
- /// The ID of the diagnostic.
- unsigned DiagnosticID;
-
- /// The Option Flag for the diagnostic
- std::string WarningOption;
-
- /// The level of the diagnostic.
- DiagnosticsEngine::Level DiagnosticLevel;
- };
-
- void EmitDiagEntry(llvm::raw_ostream &OS,
- const LogDiagnosticPrinter::DiagEntry &DE);
-
- // Conditional ownership (when StreamOwner is non-null, it's keeping OS
- // alive). We might want to replace this with a wrapper for conditional
- // ownership eventually - it seems to pop up often enough.
- raw_ostream &OS;
- std::unique_ptr<raw_ostream> StreamOwner;
- const LangOptions *LangOpts;
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
-
- SourceLocation LastWarningLoc;
- FullSourceLoc LastLoc;
-
- SmallVector<DiagEntry, 8> Entries;
-
- std::string MainFilename;
- std::string DwarfDebugFlags;
-
-public:
- LogDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions *Diags,
- std::unique_ptr<raw_ostream> StreamOwner);
-
- void setDwarfDebugFlags(StringRef Value) {
- DwarfDebugFlags = Value;
- }
-
- void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override {
- LangOpts = &LO;
- }
-
- void EndSourceFile() override;
-
- void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) override;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/MigratorOptions.h b/include/clang/Frontend/MigratorOptions.h
deleted file mode 100644
index 8eb71b1..0000000
--- a/include/clang/Frontend/MigratorOptions.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===--- MigratorOptions.h - MigratorOptions Options ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header contains the structures necessary for a front-end to specify
-// various migration analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_MIGRATOROPTIONS_H
-#define LLVM_CLANG_FRONTEND_MIGRATOROPTIONS_H
-
-namespace clang {
-
-class MigratorOptions {
-public:
- unsigned NoNSAllocReallocError : 1;
- unsigned NoFinalizeRemoval : 1;
- MigratorOptions() {
- NoNSAllocReallocError = 0;
- NoFinalizeRemoval = 0;
- }
-};
-
-}
-#endif
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
deleted file mode 100644
index 873af03..0000000
--- a/include/clang/Frontend/MultiplexConsumer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===-- MultiplexConsumer.h - AST Consumer for PCH Generation ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the MultiplexConsumer class, which can be used to
-// multiplex ASTConsumer and SemaConsumer messages to many consumers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_MULTIPLEXCONSUMER_H
-#define LLVM_CLANG_FRONTEND_MULTIPLEXCONSUMER_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Sema/SemaConsumer.h"
-#include <memory>
-#include <vector>
-
-namespace clang {
-
-class MultiplexASTMutationListener;
-class MultiplexASTDeserializationListener;
-
-// Has a list of ASTConsumers and calls each of them. Owns its children.
-class MultiplexConsumer : public SemaConsumer {
-public:
- // Takes ownership of the pointers in C.
- MultiplexConsumer(std::vector<std::unique_ptr<ASTConsumer>> C);
- ~MultiplexConsumer() override;
-
- // ASTConsumer
- void Initialize(ASTContext &Context) override;
- void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override;
- bool HandleTopLevelDecl(DeclGroupRef D) override;
- void HandleInlineMethodDefinition(CXXMethodDecl *D) override;
- void HandleInterestingDecl(DeclGroupRef D) override;
- void HandleTranslationUnit(ASTContext &Ctx) override;
- void HandleTagDeclDefinition(TagDecl *D) override;
- void HandleTagDeclRequiredDefinition(const TagDecl *D) override;
- void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override;
- void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
- void HandleImplicitImportDecl(ImportDecl *D) override;
- void HandleLinkerOptionPragma(llvm::StringRef Opts) override;
- void HandleDetectMismatch(llvm::StringRef Name,
- llvm::StringRef Value) override;
- void HandleDependentLibrary(llvm::StringRef Lib) override;
- void CompleteTentativeDefinition(VarDecl *D) override;
- void HandleVTable(CXXRecordDecl *RD) override;
- ASTMutationListener *GetASTMutationListener() override;
- ASTDeserializationListener *GetASTDeserializationListener() override;
- void PrintStats() override;
-
- // SemaConsumer
- void InitializeSema(Sema &S) override;
- void ForgetSema() override;
-
-private:
- std::vector<std::unique_ptr<ASTConsumer>> Consumers; // Owns these.
- std::unique_ptr<MultiplexASTMutationListener> MutationListener;
- std::unique_ptr<MultiplexASTDeserializationListener> DeserializationListener;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h
deleted file mode 100644
index 67c36cf..0000000
--- a/include/clang/Frontend/PCHContainerOperations.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//===--- Frontend/PCHContainerOperations.h - PCH Containers -----*- 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_PCH_CONTAINER_OPERATIONS_H
-#define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <memory>
-
-namespace llvm {
-class raw_pwrite_stream;
-class BitstreamReader;
-}
-
-using llvm::StringRef;
-
-namespace clang {
-
-class ASTConsumer;
-class CodeGenOptions;
-class DiagnosticsEngine;
-class CompilerInstance;
-
-struct PCHBuffer {
- uint64_t Signature;
- llvm::SmallVector<char, 0> Data;
- bool IsComplete;
-};
-
-/// This abstract interface provides operations for creating
-/// containers for serialized ASTs (precompiled headers and clang
-/// modules).
-class PCHContainerWriter {
-public:
- virtual ~PCHContainerWriter() = 0;
- virtual StringRef getFormat() const = 0;
-
- /// Return an ASTConsumer that can be chained with a
- /// PCHGenerator that produces a wrapper file format containing a
- /// serialized AST bitstream.
- virtual std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator(
- CompilerInstance &CI, const std::string &MainFileName,
- const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
- std::shared_ptr<PCHBuffer> Buffer) const = 0;
-};
-
-/// This abstract interface provides operations for unwrapping
-/// containers for serialized ASTs (precompiled headers and clang
-/// modules).
-class PCHContainerReader {
-public:
- virtual ~PCHContainerReader() = 0;
- /// Equivalent to the format passed to -fmodule-format=
- virtual StringRef getFormat() const = 0;
-
- /// Initialize an llvm::BitstreamReader with the serialized AST inside
- /// the PCH container Buffer.
- virtual void ExtractPCH(llvm::MemoryBufferRef Buffer,
- llvm::BitstreamReader &StreamFile) const = 0;
-};
-
-/// Implements write operations for a raw pass-through PCH container.
-class RawPCHContainerWriter : public PCHContainerWriter {
- StringRef getFormat() const override { return "raw"; }
-
- /// Return an ASTConsumer that can be chained with a
- /// PCHGenerator that writes the module to a flat file.
- std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator(
- CompilerInstance &CI, const std::string &MainFileName,
- const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
- std::shared_ptr<PCHBuffer> Buffer) const override;
-};
-
-/// Implements read operations for a raw pass-through PCH container.
-class RawPCHContainerReader : public PCHContainerReader {
- StringRef getFormat() const override { return "raw"; }
-
- /// Initialize an llvm::BitstreamReader with Buffer.
- void ExtractPCH(llvm::MemoryBufferRef Buffer,
- llvm::BitstreamReader &StreamFile) const override;
-};
-
-/// A registry of PCHContainerWriter and -Reader objects for different formats.
-class PCHContainerOperations {
- llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers;
- llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers;
-public:
- /// Automatically registers a RawPCHContainerWriter and
- /// RawPCHContainerReader.
- PCHContainerOperations();
- void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) {
- Writers[Writer->getFormat()] = std::move(Writer);
- }
- void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
- Readers[Reader->getFormat()] = std::move(Reader);
- }
- const PCHContainerWriter *getWriterOrNull(StringRef Format) {
- return Writers[Format].get();
- }
- const PCHContainerReader *getReaderOrNull(StringRef Format) {
- return Readers[Format].get();
- }
- const PCHContainerReader &getRawReader() {
- return *getReaderOrNull("raw");
- }
-};
-
-}
-
-#endif
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
deleted file mode 100644
index f86c490..0000000
--- a/include/clang/Frontend/PreprocessorOutputOptions.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//===--- PreprocessorOutputOptions.h ----------------------------*- 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_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
-#define LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
-
-namespace clang {
-
-/// PreprocessorOutputOptions - Options for controlling the C preprocessor
-/// output (e.g., -E).
-class PreprocessorOutputOptions {
-public:
- unsigned ShowCPP : 1; ///< Print normal preprocessed output.
- unsigned ShowComments : 1; ///< Show comments.
- unsigned ShowLineMarkers : 1; ///< Show \#line markers.
- unsigned UseLineDirectives : 1; ///< Use \#line instead of GCC-style \# N.
- unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
- unsigned ShowMacros : 1; ///< Print macro definitions.
- unsigned RewriteIncludes : 1; ///< Preprocess include directives only.
-
-public:
- PreprocessorOutputOptions() {
- ShowCPP = 0;
- ShowComments = 0;
- ShowLineMarkers = 1;
- UseLineDirectives = 0;
- ShowMacroComments = 0;
- ShowMacros = 0;
- RewriteIncludes = 0;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h
deleted file mode 100644
index 4c57e9d..0000000
--- a/include/clang/Frontend/SerializedDiagnosticPrinter.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===--- SerializedDiagnosticPrinter.h - Serializer for diagnostics -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICPRINTER_H
-#define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICPRINTER_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Frontend/SerializedDiagnostics.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
-
-namespace llvm {
-class raw_ostream;
-}
-
-namespace clang {
-class DiagnosticConsumer;
-class DiagnosticsEngine;
-class DiagnosticOptions;
-
-namespace serialized_diags {
-
-/// \brief 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).
-/// This allows wrapper tools for Clang to get diagnostics from Clang
-/// (via libclang) without needing to parse Clang's command line output.
-///
-std::unique_ptr<DiagnosticConsumer> create(StringRef OutputFile,
- DiagnosticOptions *Diags,
- bool MergeChildRecords = false);
-
-} // end serialized_diags namespace
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Frontend/SerializedDiagnosticReader.h b/include/clang/Frontend/SerializedDiagnosticReader.h
deleted file mode 100644
index 3db362b..0000000
--- a/include/clang/Frontend/SerializedDiagnosticReader.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//===--- SerializedDiagnosticReader.h - Reads diagnostics -------*- 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_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_
-#define LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/ErrorOr.h"
-
-namespace clang {
-namespace serialized_diags {
-
-enum class SDError {
- CouldNotLoad = 1,
- InvalidSignature,
- InvalidDiagnostics,
- MalformedTopLevelBlock,
- MalformedSubBlock,
- MalformedBlockInfoBlock,
- MalformedMetadataBlock,
- MalformedDiagnosticBlock,
- MalformedDiagnosticRecord,
- MissingVersion,
- VersionMismatch,
- UnsupportedConstruct,
- /// A generic error for subclass handlers that don't want or need to define
- /// their own error_category.
- HandlerFailed
-};
-
-const std::error_category &SDErrorCategory();
-
-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.
-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.
-///
-/// 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() {}
-
- /// \brief 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.
- llvm::ErrorOr<Cursor> skipUntilRecordOrBlock(llvm::BitstreamCursor &Stream,
- unsigned &BlockOrRecordId);
-
- /// \brief Read a metadata block from \c Stream.
- std::error_code readMetaBlock(llvm::BitstreamCursor &Stream);
-
- /// \brief 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.
- virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) {
- return std::error_code();
- }
- /// \brief 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();
- }
- /// \brief Visit a diagnostic.
- virtual std::error_code
- visitDiagnosticRecord(unsigned Severity, const Location &Location,
- unsigned Category, unsigned Flag, StringRef Message) {
- return std::error_code();
- }
- /// \brief 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();
- }
- /// \brief Visit a fixit hint.
- virtual std::error_code
- visitFixitRecord(const Location &Start, const Location &End, StringRef Text) {
- return std::error_code();
- }
- /// \brief 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();
- }
-};
-
-} // end serialized_diags namespace
-} // end clang namespace
-
-namespace std {
-template <>
-struct is_error_code_enum<clang::serialized_diags::SDError> : std::true_type {};
-}
-
-#endif
diff --git a/include/clang/Frontend/SerializedDiagnostics.h b/include/clang/Frontend/SerializedDiagnostics.h
deleted file mode 100644
index 2032cd3..0000000
--- a/include/clang/Frontend/SerializedDiagnostics.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===--- SerializedDiagnostics.h - Common data for serialized diagnostics -===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_
-#define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_
-
-#include "llvm/Bitcode/BitCodes.h"
-
-namespace clang {
-namespace serialized_diags {
-
-enum BlockIDs {
- /// \brief 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
- /// for a specific diagnostic.
- BLOCK_DIAG
-};
-
-enum RecordIDs {
- RECORD_VERSION = 1,
- RECORD_DIAG,
- RECORD_SOURCE_RANGE,
- RECORD_DIAG_FLAG,
- RECORD_CATEGORY,
- RECORD_FILENAME,
- RECORD_FIXIT,
- RECORD_FIRST = RECORD_VERSION,
- RECORD_LAST = RECORD_FIXIT
-};
-
-/// \brief 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.
-enum Level {
- Ignored = 0,
- Note,
- Warning,
- Error,
- Fatal,
- Remark
-};
-
-/// \brief The serialized diagnostics version number.
-enum { VersionNumber = 2 };
-
-} // end serialized_diags namespace
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
deleted file mode 100644
index d41f15a..0000000
--- a/include/clang/Frontend/TextDiagnostic.h
+++ /dev/null
@@ -1,122 +0,0 @@
-//===--- TextDiagnostic.h - Text Diagnostic Pretty-Printing -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a utility class that provides support for textual pretty-printing of
-// diagnostics. It is used to implement the different code paths which require
-// such functionality in a consistent way.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
-#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
-
-#include "clang/Frontend/DiagnosticRenderer.h"
-
-namespace clang {
-
-/// \brief Class to encapsulate the logic for formatting and printing a textual
-/// diagnostic message.
-///
-/// This class provides an interface for building and emitting a textual
-/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
-/// Hints, and code snippets. In the presence of macros this involves
-/// a recursive process, synthesizing notes for each macro expansion.
-///
-/// The purpose of this class is to isolate the implementation of printing
-/// beautiful text diagnostics from any particular interfaces. The Clang
-/// DiagnosticClient is implemented through this class as is diagnostic
-/// printing coming out of libclang.
-class TextDiagnostic : public DiagnosticRenderer {
- raw_ostream &OS;
-
-public:
- TextDiagnostic(raw_ostream &OS,
- const LangOptions &LangOpts,
- DiagnosticOptions *DiagOpts);
-
- ~TextDiagnostic() override;
-
- /// \brief 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
- /// TextDiagnostic emission code, but it can also be used directly by
- /// consumers that don't have a source manager or other state that the full
- /// TextDiagnostic logic requires.
- static void printDiagnosticLevel(raw_ostream &OS,
- DiagnosticsEngine::Level Level,
- bool ShowColors,
- bool CLFallbackMode = false);
-
- /// \brief 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
- /// publicly visible so that clients which do not have sufficient state to
- /// build a complete TextDiagnostic object can still get consistent
- /// formatting of their diagnostic messages.
- ///
- /// \param OS Where the message is printed
- /// \param IsSupplemental true if this is a continuation note diagnostic
- /// \param Message The text actually printed
- /// \param CurrentColumn The starting column of the first line, accounting
- /// for any prefix.
- /// \param Columns The number of columns to use in line-wrapping, 0 disables
- /// all line-wrapping.
- /// \param ShowColors Enable colorizing of the message.
- static void printDiagnosticMessage(raw_ostream &OS, bool IsSupplemental,
- StringRef Message, unsigned CurrentColumn,
- unsigned Columns, bool ShowColors);
-
-protected:
- void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
- DiagnosticsEngine::Level Level,
- StringRef Message,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager *SM,
- DiagOrStoredDiag D) override;
-
- void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
- DiagnosticsEngine::Level Level,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager &SM) override;
-
- void emitCodeContext(SourceLocation Loc,
- DiagnosticsEngine::Level Level,
- SmallVectorImpl<CharSourceRange>& Ranges,
- ArrayRef<FixItHint> Hints,
- const SourceManager &SM) override {
- emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM);
- }
-
- void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
- const SourceManager &SM) override;
-
- void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
- StringRef ModuleName,
- const SourceManager &SM) override;
-
- void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
- StringRef ModuleName,
- const SourceManager &SM) override;
-
-private:
- void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
- SmallVectorImpl<CharSourceRange>& Ranges,
- ArrayRef<FixItHint> Hints,
- const SourceManager &SM);
-
- void emitSnippet(StringRef SourceLine);
-
- void emitParseableFixits(ArrayRef<FixItHint> Hints, const SourceManager &SM);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
deleted file mode 100644
index 3bcf824..0000000
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===--- TextDiagnosticBuffer.h - Buffer Text Diagnostics -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a concrete diagnostic client, which buffers the diagnostic messages.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H
-#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H
-
-#include "clang/Basic/Diagnostic.h"
-#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;
-private:
- DiagList Errors, Warnings, Remarks, Notes;
-public:
- 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 remark_begin() const { return Remarks.begin(); }
- const_iterator remark_end() const { return Remarks.end(); }
-
- const_iterator note_begin() const { return Notes.begin(); }
- const_iterator note_end() const { return Notes.end(); }
-
- void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) override;
-
- /// FlushDiagnostics - Flush the buffered diagnostics to an given
- /// diagnostic engine.
- void FlushDiagnostics(DiagnosticsEngine &Diags) const;
-};
-
-} // end namspace clang
-
-#endif
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
deleted file mode 100644
index 04a5705..0000000
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===--- TextDiagnosticPrinter.h - Text Diagnostic Client -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a concrete diagnostic client, which prints the diagnostics to
-// standard error.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICPRINTER_H
-#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICPRINTER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include <memory>
-
-namespace clang {
-class DiagnosticOptions;
-class LangOptions;
-class TextDiagnostic;
-
-class TextDiagnosticPrinter : public DiagnosticConsumer {
- raw_ostream &OS;
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
-
- /// \brief Handle to the currently active text diagnostic emitter.
- std::unique_ptr<TextDiagnostic> TextDiag;
-
- /// A string to prefix to error messages.
- std::string Prefix;
-
- unsigned OwnsOutputStream : 1;
-
-public:
- TextDiagnosticPrinter(raw_ostream &os, DiagnosticOptions *diags,
- bool OwnsOutputStream = false);
- ~TextDiagnosticPrinter() override;
-
- /// setPrefix - Set the diagnostic printer prefix string, which will be
- /// printed at the start of any diagnostics. If empty, no prefix string is
- /// used.
- void setPrefix(std::string Value) { Prefix = Value; }
-
- void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override;
- void EndSourceFile() override;
- void HandleDiagnostic(DiagnosticsEngine::Level Level,
- const Diagnostic &Info) override;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
deleted file mode 100644
index a5f667e..0000000
--- a/include/clang/Frontend/Utils.h
+++ /dev/null
@@ -1,220 +0,0 @@
-//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header contains miscellaneous utilities for various front-end actions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_UTILS_H
-#define LLVM_CLANG_FRONTEND_UTILS_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/VirtualFileSystem.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/Option/OptSpecifier.h"
-
-namespace llvm {
-class raw_fd_ostream;
-class Triple;
-
-namespace opt {
-class ArgList;
-}
-}
-
-namespace clang {
-class ASTConsumer;
-class ASTReader;
-class CompilerInstance;
-class CompilerInvocation;
-class Decl;
-class DependencyOutputOptions;
-class DiagnosticsEngine;
-class DiagnosticOptions;
-class ExternalSemaSource;
-class FileManager;
-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,
- const HeaderSearchOptions &HSOpts,
- const LangOptions &Lang,
- const llvm::Triple &triple);
-
-/// InitializePreprocessor - Initialize the preprocessor getting it and the
-/// environment ready to process a single file.
-void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
- const PCHContainerReader &PCHContainerRdr,
- const FrontendOptions &FEOpts);
-
-/// DoPrintPreprocessedInput - Implement -E mode.
-void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
- const PreprocessorOutputOptions &Opts);
-
-/// An interface for collecting the dependencies of a compilation. Users should
-/// use \c attachToPreprocessor and \c attachToASTReader to get all of the
-/// dependencies.
-// FIXME: Migrate DependencyFileGen, DependencyGraphGen, ModuleDepCollectory to
-// use this interface.
-class DependencyCollector {
-public:
- void attachToPreprocessor(Preprocessor &PP);
- void attachToASTReader(ASTReader &R);
- llvm::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.
- ///
- /// 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() { }
- /// Return true if system files should be passed to sawDependency().
- virtual bool needSystemDependencies() { return false; }
- virtual ~DependencyCollector();
-
-public: // 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;
-};
-
-/// Builds a depdenency file when attached to a Preprocessor (for includes) and
-/// ASTReader (for module imports), and writes it out at the end of processing
-/// a source file. Users should attach to the ast reader whenever a module is
-/// loaded.
-class DependencyFileGenerator {
- void *Impl; // Opaque implementation
- DependencyFileGenerator(void *Impl);
-public:
- static DependencyFileGenerator *CreateAndAttachToPreprocessor(
- Preprocessor &PP, const DependencyOutputOptions &Opts);
- void AttachToASTReader(ASTReader &R);
-};
-
-/// Collects the dependencies for imported modules into a directory. Users
-/// should attach to the AST reader whenever a module is loaded.
-class ModuleDependencyCollector {
- std::string DestDir;
- bool HasErrors;
- llvm::StringSet<> Seen;
- vfs::YAMLVFSWriter VFSWriter;
-
-public:
- StringRef getDest() { return DestDir; }
- bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; }
- void setHasErrors() { HasErrors = true; }
- void addFileMapping(StringRef VPath, StringRef RPath) {
- VFSWriter.addFileMapping(VPath, RPath);
- }
-
- void attachToASTReader(ASTReader &R);
- void writeFileMap();
- bool hasErrors() { return HasErrors; }
- ModuleDependencyCollector(std::string DestDir)
- : DestDir(DestDir), HasErrors(false) {}
- ~ModuleDependencyCollector() { writeFileMap(); }
-};
-
-/// AttachDependencyGraphGen - Create a dependency graph generator, and attach
-/// it to the given preprocessor.
- void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile,
- StringRef SysRoot);
-
-/// AttachHeaderIncludeGen - Create a header include list generator, and attach
-/// it to the given preprocessor.
-///
-/// \param ExtraHeaders - If not empty, will write the header filenames, just
-/// like they were included during a regular preprocessing. Useful for
-/// implicit include dependencies, like sanitizer blacklists.
-/// \param ShowAllHeaders - If true, show all header information instead of just
-/// headers following the predefines buffer. This is useful for making sure
-/// includes mentioned on the command line are also reported, but differs from
-/// the default behavior used by -H.
-/// \param OutputPath - If non-empty, a path to write the header include
-/// information to, instead of writing to stderr.
-/// \param ShowDepth - Whether to indent to show the nesting of the includes.
-/// \param MSStyle - Whether to print in cl.exe /showIncludes style.
-void AttachHeaderIncludeGen(Preprocessor &PP,
- const std::vector<std::string> &ExtraHeaders,
- bool ShowAllHeaders = false,
- StringRef OutputPath = "",
- bool ShowDepth = true, bool MSStyle = false);
-
-/// Cache tokens for use with PCH. Note that this requires a seekable stream.
-void CacheTokens(Preprocessor &PP, raw_pwrite_stream *OS);
-
-/// The ChainedIncludesSource class converts headers to chained PCHs in
-/// memory, mainly for testing.
-IntrusiveRefCntPtr<ExternalSemaSource>
-createChainedIncludesSource(CompilerInstance &CI,
- IntrusiveRefCntPtr<ExternalSemaSource> &Reader);
-
-/// createInvocationFromCommandLine - Construct a compiler invocation object for
-/// a command line argument vector.
-///
-/// \return A CompilerInvocation, or 0 if none was built for the given
-/// argument vector.
-CompilerInvocation *
-createInvocationFromCommandLine(ArrayRef<const char *> Args,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
- IntrusiveRefCntPtr<DiagnosticsEngine>());
-
-/// Return the value of the last argument as an integer, or a default. If Diags
-/// is non-null, emits an error if the argument is given, but non-integral.
-int getLastArgIntValue(const llvm::opt::ArgList &Args,
- llvm::opt::OptSpecifier Id, int Default,
- DiagnosticsEngine *Diags = nullptr);
-
-inline int getLastArgIntValue(const llvm::opt::ArgList &Args,
- llvm::opt::OptSpecifier Id, int Default,
- DiagnosticsEngine &Diags) {
- return getLastArgIntValue(Args, Id, Default, &Diags);
-}
-
-uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
- llvm::opt::OptSpecifier Id, uint64_t Default,
- DiagnosticsEngine *Diags = nullptr);
-
-inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
- llvm::opt::OptSpecifier Id,
- uint64_t Default,
- DiagnosticsEngine &Diags) {
- return getLastArgUInt64Value(Args, Id, Default, &Diags);
-}
-
-// When Clang->getFrontendOpts().DisableFree is set we don't delete some of the
-// global objects, but we don't want LeakDetectors to complain, so we bury them
-// in a globally visible array.
-void BuryPointer(const void *Ptr);
-template <typename T> void BuryPointer(std::unique_ptr<T> Ptr) {
- BuryPointer(Ptr.release());
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
deleted file mode 100644
index 475f07f..0000000
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ /dev/null
@@ -1,278 +0,0 @@
-//===- VerifyDiagnosticConsumer.h - Verifying Diagnostic Client -*- 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_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
-#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/STLExtras.h"
-#include <climits>
-#include <memory>
-
-namespace clang {
-
-class DiagnosticsEngine;
-class TextDiagnosticBuffer;
-class FileEntry;
-
-/// VerifyDiagnosticConsumer - Create a diagnostic client which will use
-/// markers in the input source to check that all the emitted diagnostics match
-/// those expected.
-///
-/// USING THE DIAGNOSTIC CHECKER:
-///
-/// Indicating that a line expects an error or a warning is simple. Put a
-/// comment on the line that has the diagnostic, use:
-///
-/// \code
-/// expected-{error,warning,remark,note}
-/// \endcode
-///
-/// to tag if it's an expected error, remark or warning, and place the expected
-/// text between {{ and }} markers. The full text doesn't have to be included,
-/// only enough to ensure that the correct diagnostic was emitted.
-///
-/// Here's an example:
-///
-/// \code
-/// int A = B; // expected-error {{use of undeclared identifier 'B'}}
-/// \endcode
-///
-/// You can place as many diagnostics on one line as you wish. To make the code
-/// more readable, you can use slash-newline to separate out the diagnostics.
-///
-/// Alternatively, it is possible to specify the line on which the diagnostic
-/// should appear by appending "@<line>" to "expected-<type>", for example:
-///
-/// \code
-/// #warning some text
-/// // expected-warning@10 {{some text}}
-/// \endcode
-///
-/// The line number may be absolute (as above), or relative to the current
-/// line by prefixing the number with either '+' or '-'.
-///
-/// If the diagnostic is generated in a separate file, for example in a shared
-/// header file, it may be beneficial to be able to declare the file in which
-/// the diagnostic will appear, rather than placing the expected-* directive in
-/// the actual file itself. This can be done using the following syntax:
-///
-/// \code
-/// // expected-error@path/include.h:15 {{error message}}
-/// \endcode
-///
-/// The path can be absolute or relative and the same search paths will be used
-/// as for #include directives. The line number in an external file may be
-/// substituted with '*' meaning that any line number will match (useful where
-/// the included file is, for example, a system header where the actual line
-/// number may change and is not critical).
-///
-/// The simple syntax above allows each specification to match exactly one
-/// error. You can use the extended syntax to customize this. The extended
-/// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of
-/// "error", "warning" or "note", and \<n> is a positive integer. This allows
-/// the diagnostic to appear as many times as specified. Example:
-///
-/// \code
-/// void f(); // expected-note 2 {{previous declaration is here}}
-/// \endcode
-///
-/// Where the diagnostic is expected to occur a minimum number of times, this
-/// can be specified by appending a '+' to the number. Example:
-///
-/// \code
-/// void f(); // expected-note 0+ {{previous declaration is here}}
-/// void g(); // expected-note 1+ {{previous declaration is here}}
-/// \endcode
-///
-/// In the first example, the diagnostic becomes optional, i.e. it will be
-/// swallowed if it occurs, but will not generate an error if it does not
-/// occur. In the second example, the diagnostic must occur at least once.
-/// As a short-hand, "one or more" can be specified simply by '+'. Example:
-///
-/// \code
-/// void g(); // expected-note + {{previous declaration is here}}
-/// \endcode
-///
-/// A range can also be specified by "<n>-<m>". Example:
-///
-/// \code
-/// void f(); // expected-note 0-1 {{previous declaration is here}}
-/// \endcode
-///
-/// In this example, the diagnostic may appear only once, if at all.
-///
-/// Regex matching mode may be selected by appending '-re' to type and
-/// including regexes wrapped in double curly braces in the directive, such as:
-///
-/// \code
-/// expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}}
-/// \endcode
-///
-/// Examples matching error: "variable has incomplete type 'struct s'"
-///
-/// \code
-/// // expected-error {{variable has incomplete type 'struct s'}}
-/// // expected-error {{variable has incomplete type}}
-///
-/// // expected-error-re {{variable has type 'struct {{.}}'}}
-/// // expected-error-re {{variable has type 'struct {{.*}}'}}
-/// // expected-error-re {{variable has type 'struct {{(.*)}}'}}
-/// // expected-error-re {{variable has type 'struct{{[[:space:]](.*)}}'}}
-/// \endcode
-///
-/// VerifyDiagnosticConsumer expects at least one expected-* directive to
-/// be found inside the source code. If no diagnostics are expected the
-/// following directive can be used to indicate this:
-///
-/// \code
-/// // expected-no-diagnostics
-/// \endcode
-///
-class VerifyDiagnosticConsumer: public DiagnosticConsumer,
- public CommentHandler {
-public:
- /// Directive - Abstract class representing a parsed verify directive.
- ///
- class Directive {
- public:
- static std::unique_ptr<Directive> create(bool RegexKind,
- SourceLocation DirectiveLoc,
- SourceLocation DiagnosticLoc,
- bool MatchAnyLine, StringRef Text,
- unsigned Min, unsigned Max);
-
- public:
- /// Constant representing n or more matches.
- static const unsigned MaxCount = UINT_MAX;
-
- SourceLocation DirectiveLoc;
- SourceLocation DiagnosticLoc;
- const std::string Text;
- unsigned Min, Max;
- bool MatchAnyLine;
-
- virtual ~Directive() { }
-
- // Returns true if directive text is valid.
- // Otherwise returns false and populates E.
- virtual bool isValid(std::string &Error) = 0;
-
- // Returns true on match.
- virtual bool match(StringRef S) = 0;
-
- 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() && "DiagnosticLoc is invalid!");
- }
-
- private:
- Directive(const Directive &) = delete;
- void operator=(const Directive &) = delete;
- };
-
- typedef std::vector<std::unique_ptr<Directive>> DirectiveList;
-
- /// ExpectedData - owns directive objects and deletes on destructor.
- ///
- struct ExpectedData {
- DirectiveList Errors;
- DirectiveList Warnings;
- DirectiveList Remarks;
- DirectiveList Notes;
-
- void Reset() {
- Errors.clear();
- Warnings.clear();
- Remarks.clear();
- Notes.clear();
- }
- };
-
- enum DirectiveStatus {
- HasNoDirectives,
- HasNoDirectivesReported,
- HasExpectedNoDiagnostics,
- HasOtherExpectedDirectives
- };
-
-private:
- DiagnosticsEngine &Diags;
- DiagnosticConsumer *PrimaryClient;
- std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner;
- std::unique_ptr<TextDiagnosticBuffer> Buffer;
- const Preprocessor *CurrentPreprocessor;
- const LangOptions *LangOpts;
- SourceManager *SrcManager;
- unsigned ActiveSourceFiles;
- DirectiveStatus Status;
- ExpectedData ED;
-
- void CheckDiagnostics();
- void setSourceManager(SourceManager &SM) {
- assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!");
- SrcManager = &SM;
- }
-
- // 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) {}
- 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;
- ParsedFilesMap ParsedFiles;
- UnparsedFilesMap UnparsedFiles;
-
-public:
- /// Create a new verifying diagnostic client, which will issue errors to
- /// the currently-attached diagnostic client when a diagnostic does not match
- /// what is expected (as indicated in the source file).
- VerifyDiagnosticConsumer(DiagnosticsEngine &Diags);
- ~VerifyDiagnosticConsumer() override;
-
- void BeginSourceFile(const LangOptions &LangOpts,
- const Preprocessor *PP) override;
-
- void EndSourceFile() override;
-
- enum ParsedStatus {
- /// File has been processed via HandleComment.
- IsParsed,
-
- /// File has diagnostics and may have directives.
- IsUnparsed,
-
- /// File has diagnostics but guaranteed no directives.
- IsUnparsedNoDirectives
- };
-
- /// \brief Update lists of parsed and unparsed files.
- void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
-
- bool HandleComment(Preprocessor &PP, SourceRange Comment) override;
-
- void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) override;
-};
-
-} // end namspace clang
-
-#endif
diff --git a/include/clang/FrontendTool/Utils.h b/include/clang/FrontendTool/Utils.h
deleted file mode 100644
index 031ee7d..0000000
--- a/include/clang/FrontendTool/Utils.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header contains miscellaneous utilities for various front-end actions
-// which were split from Frontend to minimise Frontend's dependencies.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTENDTOOL_UTILS_H
-#define LLVM_CLANG_FRONTENDTOOL_UTILS_H
-
-namespace clang {
-
-class CompilerInstance;
-
-/// ExecuteCompilerInvocation - Execute the given actions described by the
-/// compiler invocation object in the given compiler instance.
-///
-/// \return - True on success.
-bool ExecuteCompilerInvocation(CompilerInstance *Clang);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Index/CommentToXML.h b/include/clang/Index/CommentToXML.h
deleted file mode 100644
index bb7b71a..0000000
--- a/include/clang/Index/CommentToXML.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===--- CommentToXML.h - Convert comments to XML representation ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_INDEX_COMMENTTOXML_H
-#define LLVM_CLANG_INDEX_COMMENTTOXML_H
-
-#include "clang/Basic/LLVM.h"
-#include <memory>
-
-namespace clang {
-class ASTContext;
-
-namespace comments {
-class FullComment;
-class HTMLTagComment;
-}
-
-namespace index {
-class SimpleFormatContext;
-
-class CommentToXMLConverter {
- std::unique_ptr<SimpleFormatContext> FormatContext;
- unsigned FormatInMemoryUniqueId;
-
-public:
- CommentToXMLConverter();
- ~CommentToXMLConverter();
-
- void convertCommentToHTML(const comments::FullComment *FC,
- SmallVectorImpl<char> &HTML,
- const ASTContext &Context);
-
- void convertHTMLTagNodeToText(const comments::HTMLTagComment *HTC,
- SmallVectorImpl<char> &Text,
- const ASTContext &Context);
-
- void convertCommentToXML(const comments::FullComment *FC,
- SmallVectorImpl<char> &XML,
- const ASTContext &Context);
-};
-
-} // namespace index
-} // namespace clang
-
-#endif // LLVM_CLANG_INDEX_COMMENTTOXML_H
-
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
deleted file mode 100644
index 55e35cc..0000000
--- a/include/clang/Index/USRGeneration.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===- USRGeneration.h - Routines for USR generation ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_INDEX_USRGENERATION_H
-#define LLVM_CLANG_INDEX_USRGENERATION_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-class Decl;
-class MacroDefinitionRecord;
-class SourceManager;
-
-namespace index {
-
-static inline StringRef getUSRSpacePrefix() {
- return "c:";
-}
-
-/// \brief 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.
-void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS);
-
-/// \brief Generate a USR fragment for an Objective-C class category.
-void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS);
-
-/// \brief 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.
-void generateUSRForObjCMethod(StringRef Sel, bool IsInstanceMethod,
- raw_ostream &OS);
-
-/// \brief Generate a USR fragment for an Objective-C property.
-void generateUSRForObjCProperty(StringRef Prop, raw_ostream &OS);
-
-/// \brief Generate a USR fragment for an Objective-C protocol.
-void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
-
-/// \brief Generate a USR for a macro, including the USR prefix.
-///
-/// \returns true on error, false on success.
-bool generateUSRForMacro(const MacroDefinitionRecord *MD,
- const SourceManager &SM, SmallVectorImpl<char> &Buf);
-
-} // namespace index
-} // namespace clang
-
-#endif // LLVM_CLANG_IDE_USRGENERATION_H
-
diff --git a/include/clang/Lex/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h
deleted file mode 100644
index 91c3b78..0000000
--- a/include/clang/Lex/CodeCompletionHandler.h
+++ /dev/null
@@ -1,71 +0,0 @@
-//===--- CodeCompletionHandler.h - Preprocessor code completion -*- 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 CodeCompletionHandler interface, which provides
-// code-completion callbacks for the preprocessor.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
-#define LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
-
-namespace clang {
-
-class IdentifierInfo;
-class MacroInfo;
-
-/// \brief 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
- /// directive.
- ///
- /// This callback will be invoked when the preprocessor processes a '#' at the
- /// start of a line, followed by the code-completion token.
- ///
- /// \param InConditional Whether we're inside a preprocessor conditional
- /// already.
- virtual void CodeCompleteDirective(bool InConditional) { }
-
- /// \brief 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
- /// 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
- /// expression, such as the condition of an \#if or \#elif directive.
- virtual void CodeCompletePreprocessorExpression() { }
-
- /// \brief Callback invoked when performing code completion inside a
- /// function-like macro argument.
- ///
- /// There will be another callback invocation after the macro arguments are
- /// parsed, so this callback should generally be used to note that the next
- /// callback is invoked inside a macro argument.
- virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
- MacroInfo *MacroInfo,
- unsigned ArgumentIndex) { }
-
- /// \brief 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() { }
-};
-
-}
-
-#endif // LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
deleted file mode 100644
index 20c4bb0..0000000
--- a/include/clang/Lex/DirectoryLookup.h
+++ /dev/null
@@ -1,196 +0,0 @@
-//===--- DirectoryLookup.h - Info for searching for headers -----*- 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 DirectoryLookup interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
-#define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/ModuleMap.h"
-
-namespace clang {
-class HeaderMap;
-class DirectoryEntry;
-class FileEntry;
-class HeaderSearch;
-class Module;
-
-/// DirectoryLookup - This class represents one entry in the search list that
-/// specifies the search order for directories in \#include directives. It
-/// represents either a directory, a framework, or a headermap.
-///
-class DirectoryLookup {
-public:
- enum LookupType_t {
- LT_NormalDir,
- LT_Framework,
- LT_HeaderMap
- };
-private:
- union { // This union is discriminated by isHeaderMap.
- /// Dir - This is the actual directory that we're referring to for a normal
- /// directory or a framework.
- const DirectoryEntry *Dir;
-
- /// Map - This is the HeaderMap if this is a headermap lookup.
- ///
- const HeaderMap *Map;
- } u;
-
- /// DirCharacteristic - The type of directory this is: this is an instance of
- /// SrcMgr::CharacteristicKind.
- unsigned DirCharacteristic : 2;
-
- /// LookupType - This indicates whether this DirectoryLookup object is a
- /// normal directory, a framework, or a headermap.
- unsigned LookupType : 2;
-
- /// \brief 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
- /// within the subdirectories of this directory.
- unsigned SearchedAllModuleMaps : 1;
-
-public:
- /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
- /// 'dir'.
- DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
- bool isFramework)
- : DirCharacteristic(DT),
- LookupType(isFramework ? LT_Framework : LT_NormalDir),
- IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {
- u.Dir = dir;
- }
-
- /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
- /// 'map'.
- DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
- bool isIndexHeaderMap)
- : DirCharacteristic(DT), LookupType(LT_HeaderMap),
- IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {
- u.Map = map;
- }
-
- /// getLookupType - Return the kind of directory lookup that this is: either a
- /// normal directory, a framework path, or a HeaderMap.
- LookupType_t getLookupType() const { return (LookupType_t)LookupType; }
-
- /// getName - Return the directory or filename corresponding to this lookup
- /// object.
- const char *getName() const;
-
- /// getDir - Return the directory that this entry refers to.
- ///
- const DirectoryEntry *getDir() const {
- return isNormalDir() ? u.Dir : nullptr;
- }
-
- /// getFrameworkDir - Return the directory that this framework refers to.
- ///
- const DirectoryEntry *getFrameworkDir() const {
- return isFramework() ? u.Dir : nullptr;
- }
-
- /// getHeaderMap - Return the directory that this entry refers to.
- ///
- const HeaderMap *getHeaderMap() const {
- return isHeaderMap() ? u.Map : nullptr;
- }
-
- /// isNormalDir - Return true if this is a normal directory, not a header map.
- bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
-
- /// isFramework - True if this is a framework directory.
- ///
- bool isFramework() const { return getLookupType() == LT_Framework; }
-
- /// 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
- /// directory for module maps.
- bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
-
- /// \brief Specify whether we have already searched all of the subdirectories
- /// for module maps.
- void setSearchedAllModuleMaps(bool SAMM) {
- SearchedAllModuleMaps = SAMM;
- }
-
- /// DirCharacteristic - The type of directory this is, one of the DirType enum
- /// values.
- SrcMgr::CharacteristicKind getDirCharacteristic() const {
- return (SrcMgr::CharacteristicKind)DirCharacteristic;
- }
-
- /// \brief 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.
- bool isIndexHeaderMap() const {
- return isHeaderMap() && IsIndexHeaderMap;
- }
-
- /// LookupFile - Lookup the specified file in this search path, returning it
- /// if it exists or returning null if not.
- ///
- /// \param Filename The file to look up relative to the search paths.
- ///
- /// \param HS The header search instance to search with.
- ///
- /// \param SearchPath If not NULL, will be set to the search path relative
- /// to which the file was found.
- ///
- /// \param RelativePath If not NULL, will be set to the path relative to
- /// SearchPath at which the file was found. This only differs from the
- /// Filename for framework includes.
- ///
- /// \param RequestingModule The module in which the lookup was performed.
- ///
- /// \param SuggestedModule If non-null, and the file found is semantically
- /// part of a known module, this will be set to the module that should
- /// be imported instead of preprocessing/parsing the file found.
- ///
- /// \param [out] InUserSpecifiedSystemFramework If the file is found,
- /// set to true if the file is located in a framework that has been
- /// user-specified to be treated as a system framework.
- ///
- /// \param [out] MappedName if this is a headermap which maps the filename to
- /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
- /// vector and point Filename to it.
- const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS,
- SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath,
- Module *RequestingModule,
- ModuleMap::KnownHeader *SuggestedModule,
- bool &InUserSpecifiedSystemFramework,
- bool &HasBeenMapped,
- SmallVectorImpl<char> &MappedName) const;
-
-private:
- const FileEntry *DoFrameworkLookup(
- StringRef Filename, HeaderSearch &HS,
- SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath,
- Module *RequestingModule,
- ModuleMap::KnownHeader *SuggestedModule,
- bool &InUserSpecifiedSystemHeader) const;
-
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
deleted file mode 100644
index adf8e71..0000000
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===- ExternalPreprocessorSource.h - Abstract Macro Interface --*- 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 ExternalPreprocessorSource interface, which enables
-// construction of macro definitions from some external source.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H
-#define LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H
-
-namespace clang {
-
-class IdentifierInfo;
-class Module;
-
-/// \brief Abstract interface for external sources of preprocessor
-/// information.
-///
-/// This abstract class allows an external sources (such as the \c ASTReader)
-/// to provide additional preprocessing information.
-class ExternalPreprocessorSource {
-public:
- virtual ~ExternalPreprocessorSource();
-
- /// \brief Read the set of macros defined by this external macro source.
- virtual void ReadDefinedMacros() = 0;
-
- /// \brief Update an out-of-date identifier.
- virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
-
- /// \brief 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.
- virtual Module *getModule(unsigned ModuleID) = 0;
-};
-
-}
-
-#endif
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
deleted file mode 100644
index 183361e..0000000
--- a/include/clang/Lex/HeaderMap.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===--- HeaderMap.h - A file that acts like dir of symlinks ----*- 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 HeaderMap interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_HEADERMAP_H
-#define LLVM_CLANG_LEX_HEADERMAP_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/Support/Compiler.h"
-#include <memory>
-
-namespace llvm {
- class MemoryBuffer;
-}
-namespace clang {
- class FileEntry;
- class FileManager;
- struct HMapBucket;
- struct HMapHeader;
-
-/// This class represents an Apple concept known as a 'header map'. To the
-/// \#include file resolution process, it basically acts like a directory of
-/// symlinks to files. Its advantages are that it is dense and more efficient
-/// to create and process than a directory of symlinks.
-class HeaderMap {
- HeaderMap(const HeaderMap &) = delete;
- void operator=(const HeaderMap &) = delete;
-
- std::unique_ptr<const llvm::MemoryBuffer> FileBuffer;
- bool NeedsBSwap;
-
- HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap)
- : FileBuffer(std::move(File)), NeedsBSwap(BSwap) {}
-public:
- /// HeaderMap::Create - This attempts to load the specified file as a header
- /// map. If it doesn't look like a HeaderMap, it gives up and returns null.
- static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
-
- /// LookupFile - Check to see if the specified relative filename is located in
- /// this HeaderMap. If so, open it and return its FileEntry.
- /// If RawPath is not NULL and the file is found, RawPath will be set to the
- /// raw path at which the file was found in the file system. For example,
- /// for a search path ".." and a filename "../file.h" this would be
- /// "../../file.h".
- const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
-
- /// If the specified relative filename is located in this HeaderMap return
- /// the filename it is mapped to, otherwise return an empty StringRef.
- StringRef lookupFilename(StringRef Filename,
- SmallVectorImpl<char> &DestPath) const;
-
- /// getFileName - Return the filename of the headermap.
- const char *getFileName() const;
-
- /// dump - Print the contents of this headermap to stderr.
- void dump() const;
-
-private:
- unsigned getEndianAdjustedWord(unsigned X) const;
- const HMapHeader &getHeader() const;
- HMapBucket getBucket(unsigned BucketNo) const;
- const char *getString(unsigned StrTabIdx) const;
-};
-
-} // end namespace clang.
-
-#endif
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
deleted file mode 100644
index 6d592e1..0000000
--- a/include/clang/Lex/HeaderSearch.h
+++ /dev/null
@@ -1,688 +0,0 @@
-//===--- HeaderSearch.h - Resolve Header File Locations ---------*- 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 HeaderSearch interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
-#define LLVM_CLANG_LEX_HEADERSEARCH_H
-
-#include "clang/Lex/DirectoryLookup.h"
-#include "clang/Lex/ModuleMap.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/Support/Allocator.h"
-#include <memory>
-#include <vector>
-
-namespace clang {
-
-class DiagnosticsEngine;
-class ExternalPreprocessorSource;
-class FileEntry;
-class FileManager;
-class HeaderSearchOptions;
-class IdentifierInfo;
-class Preprocessor;
-
-/// \brief 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.
- unsigned isImport : 1;
-
- /// \brief True if this is a \#pragma once file.
- unsigned isPragmaOnce : 1;
-
- /// DirInfo - Keep track of whether this is a system header, and if so,
- /// whether it is C++ clean or not. This can be set by the include paths or
- /// by \#pragma gcc system_header. This is an instance of
- /// SrcMgr::CharacteristicKind.
- unsigned DirInfo : 2;
-
- /// \brief 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.
- unsigned isModuleHeader : 1;
-
- /// \brief 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
- /// "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
- /// being built.
- ///
- /// When a framework is being built, the headers have not yet been placed
- /// into the appropriate framework subdirectories, and therefore are
- /// provided via a header map. This bit indicates when this is one of
- /// those framework headers.
- unsigned IndexHeaderMapHeader : 1;
-
- /// \brief Whether this file has been looked up as a header.
- unsigned IsValid : 1;
-
- /// \brief The number of times the file has been included already.
- unsigned short NumIncludes;
-
- /// \brief 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
- /// external storage.
- unsigned ControllingMacroID;
-
- /// If this file has a \#ifndef XXX (or equivalent) guard that
- /// protects the entire contents of the file, this is the identifier
- /// for the macro that controls whether or not it has any effect.
- ///
- /// Note: Most clients should use getControllingMacro() to access
- /// the controlling macro of this header, since
- /// getControllingMacro() is able to load a controlling macro from
- /// external storage.
- const IdentifierInfo *ControllingMacro;
-
- /// \brief If this header came from a framework include, this is the name
- /// of the framework.
- StringRef Framework;
-
- HeaderFileInfo()
- : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
- External(false), isModuleHeader(false), isCompilingModuleHeader(false),
- Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
- NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr) {}
-
- /// \brief 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.,
- /// it corresponds to an actual header we've included or tried to include.
- bool isNonDefault() const {
- return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
- ControllingMacroID;
- }
-};
-
-/// \brief 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.
- ///
- /// \returns Header file information for the given file entry, with the
- /// \c External bit set. If the file entry is not known, return a
- /// default-constructed \c HeaderFileInfo.
- virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
-};
-
-/// \brief Encapsulates the information needed to find the file referenced
-/// by a \#include or \#include_next, (sub-)framework lookup, etc.
-class HeaderSearch {
- /// This structure is used to record entries in our framework cache.
- struct FrameworkCacheEntry {
- /// The directory entry which should be used for the cached framework.
- const DirectoryEntry *Directory;
-
- /// Whether this framework has been "user-specified" to be treated as if it
- /// were a system framework (even if it was found outside a system framework
- /// directory).
- bool IsUserSpecifiedSystemFramework;
- };
-
- /// \brief Header-search options used to initialize this header search.
- IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
-
- DiagnosticsEngine &Diags;
- FileManager &FileMgr;
- /// \#include search path information. Requests for \#include "x" search the
- /// directory of the \#including file first, then each directory in SearchDirs
- /// consecutively. Requests for <x> search the current dir first, then each
- /// directory in SearchDirs, starting at AngledDirIdx, consecutively. If
- /// NoCurDirSearch is true, then the check for the file in the current
- /// directory is suppressed.
- std::vector<DirectoryLookup> SearchDirs;
- unsigned AngledDirIdx;
- unsigned SystemDirIdx;
- bool NoCurDirSearch;
-
- /// \brief \#include prefixes for which the 'system header' property is
- /// overridden.
- ///
- /// For a \#include "x" or \#include \<x> directive, the last string in this
- /// list which is a prefix of 'x' determines whether the file is treated as
- /// a system header.
- std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
-
- /// \brief The path to the module cache.
- std::string ModuleCachePath;
-
- /// \brief All of the preprocessor-specific data about files that are
- /// included, indexed by the FileEntry's UID.
- mutable std::vector<HeaderFileInfo> FileInfo;
-
- /// Keeps track of each lookup performed by LookupFile.
- struct LookupFileCacheInfo {
- /// Starting index in SearchDirs that the cached search was performed from.
- /// If there is a hit and this value doesn't match the current query, the
- /// cache has to be ignored.
- unsigned StartIdx;
- /// The entry in SearchDirs that satisfied the query.
- unsigned HitIdx;
- /// This is non-null if the original filename was mapped to a framework
- /// include via a headermap.
- const char *MappedName;
-
- /// Default constructor -- Initialize all members with zero.
- LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {}
-
- void reset(unsigned StartIdx) {
- this->StartIdx = StartIdx;
- this->MappedName = nullptr;
- }
- };
- llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
-
- /// \brief Collection mapping a framework or subframework
- /// name like "Carbon" to the Carbon.framework directory.
- llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
-
- /// IncludeAliases - maps include file names (including the quotes or
- /// angle brackets) to other include file names. This is used to support the
- /// include_alias pragma for Microsoft compatibility.
- typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
- IncludeAliasMap;
- std::unique_ptr<IncludeAliasMap> IncludeAliases;
-
- /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
- /// headermaps. This vector owns the headermap.
- std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
-
- /// \brief The mapping between modules and headers.
- mutable ModuleMap ModMap;
-
- /// \brief 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
- /// whether they were valid or not.
- llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
-
- /// \brief 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
- /// macros into IdentifierInfo pointers, and keep the identifire up to date,
- /// as needed.
- ExternalPreprocessorSource *ExternalLookup;
-
- /// \brief Entity used to look up stored header file information.
- ExternalHeaderFileInfoSource *ExternalSource;
-
- // Various statistics we track for performance analysis.
- unsigned NumIncluded;
- unsigned NumMultiIncludeFileOptzn;
- unsigned NumFrameworkLookups, NumSubFrameworkLookups;
-
- const LangOptions &LangOpts;
-
- // HeaderSearch doesn't support default or copy construction.
- HeaderSearch(const HeaderSearch&) = delete;
- void operator=(const HeaderSearch&) = delete;
-
- friend class DirectoryLookup;
-
-public:
- HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
- SourceManager &SourceMgr, DiagnosticsEngine &Diags,
- const LangOptions &LangOpts, const TargetInfo *Target);
- ~HeaderSearch();
-
- /// \brief 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.
- void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
- unsigned angledDirIdx, unsigned systemDirIdx,
- bool noCurDirSearch) {
- assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
- "Directory indicies are unordered");
- SearchDirs = dirs;
- AngledDirIdx = angledDirIdx;
- SystemDirIdx = systemDirIdx;
- NoCurDirSearch = noCurDirSearch;
- //LookupFileCache.clear();
- }
-
- /// \brief Add an additional search path.
- void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
- unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
- SearchDirs.insert(SearchDirs.begin() + idx, dir);
- if (!isAngled)
- AngledDirIdx++;
- SystemDirIdx++;
- }
-
- /// \brief 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.
- bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
-
- /// \brief 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.
- void AddIncludeAlias(StringRef Source, StringRef Dest) {
- if (!IncludeAliases)
- IncludeAliases.reset(new IncludeAliasMap);
- (*IncludeAliases)[Source] = Dest;
- }
-
- /// MapHeaderToIncludeAlias - Maps one header file name to a different header
- /// file name, for use with the include_alias pragma. Note that the source
- /// file name should include the angle brackets or quotes. Returns StringRef
- /// as null if the header cannot be mapped.
- StringRef MapHeaderToIncludeAlias(StringRef Source) {
- assert(IncludeAliases && "Trying to map headers when there's no map");
-
- // Do any filename replacements before anything else
- IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
- if (Iter != IncludeAliases->end())
- return Iter->second;
- return StringRef();
- }
-
- /// \brief Set the path to the module cache.
- void setModuleCachePath(StringRef CachePath) {
- ModuleCachePath = CachePath;
- }
-
- /// \brief Retrieve the path to the module cache.
- StringRef getModuleCachePath() const { return ModuleCachePath; }
-
- /// \brief 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.
- void ClearFileInfo() {
- FileInfo.clear();
- }
-
- void SetExternalLookup(ExternalPreprocessorSource *EPS) {
- ExternalLookup = EPS;
- }
-
- ExternalPreprocessorSource *getExternalLookup() const {
- return ExternalLookup;
- }
-
- /// \brief Set the external source of header information.
- void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
- ExternalSource = ES;
- }
-
- /// \brief 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,
- /// return null on failure.
- ///
- /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
- /// the file was found in, or null if not applicable.
- ///
- /// \param IncludeLoc Used for diagnostics if valid.
- ///
- /// \param isAngled indicates whether the file reference is a <> reference.
- ///
- /// \param CurDir If non-null, the file was found in the specified directory
- /// search location. This is used to implement \#include_next.
- ///
- /// \param Includers Indicates where the \#including file(s) are, in case
- /// relative searches are needed. In reverse order of inclusion.
- ///
- /// \param SearchPath If non-null, will be set to the search path relative
- /// to which the file was found. If the include path is absolute, SearchPath
- /// will be set to an empty string.
- ///
- /// \param RelativePath If non-null, will be set to the path relative to
- /// SearchPath at which the file was found. This only differs from the
- /// Filename for framework includes.
- ///
- /// \param SuggestedModule If non-null, and the file found is semantically
- /// part of a known module, this will be set to the module that should
- /// be imported instead of preprocessing/parsing the file found.
- const FileEntry *LookupFile(
- StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
- const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
- ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
- SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
- Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
- bool SkipCache = false);
-
- /// \brief 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
- /// HIToolbox is a subframework within Carbon.framework. If so, return
- /// the FileEntry for the designated file, otherwise return null.
- const FileEntry *LookupSubframeworkHeader(
- StringRef Filename, const FileEntry *RelativeFileEnt,
- SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
- Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule);
-
- /// \brief 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,
- /// \#include_next, or \#import directive.
- ///
- /// \return false if \#including the file will have no effect or true
- /// if we should include it.
- bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
- bool isImport, Module *CorrespondingModule);
-
- /// \brief 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
- /// \#pragma once.
- void MarkFileIncludeOnce(const FileEntry *File) {
- HeaderFileInfo &FI = getFileInfo(File);
- FI.isImport = true;
- FI.isPragmaOnce = true;
- }
-
- /// \brief 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.
- void MarkFileModuleHeader(const FileEntry *File,
- ModuleMap::ModuleHeaderRole Role,
- bool IsCompiledModuleHeader);
-
- /// \brief 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.
- ///
- /// This is used by the multiple-include optimization to eliminate
- /// no-op \#includes.
- void SetFileControllingMacro(const FileEntry *File,
- const IdentifierInfo *ControllingMacro) {
- getFileInfo(File).ControllingMacro = ControllingMacro;
- }
-
- /// \brief 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
- /// multiple inclusions, e.g., it has \#pragma once or a controlling
- /// macro.
- ///
- /// This routine does not consider the effect of \#import
- bool isFileMultipleIncludeGuarded(const FileEntry *File);
-
- /// CreateHeaderMap - This method returns a HeaderMap for the specified
- /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
- const HeaderMap *CreateHeaderMap(const FileEntry *FE);
-
- /// \brief Retrieve the name of the module file that should be used to
- /// load the given module.
- ///
- /// \param Module The module whose module file name will be returned.
- ///
- /// \returns The name of the module file that corresponds to this module,
- /// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(Module *Module);
-
- /// \brief Retrieve the name of the 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.
- ///
- /// \param ModuleMapPath A path that when combined with \c ModuleName
- /// uniquely identifies this module. See Module::ModuleMap.
- ///
- /// \returns The name of the module file that corresponds to this module,
- /// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);
-
- /// \brief Lookup a module Search for a module with the given name.
- ///
- /// \param ModuleName The name of the module we're looking for.
- ///
- /// \param AllowSearch Whether we are allowed to search in the various
- /// search directories to produce a module definition. If not, this lookup
- /// will only return an already-known module.
- ///
- /// \returns The module with the given name.
- Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
-
- /// \brief 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
- /// with the given file name to a (sub)module.
- /// Always returns false if modules are disabled.
- ///
- /// \param Filename The name of the file.
- ///
- /// \param Root The "root" directory, at which we should stop looking for
- /// module maps.
- ///
- /// \param IsSystem Whether the directories we're looking at are system
- /// header directories.
- bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root,
- bool IsSystem);
-
- /// \brief Retrieve the module that corresponds to the given file, if any.
- ///
- /// \param File The header that we wish to map to a module.
- ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const;
-
- /// \brief 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.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool loadModuleMapFile(const FileEntry *File, bool IsSystem);
-
- /// \brief 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.
- void loadTopLevelSystemModules();
-
-private:
- /// \brief Retrieve a module with the given name, which may be part of the
- /// given framework.
- ///
- /// \param Name The name of the module to retrieve.
- ///
- /// \param Dir The framework directory (e.g., ModuleName.framework).
- ///
- /// \param IsSystem Whether the framework directory is part of the system
- /// frameworks.
- ///
- /// \returns The module, if found; otherwise, null.
- Module *loadFrameworkModule(StringRef Name,
- const DirectoryEntry *Dir,
- bool IsSystem);
-
- /// \brief 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.
- ///
- /// \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.
- bool findUsableModuleForHeader(const FileEntry *File,
- const DirectoryEntry *Root,
- Module *RequestingModule,
- ModuleMap::KnownHeader *SuggestedModule,
- bool IsSystemHeaderDir);
-
- /// \brief 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
- /// find this file due to requirements from \p RequestingModule.
- bool findUsableModuleForFrameworkHeader(
- 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
- /// module.
- const FileEntry *
- getFileAndSuggestModule(StringRef FileName, const DirectoryEntry *Dir,
- bool IsSystemHeaderDir, Module *RequestingModule,
- ModuleMap::KnownHeader *SuggestedModule);
-
-public:
- /// \brief Retrieve the module map.
- ModuleMap &getModuleMap() { return ModMap; }
-
- /// \brief 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,
- /// in preparation for updating it in some way.
- HeaderFileInfo &getFileInfo(const FileEntry *FE);
-
- /// \brief 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).
- const HeaderFileInfo *getExistingFileInfo(const FileEntry *FE,
- bool WantExternal = true) const;
-
- // Used by external tools
- typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
- search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
- search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
- unsigned search_dir_size() const { return SearchDirs.size(); }
-
- search_dir_iterator quoted_dir_begin() const {
- return SearchDirs.begin();
- }
- search_dir_iterator quoted_dir_end() const {
- return SearchDirs.begin() + AngledDirIdx;
- }
-
- search_dir_iterator angled_dir_begin() const {
- return SearchDirs.begin() + AngledDirIdx;
- }
- search_dir_iterator angled_dir_end() const {
- return SearchDirs.begin() + SystemDirIdx;
- }
-
- search_dir_iterator system_dir_begin() const {
- return SearchDirs.begin() + SystemDirIdx;
- }
- search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
-
- /// \brief Retrieve a uniqued framework name.
- StringRef getUniqueFrameworkName(StringRef Framework);
-
- void PrintStats();
-
- size_t getTotalMemory() const;
-
- static std::string NormalizeDashIncludePath(StringRef File,
- FileManager &FileMgr);
-
-private:
- /// \brief Describes what happened when we tried to load a module map file.
- enum LoadModuleMapResult {
- /// \brief The module map file had already been loaded.
- LMM_AlreadyLoaded,
- /// \brief The module map file was loaded by this invocation.
- LMM_NewlyLoaded,
- /// \brief There is was directory with the given name.
- LMM_NoDirectory,
- /// \brief There was either no module map file or the module map file was
- /// invalid.
- LMM_InvalidModuleMap
- };
-
- LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File,
- bool IsSystem,
- const DirectoryEntry *Dir);
-
- /// \brief 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.
- /// \param IsSystem Whether this is a system header directory.
- /// \param IsFramework Whether this is a framework directory.
- ///
- /// \returns The result of attempting to load the module map file from the
- /// named directory.
- LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
- bool IsFramework);
-
- /// \brief 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.
- /// \param IsFramework Whether this is a framework directory.
- ///
- /// \returns The result of attempting to load the module map file from the
- /// named directory.
- LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir,
- bool IsSystem, bool IsFramework);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
deleted file mode 100644
index 915dbf7..0000000
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ /dev/null
@@ -1,206 +0,0 @@
-//===--- HeaderSearchOptions.h ----------------------------------*- 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_LEX_HEADERSEARCHOPTIONS_H
-#define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/StringRef.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-
-namespace frontend {
- /// IncludeDirGroup - Identifies the group an include Entry belongs to,
- /// representing its relative positive in the search list.
- /// \#include directives whose paths are enclosed by string quotes ("")
- /// start searching at the Quoted group (specified by '-iquote'),
- /// then search the Angled group, then the System group, etc.
- enum IncludeDirGroup {
- Quoted = 0, ///< '\#include ""' paths, added by 'gcc -iquote'.
- Angled, ///< Paths for '\#include <>' added by '-I'.
- IndexHeaderMap, ///< Like Angled, but marks header maps used when
- /// building frameworks.
- System, ///< Like Angled, but marks system directories.
- ExternCSystem, ///< Like System, but headers are implicitly wrapped in
- /// extern "C".
- CSystem, ///< Like System, but only used for C.
- CXXSystem, ///< Like System, but only used for C++.
- ObjCSystem, ///< Like System, but only used for ObjC.
- ObjCXXSystem, ///< Like System, but only used for ObjC++.
- After ///< Like System, but searched after the system directories.
- };
-}
-
-/// HeaderSearchOptions - Helper class for storing options related to the
-/// initialization of the HeaderSearch object.
-class HeaderSearchOptions : public RefCountedBase<HeaderSearchOptions> {
-public:
- struct Entry {
- std::string Path;
- frontend::IncludeDirGroup Group;
- unsigned IsFramework : 1;
-
- /// IgnoreSysRoot - This is false if an absolute path should be treated
- /// relative to the sysroot, or true if it should always be the absolute
- /// path.
- unsigned IgnoreSysRoot : 1;
-
- Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
- bool ignoreSysRoot)
- : Path(path), Group(group), IsFramework(isFramework),
- IgnoreSysRoot(ignoreSysRoot) {}
- };
-
- struct SystemHeaderPrefix {
- /// A prefix to be matched against paths in \#include directives.
- std::string Prefix;
-
- /// True if paths beginning with this prefix should be treated as system
- /// headers.
- bool IsSystemHeader;
-
- SystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader)
- : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
- };
-
- /// If non-empty, the directory to use as a "virtual system root" for include
- /// paths.
- std::string Sysroot;
-
- /// User specified include entries.
- std::vector<Entry> UserEntries;
-
- /// User-specified system header prefixes.
- std::vector<SystemHeaderPrefix> SystemHeaderPrefixes;
-
- /// The directory which holds the compiler resource files (builtin includes,
- /// etc.).
- std::string ResourceDir;
-
- /// \brief The directory used for the module cache.
- std::string ModuleCachePath;
-
- /// \brief The directory used for a user build.
- std::string ModuleUserBuildPath;
-
- /// The module/pch container format.
- std::string ModuleFormat;
-
- /// \brief 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
- /// modules is enabled.
- unsigned ImplicitModuleMaps : 1;
-
- /// \brief 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.
- //
- /// The home directory is where we look for files named in the module map
- /// file.
- unsigned ModuleMapFileHomeIsCwd : 1;
-
- /// \brief 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
- /// files.
- ///
- /// The default value is large, e.g., the operation runs once a week.
- unsigned ModuleCachePruneInterval;
-
- /// \brief 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
- /// accessed in this many seconds will be removed. The default value is
- /// large, e.g., a month, to avoid forcing infrequently-used modules to be
- /// regenerated often.
- unsigned ModuleCachePruneAfter;
-
- /// \brief 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;
-
- /// \brief The set of macro names that should be ignored for the purposes
- /// of computing the module hash.
- llvm::SmallSetVector<std::string, 16> ModulesIgnoreMacros;
-
- /// \brief The set of user-provided virtual filesystem overlay files.
- std::vector<std::string> VFSOverlayFiles;
-
- /// Include the compiler builtin includes.
- unsigned UseBuiltinIncludes : 1;
-
- /// Include the system standard include search directories.
- unsigned UseStandardSystemIncludes : 1;
-
- /// Include the system standard C++ library include search directories.
- unsigned UseStandardCXXIncludes : 1;
-
- /// Use libc++ instead of the default libstdc++.
- unsigned UseLibcxx : 1;
-
- /// 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
- /// 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.
- unsigned ModulesValidateSystemHeaders : 1;
-
- /// Whether the module includes debug information (-gmodules).
- unsigned UseDebugInfo : 1;
-
- HeaderSearchOptions(StringRef _Sysroot = "/")
- : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
- ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
- ModuleCachePruneInterval(7 * 24 * 60 * 60),
- ModuleCachePruneAfter(31 * 24 * 60 * 60), BuildSessionTimestamp(0),
- UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
- UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
- ModulesValidateOncePerBuildSession(false),
- ModulesValidateSystemHeaders(false),
- UseDebugInfo(false) {}
-
- /// AddPath - Add the \p Path path to the specified \p Group list.
- void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
- bool IsFramework, bool IgnoreSysRoot) {
- UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot);
- }
-
- /// AddSystemHeaderPrefix - Override whether \#include directives naming a
- /// path starting with \p Prefix should be considered as naming a system
- /// header.
- void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
- SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
- }
-
- void AddVFSOverlayFile(StringRef Name) {
- VFSOverlayFiles.push_back(Name);
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
deleted file mode 100644
index 5d724c0..0000000
--- a/include/clang/Lex/LexDiagnostic.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- 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_LEX_LEXDIAGNOSTIC_H
-#define LLVM_CLANG_LEX_LEXDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define LEXSTART
-#include "clang/Basic/DiagnosticLexKinds.inc"
-#undef DIAG
- NUM_BUILTIN_LEX_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
deleted file mode 100644
index 12565d0..0000000
--- a/include/clang/Lex/Lexer.h
+++ /dev/null
@@ -1,665 +0,0 @@
-//===--- Lexer.h - C Language Family Lexer ----------------------*- 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 Lexer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_LEXER_H
-#define LLVM_CLANG_LEX_LEXER_H
-
-#include "clang/Basic/LangOptions.h"
-#include "clang/Lex/PreprocessorLexer.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-#include <string>
-
-namespace clang {
-class DiagnosticsEngine;
-class SourceManager;
-class Preprocessor;
-class DiagnosticBuilder;
-
-/// ConflictMarkerKind - Kinds of conflict marker which the lexer might be
-/// recovering from.
-enum ConflictMarkerKind {
- /// Not within a conflict marker.
- CMK_None,
- /// A normal or diff3 conflict marker, initiated by at least 7 "<"s,
- /// separated by at least 7 "="s or "|"s, and terminated by at least 7 ">"s.
- CMK_Normal,
- /// A Perforce-style conflict marker, initiated by 4 ">"s,
- /// separated by 4 "="s, and terminated by 4 "<"s.
- CMK_Perforce
-};
-
-/// Lexer - This provides a simple interface that turns a text buffer into a
-/// stream of tokens. This provides no support for file reading or buffering,
-/// or buffering/seeking of tokens, only forward lexing is supported. It relies
-/// on the specified Preprocessor object to handle preprocessor directives, etc.
-class Lexer : public PreprocessorLexer {
- void anchor() override;
-
- //===--------------------------------------------------------------------===//
- // Constant configuration values for this lexer.
- const char *BufferStart; // Start of the buffer.
- const char *BufferEnd; // End of the buffer.
- SourceLocation FileLoc; // Location for start of file.
- LangOptions LangOpts; // LangOpts enabled by this language (cache).
- bool Is_PragmaLexer; // True if lexer for _Pragma handling.
-
- //===--------------------------------------------------------------------===//
- // Context-specific lexing flags set by the preprocessor.
- //
-
- /// ExtendedTokenMode - The lexer can optionally keep comments and whitespace
- /// and return them as tokens. This is used for -C and -CC modes, and
- /// whitespace preservation can be useful for some clients that want to lex
- /// the file in raw mode and get every character from the file.
- ///
- /// When this is set to 2 it returns comments and whitespace. When set to 1
- /// it returns comments, when it is set to 0 it returns normal tokens only.
- unsigned char ExtendedTokenMode;
-
- //===--------------------------------------------------------------------===//
- // Context that changes as the file is lexed.
- // NOTE: any state that mutates when in raw mode must have save/restore code
- // in Lexer::isNextPPTokenLParen.
-
- // BufferPtr - Current pointer into the buffer. This is the next character
- // to be lexed.
- const char *BufferPtr;
-
- // IsAtStartOfLine - True if the next lexed token should get the "start of
- // line" flag set on it.
- bool IsAtStartOfLine;
-
- bool IsAtPhysicalStartOfLine;
-
- bool HasLeadingSpace;
-
- bool HasLeadingEmptyMacro;
-
- // CurrentConflictMarkerState - The kind of conflict marker we are handling.
- ConflictMarkerKind CurrentConflictMarkerState;
-
- Lexer(const Lexer &) = delete;
- void operator=(const Lexer &) = delete;
- friend class Preprocessor;
-
- void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd);
-public:
-
- /// Lexer constructor - Create a new lexer object for the specified buffer
- /// with the specified preprocessor managing the lexing process. This lexer
- /// assumes that the associated file buffer and Preprocessor objects will
- /// outlive it, so it doesn't take ownership of either of them.
- Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer, Preprocessor &PP);
-
- /// Lexer constructor - Create a new raw lexer object. This object is only
- /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the
- /// text range will outlive it, so it doesn't take ownership of it.
- Lexer(SourceLocation FileLoc, const LangOptions &LangOpts,
- const char *BufStart, const char *BufPtr, const char *BufEnd);
-
- /// Lexer constructor - Create a new raw lexer object. This object is only
- /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the
- /// text range will outlive it, so it doesn't take ownership of it.
- Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
- const SourceManager &SM, const LangOptions &LangOpts);
-
- /// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
- /// _Pragma expansion. This has a variety of magic semantics that this method
- /// sets up. It returns a new'd Lexer that must be delete'd when done.
- static Lexer *Create_PragmaLexer(SourceLocation SpellingLoc,
- SourceLocation ExpansionLocStart,
- SourceLocation ExpansionLocEnd,
- unsigned TokLen, Preprocessor &PP);
-
-
- /// getLangOpts - Return the language features currently enabled.
- /// NOTE: this lexer modifies features as a file is parsed!
- const LangOptions &getLangOpts() const { return LangOpts; }
-
- /// getFileLoc - Return the File Location for the file we are lexing out of.
- /// The physical location encodes the location where the characters come from,
- /// the virtual location encodes where we should *claim* the characters came
- /// from. Currently this is only used by _Pragma handling.
- SourceLocation getFileLoc() const { return FileLoc; }
-
-private:
- /// Lex - Return the next token in the file. If this is the end of file, it
- /// return the tok::eof token. This implicitly involves the preprocessor.
- bool Lex(Token &Result);
-
-public:
- /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma.
- bool isPragmaLexer() const { return Is_PragmaLexer; }
-
-private:
- /// IndirectLex - An indirect call to 'Lex' that can be invoked via
- /// the PreprocessorLexer interface.
- void IndirectLex(Token &Result) override { Lex(Result); }
-
-public:
- /// LexFromRawLexer - Lex a token from a designated raw lexer (one with no
- /// associated preprocessor object. Return true if the 'next character to
- /// read' pointer points at the end of the lexer buffer, false otherwise.
- bool LexFromRawLexer(Token &Result) {
- assert(LexingRawMode && "Not already in raw mode!");
- Lex(Result);
- // Note that lexing to the end of the buffer doesn't implicitly delete the
- // lexer when in raw mode.
- return BufferPtr == BufferEnd;
- }
-
- /// isKeepWhitespaceMode - Return true if the lexer should return tokens for
- /// every character in the file, including whitespace and comments. This
- /// should only be used in raw mode, as the preprocessor is not prepared to
- /// deal with the excess tokens.
- bool isKeepWhitespaceMode() const {
- return ExtendedTokenMode > 1;
- }
-
- /// SetKeepWhitespaceMode - This method lets clients enable or disable
- /// whitespace retention mode.
- void SetKeepWhitespaceMode(bool Val) {
- assert((!Val || LexingRawMode || LangOpts.TraditionalCPP) &&
- "Can only retain whitespace in raw mode or -traditional-cpp");
- ExtendedTokenMode = Val ? 2 : 0;
- }
-
- /// inKeepCommentMode - Return true if the lexer should return comments as
- /// tokens.
- bool inKeepCommentMode() const {
- return ExtendedTokenMode > 0;
- }
-
- /// SetCommentRetentionMode - Change the comment retention mode of the lexer
- /// to the specified mode. This is really only useful when lexing in raw
- /// mode, because otherwise the lexer needs to manage this.
- void SetCommentRetentionState(bool Mode) {
- assert(!isKeepWhitespaceMode() &&
- "Can't play with comment retention state when retaining whitespace");
- ExtendedTokenMode = Mode ? 1 : 0;
- }
-
- /// Sets the extended token mode back to its initial value, according to the
- /// language options and preprocessor. This controls whether the lexer
- /// produces comment and whitespace tokens.
- ///
- /// This requires the lexer to have an associated preprocessor. A standalone
- /// lexer has nothing to reset to.
- void resetExtendedTokenMode();
-
- /// Gets source code buffer.
- StringRef getBuffer() const {
- return StringRef(BufferStart, BufferEnd - BufferStart);
- }
-
- /// ReadToEndOfLine - Read the rest of the current preprocessor line as an
- /// uninterpreted string. This switches the lexer out of directive mode.
- void ReadToEndOfLine(SmallVectorImpl<char> *Result = nullptr);
-
-
- /// Diag - Forwarding function for diagnostics. This translate a source
- /// position in the current buffer into a SourceLocation object for rendering.
- DiagnosticBuilder Diag(const char *Loc, unsigned DiagID) const;
-
- /// getSourceLocation - Return a source location identifier for the specified
- /// offset in the current file.
- SourceLocation getSourceLocation(const char *Loc, unsigned TokLen = 1) const;
-
- /// getSourceLocation - Return a source location for the next character in
- /// the current file.
- SourceLocation getSourceLocation() override {
- return getSourceLocation(BufferPtr);
- }
-
- /// \brief Return the current location in the buffer.
- const char *getBufferLocation() const { return BufferPtr; }
-
- /// Stringify - Convert the specified string into a C string by escaping '\'
- /// and " characters. This does not add surrounding ""'s to the string.
- /// If Charify is true, this escapes the ' character instead of ".
- static std::string Stringify(StringRef Str, bool Charify = false);
-
- /// Stringify - Convert the specified string into a C string by escaping '\'
- /// and " characters. This does not add surrounding ""'s to the string.
- static void Stringify(SmallVectorImpl<char> &Str);
-
-
- /// getSpelling - This method is used to 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 guaranteed to be at least
- /// Tok.getLength() bytes long. The length of the actual result is returned.
- ///
- /// Note that this method may do two possible things: it may either fill in
- /// the buffer specified with characters, or it may *change the input pointer*
- /// to point to a constant buffer with the data already in it (avoiding a
- /// copy). The caller is not allowed to modify the returned buffer pointer
- /// if an internal buffer is returned.
- static unsigned getSpelling(const Token &Tok, const char *&Buffer,
- const SourceManager &SourceMgr,
- const LangOptions &LangOpts,
- bool *Invalid = nullptr);
-
- /// getSpelling() - 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 particular, this
- /// wants to get the true, uncanonicalized, spelling of things like digraphs
- /// UCNs, etc.
- static std::string getSpelling(const Token &Tok,
- const SourceManager &SourceMgr,
- const LangOptions &LangOpts,
- bool *Invalid = nullptr);
-
- /// getSpelling - This method is used to get the spelling of the
- /// token at the given source location. If, as is usually true, it
- /// is not necessary to copy any data, then the returned string may
- /// not point into the provided buffer.
- ///
- /// This method lexes at the expansion depth of the given
- /// location and does not jump to the expansion or spelling
- /// location.
- static StringRef getSpelling(SourceLocation loc,
- SmallVectorImpl<char> &buffer,
- const SourceManager &SourceMgr,
- const LangOptions &LangOpts,
- bool *invalid = nullptr);
-
- /// MeasureTokenLength - Relex the token at the specified location and return
- /// its length in bytes in the input file. If the token needs cleaning (e.g.
- /// includes a trigraph or an escaped newline) then this count includes bytes
- /// that are part of that.
- static unsigned MeasureTokenLength(SourceLocation Loc,
- const SourceManager &SM,
- const LangOptions &LangOpts);
-
- /// \brief 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
- /// 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);
-
- /// 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,
- const SourceManager &SM,
- const LangOptions &LangOpts);
-
- /// \brief 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
- /// points just past the end of the token referenced by \p Loc, and
- /// is generally used when a diagnostic needs to point just after a
- /// token where it expected something different that it received. If
- /// the returned source location would not be meaningful (e.g., if
- /// it points into a macro), this routine returns an invalid
- /// source location.
- ///
- /// \param Offset an offset from the end of the token, where the source
- /// location should refer to. The default offset (0) produces a source
- /// location pointing just past the end of the token; an offset of 1 produces
- /// a source location pointing to the last character in the token, etc.
- static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
- const SourceManager &SM,
- const LangOptions &LangOpts);
-
- /// \brief 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.
- static CharSourceRange getAsCharRange(SourceRange Range,
- const SourceManager &SM,
- const LangOptions &LangOpts) {
- SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts);
- return End.isInvalid() ? CharSourceRange()
- : CharSourceRange::getCharRange(
- Range.getBegin(), End.getLocWithOffset(-1));
- }
- static CharSourceRange getAsCharRange(CharSourceRange Range,
- const SourceManager &SM,
- const LangOptions &LangOpts) {
- return Range.isTokenRange()
- ? getAsCharRange(Range.getAsRange(), SM, LangOpts)
- : Range;
- }
-
- /// \brief 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
- /// begin location of the macro.
- static bool isAtStartOfMacroExpansion(SourceLocation loc,
- const SourceManager &SM,
- const LangOptions &LangOpts,
- SourceLocation *MacroBegin = nullptr);
-
- /// \brief 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
- /// end location of the macro.
- static bool isAtEndOfMacroExpansion(SourceLocation loc,
- const SourceManager &SM,
- const LangOptions &LangOpts,
- SourceLocation *MacroEnd = nullptr);
-
- /// \brief 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.
- ///
- /// This function is trying to deal with macros and return a range based on
- /// file locations. The cases where it can successfully handle macros are:
- ///
- /// -begin or end range lies at the start or end of a macro expansion, in
- /// which case the location will be set to the expansion point, e.g:
- /// \#define M 1 2
- /// a M
- /// If you have a range [a, 2] (where 2 came from the macro), the function
- /// will return a range for "a M"
- /// if you have range [a, 1], the function will fail because the range
- /// overlaps with only a part of the macro
- ///
- /// -The macro is a function macro and the range can be mapped to the macro
- /// arguments, e.g:
- /// \#define M 1 2
- /// \#define FM(x) x
- /// FM(a b M)
- /// if you have range [b, 2], the function will return the file range "b M"
- /// inside the macro arguments.
- /// if you have range [a, 2], the function will return the file range
- /// "FM(a b M)" since the range includes all of the macro expansion.
- static CharSourceRange makeFileCharRange(CharSourceRange Range,
- const SourceManager &SM,
- const LangOptions &LangOpts);
-
- /// \brief 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.
- ///
- /// This routine starts from a source location, and finds the name of the macro
- /// responsible for its immediate expansion. It looks through any intervening
- /// macro argument expansions to compute this. It returns a StringRef which
- /// refers to the SourceManager-owned buffer of the source where that macro
- /// name is spelled. Thus, the result shouldn't out-live that SourceManager.
- static StringRef getImmediateMacroName(SourceLocation Loc,
- const SourceManager &SM,
- const LangOptions &LangOpts);
-
- /// \brief 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
- /// particular file actually begins. The preamble of the main source file is
- /// a potential prefix header.
- ///
- /// \param Buffer The memory buffer containing the file's contents.
- ///
- /// \param MaxLines If non-zero, restrict the length of the preamble
- /// to fewer than this number of lines.
- ///
- /// \returns The offset into the file where the preamble ends and the rest
- /// of the file begins along with a boolean value indicating whether
- /// the preamble ends at the beginning of a new line.
- static std::pair<unsigned, bool> ComputePreamble(StringRef Buffer,
- const LangOptions &LangOpts,
- unsigned MaxLines = 0);
-
- /// \brief 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
- /// invalid.
- static SourceLocation findLocationAfterToken(SourceLocation loc,
- tok::TokenKind TKind,
- const SourceManager &SM,
- const LangOptions &LangOpts,
- bool SkipTrailingWhitespaceAndNewLine);
-
- /// \brief Returns true if the given character could appear in an identifier.
- static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts);
-
- /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
- /// emit a warning.
- static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &LangOpts) {
- // If this is not a trigraph and not a UCN or escaped newline, return
- // quickly.
- if (isObviouslySimpleCharacter(Ptr[0])) {
- Size = 1;
- return *Ptr;
- }
-
- Size = 0;
- return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
- }
-
- //===--------------------------------------------------------------------===//
- // Internal implementation interfaces.
-private:
-
- /// LexTokenInternal - Internal interface to lex a preprocessing token. Called
- /// by Lex.
- ///
- bool LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine);
-
- bool CheckUnicodeWhitespace(Token &Result, uint32_t C, const char *CurPtr);
-
- /// Given that a token begins with the Unicode character \p C, figure out
- /// what kind of token it is and dispatch to the appropriate lexing helper
- /// function.
- bool LexUnicode(Token &Result, uint32_t C, const char *CurPtr);
-
- /// FormTokenWithChars - When we lex a token, we have identified a span
- /// starting at BufferPtr, going to TokEnd that forms the token. This method
- /// takes that range and assigns it to the token as its location and size. In
- /// addition, since tokens cannot overlap, this also updates BufferPtr to be
- /// TokEnd.
- void FormTokenWithChars(Token &Result, const char *TokEnd,
- tok::TokenKind Kind) {
- unsigned TokLen = TokEnd-BufferPtr;
- Result.setLength(TokLen);
- Result.setLocation(getSourceLocation(BufferPtr, TokLen));
- Result.setKind(Kind);
- BufferPtr = TokEnd;
- }
-
- /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
- /// tok::l_paren token, 0 if it is something else and 2 if there are no more
- /// tokens in the buffer controlled by this lexer.
- unsigned isNextPPTokenLParen();
-
- //===--------------------------------------------------------------------===//
- // Lexer character reading interfaces.
-
- // This lexer is built on two interfaces for reading characters, both of which
- // automatically provide phase 1/2 translation. getAndAdvanceChar is used
- // when we know that we will be reading a character from the input buffer and
- // that this character will be part of the result token. This occurs in (f.e.)
- // string processing, because we know we need to read until we find the
- // closing '"' character.
- //
- // The second interface is the combination of getCharAndSize with
- // ConsumeChar. getCharAndSize reads a phase 1/2 translated character,
- // returning it and its size. If the lexer decides that this character is
- // part of the current token, it calls ConsumeChar on it. This two stage
- // approach allows us to emit diagnostics for characters (e.g. warnings about
- // trigraphs), knowing that they only are emitted if the character is
- // consumed.
-
- /// isObviouslySimpleCharacter - Return true if the specified character is
- /// obviously the same in translation phase 1 and translation phase 3. This
- /// can return false for characters that end up being the same, but it will
- /// never return true for something that needs to be mapped.
- static bool isObviouslySimpleCharacter(char C) {
- return C != '?' && C != '\\';
- }
-
- /// getAndAdvanceChar - Read a single 'character' from the specified buffer,
- /// advance over it, and return it. This is tricky in several cases. Here we
- /// just handle the trivial case and fall-back to the non-inlined
- /// getCharAndSizeSlow method to handle the hard case.
- inline char getAndAdvanceChar(const char *&Ptr, Token &Tok) {
- // If this is not a trigraph and not a UCN or escaped newline, return
- // quickly.
- if (isObviouslySimpleCharacter(Ptr[0])) return *Ptr++;
-
- unsigned Size = 0;
- char C = getCharAndSizeSlow(Ptr, Size, &Tok);
- Ptr += Size;
- return C;
- }
-
- /// ConsumeChar - When a character (identified by getCharAndSize) is consumed
- /// and added to a given token, check to see if there are diagnostics that
- /// need to be emitted or flags that need to be set on the token. If so, do
- /// it.
- const char *ConsumeChar(const char *Ptr, unsigned Size, Token &Tok) {
- // Normal case, we consumed exactly one token. Just return it.
- if (Size == 1)
- return Ptr+Size;
-
- // Otherwise, re-lex the character with a current token, allowing
- // diagnostics to be emitted and flags to be set.
- Size = 0;
- getCharAndSizeSlow(Ptr, Size, &Tok);
- return Ptr+Size;
- }
-
- /// getCharAndSize - Peek a single 'character' from the specified buffer,
- /// get its size, and return it. This is tricky in several cases. Here we
- /// just handle the trivial case and fall-back to the non-inlined
- /// getCharAndSizeSlow method to handle the hard case.
- inline char getCharAndSize(const char *Ptr, unsigned &Size) {
- // If this is not a trigraph and not a UCN or escaped newline, return
- // quickly.
- if (isObviouslySimpleCharacter(Ptr[0])) {
- Size = 1;
- return *Ptr;
- }
-
- Size = 0;
- return getCharAndSizeSlow(Ptr, Size);
- }
-
- /// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize
- /// method.
- char getCharAndSizeSlow(const char *Ptr, unsigned &Size,
- Token *Tok = nullptr);
-
- /// getEscapedNewLineSize - Return the size of the specified escaped newline,
- /// or 0 if it is not an escaped newline. P[-1] is known to be a "\" on entry
- /// to this function.
- static unsigned getEscapedNewLineSize(const char *P);
-
- /// SkipEscapedNewLines - If P points to an escaped newline (or a series of
- /// them), skip over them and return the first non-escaped-newline found,
- /// otherwise return P.
- static const char *SkipEscapedNewLines(const char *P);
-
- /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
- /// diagnostic.
- static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &LangOpts);
-
- //===--------------------------------------------------------------------===//
- // Other lexer functions.
-
- void SkipBytes(unsigned Bytes, bool StartOfLine);
-
- void PropagateLineStartLeadingSpaceInfo(Token &Result);
-
- const char *LexUDSuffix(Token &Result, const char *CurPtr,
- bool IsStringLiteral);
-
- // Helper functions to lex the remainder of a token of the specific type.
- bool LexIdentifier (Token &Result, const char *CurPtr);
- bool LexNumericConstant (Token &Result, const char *CurPtr);
- bool LexStringLiteral (Token &Result, const char *CurPtr,
- tok::TokenKind Kind);
- bool LexRawStringLiteral (Token &Result, const char *CurPtr,
- tok::TokenKind Kind);
- bool LexAngledStringLiteral(Token &Result, const char *CurPtr);
- bool LexCharConstant (Token &Result, const char *CurPtr,
- tok::TokenKind Kind);
- bool LexEndOfFile (Token &Result, const char *CurPtr);
- bool SkipWhitespace (Token &Result, const char *CurPtr,
- bool &TokAtPhysicalStartOfLine);
- bool SkipLineComment (Token &Result, const char *CurPtr,
- bool &TokAtPhysicalStartOfLine);
- bool SkipBlockComment (Token &Result, const char *CurPtr,
- bool &TokAtPhysicalStartOfLine);
- bool SaveLineComment (Token &Result, const char *CurPtr);
-
- bool IsStartOfConflictMarker(const char *CurPtr);
- bool HandleEndOfConflictMarker(const char *CurPtr);
-
- bool isCodeCompletionPoint(const char *CurPtr) const;
- void cutOffLexing() { BufferPtr = BufferEnd; }
-
- bool isHexaLiteral(const char *Start, const LangOptions &LangOpts);
-
-
- /// Read a universal character name.
- ///
- /// \param CurPtr The position in the source buffer after the initial '\'.
- /// If the UCN is syntactically well-formed (but not necessarily
- /// valid), this parameter will be updated to point to the
- /// character after the UCN.
- /// \param SlashLoc The position in the source buffer of the '\'.
- /// \param Tok The token being formed. Pass \c NULL to suppress diagnostics
- /// and handle token formation in the caller.
- ///
- /// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is
- /// 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
- /// location.
- /// \param CurPtr Initially points to the range of characters in the source
- /// buffer containing the '\'. Updated to point past the end of
- /// the UCN on success.
- /// \param Size The number of characters occupied by the '\' (including
- /// trigraphs and escaped newlines).
- /// \param Result The token being produced. Marked as containing a UCN on
- /// success.
- /// \return \c true if a UCN was lexed and it produced an acceptable
- /// identifier character, \c false otherwise.
- bool tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size,
- Token &Result);
-
- /// \brief 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
- /// character was lexed, \c false otherwise.
- bool tryConsumeIdentifierUTF8Char(const char *&CurPtr);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
deleted file mode 100644
index 5210e3f..0000000
--- a/include/clang/Lex/LiteralSupport.h
+++ /dev/null
@@ -1,260 +0,0 @@
-//===--- LiteralSupport.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 the NumericLiteralParser, CharLiteralParser, and
-// StringLiteralParser interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_LITERALSUPPORT_H
-#define LLVM_CLANG_LEX_LITERALSUPPORT_H
-
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/TokenKinds.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace clang {
-
-class DiagnosticsEngine;
-class Preprocessor;
-class Token;
-class SourceLocation;
-class TargetInfo;
-class SourceManager;
-class LangOptions;
-
-/// Copy characters from Input to Buf, expanding any UCNs.
-void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input);
-
-/// NumericLiteralParser - This performs strict semantic analysis of the content
-/// of a ppnumber, classifying it as either integer, floating, or erroneous,
-/// determines the radix of the value and can convert it to a useful value.
-class NumericLiteralParser {
- Preprocessor &PP; // needed for diagnostics
-
- const char *const ThisTokBegin;
- const char *const ThisTokEnd;
- const char *DigitsBegin, *SuffixBegin; // markers
- const char *s; // cursor
-
- unsigned radix;
-
- bool saw_exponent, saw_period, saw_ud_suffix;
-
- SmallString<32> UDSuffixBuf;
-
-public:
- NumericLiteralParser(StringRef TokSpelling,
- SourceLocation TokLoc,
- Preprocessor &PP);
- bool hadError : 1;
- bool isUnsigned : 1;
- bool isLong : 1; // This is *not* set for long long.
- bool isLongLong : 1;
- bool isFloat : 1; // 1.0f
- bool isImaginary : 1; // 1.0i
- uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
-
- bool isIntegerLiteral() const {
- return !saw_period && !saw_exponent;
- }
- bool isFloatingLiteral() const {
- return saw_period || saw_exponent;
- }
-
- bool hasUDSuffix() const {
- return saw_ud_suffix;
- }
- StringRef getUDSuffix() const {
- assert(saw_ud_suffix);
- return UDSuffixBuf;
- }
- unsigned getUDSuffixOffset() const {
- assert(saw_ud_suffix);
- return SuffixBegin - ThisTokBegin;
- }
-
- static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix);
-
- unsigned getRadix() const { return radix; }
-
- /// GetIntegerValue - Convert this numeric literal value to an APInt that
- /// matches Val's input width. If there is an overflow (i.e., if the unsigned
- /// value read is larger than the APInt's bits will hold), set Val to the low
- /// bits of the result and return true. Otherwise, return false.
- bool GetIntegerValue(llvm::APInt &Val);
-
- /// GetFloatValue - Convert this numeric literal to a floating value, using
- /// the specified APFloat fltSemantics (specifying float, double, etc).
- /// The optional bool isExact (passed-by-reference) has its value
- /// set to true if the returned APFloat can represent the number in the
- /// literal exactly, and false otherwise.
- llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result);
-
-private:
-
- void ParseNumberStartingWithZero(SourceLocation TokLoc);
-
- static bool isDigitSeparator(char C) { return C == '\''; }
-
- enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits };
-
- /// \brief Ensure that we don't have a digit separator here.
- void checkSeparator(SourceLocation TokLoc, const char *Pos,
- CheckSeparatorKind IsAfterDigits);
-
- /// SkipHexDigits - Read and skip over any hex digits, up to End.
- /// Return a pointer to the first non-hex digit or End.
- const char *SkipHexDigits(const char *ptr) {
- while (ptr != ThisTokEnd && (isHexDigit(*ptr) || isDigitSeparator(*ptr)))
- ptr++;
- return ptr;
- }
-
- /// SkipOctalDigits - Read and skip over any octal digits, up to End.
- /// Return a pointer to the first non-hex digit or End.
- const char *SkipOctalDigits(const char *ptr) {
- while (ptr != ThisTokEnd &&
- ((*ptr >= '0' && *ptr <= '7') || isDigitSeparator(*ptr)))
- ptr++;
- return ptr;
- }
-
- /// SkipDigits - Read and skip over any digits, up to End.
- /// Return a pointer to the first non-hex digit or End.
- const char *SkipDigits(const char *ptr) {
- while (ptr != ThisTokEnd && (isDigit(*ptr) || isDigitSeparator(*ptr)))
- ptr++;
- return ptr;
- }
-
- /// SkipBinaryDigits - Read and skip over any binary digits, up to End.
- /// Return a pointer to the first non-binary digit or End.
- const char *SkipBinaryDigits(const char *ptr) {
- while (ptr != ThisTokEnd &&
- (*ptr == '0' || *ptr == '1' || isDigitSeparator(*ptr)))
- ptr++;
- return ptr;
- }
-
-};
-
-/// CharLiteralParser - Perform interpretation and semantic analysis of a
-/// character literal.
-class CharLiteralParser {
- uint64_t Value;
- tok::TokenKind Kind;
- bool IsMultiChar;
- bool HadError;
- SmallString<32> UDSuffixBuf;
- unsigned UDSuffixOffset;
-public:
- CharLiteralParser(const char *begin, const char *end,
- SourceLocation Loc, Preprocessor &PP,
- tok::TokenKind kind);
-
- bool hadError() const { return HadError; }
- bool isAscii() const { return Kind == tok::char_constant; }
- bool isWide() const { return Kind == tok::wide_char_constant; }
- bool isUTF16() const { return Kind == tok::utf16_char_constant; }
- bool isUTF32() const { return Kind == tok::utf32_char_constant; }
- bool isMultiChar() const { return IsMultiChar; }
- uint64_t getValue() const { return Value; }
- StringRef getUDSuffix() const { return UDSuffixBuf; }
- unsigned getUDSuffixOffset() const {
- assert(!UDSuffixBuf.empty() && "no ud-suffix");
- return UDSuffixOffset;
- }
-};
-
-/// StringLiteralParser - This decodes string escape characters and performs
-/// wide string analysis and Translation Phase #6 (concatenation of string
-/// literals) (C99 5.1.1.2p1).
-class StringLiteralParser {
- const SourceManager &SM;
- const LangOptions &Features;
- const TargetInfo &Target;
- DiagnosticsEngine *Diags;
-
- unsigned MaxTokenLength;
- unsigned SizeBound;
- unsigned CharByteWidth;
- tok::TokenKind Kind;
- SmallString<512> ResultBuf;
- char *ResultPtr; // cursor
- SmallString<32> UDSuffixBuf;
- unsigned UDSuffixToken;
- unsigned UDSuffixOffset;
-public:
- StringLiteralParser(ArrayRef<Token> StringToks,
- Preprocessor &PP, bool Complain = true);
- StringLiteralParser(ArrayRef<Token> StringToks,
- const SourceManager &sm, const LangOptions &features,
- const TargetInfo &target,
- DiagnosticsEngine *diags = nullptr)
- : SM(sm), Features(features), Target(target), Diags(diags),
- MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
- ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
- init(StringToks);
- }
-
-
- bool hadError;
- bool Pascal;
-
- StringRef GetString() const {
- return StringRef(ResultBuf.data(), GetStringLength());
- }
- unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); }
-
- unsigned GetNumStringChars() const {
- return GetStringLength() / CharByteWidth;
- }
- /// getOffsetOfStringByte - This function returns the offset of the
- /// specified byte of the string data represented by Token. This handles
- /// advancing over escape sequences in the string.
- ///
- /// If the Diagnostics pointer is non-null, then this will do semantic
- /// checking of the string literal and emit errors and warnings.
- unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const;
-
- bool isAscii() const { return Kind == tok::string_literal; }
- bool isWide() const { return Kind == tok::wide_string_literal; }
- bool isUTF8() const { return Kind == tok::utf8_string_literal; }
- bool isUTF16() const { return Kind == tok::utf16_string_literal; }
- bool isUTF32() const { return Kind == tok::utf32_string_literal; }
- bool isPascal() const { return Pascal; }
-
- StringRef getUDSuffix() const { return UDSuffixBuf; }
-
- /// Get the index of a token containing a ud-suffix.
- unsigned getUDSuffixToken() const {
- assert(!UDSuffixBuf.empty() && "no ud-suffix");
- return UDSuffixToken;
- }
- /// Get the spelling offset of the first byte of the ud-suffix.
- unsigned getUDSuffixOffset() const {
- assert(!UDSuffixBuf.empty() && "no ud-suffix");
- return UDSuffixOffset;
- }
-
-private:
- void init(ArrayRef<Token> StringToks);
- bool CopyStringFragment(const Token &Tok, const char *TokBegin,
- StringRef Fragment);
- void DiagnoseLexingError(SourceLocation Loc);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
deleted file mode 100644
index 243b143..0000000
--- a/include/clang/Lex/MacroArgs.h
+++ /dev/null
@@ -1,127 +0,0 @@
-//===--- MacroArgs.h - Formal argument info for Macros ----------*- 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 MacroArgs interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_MACROARGS_H
-#define LLVM_CLANG_LEX_MACROARGS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include <vector>
-
-namespace clang {
- class MacroInfo;
- class Preprocessor;
- class Token;
- class SourceLocation;
-
-/// MacroArgs - An instance of this class captures information about
-/// the formal arguments specified to a function-like macro invocation.
-class MacroArgs {
- /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
- /// arguments. All of the actual argument tokens are allocated immediately
- /// after the MacroArgs object in memory. This is all of the arguments
- /// concatenated together, with 'EOF' markers at the end of each argument.
- unsigned NumUnexpArgTokens;
-
- /// VarargsElided - True if this is a C99 style varargs macro invocation and
- /// there was no argument specified for the "..." argument. If the argument
- /// was specified (even empty) or this isn't a C99 style varargs function, or
- /// if in strict mode and the C99 varargs macro had only a ... argument, this
- /// is false.
- bool VarargsElided;
-
- /// PreExpArgTokens - Pre-expanded tokens for arguments that need them. Empty
- /// if not yet computed. This includes the EOF marker at the end of the
- /// stream.
- std::vector<std::vector<Token> > PreExpArgTokens;
-
- /// StringifiedArgs - This contains arguments in 'stringified' form. If the
- /// stringified form of an argument has not yet been computed, this is empty.
- std::vector<Token> StringifiedArgs;
-
- /// ArgCache - This is a linked list of MacroArgs objects that the
- /// Preprocessor owns which we use to avoid thrashing malloc/free.
- MacroArgs *ArgCache;
-
- MacroArgs(unsigned NumToks, bool varargsElided)
- : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided),
- ArgCache(nullptr) {}
- ~MacroArgs() = default;
-
-public:
- /// MacroArgs ctor function - Create a new MacroArgs object with the specified
- /// macro and argument info.
- static MacroArgs *create(const MacroInfo *MI,
- ArrayRef<Token> UnexpArgTokens,
- bool VarargsElided, Preprocessor &PP);
-
- /// destroy - Destroy and deallocate the memory for this object.
- ///
- void destroy(Preprocessor &PP);
-
- /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
- /// by pre-expansion, return false. Otherwise, conservatively return true.
- bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const;
-
- /// getUnexpArgument - Return a pointer to the first token of the unexpanded
- /// token list for the specified formal.
- ///
- const Token *getUnexpArgument(unsigned Arg) const;
-
- /// getArgLength - Given a pointer to an expanded or unexpanded argument,
- /// return the number of tokens, not counting the EOF, that make up the
- /// argument.
- static unsigned getArgLength(const Token *ArgPtr);
-
- /// getPreExpArgument - Return the pre-expanded form of the specified
- /// argument.
- const std::vector<Token> &
- getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP);
-
- /// getStringifiedArgument - Compute, cache, and return the specified argument
- /// that has been 'stringified' as required by the # operator.
- const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP,
- SourceLocation ExpansionLocStart,
- SourceLocation ExpansionLocEnd);
-
- /// getNumArguments - Return the number of arguments passed into this macro
- /// invocation.
- unsigned getNumArguments() const { return NumUnexpArgTokens; }
-
-
- /// isVarargsElidedUse - Return true if this is a C99 style varargs macro
- /// invocation and there was no argument specified for the "..." argument. If
- /// the argument was specified (even empty) or this isn't a C99 style varargs
- /// function, or if in strict mode and the C99 varargs macro had only a ...
- /// argument, this returns false.
- bool isVarargsElidedUse() const { return VarargsElided; }
-
- /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
- /// tokens into the literal string token that should be produced by the C #
- /// preprocessor operator. If Charify is true, then it should be turned into
- /// a character literal for the Microsoft charize (#@) extension.
- ///
- static Token StringifyArgument(const Token *ArgToks,
- Preprocessor &PP, bool Charify,
- SourceLocation ExpansionLocStart,
- SourceLocation ExpansionLocEnd);
-
-
- /// deallocate - This should only be called by the Preprocessor when managing
- /// its freelist.
- MacroArgs *deallocate();
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
deleted file mode 100644
index 320645e..0000000
--- a/include/clang/Lex/MacroInfo.h
+++ /dev/null
@@ -1,609 +0,0 @@
-//===--- MacroInfo.h - Information about #defined identifiers ---*- 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::MacroInfo and clang::MacroDirective classes.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_MACROINFO_H
-#define LLVM_CLANG_LEX_MACROINFO_H
-
-#include "clang/Lex/Token.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Allocator.h"
-#include <cassert>
-
-namespace clang {
-class Module;
-class ModuleMacro;
-class Preprocessor;
-
-/// \brief 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.
- SourceLocation Location;
- /// \brief The location of the last token in the macro.
- SourceLocation EndLocation;
-
- /// \brief The list of arguments for a function-like macro.
- ///
- /// ArgumentList points to the first of NumArguments pointers.
- ///
- /// This can be empty, for, e.g. "#define X()". In a C99-style variadic
- /// macro, this includes the \c __VA_ARGS__ identifier on the list.
- IdentifierInfo **ArgumentList;
-
- /// \see ArgumentList
- unsigned NumArguments;
-
- /// \brief This is the list of tokens that the macro is defined to.
- SmallVector<Token, 8> ReplacementTokens;
-
- /// \brief 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.
- bool IsFunctionLike : 1;
-
- /// \brief 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...)".
- ///
- /// 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.
- ///
- /// 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__"
- bool HasCommaPasting : 1;
-
- //===--------------------------------------------------------------------===//
- // State that changes as the macro is used.
-
- /// \brief 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
- /// 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.
- bool IsAllowRedefinitionsWithoutWarning : 1;
-
- /// \brief Must warn if the macro is unused at the end of translation unit.
- bool IsWarnIfUnused : 1;
-
- /// \brief Whether this macro info was loaded from an AST file.
- unsigned FromASTFile : 1;
-
- /// \brief Whether this macro was used as header guard.
- bool UsedForHeaderGuard : 1;
-
- // Only the Preprocessor gets to create and destroy these.
- MacroInfo(SourceLocation DefLoc);
- ~MacroInfo() = default;
-
-public:
- /// \brief 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.
- void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; }
-
- /// \brief Return the location of the last token in the macro.
- SourceLocation getDefinitionEndLoc() const { return EndLocation; }
-
- /// \brief Get length in characters of the macro definition.
- unsigned getDefinitionLength(SourceManager &SM) const {
- if (IsDefinitionLengthCached)
- return DefinitionLength;
- return getDefinitionLengthSlow(SM);
- }
-
- /// \brief 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
- /// if they use different identifiers for the function macro parameters.
- /// Otherwise the comparison is lexical and this implements the rules in
- /// C99 6.10.3.
- bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
- bool Syntactically) const;
-
- /// \brief Set or clear the isBuiltinMacro flag.
- void setIsBuiltinMacro(bool Val = true) { IsBuiltinMacro = Val; }
-
- /// \brief Set the value of the IsUsed flag.
- void setIsUsed(bool Val) { IsUsed = Val; }
-
- /// \brief Set the value of the IsAllowRedefinitionsWithoutWarning flag.
- void setIsAllowRedefinitionsWithoutWarning(bool Val) {
- IsAllowRedefinitionsWithoutWarning = Val;
- }
-
- /// \brief Set the value of the IsWarnIfUnused flag.
- void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
-
- /// \brief Set the specified list of identifiers as the argument list for
- /// this macro.
- void setArgumentList(ArrayRef<IdentifierInfo *> List,
- llvm::BumpPtrAllocator &PPAllocator) {
- assert(ArgumentList == nullptr && NumArguments == 0 &&
- "Argument list already set!");
- if (List.empty())
- return;
-
- NumArguments = List.size();
- ArgumentList = PPAllocator.Allocate<IdentifierInfo *>(List.size());
- std::copy(List.begin(), List.end(), ArgumentList);
- }
-
- /// Arguments - The list of arguments for a function-like macro. This can be
- /// empty, for, e.g. "#define X()".
- typedef IdentifierInfo *const *arg_iterator;
- bool arg_empty() const { return NumArguments == 0; }
- arg_iterator arg_begin() const { return ArgumentList; }
- arg_iterator arg_end() const { return ArgumentList + NumArguments; }
- unsigned getNumArgs() const { return NumArguments; }
- ArrayRef<const IdentifierInfo *> args() const {
- return ArrayRef<const IdentifierInfo *>(ArgumentList, NumArguments);
- }
-
- /// \brief Return the argument number of the specified identifier,
- /// or -1 if the identifier is not a formal argument identifier.
- int getArgumentNum(const IdentifierInfo *Arg) const {
- for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
- if (*I == Arg)
- return I - arg_begin();
- return -1;
- }
-
- /// Function/Object-likeness. Keep track of whether this macro has formal
- /// parameters.
- void setIsFunctionLike() { IsFunctionLike = true; }
- bool isFunctionLike() const { return IsFunctionLike; }
- bool isObjectLike() const { return !IsFunctionLike; }
-
- /// Varargs querying methods. This can only be set for function-like macros.
- void setIsC99Varargs() { IsC99Varargs = true; }
- void setIsGNUVarargs() { IsGNUVarargs = true; }
- bool isC99Varargs() const { return IsC99Varargs; }
- bool isGNUVarargs() const { return IsGNUVarargs; }
- bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
-
- /// \brief 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
- /// from the "<built-in>" buffer are not reported as builtins by this
- /// function.
- bool isBuiltinMacro() const { return IsBuiltinMacro; }
-
- bool hasCommaPasting() const { return HasCommaPasting; }
- void setHasCommaPasting() { HasCommaPasting = true; }
-
- /// \brief 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.
- bool isAllowRedefinitionsWithoutWarning() const {
- return IsAllowRedefinitionsWithoutWarning;
- }
-
- /// \brief 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.
- ///
- unsigned getNumTokens() const { return ReplacementTokens.size(); }
-
- const Token &getReplacementToken(unsigned Tok) const {
- assert(Tok < ReplacementTokens.size() && "Invalid token #");
- return ReplacementTokens[Tok];
- }
-
- typedef SmallVectorImpl<Token>::const_iterator tokens_iterator;
- tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
- tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
- 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.
- void AddTokenToBody(const Token &Tok) {
- assert(
- !IsDefinitionLengthCached &&
- "Changing replacement tokens after definition length got calculated");
- ReplacementTokens.push_back(Tok);
- }
-
- /// \brief 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; }
-
- void EnableMacro() {
- assert(IsDisabled && "Cannot enable an already-enabled macro!");
- IsDisabled = false;
- }
-
- void DisableMacro() {
- assert(!IsDisabled && "Cannot disable an already-disabled macro!");
- IsDisabled = true;
- }
-
- /// \brief Determine whether this macro info came from an AST file (such as
- /// a precompiled header or module) rather than having been parsed.
- bool isFromASTFile() const { return FromASTFile; }
-
- /// \brief Determine whether this macro was used for a header guard.
- bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; }
-
- void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; }
-
- /// \brief Retrieve the global ID of the module that owns this particular
- /// macro info.
- unsigned getOwningModuleID() const {
- if (isFromASTFile())
- return *(const unsigned *)(this + 1);
-
- return 0;
- }
-
- void dump() const;
-
-private:
- unsigned getDefinitionLengthSlow(SourceManager &SM) const;
-
- void setOwningModuleID(unsigned ID) {
- assert(isFromASTFile());
- *(unsigned *)(this + 1) = ID;
- }
-
- friend class Preprocessor;
-};
-
-class DefMacroDirective;
-
-/// \brief 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
-/// history. Usually a macro definition (MacroInfo) is where a macro name
-/// becomes active (MacroDirective) but #pragma push_macro / pop_macro can
-/// create additional DefMacroDirectives for the same MacroInfo.
-class MacroDirective {
-public:
- enum Kind { MD_Define, MD_Undefine, MD_Visibility };
-
-protected:
- /// \brief Previous macro directive for the same identifier, or NULL.
- MacroDirective *Previous;
-
- SourceLocation Loc;
-
- /// \brief MacroDirective kind.
- unsigned MDKind : 2;
-
- /// \brief True if the macro directive was loaded from a PCH file.
- bool IsFromPCH : 1;
-
- // Used by VisibilityMacroDirective ----------------------------------------//
-
- /// \brief Whether the macro has public visibility (when described in a
- /// module).
- bool IsPublic : 1;
-
- MacroDirective(Kind K, SourceLocation Loc)
- : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
- IsPublic(true) {}
-
-public:
- Kind getKind() const { return Kind(MDKind); }
-
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief 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.
- const MacroDirective *getPrevious() const { return Previous; }
-
- /// \brief 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.
- bool isFromPCH() const { return IsFromPCH; }
-
- void setIsFromPCH() { IsFromPCH = true; }
-
- class DefInfo {
- DefMacroDirective *DefDirective;
- SourceLocation UndefLoc;
- bool IsPublic;
-
- public:
- DefInfo() : DefDirective(nullptr), IsPublic(true) {}
-
- DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
- bool isPublic)
- : DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) {}
-
- const DefMacroDirective *getDirective() const { return DefDirective; }
- DefMacroDirective *getDirective() { return DefDirective; }
-
- inline SourceLocation getLocation() const;
- inline MacroInfo *getMacroInfo();
- const MacroInfo *getMacroInfo() const {
- return const_cast<DefInfo *>(this)->getMacroInfo();
- }
-
- SourceLocation getUndefLocation() const { return UndefLoc; }
- bool isUndefined() const { return UndefLoc.isValid(); }
-
- bool isPublic() const { return IsPublic; }
-
- bool isValid() const { return DefDirective != nullptr; }
- bool isInvalid() const { return !isValid(); }
-
- explicit operator bool() const { return isValid(); }
-
- inline DefInfo getPreviousDefinition();
- const DefInfo getPreviousDefinition() const {
- return const_cast<DefInfo *>(this)->getPreviousDefinition();
- }
- };
-
- /// \brief 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();
- const DefInfo getDefinition() const {
- return const_cast<MacroDirective *>(this)->getDefinition();
- }
-
- bool isDefined() const {
- if (const DefInfo Def = getDefinition())
- return !Def.isUndefined();
- return false;
- }
-
- const MacroInfo *getMacroInfo() const {
- return getDefinition().getMacroInfo();
- }
- MacroInfo *getMacroInfo() { return getDefinition().getMacroInfo(); }
-
- /// \brief 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;
-
- void dump() const;
-
- static bool classof(const MacroDirective *) { return true; }
-};
-
-/// \brief A directive for a defined macro or a macro imported from a module.
-class DefMacroDirective : public MacroDirective {
- MacroInfo *Info;
-
-public:
- DefMacroDirective(MacroInfo *MI, SourceLocation Loc)
- : MacroDirective(MD_Define, Loc), Info(MI) {
- assert(MI && "MacroInfo is null");
- }
- explicit DefMacroDirective(MacroInfo *MI)
- : DefMacroDirective(MI, MI->getDefinitionLoc()) {}
-
- /// \brief The data for the macro definition.
- const MacroInfo *getInfo() const { return Info; }
- MacroInfo *getInfo() { return Info; }
-
- static bool classof(const MacroDirective *MD) {
- return MD->getKind() == MD_Define;
- }
- static bool classof(const DefMacroDirective *) { return true; }
-};
-
-/// \brief A directive for an undefined macro.
-class UndefMacroDirective : public MacroDirective {
-public:
- explicit UndefMacroDirective(SourceLocation UndefLoc)
- : MacroDirective(MD_Undefine, UndefLoc) {
- assert(UndefLoc.isValid() && "Invalid UndefLoc!");
- }
-
- static bool classof(const MacroDirective *MD) {
- return MD->getKind() == MD_Undefine;
- }
- static bool classof(const UndefMacroDirective *) { return true; }
-};
-
-/// \brief A directive for setting the module visibility of a macro.
-class VisibilityMacroDirective : public MacroDirective {
-public:
- explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
- : MacroDirective(MD_Visibility, Loc) {
- IsPublic = Public;
- }
-
- /// \brief Determine whether this macro is part of the public API of its
- /// module.
- bool isPublic() const { return IsPublic; }
-
- static bool classof(const MacroDirective *MD) {
- return MD->getKind() == MD_Visibility;
- }
- static bool classof(const VisibilityMacroDirective *) { return true; }
-};
-
-inline SourceLocation MacroDirective::DefInfo::getLocation() const {
- if (isInvalid())
- return SourceLocation();
- return DefDirective->getLocation();
-}
-
-inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
- if (isInvalid())
- return nullptr;
- return DefDirective->getInfo();
-}
-
-inline MacroDirective::DefInfo
-MacroDirective::DefInfo::getPreviousDefinition() {
- if (isInvalid() || DefDirective->getPrevious() == nullptr)
- return DefInfo();
- return DefDirective->getPrevious()->getDefinition();
-}
-
-/// \brief 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
-/// represent the macro override graph.
-///
-/// These are stored in a FoldingSet in the preprocessor.
-class ModuleMacro : public llvm::FoldingSetNode {
- /// The name defined by the macro.
- IdentifierInfo *II;
- /// The body of the #define, or nullptr if this is a #undef.
- MacroInfo *Macro;
- /// The module that exports this macro.
- Module *OwningModule;
- /// The number of module macros that override this one.
- unsigned NumOverriddenBy;
- /// The number of modules whose macros are directly overridden by this one.
- unsigned NumOverrides;
- // ModuleMacro *OverriddenMacros[NumOverrides];
-
- friend class Preprocessor;
-
- ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
- ArrayRef<ModuleMacro *> Overrides)
- : II(II), Macro(Macro), OwningModule(OwningModule), NumOverriddenBy(0),
- NumOverrides(Overrides.size()) {
- std::copy(Overrides.begin(), Overrides.end(),
- reinterpret_cast<ModuleMacro **>(this + 1));
- }
-
-public:
- static ModuleMacro *create(Preprocessor &PP, Module *OwningModule,
- IdentifierInfo *II, MacroInfo *Macro,
- ArrayRef<ModuleMacro *> Overrides);
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- return Profile(ID, OwningModule, II);
- }
- static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule,
- IdentifierInfo *II) {
- ID.AddPointer(OwningModule);
- ID.AddPointer(II);
- }
-
- /// Get the ID of the module that exports this macro.
- Module *getOwningModule() const { return OwningModule; }
-
- /// Get definition for this exported #define, or nullptr if this
- /// represents a #undef.
- MacroInfo *getMacroInfo() const { return Macro; }
-
- /// Iterators over the overridden module IDs.
- /// \{
- typedef ModuleMacro *const *overrides_iterator;
- overrides_iterator overrides_begin() const {
- return reinterpret_cast<overrides_iterator>(this + 1);
- }
- overrides_iterator overrides_end() const {
- return overrides_begin() + NumOverrides;
- }
- ArrayRef<ModuleMacro *> overrides() const {
- return llvm::makeArrayRef(overrides_begin(), overrides_end());
- }
- /// \}
-
- /// Get the number of macros that override this one.
- unsigned getNumOverridingMacros() const { return NumOverriddenBy; }
-};
-
-/// \brief 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.
-class MacroDefinition {
- llvm::PointerIntPair<DefMacroDirective *, 1, bool> LatestLocalAndAmbiguous;
- ArrayRef<ModuleMacro *> ModuleMacros;
-
-public:
- MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {}
- MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs,
- bool IsAmbiguous)
- : LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {}
-
- /// \brief 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.
- MacroInfo *getMacroInfo() const {
- if (!ModuleMacros.empty())
- return ModuleMacros.back()->getMacroInfo();
- if (auto *MD = getLocalDirective())
- return MD->getMacroInfo();
- return nullptr;
- }
-
- /// \brief \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
- /// for this macro.
- DefMacroDirective *getLocalDirective() const {
- return LatestLocalAndAmbiguous.getPointer();
- }
-
- /// \brief Get the active module macros for this macro.
- ArrayRef<ModuleMacro *> getModuleMacros() const { return ModuleMacros; }
-
- template <typename Fn> void forAllDefinitions(Fn F) const {
- if (auto *MD = getLocalDirective())
- F(MD->getMacroInfo());
- for (auto *MM : getModuleMacros())
- F(MM->getMacroInfo());
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
deleted file mode 100644
index ae79650..0000000
--- a/include/clang/Lex/ModuleLoader.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- ModuleLoader.h - Module Loader Interface ---------------*- 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 ModuleLoader interface, which is responsible for
-// loading named modules.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_MODULELOADER_H
-#define LLVM_CLANG_LEX_MODULELOADER_H
-
-#include "clang/Basic/Module.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/PointerIntPair.h"
-
-namespace clang {
-
-class GlobalModuleIndex;
-class IdentifierInfo;
-class Module;
-
-/// \brief A sequence of identifier/location pairs used to describe a particular
-/// module or submodule, e.g., std.vector.
-typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath;
-
-/// \brief Describes the result of attempting to load a module.
-class ModuleLoadResult {
- llvm::PointerIntPair<Module *, 1, bool> Storage;
-
-public:
- ModuleLoadResult() : Storage() { }
-
- ModuleLoadResult(Module *module, bool missingExpected)
- : Storage(module, missingExpected) { }
-
- operator Module *() const { return Storage.getPointer(); }
-
- /// \brief 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(); }
-};
-
-/// \brief 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
-/// then loading that module.
-class ModuleLoader {
- // Building a module if true.
- bool BuildingModule;
-public:
- explicit ModuleLoader(bool BuildingModule = false) :
- BuildingModule(BuildingModule),
- HadFatalFailure(false) {}
-
- virtual ~ModuleLoader();
-
- /// \brief Returns true if this instance is building a module.
- bool buildingModule() const {
- return BuildingModule;
- }
- /// \brief Flag indicating whether this instance is building a module.
- void setBuildingModule(bool BuildingModuleFlag) {
- BuildingModule = BuildingModuleFlag;
- }
-
- /// \brief Attempt to load the given module.
- ///
- /// This routine attempts to load the module described by the given
- /// parameters.
- ///
- /// \param ImportLoc The location of the 'import' keyword.
- ///
- /// \param Path The identifiers (and their locations) of the module
- /// "path", e.g., "std.vector" would be split into "std" and "vector".
- ///
- /// \param Visibility The visibility provided for the names in the loaded
- /// module.
- ///
- /// \param IsInclusionDirective Indicates that this module is being loaded
- /// implicitly, due to the presence of an inclusion directive. Otherwise,
- /// it is being loaded due to an import declaration.
- ///
- /// \returns If successful, returns the loaded module. Otherwise, returns
- /// NULL to indicate that the module could not be loaded.
- virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) = 0;
-
- /// \brief Make the given module visible.
- virtual void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc) = 0;
-
- /// \brief 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.
- /// Also, importantly, if the index doesn't cover all the modules
- /// in the module map, it will be update to do so here, because
- /// of its use in searching for needed module imports and
- /// associated fixit messages.
- /// \param TriggerLoc The location for what triggered the load.
- /// \returns Returns null if load failed.
- virtual GlobalModuleIndex *loadGlobalModuleIndex(
- SourceLocation TriggerLoc) = 0;
-
- /// Check global module index for missing imports.
- /// \param Name The symbol name to look for.
- /// \param TriggerLoc The location for what triggered the load.
- /// \returns Returns true if any modules with that symbol found.
- virtual bool lookupMissingImports(StringRef Name,
- SourceLocation TriggerLoc) = 0;
-
- bool HadFatalFailure;
-};
-
-}
-
-#endif
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
deleted file mode 100644
index 155943e..0000000
--- a/include/clang/Lex/ModuleMap.h
+++ /dev/null
@@ -1,514 +0,0 @@
-//===--- ModuleMap.h - Describe the layout of modules -----------*- 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 ModuleMap interface, which describes the layout of a
-// module as it relates to headers.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_LEX_MODULEMAP_H
-#define LLVM_CLANG_LEX_MODULEMAP_H
-
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <string>
-
-namespace clang {
-
-class DirectoryEntry;
-class FileEntry;
-class FileManager;
-class DiagnosticConsumer;
-class DiagnosticsEngine;
-class HeaderSearch;
-class ModuleMapParser;
-
-/// \brief A mechanism to observe the actions of the module map parser as it
-/// reads module map files.
-class ModuleMapCallbacks {
-public:
- virtual ~ModuleMapCallbacks() {}
-
- /// \brief Called when a module map file has been read.
- ///
- /// \param FileStart A SourceLocation referring to the start of the file's
- /// contents.
- /// \param File The file itself.
- /// \param IsSystem Whether this is a module map from a system include path.
- virtual void moduleMapFileRead(SourceLocation FileStart,
- const FileEntry &File, bool IsSystem) {}
-};
-
-class ModuleMap {
- SourceManager &SourceMgr;
- DiagnosticsEngine &Diags;
- const LangOptions &LangOpts;
- const TargetInfo *Target;
- HeaderSearch &HeaderInfo;
-
- llvm::SmallVector<std::unique_ptr<ModuleMapCallbacks>, 1> Callbacks;
-
- /// \brief The directory used for Clang-supplied, builtin include headers,
- /// such as "stdint.h".
- const DirectoryEntry *BuiltinIncludeDir;
-
- /// \brief Language options used to parse the module map itself.
- ///
- /// These are always simple C language options.
- LangOptions MMapLangOpts;
-
- // The module that we are building; related to \c LangOptions::CurrentModule.
- Module *CompilingModule;
-
-public:
- // The module that the .cc source file is associated with.
- Module *SourceModule;
- std::string SourceModuleName;
-
-private:
- /// \brief The top-level modules that are known.
- llvm::StringMap<Module *> Modules;
-
- /// \brief The number of modules we have created in total.
- unsigned NumCreatedModules;
-
-public:
- /// \brief Flags describing the role of a module header.
- enum ModuleHeaderRole {
- /// \brief This header is normally included in the module.
- NormalHeader = 0x0,
- /// \brief This header is included but private.
- PrivateHeader = 0x1,
- /// \brief This header is part of the module (for layering purposes) but
- /// should be textually included.
- TextualHeader = 0x2,
- // Caution: Adding an enumerator needs other changes.
- // Adjust the number of bits for KnownHeader::Storage.
- // Adjust the bitfield HeaderFileInfo::HeaderRole size.
- // Adjust the HeaderFileInfoTrait::ReadData streaming.
- // Adjust the HeaderFileInfoTrait::EmitData streaming.
- // Adjust ModuleMap::addHeader.
- };
-
- /// \brief 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;
-
- public:
- KnownHeader() : Storage(nullptr, NormalHeader) { }
- KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { }
-
- friend bool operator==(const KnownHeader &A, const KnownHeader &B) {
- return A.Storage == B.Storage;
- }
- friend bool operator!=(const KnownHeader &A, const KnownHeader &B) {
- return A.Storage != B.Storage;
- }
-
- /// \brief Retrieve the module the header is stored in.
- Module *getModule() const { return Storage.getPointer(); }
-
- /// \brief The role of this header within the module.
- ModuleHeaderRole getRole() const { return Storage.getInt(); }
-
- /// \brief Whether this header is available in the module.
- bool isAvailable() const {
- return getModule()->isAvailable();
- }
-
- // \brief Whether this known header is valid (i.e., it has an
- // associated module).
- explicit operator bool() const {
- return Storage.getPointer() != nullptr;
- }
- };
-
- typedef llvm::SmallPtrSet<const FileEntry *, 1> AdditionalModMapsSet;
-
-private:
- typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> >
- HeadersMap;
-
- /// \brief Mapping from each header to the module that owns the contents of
- /// that header.
- HeadersMap Headers;
-
- /// \brief 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
- /// in the module map over to the module that includes them via its umbrella
- /// header.
- llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
-
- /// \brief The set of attributes that can be attached to a module.
- struct Attributes {
- Attributes() : IsSystem(), IsExternC(), IsExhaustive() {}
-
- /// \brief Whether this is a system module.
- unsigned IsSystem : 1;
-
- /// \brief Whether this is an extern "C" module.
- unsigned IsExternC : 1;
-
- /// \brief Whether this is an exhaustive set of configuration macros.
- unsigned IsExhaustive : 1;
- };
-
- /// \brief A directory for which framework modules can be inferred.
- struct InferredDirectory {
- InferredDirectory() : InferModules() {}
-
- /// \brief Whether to infer modules from this directory.
- unsigned InferModules : 1;
-
- /// \brief The attributes to use for inferred modules.
- Attributes Attrs;
-
- /// \brief 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
- /// directory.
- SmallVector<std::string, 2> ExcludedModules;
- };
-
- /// \brief A mapping from directories to information about inferring
- /// framework modules from within those directories.
- llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories;
-
- /// A mapping from an inferred module to the module map that allowed the
- /// inference.
- llvm::DenseMap<const Module *, const FileEntry *> InferredModuleAllowedBy;
-
- llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps;
-
- /// \brief Describes whether we haved parsed a particular file as a module
- /// map.
- llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
-
- friend class ModuleMapParser;
-
- /// \brief Resolve the given export declaration into an actual export
- /// declaration.
- ///
- /// \param Mod The module in which we're resolving the export declaration.
- ///
- /// \param Unresolved The export declaration to resolve.
- ///
- /// \param Complain Whether this routine should complain about unresolvable
- /// exports.
- ///
- /// \returns The resolved export declaration, which will have a NULL pointer
- /// if the export could not be resolved.
- Module::ExportDecl
- resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved,
- bool Complain) const;
-
- /// \brief Resolve the given module id to an actual module.
- ///
- /// \param Id The module-id to resolve.
- ///
- /// \param Mod The module in which we're resolving the module-id.
- ///
- /// \param Complain Whether this routine should complain about unresolvable
- /// module-ids.
- ///
- /// \returns The resolved module, or null if the module-id could not be
- /// resolved.
- Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
-
- /// \brief 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.
- ///
- /// \param File The header to search for.
- ///
- /// \param IntermediateDirs On success, contains the set of directories
- /// searched before finding \p File.
- KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File,
- SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs);
-
- /// \brief 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)
- /// in an umbrella directory.
- bool isHeaderInUmbrellaDirs(const FileEntry *File) {
- SmallVector<const DirectoryEntry *, 2> IntermediateDirs;
- return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs));
- }
-
- Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir,
- Attributes Attrs, Module *Parent);
-
-public:
- /// \brief 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,
- /// since they will refer to the same headers.
- ///
- /// \param Diags A diagnostic engine used for diagnostics.
- ///
- /// \param LangOpts Language options for this translation unit.
- ///
- /// \param Target The target for this translation unit.
- ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
- const LangOptions &LangOpts, const TargetInfo *Target,
- HeaderSearch &HeaderInfo);
-
- /// \brief Destroy the module map.
- ///
- ~ModuleMap();
-
- /// \brief Set the target information.
- void setTarget(const TargetInfo &Target);
-
- /// \brief 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 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.
- ///
- /// \param File The header file that is likely to be included.
- ///
- /// \returns The module KnownHeader, which provides the module that owns the
- /// given header file. The KnownHeader is default constructed to indicate
- /// that no module owns this header file.
- KnownHeader findModuleForHeader(const FileEntry *File);
-
- /// \brief 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.
- ///
- /// Typically, \ref findModuleForHeader should be used instead, as it picks
- /// the preferred module for the header.
- ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File) const;
-
- /// \brief Reports errors if a module must not include a specific file.
- ///
- /// \param RequestingModule The module including a file.
- ///
- /// \param FilenameLoc The location of the inclusion's filename.
- ///
- /// \param Filename The included filename as written.
- ///
- /// \param File The included file.
- void diagnoseHeaderInclusion(Module *RequestingModule,
- SourceLocation FilenameLoc, StringRef Filename,
- const FileEntry *File);
-
- /// \brief 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
- /// of the specified module.
- bool isHeaderUnavailableInModule(const FileEntry *Header,
- const Module *RequestingModule) const;
-
- /// \brief 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,
- /// starting at the given context.
- ///
- /// \param Name The name of the module to look up.
- ///
- /// \param Context The module context, from which we will perform lexical
- /// name lookup.
- ///
- /// \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,
- /// using direct (qualified) name lookup.
- ///
- /// \param Name The name of the module to look up.
- ///
- /// \param Context The module for which we will look for a submodule. If
- /// null, we will look for a top-level module.
- ///
- /// \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
- /// exist.
- ///
- /// \param Name The name of the module to find or create.
- ///
- /// \param Parent The module that will act as the parent of this submodule,
- /// or NULL to indicate that this is a top-level module.
- ///
- /// \param IsFramework Whether this is a framework module.
- ///
- /// \param IsExplicit Whether this is an explicit submodule.
- ///
- /// \returns The found or newly-created module, along with a boolean value
- /// that will be true if the module is newly-created.
- std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
- bool IsFramework,
- bool IsExplicit);
-
- /// \brief 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
- /// module.
- ///
- /// \param Module The module whose module map file will be returned, if known.
- ///
- /// \returns The file entry for the module map file containing the given
- /// module, or NULL 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
- /// identifies this module.
- ///
- /// The particular module that \c Name refers to may depend on how the module
- /// was found in header search. However, the combination of \c Name and
- /// this module map will be globally unique for top-level modules. In the case
- /// of inferred modules, returns the module map that allowed the inference
- /// (e.g. contained 'module *'). Otherwise, returns
- /// getContainingModuleMapFile().
- const FileEntry *getModuleMapFileForUniquing(const Module *M) const;
-
- void setInferredModuleAllowedBy(Module *M, const FileEntry *ModuleMap);
-
- /// \brief 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.
- AdditionalModMapsSet *getAdditionalModuleMapFiles(const Module *M) {
- auto I = AdditionalModMaps.find(M);
- if (I == AdditionalModMaps.end())
- return nullptr;
- return &I->second;
- }
-
- void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap) {
- AdditionalModMaps[M].insert(ModuleMap);
- }
-
- /// \brief Resolve all of the unresolved exports in the given module.
- ///
- /// \param Mod The module whose exports should be resolved.
- ///
- /// \param Complain Whether to emit diagnostics for failures.
- ///
- /// \returns true if any errors were encountered while resolving exports,
- /// false otherwise.
- bool resolveExports(Module *Mod, bool Complain);
-
- /// \brief Resolve all of the unresolved uses in the given module.
- ///
- /// \param Mod The module whose uses should be resolved.
- ///
- /// \param Complain Whether to emit diagnostics for failures.
- ///
- /// \returns true if any errors were encountered while resolving uses,
- /// false otherwise.
- bool resolveUses(Module *Mod, bool Complain);
-
- /// \brief Resolve all of the unresolved conflicts in the given module.
- ///
- /// \param Mod The module whose conflicts should be resolved.
- ///
- /// \param Complain Whether to emit diagnostics for failures.
- ///
- /// \returns true if any errors were encountered while resolving conflicts,
- /// false otherwise.
- bool resolveConflicts(Module *Mod, bool Complain);
-
- /// \brief Infers the (sub)module based on the given source location and
- /// source manager.
- ///
- /// \param Loc The location within the source that we are querying, along
- /// with its source manager.
- ///
- /// \returns The module that owns this source location, or null if no
- /// module owns this source location.
- Module *inferModuleFromLocation(FullSourceLoc Loc);
-
- /// \brief 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
- /// directory.
- void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
- Twine NameAsWritten);
-
- /// \brief 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.
- void excludeHeader(Module *Mod, Module::Header Header);
-
- /// \brief Parse the given module map file, and record any modules we
- /// encounter.
- ///
- /// \param File The file to be parsed.
- ///
- /// \param IsSystem Whether this module map file is in a system header
- /// directory, and therefore should be considered a system module.
- ///
- /// \param HomeDir The directory in which relative paths within this module
- /// map file will be resolved.
- ///
- /// \param ExternModuleLoc The location of the "extern module" declaration
- /// that caused us to load this module map file, if any.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool parseModuleMapFile(const FileEntry *File, bool IsSystem,
- const DirectoryEntry *HomeDir,
- SourceLocation ExternModuleLoc = SourceLocation());
-
- /// \brief Dump the contents of the module map, for debugging purposes.
- void dump();
-
- typedef llvm::StringMap<Module *>::const_iterator module_iterator;
- module_iterator module_begin() const { return Modules.begin(); }
- module_iterator module_end() const { return Modules.end(); }
-};
-
-}
-#endif
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
deleted file mode 100644
index 83e6f99..0000000
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ /dev/null
@@ -1,181 +0,0 @@
-//===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- 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 MultipleIncludeOpt interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H
-#define LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H
-
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-class IdentifierInfo;
-
-/// \brief 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
-/// events that occur when a file is lexed, and after the entire file is lexed,
-/// information about which macro (if any) controls the header is returned.
-class MultipleIncludeOpt {
- /// ReadAnyTokens - This is set to false when a file is first opened and true
- /// any time a token is returned to the client or a (non-multiple-include)
- /// directive is parsed. When the final \#endif is parsed this is reset back
- /// to false, that way any tokens before the first \#ifdef or after the last
- /// \#endif can be easily detected.
- bool ReadAnyTokens;
-
- /// ImmediatelyAfterTopLevelIfndef - This is true when the only tokens
- /// processed in the file so far is an #ifndef and an identifier. Used in
- /// the detection of header guards in a file.
- bool ImmediatelyAfterTopLevelIfndef;
-
- /// ReadAnyTokens - This is set to false when a file is first opened and true
- /// any time a token is returned to the client or a (non-multiple-include)
- /// directive is parsed. When the final #endif is parsed this is reset back
- /// to false, that way any tokens before the first #ifdef or after the last
- /// #endif can be easily detected.
- bool DidMacroExpansion;
-
- /// TheMacro - The controlling macro for a file, if valid.
- ///
- const IdentifierInfo *TheMacro;
-
- /// DefinedMacro - The macro defined right after TheMacro, if any.
- const IdentifierInfo *DefinedMacro;
-
- SourceLocation MacroLoc;
- SourceLocation DefinedLoc;
-public:
- MultipleIncludeOpt() {
- ReadAnyTokens = false;
- ImmediatelyAfterTopLevelIfndef = false;
- DidMacroExpansion = false;
- TheMacro = nullptr;
- DefinedMacro = nullptr;
- }
-
- SourceLocation GetMacroLocation() const {
- return MacroLoc;
- }
-
- SourceLocation GetDefinedLocation() const {
- return DefinedLoc;
- }
-
- void resetImmediatelyAfterTopLevelIfndef() {
- ImmediatelyAfterTopLevelIfndef = false;
- }
-
- void SetDefinedMacro(IdentifierInfo *M, SourceLocation Loc) {
- DefinedMacro = M;
- DefinedLoc = Loc;
- }
-
- /// Invalidate - Permanently mark this file as not being suitable for the
- /// include-file optimization.
- void Invalidate() {
- // If we have read tokens but have no controlling macro, the state-machine
- // below can never "accept".
- ReadAnyTokens = true;
- ImmediatelyAfterTopLevelIfndef = false;
- DefinedMacro = nullptr;
- TheMacro = nullptr;
- }
-
- /// getHasReadAnyTokensVal - This is used for the \#ifndef hande-shake at the
- /// top of the file when reading preprocessor directives. Otherwise, reading
- /// the "ifndef x" would count as reading tokens.
- bool getHasReadAnyTokensVal() const { return ReadAnyTokens; }
-
- /// getImmediatelyAfterTopLevelIfndef - returns true if the last directive
- /// was an #ifndef at the beginning of the file.
- bool getImmediatelyAfterTopLevelIfndef() const {
- return ImmediatelyAfterTopLevelIfndef;
- }
-
- // If a token is read, remember that we have seen a side-effect in this file.
- void ReadToken() {
- ReadAnyTokens = true;
- ImmediatelyAfterTopLevelIfndef = false;
- }
-
- /// ExpandedMacro - When a macro is expanded with this lexer as the current
- /// 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
- /// "\#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.
- void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc) {
- // If the macro is already set, this is after the top-level #endif.
- if (TheMacro)
- return Invalidate();
-
- // If we have already expanded a macro by the end of the #ifndef line, then
- // there is a macro expansion *in* the #ifndef line. This means that the
- // condition could evaluate differently when subsequently #included. Reject
- // this.
- if (DidMacroExpansion)
- return Invalidate();
-
- // Remember that we're in the #if and that we have the macro.
- ReadAnyTokens = true;
- ImmediatelyAfterTopLevelIfndef = true;
- TheMacro = M;
- MacroLoc = Loc;
- }
-
- /// \brief 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.
- 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
- // #endif.
- if (!TheMacro) return Invalidate();
-
- // At this point, we haven't "read any tokens" but we do have a controlling
- // macro.
- ReadAnyTokens = false;
- ImmediatelyAfterTopLevelIfndef = false;
- }
-
- /// \brief 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
- // macro if it's valid (if it isn't, it will be null).
- if (!ReadAnyTokens)
- return TheMacro;
- return nullptr;
- }
-
- /// \brief If the ControllingMacro is followed by a macro definition, return
- /// the macro that was defined.
- const IdentifierInfo *GetDefinedMacro() const {
- return DefinedMacro;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
deleted file mode 100644
index 68b8f1c..0000000
--- a/include/clang/Lex/PPCallbacks.h
+++ /dev/null
@@ -1,509 +0,0 @@
-//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- 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 PPCallbacks interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
-#define LLVM_CLANG_LEX_PPCALLBACKS_H
-
-#include "clang/Basic/DiagnosticIDs.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/DirectoryLookup.h"
-#include "clang/Lex/ModuleLoader.h"
-#include "clang/Lex/Pragma.h"
-#include "llvm/ADT/StringRef.h"
-#include <string>
-
-namespace clang {
- class SourceLocation;
- class Token;
- class IdentifierInfo;
- class MacroDefinition;
- class MacroDirective;
- class MacroArgs;
-
-/// \brief 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.
-class PPCallbacks {
-public:
- virtual ~PPCallbacks();
-
- enum FileChangeReason {
- EnterFile, ExitFile, SystemHeaderPragma, RenameFile
- };
-
- /// \brief 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.
- virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- SrcMgr::CharacteristicKind FileType,
- FileID PrevFID = FileID()) {
- }
-
- /// \brief 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
- ///
- /// \param FilenameTok The file name token in \#include "FileName" directive
- /// or macro expanded file name token from \#include MACRO(PARAMS) directive.
- /// Note that FilenameTok contains corresponding quotes/angles symbols.
- virtual void FileSkipped(const FileEntry &SkippedFile,
- const Token &FilenameTok,
- SrcMgr::CharacteristicKind FileType) {
- }
-
- /// \brief 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
- /// source code.
- ///
- /// \param RecoveryPath If this client indicates that it can recover from
- /// this missing file, the client should set this as an additional header
- /// search patch.
- ///
- /// \returns true to indicate that the preprocessor should attempt to recover
- /// by adding \p RecoveryPath as a header search path.
- virtual bool FileNotFound(StringRef FileName,
- SmallVectorImpl<char> &RecoveryPath) {
- return false;
- }
-
- /// \brief 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.
- ///
- /// \param HashLoc The location of the '#' that starts the inclusion
- /// directive.
- ///
- /// \param IncludeTok The token that indicates the kind of inclusion
- /// directive, e.g., 'include' or 'import'.
- ///
- /// \param FileName The name of the file being included, as written in the
- /// source code.
- ///
- /// \param IsAngled Whether the file name was enclosed in angle brackets;
- /// otherwise, it was enclosed in quotes.
- ///
- /// \param FilenameRange The character range of the quotes or angle brackets
- /// for the written file name.
- ///
- /// \param File The actual file that may be included by this inclusion
- /// directive.
- ///
- /// \param SearchPath Contains the search path which was used to find the file
- /// in the file system. If the file was found via an absolute include path,
- /// SearchPath will be empty. For framework includes, the SearchPath and
- /// RelativePath will be split up. For example, if an include of "Some/Some.h"
- /// is found via the framework path
- /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
- /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
- /// "Some.h".
- ///
- /// \param RelativePath The path relative to SearchPath, at which the include
- /// file was found. This is equal to FileName except for framework includes.
- ///
- /// \param Imported The module, whenever an inclusion directive was
- /// automatically turned into a module import or null otherwise.
- ///
- virtual void InclusionDirective(SourceLocation HashLoc,
- const Token &IncludeTok,
- StringRef FileName,
- bool IsAngled,
- CharSourceRange FilenameRange,
- const FileEntry *File,
- StringRef SearchPath,
- StringRef RelativePath,
- const Module *Imported) {
- }
-
- /// \brief Callback invoked whenever there was an explicit module-import
- /// syntax.
- ///
- /// \param ImportLoc The location of import directive token.
- ///
- /// \param Path The identifiers (and their locations) of the module
- /// "path", e.g., "std.vector" would be split into "std" and "vector".
- ///
- /// \param Imported The imported module; can be null if importing failed.
- ///
- virtual void moduleImport(SourceLocation ImportLoc,
- ModuleIdPath Path,
- const Module *Imported) {
- }
-
- /// \brief 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.
- /// \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.
- virtual void PragmaDirective(SourceLocation Loc,
- PragmaIntroducerKind Introducer) {
- }
-
- /// \brief 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
- /// read.
- virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
- StringRef Value) {
- }
-
- /// \brief 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.
- enum PragmaMessageKind {
- /// \brief \#pragma message has been invoked.
- PMK_Message,
-
- /// \brief \#pragma GCC warning has been invoked.
- PMK_Warning,
-
- /// \brief \#pragma GCC error has been invoked.
- PMK_Error
- };
-
- /// \brief 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.
- /// \param Str The text of the message directive.
- virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
- PragmaMessageKind Kind, StringRef Str) {
- }
-
- /// \brief 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
- /// is read.
- virtual void PragmaDiagnosticPop(SourceLocation Loc,
- StringRef Namespace) {
- }
-
- /// \brief 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
- /// 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.
- virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
- ArrayRef<int> Ids) {
- }
-
- /// \brief 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.
- virtual void PragmaWarningPop(SourceLocation Loc) {
- }
-
- /// \brief 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.
- virtual void MacroDefined(const Token &MacroNameTok,
- const MacroDirective *MD) {
- }
-
- /// \brief Hook called whenever a macro \#undef is seen.
- ///
- /// MD is released immediately following this callback.
- virtual void MacroUndefined(const Token &MacroNameTok,
- const MacroDefinition &MD) {
- }
-
- /// \brief 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.
- /// \param Range The SourceRange that was skipped. The range begins at the
- /// \#if/\#else directive and ends after the \#endif/\#else directive.
- virtual void SourceRangeSkipped(SourceRange Range) {
- }
-
- enum ConditionValueKind {
- CVK_NotEvaluated, CVK_False, CVK_True
- };
-
- /// \brief 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.
- ///
- // FIXME: better to pass in a list (or tree!) of Tokens.
- virtual void If(SourceLocation Loc, SourceRange ConditionRange,
- ConditionValueKind ConditionValue) {
- }
-
- /// \brief 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.
- /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
- // FIXME: better to pass in a list (or tree!) of Tokens.
- virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
- ConditionValueKind ConditionValue, SourceLocation IfLoc) {
- }
-
- /// \brief 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.
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDefinition &MD) {
- }
-
- /// \brief 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.
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDefinition &MD) {
- }
-
- /// \brief 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.
- /// \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.
-class PPChainedCallbacks : public PPCallbacks {
- virtual void anchor();
- std::unique_ptr<PPCallbacks> First, Second;
-
-public:
- PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,
- std::unique_ptr<PPCallbacks> _Second)
- : First(std::move(_First)), Second(std::move(_Second)) {}
-
- void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- SrcMgr::CharacteristicKind FileType,
- FileID PrevFID) override {
- First->FileChanged(Loc, Reason, FileType, PrevFID);
- Second->FileChanged(Loc, Reason, FileType, PrevFID);
- }
-
- void FileSkipped(const FileEntry &SkippedFile,
- const Token &FilenameTok,
- SrcMgr::CharacteristicKind FileType) override {
- First->FileSkipped(SkippedFile, FilenameTok, FileType);
- Second->FileSkipped(SkippedFile, FilenameTok, FileType);
- }
-
- bool FileNotFound(StringRef FileName,
- SmallVectorImpl<char> &RecoveryPath) override {
- return First->FileNotFound(FileName, RecoveryPath) ||
- Second->FileNotFound(FileName, RecoveryPath);
- }
-
- void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
- StringRef FileName, bool IsAngled,
- CharSourceRange FilenameRange, const FileEntry *File,
- StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override {
- First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
- FilenameRange, File, SearchPath, RelativePath,
- Imported);
- Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
- FilenameRange, File, SearchPath, RelativePath,
- Imported);
- }
-
- void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
- const Module *Imported) override {
- First->moduleImport(ImportLoc, Path, Imported);
- Second->moduleImport(ImportLoc, Path, Imported);
- }
-
- void EndOfMainFile() override {
- First->EndOfMainFile();
- Second->EndOfMainFile();
- }
-
- void Ident(SourceLocation Loc, StringRef str) override {
- First->Ident(Loc, str);
- Second->Ident(Loc, str);
- }
-
- void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
- StringRef Str) override {
- First->PragmaComment(Loc, Kind, Str);
- Second->PragmaComment(Loc, Kind, Str);
- }
-
- void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
- StringRef Value) override {
- First->PragmaDetectMismatch(Loc, Name, Value);
- Second->PragmaDetectMismatch(Loc, Name, Value);
- }
-
- void PragmaMessage(SourceLocation Loc, StringRef Namespace,
- PragmaMessageKind Kind, StringRef Str) override {
- First->PragmaMessage(Loc, Namespace, Kind, Str);
- Second->PragmaMessage(Loc, Namespace, Kind, Str);
- }
-
- void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
- First->PragmaDiagnosticPush(Loc, Namespace);
- Second->PragmaDiagnosticPush(Loc, Namespace);
- }
-
- void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
- First->PragmaDiagnosticPop(Loc, Namespace);
- Second->PragmaDiagnosticPop(Loc, Namespace);
- }
-
- void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
- diag::Severity mapping, StringRef Str) override {
- First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
- Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
- }
-
- void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
- SourceLocation StateLoc, unsigned State) override {
- First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
- Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
- }
-
- void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
- ArrayRef<int> Ids) override {
- First->PragmaWarning(Loc, WarningSpec, Ids);
- Second->PragmaWarning(Loc, WarningSpec, Ids);
- }
-
- void PragmaWarningPush(SourceLocation Loc, int Level) override {
- First->PragmaWarningPush(Loc, Level);
- Second->PragmaWarningPush(Loc, Level);
- }
-
- void PragmaWarningPop(SourceLocation Loc) override {
- First->PragmaWarningPop(Loc);
- Second->PragmaWarningPop(Loc);
- }
-
- void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
- SourceRange Range, const MacroArgs *Args) override {
- First->MacroExpands(MacroNameTok, MD, Range, Args);
- Second->MacroExpands(MacroNameTok, MD, Range, Args);
- }
-
- void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override {
- First->MacroDefined(MacroNameTok, MD);
- Second->MacroDefined(MacroNameTok, MD);
- }
-
- void MacroUndefined(const Token &MacroNameTok,
- const MacroDefinition &MD) override {
- First->MacroUndefined(MacroNameTok, MD);
- Second->MacroUndefined(MacroNameTok, MD);
- }
-
- void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
- SourceRange Range) override {
- First->Defined(MacroNameTok, MD, Range);
- Second->Defined(MacroNameTok, MD, Range);
- }
-
- void SourceRangeSkipped(SourceRange Range) override {
- First->SourceRangeSkipped(Range);
- Second->SourceRangeSkipped(Range);
- }
-
- /// \brief 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.
- 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.
- 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.
- 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.
- void Else(SourceLocation Loc, SourceLocation IfLoc) override {
- First->Else(Loc, IfLoc);
- Second->Else(Loc, IfLoc);
- }
-
- /// \brief Hook called whenever an \#endif is seen.
- void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
- First->Endif(Loc, IfLoc);
- Second->Endif(Loc, IfLoc);
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
deleted file mode 100644
index 8c52275..0000000
--- a/include/clang/Lex/PPConditionalDirectiveRecord.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- 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 PPConditionalDirectiveRecord class, which maintains
-// a record of conditional directive regions.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
-#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "llvm/ADT/SmallVector.h"
-#include <vector>
-
-namespace clang {
-
-/// \brief Records preprocessor conditional directive regions and allows
-/// querying in which region source locations belong to.
-class PPConditionalDirectiveRecord : public PPCallbacks {
- SourceManager &SourceMgr;
-
- SmallVector<SourceLocation, 6> CondDirectiveStack;
-
- class CondDirectiveLoc {
- SourceLocation Loc;
- SourceLocation RegionLoc;
-
- public:
- CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
- : Loc(Loc), RegionLoc(RegionLoc) {}
-
- SourceLocation getLoc() const { return Loc; }
- SourceLocation getRegionLoc() const { return RegionLoc; }
-
- class Comp {
- SourceManager &SM;
- public:
- explicit Comp(SourceManager &SM) : SM(SM) {}
- bool operator()(const CondDirectiveLoc &LHS,
- const CondDirectiveLoc &RHS) {
- return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
- }
- bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
- return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
- }
- bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
- return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
- }
- };
- };
-
- typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
- /// \brief The locations of conditional directives in source order.
- CondDirectiveLocsTy CondDirectiveLocs;
-
- void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
-
-public:
- /// \brief 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
- /// 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,
- /// separated by conditional directive blocks.
- bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
- SourceLocation RHS) const {
- return findConditionalDirectiveRegionLoc(LHS) !=
- findConditionalDirectiveRegionLoc(RHS);
- }
-
- SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
-
-private:
- void If(SourceLocation Loc, SourceRange ConditionRange,
- ConditionValueKind ConditionValue) override;
- void Elif(SourceLocation Loc, SourceRange ConditionRange,
- ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
- void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDefinition &MD) override;
- void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDefinition &MD) override;
- void Else(SourceLocation Loc, SourceLocation IfLoc) override;
- void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
deleted file mode 100644
index 904be79..0000000
--- a/include/clang/Lex/PTHLexer.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===--- PTHLexer.h - Lexer based on Pre-tokenized input --------*- 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 PTHLexer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PTHLEXER_H
-#define LLVM_CLANG_LEX_PTHLEXER_H
-
-#include "clang/Lex/PreprocessorLexer.h"
-
-namespace clang {
-
-class PTHManager;
-class PTHSpellingSearch;
-
-class PTHLexer : public PreprocessorLexer {
- SourceLocation FileStartLoc;
-
- /// TokBuf - Buffer from PTH file containing raw token data.
- const unsigned char* TokBuf;
-
- /// CurPtr - Pointer into current offset of the token buffer where
- /// the next token will be read.
- const unsigned char* CurPtr;
-
- /// LastHashTokPtr - Pointer into TokBuf of the last processed '#'
- /// token that appears at the start of a line.
- const unsigned char* LastHashTokPtr;
-
- /// PPCond - Pointer to a side table in the PTH file that provides a
- /// a consise summary of the preproccessor conditional block structure.
- /// This is used to perform quick skipping of conditional blocks.
- const unsigned char* PPCond;
-
- /// CurPPCondPtr - Pointer inside PPCond that refers to the next entry
- /// to process when doing quick skipping of preprocessor blocks.
- const unsigned char* CurPPCondPtr;
-
- PTHLexer(const PTHLexer &) = delete;
- void operator=(const PTHLexer &) = delete;
-
- /// ReadToken - Used by PTHLexer to read tokens TokBuf.
- void ReadToken(Token& T);
-
- bool LexEndOfFile(Token &Result);
-
- /// PTHMgr - The PTHManager object that created this PTHLexer.
- PTHManager& PTHMgr;
-
- Token EofToken;
-
-protected:
- friend class PTHManager;
-
- /// Create a PTHLexer for the specified token stream.
- PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D,
- const unsigned char* ppcond, PTHManager &PM);
-public:
- ~PTHLexer() override {}
-
- /// Lex - Return the next token.
- bool Lex(Token &Tok);
-
- void getEOF(Token &Tok);
-
- /// DiscardToEndOfLine - Read the rest of the current preprocessor line as an
- /// uninterpreted string. This switches the lexer out of directive mode.
- void DiscardToEndOfLine();
-
- /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
- /// tok::l_paren token, 0 if it is something else and 2 if there are no more
- /// tokens controlled by this lexer.
- unsigned isNextPPTokenLParen() {
- // isNextPPTokenLParen is not on the hot path, and all we care about is
- // whether or not we are at a token with kind tok::eof or tok::l_paren.
- // Just read the first byte from the current token pointer to determine
- // its kind.
- tok::TokenKind x = (tok::TokenKind)*CurPtr;
- return x == tok::eof ? 2 : x == tok::l_paren;
- }
-
- /// IndirectLex - An indirect call to 'Lex' that can be invoked via
- /// the PreprocessorLexer interface.
- void IndirectLex(Token &Result) override { Lex(Result); }
-
- /// getSourceLocation - Return a source location for the token in
- /// the current file.
- SourceLocation getSourceLocation() override;
-
- /// SkipBlock - Used by Preprocessor to skip the current conditional block.
- bool SkipBlock();
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
deleted file mode 100644
index 26178ed..0000000
--- a/include/clang/Lex/PTHManager.h
+++ /dev/null
@@ -1,150 +0,0 @@
-//===--- PTHManager.h - Manager object for PTH processing -------*- 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 PTHManager interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PTHMANAGER_H
-#define LLVM_CLANG_LEX_PTHMANAGER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Lex/PTHLexer.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/OnDiskHashTable.h"
-#include <string>
-
-namespace llvm {
- class MemoryBuffer;
-}
-
-namespace clang {
-
-class FileEntry;
-class PTHLexer;
-class DiagnosticsEngine;
-class FileSystemStatCache;
-
-class PTHManager : public IdentifierInfoLookup {
- friend class PTHLexer;
-
- friend class PTHStatCache;
-
- class PTHStringLookupTrait;
- class PTHFileLookupTrait;
- typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
- typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup;
-
- /// The memory mapped PTH file.
- std::unique_ptr<const llvm::MemoryBuffer> Buf;
-
- /// Alloc - Allocator used for IdentifierInfo objects.
- llvm::BumpPtrAllocator Alloc;
-
- /// IdMap - A lazily generated cache mapping from persistent identifiers to
- /// IdentifierInfo*.
- std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> PerIDCache;
-
- /// FileLookup - Abstract data structure used for mapping between files
- /// and token data in the PTH file.
- std::unique_ptr<PTHFileLookup> FileLookup;
-
- /// IdDataTable - Array representing the mapping from persistent IDs to the
- /// data offset within the PTH file containing the information to
- /// reconsitute an IdentifierInfo.
- const unsigned char* const IdDataTable;
-
- /// SortedIdTable - Abstract data structure mapping from strings to
- /// persistent IDs. This is used by get().
- std::unique_ptr<PTHStringIdLookup> StringIdLookup;
-
- /// NumIds - The number of identifiers in the PTH file.
- const unsigned NumIds;
-
- /// PP - The Preprocessor object that will use this PTHManager to create
- /// PTHLexer objects.
- Preprocessor* PP;
-
- /// SpellingBase - The base offset within the PTH memory buffer that
- /// contains the cached spellings for literals.
- const unsigned char* const SpellingBase;
-
- /// OriginalSourceFile - A null-terminated C-string that specifies the name
- /// if the file (if any) that was to used to generate the PTH cache.
- const char* OriginalSourceFile;
-
- /// This constructor is intended to only be called by the static 'Create'
- /// method.
- PTHManager(std::unique_ptr<const llvm::MemoryBuffer> buf,
- std::unique_ptr<PTHFileLookup> fileLookup,
- const unsigned char *idDataTable,
- std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> perIDCache,
- std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds,
- const unsigned char *spellingBase, const char *originalSourceFile);
-
- PTHManager(const PTHManager &) = delete;
- void operator=(const PTHManager &) = delete;
-
- /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached
- /// spelling for a token.
- unsigned getSpellingAtPTHOffset(unsigned PTHOffset, const char*& Buffer);
-
- /// GetIdentifierInfo - Used to reconstruct IdentifierInfo objects from the
- /// PTH file.
- inline IdentifierInfo* GetIdentifierInfo(unsigned PersistentID) {
- // Check if the IdentifierInfo has already been resolved.
- if (IdentifierInfo* II = PerIDCache[PersistentID])
- return II;
- return LazilyCreateIdentifierInfo(PersistentID);
- }
- IdentifierInfo* LazilyCreateIdentifierInfo(unsigned PersistentID);
-
-public:
- // The current PTH version.
- enum { Version = 10 };
-
- ~PTHManager() override;
-
- /// getOriginalSourceFile - Return the full path to the original header
- /// file name that was used to generate the PTH cache.
- const char* getOriginalSourceFile() const {
- return OriginalSourceFile;
- }
-
- /// get - Return the identifier token info 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.
- IdentifierInfo *get(StringRef Name) override;
-
- /// Create - This method creates PTHManager objects. The 'file' argument
- /// is the name of the PTH file. This method returns NULL upon failure.
- static PTHManager *Create(StringRef file, DiagnosticsEngine &Diags);
-
- void setPreprocessor(Preprocessor *pp) { PP = pp; }
-
- /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the
- /// specified file. This method returns NULL if no cached tokens exist.
- /// It is the responsibility of the caller to 'delete' the returned object.
- PTHLexer *CreateLexer(FileID FID);
-
- /// createStatCache - Returns a FileSystemStatCache object for use with
- /// FileManager objects. These objects use the PTH data to speed up
- /// calls to stat by memoizing their results from when the PTH file
- /// was generated.
- std::unique_ptr<FileSystemStatCache> createStatCache();
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
deleted file mode 100644
index 274f0da..0000000
--- a/include/clang/Lex/Pragma.h
+++ /dev/null
@@ -1,126 +0,0 @@
-//===--- Pragma.h - Pragma registration and handling ------------*- 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 PragmaHandler and PragmaTable interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PRAGMA_H
-#define LLVM_CLANG_LEX_PRAGMA_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <cassert>
-
-namespace clang {
- class Preprocessor;
- class Token;
- class IdentifierInfo;
- class PragmaNamespace;
-
- /**
- * \brief Describes how the pragma was introduced, e.g., with \#pragma,
- * _Pragma, or __pragma.
- */
- enum PragmaIntroducerKind {
- /**
- * \brief The pragma was introduced via \#pragma.
- */
- PIK_HashPragma,
-
- /**
- * \brief The pragma was introduced via the C99 _Pragma(string-literal).
- */
- PIK__Pragma,
-
- /**
- * \brief The pragma was introduced via the Microsoft
- * __pragma(token-string).
- */
- PIK___pragma
- };
-
-/// PragmaHandler - Instances of this interface defined to handle the various
-/// pragmas that the language front-end uses. Each handler optionally has a
-/// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
-/// that identifier is found. If a handler does not match any of the declared
-/// pragmas the handler with a null identifier is invoked, if it exists.
-///
-/// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
-/// we treat "\#pragma STDC" and "\#pragma GCC" as namespaces that contain other
-/// pragmas.
-class PragmaHandler {
- std::string Name;
-public:
- explicit PragmaHandler(StringRef name) : Name(name) {}
- PragmaHandler() {}
- virtual ~PragmaHandler();
-
- StringRef getName() const { return Name; }
- virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &FirstToken) = 0;
-
- /// getIfNamespace - If this is a namespace, return it. This is equivalent to
- /// using a dynamic_cast, but doesn't require RTTI.
- virtual PragmaNamespace *getIfNamespace() { return nullptr; }
-};
-
-/// EmptyPragmaHandler - A pragma handler which takes no action, which can be
-/// used to ignore particular pragmas.
-class EmptyPragmaHandler : public PragmaHandler {
-public:
- explicit EmptyPragmaHandler(StringRef Name = StringRef());
-
- void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &FirstToken) override;
-};
-
-/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
-/// allowing hierarchical pragmas to be defined. Common examples of namespaces
-/// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces
-/// may be (potentially recursively) defined.
-class PragmaNamespace : public PragmaHandler {
- /// Handlers - This is a map of the handlers in this namespace with their name
- /// as key.
- ///
- llvm::StringMap<PragmaHandler*> Handlers;
-public:
- explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
- ~PragmaNamespace() override;
-
- /// FindHandler - Check to see if there is already a handler for the
- /// specified name. If not, return the handler for the null name if it
- /// exists, otherwise return null. If IgnoreNull is true (the default) then
- /// the null handler isn't returned on failure to match.
- PragmaHandler *FindHandler(StringRef Name,
- bool IgnoreNull = true) const;
-
- /// AddPragma - Add a pragma to this namespace.
- ///
- void AddPragma(PragmaHandler *Handler);
-
- /// RemovePragmaHandler - Remove the given handler from the
- /// namespace.
- void RemovePragmaHandler(PragmaHandler *Handler);
-
- bool IsEmpty() {
- return Handlers.empty();
- }
-
- void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &FirstToken) override;
-
- PragmaNamespace *getIfNamespace() override { return this; }
-};
-
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
deleted file mode 100644
index 87b8ce1..0000000
--- a/include/clang/Lex/PreprocessingRecord.h
+++ /dev/null
@@ -1,536 +0,0 @@
-//===--- PreprocessingRecord.h - Record of Preprocessing --------*- 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 PreprocessingRecord class, which maintains a record
-// of what occurred during preprocessing.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
-#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
-#include <vector>
-
-namespace clang {
- class IdentifierInfo;
- class MacroInfo;
- class PreprocessingRecord;
-}
-
-/// \brief Allocates memory within a Clang preprocessing record.
-void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
- unsigned alignment = 8) LLVM_NOEXCEPT;
-
-/// \brief Frees memory allocated in a Clang preprocessing record.
-void operator delete(void *ptr, clang::PreprocessingRecord &PR,
- unsigned) LLVM_NOEXCEPT;
-
-namespace clang {
- class MacroDefinitionRecord;
- class FileEntry;
-
- /// \brief 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.
- enum EntityKind {
- /// \brief Indicates a problem trying to load the preprocessed entity.
- InvalidKind,
-
- /// \brief A macro expansion.
- MacroExpansionKind,
-
- /// \defgroup Preprocessing directives
- /// @{
-
- /// \brief A macro definition.
- MacroDefinitionKind,
-
- /// \brief An inclusion directive, such as \c \#include, \c
- /// \#import, or \c \#include_next.
- InclusionDirectiveKind,
-
- /// @}
-
- FirstPreprocessingDirective = MacroDefinitionKind,
- LastPreprocessingDirective = InclusionDirectiveKind
- };
-
- private:
- /// \brief The kind of preprocessed entity that this object describes.
- EntityKind Kind;
-
- /// \brief The source range that covers this preprocessed entity.
- SourceRange Range;
-
- protected:
- PreprocessedEntity(EntityKind Kind, SourceRange Range)
- : Kind(Kind), Range(Range) { }
-
- friend class PreprocessingRecord;
-
- public:
- /// \brief 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
- /// entity.
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- /// \brief Returns true if there was a problem loading the preprocessed
- /// entity.
- bool isInvalid() const { return Kind == InvalidKind; }
-
- // Only allow allocation of preprocessed entities using the allocator
- // in PreprocessingRecord or by doing a placement new.
- void *operator new(size_t bytes, PreprocessingRecord &PR,
- unsigned alignment = 8) LLVM_NOEXCEPT {
- return ::operator new(bytes, PR, alignment);
- }
-
- void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; }
-
- void operator delete(void *ptr, PreprocessingRecord &PR,
- unsigned alignment) LLVM_NOEXCEPT {
- return ::operator delete(ptr, PR, alignment);
- }
-
- void operator delete(void *, std::size_t) LLVM_NOEXCEPT {}
- void operator delete(void *, void *) LLVM_NOEXCEPT {}
-
- private:
- // Make vanilla 'new' and 'delete' illegal for preprocessed entities.
- void *operator new(size_t bytes) LLVM_NOEXCEPT;
- void operator delete(void *data) LLVM_NOEXCEPT;
- };
-
- /// \brief Records the presence of a preprocessor directive.
- class PreprocessingDirective : public PreprocessedEntity {
- public:
- PreprocessingDirective(EntityKind Kind, SourceRange Range)
- : PreprocessedEntity(Kind, Range) { }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const PreprocessedEntity *PD) {
- return PD->getKind() >= FirstPreprocessingDirective &&
- PD->getKind() <= LastPreprocessingDirective;
- }
- };
-
- /// \brief Record the location of a macro definition.
- class MacroDefinitionRecord : public PreprocessingDirective {
- /// \brief The name of the macro being defined.
- const IdentifierInfo *Name;
-
- public:
- explicit MacroDefinitionRecord(const IdentifierInfo *Name,
- SourceRange Range)
- : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) {}
-
- /// \brief 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.
- SourceLocation getLocation() const { return getSourceRange().getBegin(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const PreprocessedEntity *PE) {
- return PE->getKind() == MacroDefinitionKind;
- }
- };
-
- /// \brief 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
- /// a builtin macro.
- llvm::PointerUnion<IdentifierInfo *, MacroDefinitionRecord *> NameOrDef;
-
- public:
- MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range)
- : PreprocessedEntity(MacroExpansionKind, Range),
- NameOrDef(BuiltinName) {}
-
- MacroExpansion(MacroDefinitionRecord *Definition, SourceRange Range)
- : PreprocessedEntity(MacroExpansionKind, Range), NameOrDef(Definition) {
- }
-
- /// \brief True if it is a builtin macro.
- bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); }
-
- /// \brief 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
- /// this is a builtin macro.
- MacroDefinitionRecord *getDefinition() const {
- return NameOrDef.dyn_cast<MacroDefinitionRecord *>();
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const PreprocessedEntity *PE) {
- return PE->getKind() == MacroExpansionKind;
- }
- };
-
- /// \brief 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
- /// preprocessor.
- enum InclusionKind {
- /// \brief An \c \#include directive.
- Include,
- /// \brief An Objective-C \c \#import directive.
- Import,
- /// \brief A GNU \c \#include_next directive.
- IncludeNext,
- /// \brief A Clang \c \#__include_macros directive.
- IncludeMacros
- };
-
- private:
- /// \brief 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
- /// in angle brackets.
- unsigned InQuotes : 1;
-
- /// \brief 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
- /// a module import.
- unsigned ImportedModule : 1;
-
- /// \brief The file that was included.
- const FileEntry *File;
-
- public:
- InclusionDirective(PreprocessingRecord &PPRec,
- InclusionKind Kind, StringRef FileName,
- bool InQuotes, bool ImportedModule,
- const FileEntry *File, SourceRange Range);
-
- /// \brief 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.
- StringRef getFileName() const { return FileName; }
-
- /// \brief 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
- /// turned into a module import.
- bool importedModule() const { return ImportedModule; }
-
- /// \brief Retrieve the file entry for the actual file that was included
- /// by this directive.
- const FileEntry *getFile() const { return File; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const PreprocessedEntity *PE) {
- return PE->getKind() == InclusionDirectiveKind;
- }
- };
-
- /// \brief 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.
- ///
- /// \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
- /// 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
- /// entity with index \p Index came from file \p FID.
- virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
- FileID FID) {
- return None;
- }
- };
-
- /// \brief 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.
- llvm::BumpPtrAllocator BumpAlloc;
-
- /// \brief 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
- /// 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,
- std::vector<SourceRange> SkippedRanges;
-
- /// \brief 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.
- /// Value -1 corresponds to element 0 in the loaded entities vector,
- /// value -2 corresponds to element 1 in the loaded entities vector, etc.
- /// Value 0 is an invalid value, the index to local entities is 1-based,
- /// value 1 corresponds to element 0 in the local entities vector,
- /// value 2 corresponds to element 1 in the local entities vector, etc.
- class PPEntityID {
- int ID;
- explicit PPEntityID(int ID) : ID(ID) {}
- friend class PreprocessingRecord;
- public:
- PPEntityID() : ID(0) {}
- };
-
- static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) {
- return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1);
- }
-
- /// \brief Mapping from MacroInfo structures to their definitions.
- llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions;
-
- /// \brief External source of preprocessed entities.
- ExternalPreprocessingRecordSource *ExternalSource;
-
- /// \brief Retrieve the preprocessed entity at the given ID.
- PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID);
-
- /// \brief Retrieve the loaded preprocessed entity at the given index.
- PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index);
-
- /// \brief 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
- /// 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.
- ///
- /// \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.
- void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinitionRecord *Def);
-
- public:
- /// \brief Construct a new preprocessing record.
- explicit PreprocessingRecord(SourceManager &SM);
-
- /// \brief 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.
- void Deallocate(void *Ptr) { }
-
- size_t getTotalMemory() const;
-
- SourceManager &getSourceManager() const { return SourceMgr; }
-
- /// Iteration over the preprocessed entities.
- ///
- /// In a complete iteration, the iterator walks the range [-M, N),
- /// where 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.
- /// However, to provide iteration in source order (for, e.g., chained
- /// precompiled headers), dereferencing the iterator flips the negative
- /// values (corresponding to loaded entities), so that position -M
- /// corresponds to element 0 in the loaded entities vector, position -M+1
- /// corresponds to element 1 in the loaded entities vector, etc. This
- /// gives us a reasonably efficient, source-order walk.
- ///
- /// We define this as a wrapping iterator around an int. The
- /// iterator_adaptor_base class forwards the iterator methods to basic
- /// integer arithmetic.
- class iterator : public llvm::iterator_adaptor_base<
- iterator, int, std::random_access_iterator_tag,
- PreprocessedEntity *, int, PreprocessedEntity *,
- PreprocessedEntity *> {
- PreprocessingRecord *Self;
-
- iterator(PreprocessingRecord *Self, int Position)
- : iterator::iterator_adaptor_base(Position), Self(Self) {}
- friend class PreprocessingRecord;
-
- public:
- iterator() : iterator(nullptr, 0) {}
-
- PreprocessedEntity *operator*() const {
- bool isLoaded = this->I < 0;
- unsigned Index = isLoaded ?
- Self->LoadedPreprocessedEntities.size() + this->I : this->I;
- PPEntityID ID = Self->getPPEntityID(Index, isLoaded);
- return Self->getPreprocessedEntity(ID);
- }
- PreprocessedEntity *operator->() const { return **this; }
- };
-
- /// \brief Begin iterator for all preprocessed entities.
- iterator begin() {
- return iterator(this, -(int)LoadedPreprocessedEntities.size());
- }
-
- /// \brief End iterator for all preprocessed entities.
- iterator end() {
- return iterator(this, PreprocessedEntities.size());
- }
-
- /// \brief Begin iterator for local, non-loaded, preprocessed entities.
- iterator local_begin() {
- return iterator(this, 0);
- }
-
- /// \brief 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
- /// preprocessed entities.
- llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start,
- unsigned count) {
- unsigned end = start + count;
- assert(end <= LoadedPreprocessedEntities.size());
- return llvm::make_range(
- iterator(this, int(start) - LoadedPreprocessedEntities.size()),
- iterator(this, int(end) - LoadedPreprocessedEntities.size()));
- }
-
- /// \brief 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
- /// points to is coming from the file \p FID.
- ///
- /// Can be used to avoid implicit deserializations of preallocated
- /// preprocessed entities if we only care about entities of a specific file
- /// and not from files \#included in the range given at
- /// \see getPreprocessedEntitiesInRange.
- bool isEntityInFileID(iterator PPEI, FileID FID);
-
- /// \brief Add a new preprocessed entity to this record.
- PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity);
-
- /// \brief Set the external source for preprocessed entities.
- void SetExternalSource(ExternalPreprocessingRecordSource &Source);
-
- /// \brief Retrieve the external source for preprocessed entities.
- ExternalPreprocessingRecordSource *getExternalSource() const {
- return ExternalSource;
- }
-
- /// \brief 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 {
- return SkippedRanges;
- }
-
- private:
- void MacroExpands(const Token &Id, const MacroDefinition &MD,
- SourceRange Range, const MacroArgs *Args) override;
- void MacroDefined(const Token &Id, const MacroDirective *MD) override;
- void MacroUndefined(const Token &Id, const MacroDefinition &MD) override;
- void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
- StringRef FileName, bool IsAngled,
- CharSourceRange FilenameRange,
- const FileEntry *File, StringRef SearchPath,
- StringRef RelativePath,
- const Module *Imported) 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.
- void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
- SourceRange Range) override;
-
- void SourceRangeSkipped(SourceRange Range) override;
-
- void addMacroExpansion(const Token &Id, const MacroInfo *MI,
- SourceRange Range);
-
- /// \brief Cached result of the last \see getPreprocessedEntitiesInRange
- /// query.
- struct {
- SourceRange Range;
- std::pair<int, int> Result;
- } CachedRangeQuery;
-
- std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R);
-
- friend class ASTReader;
- friend class ASTWriter;
- };
-} // end namespace clang
-
-inline void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
- unsigned alignment) LLVM_NOEXCEPT {
- return PR.Allocate(bytes, alignment);
-}
-
-inline void operator delete(void *ptr, clang::PreprocessingRecord &PR,
- unsigned) LLVM_NOEXCEPT {
- PR.Deallocate(ptr);
-}
-
-#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
deleted file mode 100644
index f6154b6..0000000
--- a/include/clang/Lex/Preprocessor.h
+++ /dev/null
@@ -1,1911 +0,0 @@
-//===--- Preprocessor.h - C Language Family Preprocessor --------*- 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::Preprocessor interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
-#define LLVM_CLANG_LEX_PREPROCESSOR_H
-
-#include "clang/Basic/Builtins.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/ModuleMap.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/PTHLexer.h"
-#include "clang/Lex/TokenLexer.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Support/Allocator.h"
-#include <memory>
-#include <vector>
-
-namespace llvm {
- template<unsigned InternalLen> class SmallString;
-}
-
-namespace clang {
-
-class SourceManager;
-class ExternalPreprocessorSource;
-class FileManager;
-class FileEntry;
-class HeaderSearch;
-class PragmaNamespace;
-class PragmaHandler;
-class CommentHandler;
-class ScratchBuffer;
-class TargetInfo;
-class PPCallbacks;
-class CodeCompletionHandler;
-class DirectoryLookup;
-class PreprocessingRecord;
-class ModuleLoader;
-class PTHManager;
-class PreprocessorOptions;
-
-/// \brief Stores token information for comparing actual tokens with
-/// predefined values. Only handles simple tokens and identifiers.
-class TokenValue {
- tok::TokenKind Kind;
- IdentifierInfo *II;
-
-public:
- TokenValue(tok::TokenKind Kind) : Kind(Kind), II(nullptr) {
- assert(Kind != tok::raw_identifier && "Raw identifiers are not supported.");
- assert(Kind != tok::identifier &&
- "Identifiers should be created by TokenValue(IdentifierInfo *)");
- assert(!tok::isLiteral(Kind) && "Literals are not supported.");
- assert(!tok::isAnnotation(Kind) && "Annotations are not supported.");
- }
- TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {}
- bool operator==(const Token &Tok) const {
- return Tok.getKind() == Kind &&
- (!II || II == Tok.getIdentifierInfo());
- }
-};
-
-/// \brief Context in which macro name is used.
-enum MacroUse {
- MU_Other = 0, // other than #define or #undef
- MU_Define = 1, // macro name specified in #define
- MU_Undef = 2 // macro name specified in #undef
-};
-
-/// \brief 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
-/// know anything about preprocessor-level issues like the \#include stack,
-/// token expansion, etc.
-class Preprocessor : public RefCountedBase<Preprocessor> {
- IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
- DiagnosticsEngine *Diags;
- LangOptions &LangOpts;
- const TargetInfo *Target;
- const TargetInfo *AuxTarget;
- FileManager &FileMgr;
- SourceManager &SourceMgr;
- std::unique_ptr<ScratchBuffer> ScratchBuf;
- HeaderSearch &HeaderInfo;
- ModuleLoader &TheModuleLoader;
-
- /// \brief External source of macros.
- ExternalPreprocessorSource *ExternalSource;
-
-
- /// An optional PTHManager object used for getting tokens from
- /// a token cache rather than lexing the original source file.
- std::unique_ptr<PTHManager> PTH;
-
- /// A BumpPtrAllocator object used to quickly allocate and release
- /// objects internal to the Preprocessor.
- llvm::BumpPtrAllocator BP;
-
- /// Identifiers for builtin macros and other builtins.
- IdentifierInfo *Ident__LINE__, *Ident__FILE__; // __LINE__, __FILE__
- IdentifierInfo *Ident__DATE__, *Ident__TIME__; // __DATE__, __TIME__
- IdentifierInfo *Ident__INCLUDE_LEVEL__; // __INCLUDE_LEVEL__
- IdentifierInfo *Ident__BASE_FILE__; // __BASE_FILE__
- IdentifierInfo *Ident__TIMESTAMP__; // __TIMESTAMP__
- IdentifierInfo *Ident__COUNTER__; // __COUNTER__
- IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma
- IdentifierInfo *Ident__identifier; // __identifier
- IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__
- IdentifierInfo *Ident__has_feature; // __has_feature
- IdentifierInfo *Ident__has_extension; // __has_extension
- IdentifierInfo *Ident__has_builtin; // __has_builtin
- IdentifierInfo *Ident__has_attribute; // __has_attribute
- IdentifierInfo *Ident__has_include; // __has_include
- IdentifierInfo *Ident__has_include_next; // __has_include_next
- IdentifierInfo *Ident__has_warning; // __has_warning
- IdentifierInfo *Ident__is_identifier; // __is_identifier
- IdentifierInfo *Ident__building_module; // __building_module
- IdentifierInfo *Ident__MODULE__; // __MODULE__
- IdentifierInfo *Ident__has_cpp_attribute; // __has_cpp_attribute
- IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute
-
- SourceLocation DATELoc, TIMELoc;
- unsigned CounterValue; // Next __COUNTER__ value.
-
- enum {
- /// \brief Maximum depth of \#includes.
- MaxAllowedIncludeStackDepth = 200
- };
-
- // State that is set before the preprocessor begins.
- bool KeepComments : 1;
- bool KeepMacroComments : 1;
- bool SuppressIncludeNotFoundError : 1;
-
- // State that changes while the preprocessor runs:
- bool InMacroArgs : 1; // True if parsing fn macro invocation args.
-
- /// Whether the preprocessor owns the header search object.
- bool OwnsHeaderSearch : 1;
-
- /// True if macro expansion is disabled.
- bool DisableMacroExpansion : 1;
-
- /// Temporarily disables DisableMacroExpansion (i.e. enables expansion)
- /// when parsing preprocessor directives.
- bool MacroExpansionInDirectivesOverride : 1;
-
- class ResetMacroExpansionHelper;
-
- /// \brief Whether we have already loaded macros from the external source.
- mutable bool ReadMacrosFromExternalSource : 1;
-
- /// \brief True if pragmas are enabled.
- bool PragmasEnabled : 1;
-
- /// \brief 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
- bool ParsingIfOrElifDirective;
-
- /// \brief True if we are pre-expanding macro arguments.
- bool InMacroArgPreExpansion;
-
- /// \brief 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.
- ///
- /// Unlike IdentifierTable above, this table *isn't* populated by the
- /// preprocessor. It is declared/expanded here because its role/lifetime is
- /// conceptually similar to the IdentifierTable. In addition, the current
- /// control flow (in clang::ParseAST()), make it convenient to put here.
- ///
- /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
- /// the lifetime of the preprocessor.
- SelectorTable Selectors;
-
- /// \brief Information about builtins.
- Builtin::Context BuiltinInfo;
-
- /// \brief 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
- /// parsing of a model file.
- std::unique_ptr<PragmaNamespace> PragmaHandlersBackup;
-
- /// \brief 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
- /// avoid tearing the Lexer and etc. down).
- bool IncrementalProcessing;
-
- /// The kind of translation unit we are processing.
- TranslationUnitKind TUKind;
-
- /// \brief The code-completion handler.
- CodeCompletionHandler *CodeComplete;
-
- /// \brief The file that we're performing code-completion for, if any.
- const FileEntry *CodeCompletionFile;
-
- /// \brief The offset in file for the code-completion point.
- unsigned CodeCompletionOffset;
-
- /// \brief 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.
- ///
- /// 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
- /// lexed, if any.
- SourceLocation ModuleImportLoc;
-
- /// \brief 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 '@'.
- bool LastTokenWasAt;
-
- /// \brief Whether the module import expects an identifier next. Otherwise,
- /// it expects a '.' or ';'.
- bool ModuleImportExpectsIdentifier;
-
- /// \brief The source location of the currently-active
- /// \#pragma clang arc_cf_code_audited begin.
- SourceLocation PragmaARCCFCodeAuditedLoc;
-
- /// \brief The source location of the currently-active
- /// \#pragma clang assume_nonnull begin.
- SourceLocation PragmaAssumeNonNullLoc;
-
- /// \brief True if we hit the code-completion point.
- bool CodeCompletionReached;
-
- /// \brief 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;
-
- /// \brief 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.
- ///
- /// This is used when loading a precompiled preamble.
- std::pair<int, bool> SkipMainFilePreamble;
-
- /// \brief 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
- /// 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
- /// if not expanding a macro.
- ///
- /// This is an alias for either CurLexer or CurPTHLexer.
- PreprocessorLexer *CurPPLexer;
-
- /// \brief 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;
-
- /// \brief 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.
- enum CurLexerKind {
- CLK_Lexer,
- CLK_PTHLexer,
- CLK_TokenLexer,
- CLK_CachingLexer,
- CLK_LexAfterModuleImport
- } CurLexerKind;
-
- /// \brief If the current lexer is for a submodule that is being built, this
- /// is that submodule.
- Module *CurSubmodule;
-
- /// \brief Keeps track of the stack of files currently
- /// \#included, and macros currently being expanded from, not counting
- /// CurLexer/CurTokenLexer.
- struct IncludeStackInfo {
- enum CurLexerKind CurLexerKind;
- Module *TheSubmodule;
- std::unique_ptr<Lexer> TheLexer;
- std::unique_ptr<PTHLexer> ThePTHLexer;
- PreprocessorLexer *ThePPLexer;
- std::unique_ptr<TokenLexer> TheTokenLexer;
- const DirectoryLookup *TheDirLookup;
-
- // The following constructors are completely useless copies of the default
- // versions, only needed to pacify MSVC.
- IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule,
- std::unique_ptr<Lexer> &&TheLexer,
- std::unique_ptr<PTHLexer> &&ThePTHLexer,
- PreprocessorLexer *ThePPLexer,
- std::unique_ptr<TokenLexer> &&TheTokenLexer,
- const DirectoryLookup *TheDirLookup)
- : CurLexerKind(std::move(CurLexerKind)),
- TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
- ThePTHLexer(std::move(ThePTHLexer)),
- ThePPLexer(std::move(ThePPLexer)),
- TheTokenLexer(std::move(TheTokenLexer)),
- TheDirLookup(std::move(TheDirLookup)) {}
- IncludeStackInfo(IncludeStackInfo &&RHS)
- : CurLexerKind(std::move(RHS.CurLexerKind)),
- TheSubmodule(std::move(RHS.TheSubmodule)),
- TheLexer(std::move(RHS.TheLexer)),
- ThePTHLexer(std::move(RHS.ThePTHLexer)),
- ThePPLexer(std::move(RHS.ThePPLexer)),
- TheTokenLexer(std::move(RHS.TheTokenLexer)),
- TheDirLookup(std::move(RHS.TheDirLookup)) {}
- };
- std::vector<IncludeStackInfo> IncludeMacroStack;
-
- /// \brief Actions invoked when some preprocessor activity is
- /// encountered (e.g. a file is \#included, etc).
- std::unique_ptr<PPCallbacks> Callbacks;
-
- struct MacroExpandsInfo {
- Token Tok;
- MacroDefinition MD;
- SourceRange Range;
- MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range)
- : Tok(Tok), MD(MD), Range(Range) { }
- };
- SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
-
- /// Information about a name that has been used to define a module macro.
- struct ModuleMacroInfo {
- ModuleMacroInfo(MacroDirective *MD)
- : MD(MD), ActiveModuleMacrosGeneration(0), IsAmbiguous(false) {}
-
- /// The most recent macro directive for this identifier.
- MacroDirective *MD;
- /// The active module macros for this identifier.
- llvm::TinyPtrVector<ModuleMacro*> ActiveModuleMacros;
- /// The generation number at which we last updated ActiveModuleMacros.
- /// \see Preprocessor::VisibleModules.
- unsigned ActiveModuleMacrosGeneration;
- /// Whether this macro name is ambiguous.
- bool IsAmbiguous;
- /// The module macros that are overridden by this macro.
- llvm::TinyPtrVector<ModuleMacro*> OverriddenMacros;
- };
-
- /// The state of a macro for an identifier.
- class MacroState {
- mutable llvm::PointerUnion<MacroDirective *, ModuleMacroInfo *> State;
-
- ModuleMacroInfo *getModuleInfo(Preprocessor &PP,
- const IdentifierInfo *II) const {
- // FIXME: Find a spare bit on IdentifierInfo and store a
- // HasModuleMacros flag.
- if (!II->hasMacroDefinition() ||
- (!PP.getLangOpts().Modules &&
- !PP.getLangOpts().ModulesLocalVisibility) ||
- !PP.CurSubmoduleState->VisibleModules.getGeneration())
- return nullptr;
-
- auto *Info = State.dyn_cast<ModuleMacroInfo*>();
- if (!Info) {
- Info = new (PP.getPreprocessorAllocator())
- ModuleMacroInfo(State.get<MacroDirective *>());
- State = Info;
- }
-
- if (PP.CurSubmoduleState->VisibleModules.getGeneration() !=
- Info->ActiveModuleMacrosGeneration)
- PP.updateModuleMacroInfo(II, *Info);
- return Info;
- }
-
- public:
- MacroState() : MacroState(nullptr) {}
- MacroState(MacroDirective *MD) : State(MD) {}
- MacroState(MacroState &&O) LLVM_NOEXCEPT : State(O.State) {
- O.State = (MacroDirective *)nullptr;
- }
- MacroState &operator=(MacroState &&O) LLVM_NOEXCEPT {
- auto S = O.State;
- O.State = (MacroDirective *)nullptr;
- State = S;
- return *this;
- }
- ~MacroState() {
- if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
- Info->~ModuleMacroInfo();
- }
-
- MacroDirective *getLatest() const {
- if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
- return Info->MD;
- return State.get<MacroDirective*>();
- }
- void setLatest(MacroDirective *MD) {
- if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
- Info->MD = MD;
- else
- State = MD;
- }
-
- bool isAmbiguous(Preprocessor &PP, const IdentifierInfo *II) const {
- auto *Info = getModuleInfo(PP, II);
- return Info ? Info->IsAmbiguous : false;
- }
- ArrayRef<ModuleMacro *>
- getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const {
- if (auto *Info = getModuleInfo(PP, II))
- return Info->ActiveModuleMacros;
- return None;
- }
-
- MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc,
- SourceManager &SourceMgr) const {
- // FIXME: Incorporate module macros into the result of this.
- if (auto *Latest = getLatest())
- return Latest->findDirectiveAtLoc(Loc, SourceMgr);
- return MacroDirective::DefInfo();
- }
-
- void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) {
- if (auto *Info = getModuleInfo(PP, II)) {
- Info->OverriddenMacros.insert(Info->OverriddenMacros.end(),
- Info->ActiveModuleMacros.begin(),
- Info->ActiveModuleMacros.end());
- Info->ActiveModuleMacros.clear();
- Info->IsAmbiguous = false;
- }
- }
- ArrayRef<ModuleMacro*> getOverriddenMacros() const {
- if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
- return Info->OverriddenMacros;
- return None;
- }
- void setOverriddenMacros(Preprocessor &PP,
- ArrayRef<ModuleMacro *> Overrides) {
- auto *Info = State.dyn_cast<ModuleMacroInfo*>();
- if (!Info) {
- if (Overrides.empty())
- return;
- Info = new (PP.getPreprocessorAllocator())
- ModuleMacroInfo(State.get<MacroDirective *>());
- State = Info;
- }
- Info->OverriddenMacros.clear();
- Info->OverriddenMacros.insert(Info->OverriddenMacros.end(),
- Overrides.begin(), Overrides.end());
- Info->ActiveModuleMacrosGeneration = 0;
- }
- };
-
- /// For each IdentifierInfo that was associated with a macro, we
- /// keep a mapping to the history of all macro definitions and #undefs in
- /// the reverse order (the latest one is in the head of the list).
- ///
- /// This mapping lives within the \p CurSubmoduleState.
- typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap;
-
- friend class ASTReader;
-
- struct SubmoduleState;
-
- /// \brief Information about a submodule that we're currently building.
- struct BuildingSubmoduleInfo {
- BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc,
- SubmoduleState *OuterSubmoduleState)
- : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState) {
- }
-
- /// The module that we are building.
- Module *M;
- /// The location at which the module was included.
- SourceLocation ImportLoc;
- /// The previous SubmoduleState.
- SubmoduleState *OuterSubmoduleState;
- };
- SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
-
- /// \brief Information about a submodule's preprocessor state.
- struct SubmoduleState {
- /// The macros for the submodule.
- MacroMap Macros;
- /// The set of modules that are visible within the submodule.
- VisibleModuleSet VisibleModules;
- // FIXME: CounterValue?
- // FIXME: PragmaPushMacroInfo?
- };
- std::map<Module*, SubmoduleState> Submodules;
-
- /// The preprocessor state for preprocessing outside of any submodule.
- SubmoduleState NullSubmoduleState;
-
- /// The current submodule state. Will be \p NullSubmoduleState if we're not
- /// in a submodule.
- SubmoduleState *CurSubmoduleState;
-
- /// The set of known macros exported from modules.
- llvm::FoldingSet<ModuleMacro> ModuleMacros;
-
- /// The list of module macros, for each identifier, that are not overridden by
- /// any other module macro.
- llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>>
- LeafModuleMacros;
-
- /// \brief 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
- /// something like MacroInfo*. The benefit of this is that when we are
- /// deserializing from PCH, we don't need to deserialize identifier & macros
- /// just so that we can report that they are unused, we just warn using
- /// the SourceLocations of this set (that will be filled by the ASTReader).
- /// We are using SmallPtrSet instead of a vector for faster removal.
- typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy;
- WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
-
- /// \brief A "freelist" of MacroArg objects that can be
- /// reused for quick allocation.
- MacroArgs *MacroArgCache;
- friend class MacroArgs;
-
- /// For each IdentifierInfo used in a \#pragma push_macro directive,
- /// we keep a MacroInfo stack used to restore the previous macro value.
- llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
-
- // Various statistics we track for performance analysis.
- unsigned NumDirectives, NumDefined, NumUndefined, NumPragma;
- unsigned NumIf, NumElse, NumEndif;
- unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
- unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
- unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
- unsigned NumSkipped;
-
- /// \brief The predefined macros that preprocessor should use from the
- /// command line etc.
- std::string Predefines;
-
- /// \brief The file ID for the preprocessor predefines.
- FileID PredefinesFileID;
-
- /// \{
- /// \brief 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.
- //
- /// 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
- /// from the end of the cache.
- SmallVector<Token, 16> MacroExpandedTokens;
- std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack;
-
- /// \brief A record of the macro definitions and expansions that
- /// occurred during preprocessing.
- ///
- /// This is an optional side structure that can be enabled with
- /// \c createPreprocessingRecord() prior to preprocessing.
- PreprocessingRecord *Record;
-
- /// Cached tokens state.
- typedef SmallVector<Token, 1> CachedTokensTy;
-
- /// \brief 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
- /// "lex" next.
- ///
- /// If it points beyond the CachedTokens vector, it means that a normal
- /// Lex() should be invoked.
- CachedTokensTy::size_type CachedLexPos;
-
- /// \brief 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
- /// invoked (at which point the last position is popped).
- std::vector<CachedTokensTy::size_type> BacktrackPositions;
-
- struct MacroInfoChain {
- MacroInfo MI;
- MacroInfoChain *Next;
- };
-
- /// MacroInfos are managed as a chain for easy disposal. This is the head
- /// of that list.
- MacroInfoChain *MIChainHead;
-
- struct DeserializedMacroInfoChain {
- MacroInfo MI;
- unsigned OwningModuleID; // MUST be immediately after the MacroInfo object
- // so it can be accessed by MacroInfo::getOwningModuleID().
- DeserializedMacroInfoChain *Next;
- };
- DeserializedMacroInfoChain *DeserialMIChainHead;
-
-public:
- Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
- DiagnosticsEngine &diags, LangOptions &opts,
- SourceManager &SM, HeaderSearch &Headers,
- ModuleLoader &TheModuleLoader,
- IdentifierInfoLookup *IILookup = nullptr,
- bool OwnsHeaderSearch = false,
- TranslationUnitKind TUKind = TU_Complete);
-
- ~Preprocessor();
-
- /// \brief 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.
- /// \param AuxTarget is owned by the caller and must remain valid for
- /// the lifetime of the preprocessor.
- void Initialize(const TargetInfo &Target,
- const TargetInfo *AuxTarget = nullptr);
-
- /// \brief 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
- /// information in the preprocessor some cleanup is needed before it is used
- /// to parse model files. This method does that cleanup.
- void InitializeForModelFile();
-
- /// \brief Cleanup after model file parsing
- void FinalizeForModelFile();
-
- /// \brief Retrieve the preprocessor options used to initialize this
- /// preprocessor.
- PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
-
- DiagnosticsEngine &getDiagnostics() const { return *Diags; }
- void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
-
- const LangOptions &getLangOpts() const { return LangOpts; }
- const TargetInfo &getTargetInfo() const { return *Target; }
- const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
- FileManager &getFileManager() const { return FileMgr; }
- SourceManager &getSourceManager() const { return SourceMgr; }
- HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
-
- IdentifierTable &getIdentifierTable() { return Identifiers; }
- const IdentifierTable &getIdentifierTable() const { return Identifiers; }
- SelectorTable &getSelectorTable() { return Selectors; }
- Builtin::Context &getBuiltinInfo() { return BuiltinInfo; }
- llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; }
-
- void setPTHManager(PTHManager* pm);
-
- PTHManager *getPTHManager() { return PTH.get(); }
-
- void setExternalSource(ExternalPreprocessorSource *Source) {
- ExternalSource = Source;
- }
-
- ExternalPreprocessorSource *getExternalSource() const {
- return ExternalSource;
- }
-
- /// \brief 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
- bool isParsingIfOrElifDirective() const {
- return ParsingIfOrElifDirective;
- }
-
- /// \brief Control whether the preprocessor retains comments in output.
- void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
- this->KeepComments = KeepComments | KeepMacroComments;
- this->KeepMacroComments = KeepMacroComments;
- }
-
- bool getCommentRetentionState() const { return KeepComments; }
-
- void setPragmasEnabled(bool Enabled) { PragmasEnabled = Enabled; }
- bool getPragmasEnabled() const { return PragmasEnabled; }
-
- void SetSuppressIncludeNotFoundError(bool Suppress) {
- SuppressIncludeNotFoundError = Suppress;
- }
-
- bool GetSuppressIncludeNotFoundError() {
- return SuppressIncludeNotFoundError;
- }
-
- /// Sets whether the preprocessor is responsible for producing output or if
- /// it is producing tokens to be consumed by Parse and Sema.
- void setPreprocessedOutput(bool IsPreprocessedOutput) {
- PreprocessedOutput = IsPreprocessedOutput;
- }
-
- /// Returns true if the preprocessor is responsible for generating output,
- /// 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.
- bool isCurrentLexer(const PreprocessorLexer *L) const {
- return CurPPLexer == L;
- }
-
- /// \brief 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.
- ///
- /// 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.
- Module *getCurrentSubmodule() const { return CurSubmodule; }
-
- /// \brief Returns the FileID for the preprocessor predefines.
- FileID getPredefinesFileID() const { return PredefinesFileID; }
-
- /// \{
- /// \brief Accessors for preprocessor callbacks.
- ///
- /// Note that this class takes ownership of any PPCallbacks object given to
- /// it.
- PPCallbacks *getPPCallbacks() const { return Callbacks.get(); }
- void addPPCallbacks(std::unique_ptr<PPCallbacks> C) {
- if (Callbacks)
- C = llvm::make_unique<PPChainedCallbacks>(std::move(C),
- std::move(Callbacks));
- Callbacks = std::move(C);
- }
- /// \}
-
- bool isMacroDefined(StringRef Id) {
- return isMacroDefined(&Identifiers.get(Id));
- }
- bool isMacroDefined(const IdentifierInfo *II) {
- return II->hasMacroDefinition() &&
- (!getLangOpts().Modules || (bool)getMacroDefinition(II));
- }
-
- /// \brief 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) {
- if (!II->hasMacroDefinition())
- return false;
- auto I = Submodules.find(M);
- if (I == Submodules.end())
- return false;
- auto J = I->second.Macros.find(II);
- if (J == I->second.Macros.end())
- return false;
- auto *MD = J->second.getLatest();
- return MD && MD->isDefined();
- }
-
- MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
- if (!II->hasMacroDefinition())
- return MacroDefinition();
-
- MacroState &S = CurSubmoduleState->Macros[II];
- auto *MD = S.getLatest();
- while (MD && isa<VisibilityMacroDirective>(MD))
- MD = MD->getPrevious();
- return MacroDefinition(dyn_cast_or_null<DefMacroDirective>(MD),
- S.getActiveModuleMacros(*this, II),
- S.isAmbiguous(*this, II));
- }
-
- MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II,
- SourceLocation Loc) {
- if (!II->hadMacroDefinition())
- return MacroDefinition();
-
- MacroState &S = CurSubmoduleState->Macros[II];
- MacroDirective::DefInfo DI;
- if (auto *MD = S.getLatest())
- DI = MD->findDirectiveAtLoc(Loc, getSourceManager());
- // FIXME: Compute the set of active module macros at the specified location.
- return MacroDefinition(DI.getDirective(),
- S.getActiveModuleMacros(*this, II),
- S.isAmbiguous(*this, II));
- }
-
- /// \brief 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())
- return nullptr;
-
- auto *MD = getLocalMacroDirectiveHistory(II);
- if (!MD || MD->getDefinition().isUndefined())
- return nullptr;
-
- return MD;
- }
-
- const MacroInfo *getMacroInfo(const IdentifierInfo *II) const {
- return const_cast<Preprocessor*>(this)->getMacroInfo(II);
- }
-
- MacroInfo *getMacroInfo(const IdentifierInfo *II) {
- if (!II->hasMacroDefinition())
- return nullptr;
- if (auto MD = getMacroDefinition(II))
- return MD.getMacroInfo();
- return nullptr;
- }
-
- /// \brief 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.
- void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
- DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
- SourceLocation Loc) {
- DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc);
- appendMacroDirective(II, MD);
- return MD;
- }
- DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II,
- MacroInfo *MI) {
- return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
- }
- /// \brief Set a MacroDirective that was loaded from a PCH file.
- void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
-
- /// \brief 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.
- ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
- auto I = LeafModuleMacros.find(II);
- if (I != LeafModuleMacros.end())
- return I->second;
- return None;
- }
-
- /// \{
- /// Iterators for the macro history table. Currently defined macros have
- /// IdentifierInfo::hasMacroDefinition() set and an empty
- /// MacroInfo::getUndefLoc() at the head of the list.
- typedef MacroMap::const_iterator macro_iterator;
- macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
- macro_iterator macro_end(bool IncludeExternalMacros = true) const;
- llvm::iterator_range<macro_iterator>
- macros(bool IncludeExternalMacros = true) const {
- return llvm::make_range(macro_begin(IncludeExternalMacros),
- macro_end(IncludeExternalMacros));
- }
- /// \}
-
- /// \brief 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,
- ArrayRef<TokenValue> Tokens) const;
-
- const std::string &getPredefines() const { return Predefines; }
- /// \brief Set the predefines for this Preprocessor.
- ///
- /// These predefines are automatically injected when parsing the main file.
- void setPredefines(const char *P) { Predefines = P; }
- void setPredefines(StringRef P) { Predefines = P; }
-
- /// Return information about the specified preprocessor
- /// identifier token.
- IdentifierInfo *getIdentifierInfo(StringRef Name) const {
- return &Identifiers.get(Name);
- }
-
- /// \brief 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".
- void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler);
- void AddPragmaHandler(PragmaHandler *Handler) {
- AddPragmaHandler(StringRef(), Handler);
- }
-
- /// \brief 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
- /// has not been registered.
- void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler);
- void RemovePragmaHandler(PragmaHandler *Handler) {
- RemovePragmaHandler(StringRef(), Handler);
- }
-
- /// Install empty handlers for all pragmas (making them ignored).
- void IgnorePragmas();
-
- /// \brief Add the specified comment handler to the preprocessor.
- void addCommentHandler(CommentHandler *Handler);
-
- /// \brief 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.
- void setCodeCompletionHandler(CodeCompletionHandler &Handler) {
- CodeComplete = &Handler;
- }
-
- /// \brief Retrieve the current code-completion handler.
- CodeCompletionHandler *getCodeCompletionHandler() const {
- return CodeComplete;
- }
-
- /// \brief Clear out the code completion handler.
- void clearCodeCompletionHandler() {
- CodeComplete = nullptr;
- }
-
- /// \brief Hook used by the lexer to invoke the "natural language" code
- /// completion point.
- void CodeCompleteNaturalLanguage();
-
- /// \brief 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
- /// all macro expansions, macro definitions, etc.
- void createPreprocessingRecord();
-
- /// \brief 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.
- void EndSourceFile();
-
- /// \brief 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
- /// tokens from it instead of the current buffer.
- ///
- /// \param Args specifies the tokens input to a function-like macro.
- /// \param ILEnd specifies the location of the ')' for a function-like macro
- /// or the identifier for an object-like macro.
- void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro,
- MacroArgs *Args);
-
- /// \brief 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
- /// will not be subject to further macro expansion. Otherwise, these tokens
- /// will be re-macro-expanded when/if expansion is enabled.
- ///
- /// If \p OwnsTokens is false, this method assumes that the specified stream
- /// of tokens has a permanent owner somewhere, so they do not need to be
- /// copied. If it is true, it assumes the array of tokens is allocated with
- /// \c new[] and must be freed.
- void EnterTokenStream(const Token *Toks, unsigned NumToks,
- bool DisableMacroExpansion, bool OwnsTokens);
-
- /// \brief 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.
- void RemoveTopOfLexerStack();
-
- /// From the point that this method is called, and until
- /// CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
- /// keeps track of the lexed tokens so that a subsequent Backtrack() call will
- /// make the Preprocessor re-lex the same tokens.
- ///
- /// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
- /// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
- /// be combined with the EnableBacktrackAtThisPos calls in reverse order.
- ///
- /// NOTE: *DO NOT* forget to call either CommitBacktrackedTokens or Backtrack
- /// at some point after EnableBacktrackAtThisPos. If you don't, caching of
- /// tokens will continue indefinitely.
- ///
- void EnableBacktrackAtThisPos();
-
- /// \brief Disable the last EnableBacktrackAtThisPos call.
- void CommitBacktrackedTokens();
-
- /// \brief Make Preprocessor re-lex the tokens that were lexed since
- /// EnableBacktrackAtThisPos() was previously called.
- void Backtrack();
-
- /// \brief 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.
- void Lex(Token &Result);
-
- void LexAfterModuleImport(Token &Result);
-
- void makeModuleVisible(Module *M, SourceLocation Loc);
-
- SourceLocation getModuleImportLoc(Module *M) const {
- return CurSubmoduleState->VisibleModules.getImportLoc(M);
- }
-
- /// \brief 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,
- const char *DiagnosticTag, bool AllowMacroExpansion) {
- if (AllowMacroExpansion)
- Lex(Result);
- else
- LexUnexpandedToken(Result);
- return FinishLexStringLiteral(Result, String, DiagnosticTag,
- AllowMacroExpansion);
- }
-
- /// \brief 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
- /// something not a comment.
- ///
- /// This is useful in -E -C mode where comments would foul up preprocessor
- /// directive handling.
- void LexNonComment(Token &Result) {
- do
- Lex(Result);
- while (Result.getKind() == tok::comment);
- }
-
- /// \brief Just like Lex, but disables macro expansion of identifier tokens.
- void LexUnexpandedToken(Token &Result) {
- // Disable macro expansion.
- bool OldVal = DisableMacroExpansion;
- DisableMacroExpansion = true;
- // Lex the token.
- Lex(Result);
-
- // Reenable it.
- DisableMacroExpansion = OldVal;
- }
-
- /// \brief Like LexNonComment, but this disables macro expansion of
- /// identifier tokens.
- void LexUnexpandedNonComment(Token &Result) {
- do
- LexUnexpandedToken(Result);
- while (Result.getKind() == tok::comment);
- }
-
- /// \brief 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);
-
- /// Disables macro expansion everywhere except for preprocessor directives.
- void SetMacroExpansionOnlyInDirectives() {
- DisableMacroExpansion = true;
- MacroExpansionInDirectivesOverride = true;
- }
-
- /// \brief Peeks ahead N tokens and returns that token without consuming any
- /// tokens.
- ///
- /// LookAhead(0) returns the next token that would be returned by Lex(),
- /// LookAhead(1) returns the token after it, etc. This returns normal
- /// tokens after phase 5. As such, it is equivalent to using
- /// 'Lex', not 'LexUnexpandedToken'.
- const Token &LookAhead(unsigned N) {
- if (CachedLexPos + N < CachedTokens.size())
- return CachedTokens[CachedLexPos+N];
- else
- return PeekAhead(N+1);
- }
-
- /// \brief 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
- /// backtrack position, not more.
- void RevertCachedTokens(unsigned N) {
- assert(isBacktrackEnabled() &&
- "Should only be called when tokens are cached for backtracking");
- assert(signed(CachedLexPos) - signed(N) >= signed(BacktrackPositions.back())
- && "Should revert tokens up to the last backtrack position, not more");
- assert(signed(CachedLexPos) - signed(N) >= 0 &&
- "Corrupted backtrack positions ?");
- CachedLexPos -= N;
- }
-
- /// \brief Enters a token in the token stream to be lexed next.
- ///
- /// If BackTrack() is called afterwards, the token will remain at the
- /// insertion point.
- void EnterToken(const Token &Tok) {
- EnterCachingLexMode();
- CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
- }
-
- /// We notify the Preprocessor that if it is caching tokens (because
- /// backtrack is enabled) it should replace the most recent cached tokens
- /// with the given annotation token. This function has no effect if
- /// backtracking is not enabled.
- ///
- /// Note that the use of this function is just for optimization, so that the
- /// cached tokens doesn't get re-parsed and re-resolved after a backtrack is
- /// invoked.
- void AnnotateCachedTokens(const Token &Tok) {
- assert(Tok.isAnnotation() && "Expected annotation token");
- if (CachedLexPos != 0 && isBacktrackEnabled())
- AnnotatePreviousCachedTokens(Tok);
- }
-
- /// Get the location of the last cached token, suitable for setting the end
- /// location of an annotation token.
- SourceLocation getLastCachedTokenLocation() const {
- assert(CachedLexPos != 0);
- return CachedTokens[CachedLexPos-1].getLastLoc();
- }
-
- /// \brief Replace the last token with an annotation token.
- ///
- /// Like AnnotateCachedTokens(), this routine replaces an
- /// already-parsed (and resolved) token with an annotation
- /// token. However, this routine only replaces the last token with
- /// the annotation token; it does not affect any other cached
- /// tokens. This function has no effect if backtracking is not
- /// enabled.
- void ReplaceLastTokenWithAnnotation(const Token &Tok) {
- assert(Tok.isAnnotation() && "Expected annotation token");
- if (CachedLexPos != 0 && isBacktrackEnabled())
- CachedTokens[CachedLexPos-1] = Tok;
- }
-
- /// Update the current token to represent the provided
- /// identifier, in order to cache an action performed by typo correction.
- void TypoCorrectToken(const Token &Tok) {
- assert(Tok.getIdentifierInfo() && "Expected identifier token");
- if (CachedLexPos != 0 && isBacktrackEnabled())
- CachedTokens[CachedLexPos-1] = Tok;
- }
-
- /// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
- /// CurTokenLexer pointers.
- void recomputeCurLexerKind();
-
- /// \brief Returns true if incremental processing is enabled
- bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
-
- /// \brief Enables the incremental processing
- void enableIncrementalProcessing(bool value = true) {
- IncrementalProcessing = value;
- }
-
- /// \brief 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
- /// perform completion the first time it is included. If NULL, this
- /// function clears out the code-completion point.
- ///
- /// \param Line the line at which code completion should occur
- /// (1-based).
- ///
- /// \param Column the column at which code completion should occur
- /// (1-based).
- ///
- /// \returns true if an error occurred, false otherwise.
- bool SetCodeCompletionPoint(const FileEntry *File,
- unsigned Line, unsigned Column);
-
- /// \brief Determine if we are performing code completion.
- bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; }
-
- /// \brief 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 an invalid location if code-completion is not enabled or the file
- /// containing the code-completion point has not been lexed yet.
- SourceLocation getCodeCompletionFileLoc() const {
- return CodeCompletionFileLoc;
- }
-
- /// \brief 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.
- void setCodeCompletionReached() {
- assert(isCodeCompletionEnabled() && "Code-completion not enabled!");
- CodeCompletionReached = true;
- // Silence any diagnostics that occur after we hit the code-completion.
- getDiagnostics().setSuppressAllDiagnostics(true);
- }
-
- /// \brief The location of the currently-active \#pragma clang
- /// arc_cf_code_audited begin.
- ///
- /// Returns an invalid location if there is no such pragma active.
- SourceLocation getPragmaARCCFCodeAuditedLoc() const {
- return PragmaARCCFCodeAuditedLoc;
- }
-
- /// \brief 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
- /// assume_nonnull begin.
- ///
- /// Returns an invalid location if there is no such pragma active.
- SourceLocation getPragmaAssumeNonNullLoc() const {
- return PragmaAssumeNonNullLoc;
- }
-
- /// \brief 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
- /// 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.
- ///
- /// \param Bytes The number of bytes in the preamble to skip.
- ///
- /// \param StartOfLine Whether skipping these bytes puts the lexer at the
- /// start of a line.
- void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) {
- SkipMainFilePreamble.first = Bytes;
- SkipMainFilePreamble.second = StartOfLine;
- }
-
- /// Forwarding function for diagnostics. This emits a diagnostic at
- /// the specified Token's location, translating the token's start
- /// position in the current buffer into a SourcePosition object for rendering.
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
- return Diags->Report(Loc, DiagID);
- }
-
- DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const {
- return Diags->Report(Tok.getLocation(), DiagID);
- }
-
- /// Return the 'spelling' of the token at the given
- /// location; does not go up to the spelling location or down to the
- /// expansion location.
- ///
- /// \param buffer A buffer which will be used only if the token requires
- /// "cleaning", e.g. if it contains trigraphs or escaped newlines
- /// \param invalid If non-null, will be set \c true if an error occurs.
- StringRef getSpelling(SourceLocation loc,
- SmallVectorImpl<char> &buffer,
- bool *invalid = nullptr) const {
- return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
- }
-
- /// \brief 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
- /// particular, this wants to get the true, uncanonicalized, spelling of
- /// things like digraphs, UCNs, etc.
- ///
- /// \param Invalid If non-null, will be set \c true if an error occurs.
- std::string getSpelling(const Token &Tok, bool *Invalid = nullptr) const {
- return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
- }
-
- /// \brief 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
- /// guaranteed to be at least Tok.getLength() bytes long. The length of the
- /// actual result is returned.
- ///
- /// Note that this method may do two possible things: it may either fill in
- /// the buffer specified with characters, or it may *change the input pointer*
- /// to point to a constant buffer with the data already in it (avoiding a
- /// copy). The caller is not allowed to modify the returned buffer pointer
- /// if an internal buffer is returned.
- unsigned getSpelling(const Token &Tok, const char *&Buffer,
- bool *Invalid = nullptr) const {
- return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
- }
-
- /// \brief 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.
- StringRef getSpelling(const Token &Tok,
- SmallVectorImpl<char> &Buffer,
- bool *Invalid = nullptr) const;
-
- /// \brief 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,
- /// return the character.
- char
- getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
- bool *Invalid = nullptr) const {
- assert(Tok.is(tok::numeric_constant) &&
- Tok.getLength() == 1 && "Called on unsupported token");
- assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1");
-
- // If the token is carrying a literal data pointer, just use it.
- if (const char *D = Tok.getLiteralData())
- return *D;
-
- // Otherwise, fall back on getCharacterData, which is slower, but always
- // works.
- return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid);
- }
-
- /// \brief 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 macro argument expansions to compute this. It returns a
- /// StringRef that refers to the SourceManager-owned buffer of the source
- /// where that macro name is spelled. Thus, the result shouldn't out-live
- /// the SourceManager.
- StringRef getImmediateMacroName(SourceLocation Loc) {
- return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
- }
-
- /// \brief 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
- /// point of the token.
- void CreateString(StringRef Str, Token &Tok,
- SourceLocation ExpansionLocStart = SourceLocation(),
- SourceLocation ExpansionLocEnd = SourceLocation());
-
- /// \brief 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
- /// points just past the end of the token referenced by \p Loc, and
- /// is generally used when a diagnostic needs to point just after a
- /// token where it expected something different that it received. If
- /// the returned source location would not be meaningful (e.g., if
- /// it points into a macro), this routine returns an invalid
- /// source location.
- ///
- /// \param Offset an offset from the end of the token, where the source
- /// location should refer to. The default offset (0) produces a source
- /// location pointing just past the end of the token; an offset of 1 produces
- /// a source location pointing to the last character in the token, etc.
- SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) {
- return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
- }
-
- /// \brief 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
- /// begin location of the macro.
- bool isAtStartOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroBegin = nullptr) const {
- return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts,
- MacroBegin);
- }
-
- /// \brief 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
- /// end location of the macro.
- bool isAtEndOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroEnd = nullptr) const {
- return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
- }
-
- /// \brief 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
- /// 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
- /// performed.
- ///
- /// If fast was specified, this is a 'fast paste' case we handled.
- void IncrementPasteCounter(bool isFast) {
- if (isFast)
- ++NumFastTokenPaste;
- else
- ++NumTokenPaste;
- }
-
- void PrintStats();
-
- size_t getTotalMemory() const;
-
- /// When the macro expander pastes together a comment (/##/) in Microsoft
- /// mode, this method handles updating the current state, returning the
- /// token on the next source line.
- void HandleMicrosoftCommentPaste(Token &Tok);
-
- //===--------------------------------------------------------------------===//
- // Preprocessor callback methods. These are invoked by a lexer as various
- // directives and events are found.
-
- /// Given a tok::raw_identifier token, look up the
- /// identifier information for the token and install it into the token,
- /// updating the token kind accordingly.
- IdentifierInfo *LookUpIdentifierInfo(Token &Identifier) const;
-
-private:
- llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons;
-
-public:
-
- /// \brief 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.
- void HandlePoisonedIdentifier(Token & Tok);
-
- void MaybeHandlePoisonedIdentifier(Token & Identifier) {
- if(IdentifierInfo * II = Identifier.getIdentifierInfo()) {
- if(II->isPoisoned()) {
- HandlePoisonedIdentifier(Identifier);
- }
- }
- }
-
-private:
- /// Identifiers used for SEH handling in Borland. These are only
- /// allowed in particular circumstances
- // __except block
- IdentifierInfo *Ident__exception_code,
- *Ident___exception_code,
- *Ident_GetExceptionCode;
- // __except filter expression
- IdentifierInfo *Ident__exception_info,
- *Ident___exception_info,
- *Ident_GetExceptionInfo;
- // __finally
- IdentifierInfo *Ident__abnormal_termination,
- *Ident___abnormal_termination,
- *Ident_AbnormalTermination;
-
- const char *getCurLexerEndPos();
-
-public:
- void PoisonSEHIdentifiers(bool Poison = true); // Borland
-
- /// \brief 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
- /// token (like 'for').
- ///
- /// \returns true if we actually computed a token, false if we need to
- /// lex again.
- bool HandleIdentifier(Token &Identifier);
-
-
- /// \brief 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
- /// token stream.
- bool HandleEndOfTokenLexer(Token &Result);
-
- /// \brief 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.
- ///
- /// 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
- /// the tok::eod token is found.
- void DiscardUntilEndOfDirective();
-
- /// \brief 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();
- }
- unsigned getCounterValue() const { return CounterValue; }
- void setCounterValue(unsigned V) { CounterValue = V; }
-
- /// \brief Retrieves the module that we're currently building, if any.
- Module *getCurrentModule();
-
- /// \brief Allocate a new MacroInfo object with the provided SourceLocation.
- MacroInfo *AllocateMacroInfo(SourceLocation L);
-
- /// \brief Allocate a new MacroInfo object loaded from an AST file.
- MacroInfo *AllocateDeserializedMacroInfo(SourceLocation L,
- unsigned SubModuleID);
-
- /// \brief 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
- /// the spelling of the filename, but is also expected to handle the case
- /// when this method decides to use a different buffer.
- ///
- /// \returns true if the input filename was in <>'s or false if it was
- /// in ""'s.
- bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Filename);
-
- /// \brief 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 "").
- const FileEntry *LookupFile(SourceLocation FilenameLoc, StringRef Filename,
- bool isAngled, const DirectoryLookup *FromDir,
- const FileEntry *FromFile,
- const DirectoryLookup *&CurDir,
- SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath,
- ModuleMap::KnownHeader *SuggestedModule,
- bool SkipCache = false);
-
- /// \brief 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.
- bool isInPrimaryFile() const;
-
- /// \brief 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:
- /// \code
- /// \#define FOO <x/y.h>
- /// \#include FOO
- /// \endcode
- /// because in this case, "<x/y.h>" is returned as 7 tokens, not one.
- ///
- /// This code concatenates and consumes tokens up to the '>' token. It
- /// returns false if the > was found, otherwise it returns true if it finds
- /// and consumes the EOD marker.
- bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
- SourceLocation &End);
-
- /// \brief 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);
-
- bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
- bool *ShadowFlag = nullptr);
-
-private:
-
- void PushIncludeMacroStack() {
- assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
- IncludeMacroStack.emplace_back(
- CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
- CurPPLexer, std::move(CurTokenLexer), CurDirLookup);
- CurPPLexer = nullptr;
- }
-
- void PopIncludeMacroStack() {
- CurLexer = std::move(IncludeMacroStack.back().TheLexer);
- CurPTHLexer = std::move(IncludeMacroStack.back().ThePTHLexer);
- CurPPLexer = IncludeMacroStack.back().ThePPLexer;
- CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
- CurDirLookup = IncludeMacroStack.back().TheDirLookup;
- CurSubmodule = IncludeMacroStack.back().TheSubmodule;
- CurLexerKind = IncludeMacroStack.back().CurLexerKind;
- IncludeMacroStack.pop_back();
- }
-
- void PropagateLineStartLeadingSpaceInfo(Token &Result);
-
- void EnterSubmodule(Module *M, SourceLocation ImportLoc);
- void LeaveSubmodule();
-
- /// Update the set of active module macros and ambiguity flag for a module
- /// macro name.
- void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info);
-
- /// \brief Allocate a new MacroInfo object.
- MacroInfo *AllocateMacroInfo();
-
- DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
- SourceLocation Loc);
- UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
- VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
- bool isPublic);
-
- /// \brief Lex and validate a macro name, which occurs after a
- /// \#define or \#undef.
- ///
- /// \param MacroNameTok Token that represents the name defined or undefined.
- /// \param IsDefineUndef Kind if preprocessor directive.
- /// \param ShadowFlag Points to flag that is set if macro name shadows
- /// a keyword.
- ///
- /// This emits a diagnostic, sets the token kind to eod,
- /// and discards the rest of the macro line if the macro name is invalid.
- void ReadMacroName(Token &MacroNameTok, MacroUse IsDefineUndef = MU_Other,
- bool *ShadowFlag = nullptr);
-
- /// The ( starting an argument list of a macro definition has just been read.
- /// Lex the rest of the arguments and the closing ), updating \p MI with
- /// what we learn and saving in \p LastTok the last token read.
- /// Return true if an error occurs parsing the arg list.
- bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok);
-
- /// We just read a \#if or related directive and decided that the
- /// subsequent tokens are in the \#if'd out portion of the
- /// file. Lex the rest of the file, until we see an \#endif. If \p
- /// FoundNonSkipPortion is true, then we have already emitted code for part of
- /// this \#if directive, so \#else/\#elif blocks should never be entered. If
- /// \p FoundElse is false, then \#else directives are ok, if not, then we have
- /// already seen one so a \#else directive is a duplicate. When this returns,
- /// the caller can lex the first valid token.
- void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
- bool FoundNonSkipPortion, bool FoundElse,
- SourceLocation ElseLoc = SourceLocation());
-
- /// \brief A fast PTH version of SkipExcludedConditionalBlock.
- void PTHSkipExcludedConditionalBlock();
-
- /// \brief Evaluate an integer constant expression that may occur after a
- /// \#if or \#elif directive and return it as a bool.
- ///
- /// If the expression is equivalent to "!defined(X)" return X in IfNDefMacro.
- bool EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
-
- /// \brief 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.
- void RegisterBuiltinMacros();
-
- /// If an identifier token is read that is to be expanded as a macro, handle
- /// it and return the next token as 'Tok'. If we lexed a token, return true;
- /// otherwise the caller should lex again.
- bool HandleMacroExpandedIdentifier(Token &Tok, const MacroDefinition &MD);
-
- /// \brief 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
- /// from the end of the cache.
- Token *cacheMacroExpandedTokens(TokenLexer *tokLexer,
- ArrayRef<Token> tokens);
- void removeCachedMacroExpandedTokensOfLastLexer();
- friend void TokenLexer::ExpandFunctionArguments();
-
- /// Determine whether the next preprocessor token to be
- /// lexed is a '('. If so, consume the token and return true, if not, this
- /// method should have no observable side-effect on the lexed tokens.
- bool isNextPPTokenLParen();
-
- /// After reading "MACRO(", this method is invoked to read all of the formal
- /// arguments specified for the macro invocation. Returns null on error.
- MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
- SourceLocation &ExpansionEnd);
-
- /// \brief 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
- /// 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
- /// a string literal.
- void HandleMicrosoft__pragma(Token &Tok);
-
- /// \brief 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
- /// start getting tokens from it using the PTH cache.
- void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
-
- /// \brief 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
- /// pragma or a macro.
- static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
- return L ? !L->isPragmaLexer() : P != nullptr;
- }
-
- static bool IsFileLexer(const IncludeStackInfo& I) {
- return IsFileLexer(I.TheLexer.get(), I.ThePPLexer);
- }
-
- bool IsFileLexer() const {
- return IsFileLexer(CurLexer.get(), CurPPLexer);
- }
-
- //===--------------------------------------------------------------------===//
- // Caching stuff.
- void CachingLex(Token &Result);
- bool InCachingLexMode() const {
- // If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
- // that we are past EOF, not that we are in CachingLex mode.
- return !CurPPLexer && !CurTokenLexer && !CurPTHLexer &&
- !IncludeMacroStack.empty();
- }
- void EnterCachingLexMode();
- void ExitCachingLexMode() {
- if (InCachingLexMode())
- RemoveTopOfLexerStack();
- }
- const Token &PeekAhead(unsigned N);
- void AnnotatePreviousCachedTokens(const Token &Tok);
-
- //===--------------------------------------------------------------------===//
- /// Handle*Directive - implement the various preprocessor directives. These
- /// should side-effect the current preprocessor object so that the next call
- /// to Lex() will return the appropriate token next.
- void HandleLineDirective(Token &Tok);
- void HandleDigitDirective(Token &Tok);
- void HandleUserDiagnosticDirective(Token &Tok, bool isWarning);
- void HandleIdentSCCSDirective(Token &Tok);
- void HandleMacroPublicDirective(Token &Tok);
- void HandleMacroPrivateDirective(Token &Tok);
-
- // File inclusion.
- void HandleIncludeDirective(SourceLocation HashLoc,
- Token &Tok,
- const DirectoryLookup *LookupFrom = nullptr,
- const FileEntry *LookupFromFile = nullptr,
- bool isImport = false);
- void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
- void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
- void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
- void HandleMicrosoftImportDirective(Token &Tok);
-
-public:
- // Module inclusion testing.
- /// \brief 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 Find the module that contains the specified location, either
- /// directly or indirectly.
- Module *getModuleContainingLocation(SourceLocation Loc);
-
-private:
- // Macro handling.
- void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
- void HandleUndefDirective(Token &Tok);
-
- // Conditional Inclusion.
- void HandleIfdefDirective(Token &Tok, bool isIfndef,
- bool ReadAnyTokensBeforeDirective);
- void HandleIfDirective(Token &Tok, bool ReadAnyTokensBeforeDirective);
- void HandleEndifDirective(Token &Tok);
- void HandleElseDirective(Token &Tok);
- void HandleElifDirective(Token &Tok);
-
- // Pragmas.
- void HandlePragmaDirective(SourceLocation IntroducerLoc,
- PragmaIntroducerKind Introducer);
-public:
- void HandlePragmaOnce(Token &OnceTok);
- void HandlePragmaMark();
- void HandlePragmaPoison(Token &PoisonTok);
- void HandlePragmaSystemHeader(Token &SysHeaderTok);
- void HandlePragmaDependency(Token &DependencyTok);
- void HandlePragmaPushMacro(Token &Tok);
- void HandlePragmaPopMacro(Token &Tok);
- void HandlePragmaIncludeAlias(Token &Tok);
- IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
-
- // Return true and store the first token only if any CommentHandler
- // 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
- /// warnings.
- void markMacroAsUsed(MacroInfo *MI);
-};
-
-/// \brief 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:
- virtual ~CommentHandler();
-
- // The handler shall return true if it has pushed any tokens
- // to be read using e.g. EnterToken or EnterTokenStream.
- virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
deleted file mode 100644
index 6d6cf05..0000000
--- a/include/clang/Lex/PreprocessorLexer.h
+++ /dev/null
@@ -1,183 +0,0 @@
-//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- 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 PreprocessorLexer interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
-#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H
-
-#include "clang/Lex/MultipleIncludeOpt.h"
-#include "clang/Lex/Token.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-class FileEntry;
-class Preprocessor;
-
-class PreprocessorLexer {
- virtual void anchor();
-protected:
- Preprocessor *PP; // Preprocessor object controlling lexing.
-
- /// The SourceManager FileID corresponding to the file being lexed.
- const FileID FID;
-
- /// \brief Number of SLocEntries before lexing the file.
- unsigned InitialNumSLocEntries;
-
- //===--------------------------------------------------------------------===//
- // Context-specific lexing flags set by the preprocessor.
- //===--------------------------------------------------------------------===//
-
- /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
- bool ParsingPreprocessorDirective;
-
- /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
- /// token.
- bool ParsingFilename;
-
- /// \brief 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:
- /// 1. If EOF of the current lexer is found, the include stack isn't popped.
- /// 2. Identifier information is not looked up for identifier tokens. As an
- /// effect of this, implicit macro expansion is naturally disabled.
- /// 3. "#" tokens at the start of a line are treated as normal tokens, not
- /// implicitly transformed by the lexer.
- /// 4. All diagnostic messages are disabled.
- /// 5. No callbacks are made into the preprocessor.
- ///
- /// Note that in raw mode that the PP pointer may be null.
- bool LexingRawMode;
-
- /// \brief 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
- /// we are currently in.
- SmallVector<PPConditionalInfo, 4> ConditionalStack;
-
- PreprocessorLexer(const PreprocessorLexer &) = delete;
- void operator=(const PreprocessorLexer &) = delete;
- friend class Preprocessor;
-
- PreprocessorLexer(Preprocessor *pp, FileID fid);
-
- PreprocessorLexer()
- : PP(nullptr), InitialNumSLocEntries(0),
- ParsingPreprocessorDirective(false),
- ParsingFilename(false),
- LexingRawMode(false) {}
-
- virtual ~PreprocessorLexer() {}
-
- virtual void IndirectLex(Token& Result) = 0;
-
- /// \brief Return the source location for the next observable location.
- virtual SourceLocation getSourceLocation() = 0;
-
- //===--------------------------------------------------------------------===//
- // #if directive handling.
-
- /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
- /// what we are currently in for diagnostic emission (e.g. \#if with missing
- /// \#endif).
- void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
- bool FoundNonSkip, bool FoundElse) {
- PPConditionalInfo CI;
- CI.IfLoc = DirectiveStart;
- CI.WasSkipping = WasSkipping;
- CI.FoundNonSkip = FoundNonSkip;
- CI.FoundElse = FoundElse;
- ConditionalStack.push_back(CI);
- }
- void pushConditionalLevel(const PPConditionalInfo &CI) {
- ConditionalStack.push_back(CI);
- }
-
- /// popConditionalLevel - Remove an entry off the top of the conditional
- /// stack, returning information about it. If the conditional stack is empty,
- /// this returns true and does not fill in the arguments.
- bool popConditionalLevel(PPConditionalInfo &CI) {
- if (ConditionalStack.empty())
- return true;
- CI = ConditionalStack.pop_back_val();
- return false;
- }
-
- /// \brief Return the top of the conditional stack.
- /// \pre This requires that there be a conditional active.
- PPConditionalInfo &peekConditionalLevel() {
- assert(!ConditionalStack.empty() && "No conditionals active!");
- return ConditionalStack.back();
- }
-
- unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
-
-public:
-
- //===--------------------------------------------------------------------===//
- // Misc. lexing methods.
-
- /// \brief 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
- /// preprocessor directive.
- void setParsingPreprocessorDirective(bool f) {
- ParsingPreprocessorDirective = f;
- }
-
- /// \brief Return true if this lexer is in raw mode or not.
- bool isLexingRawMode() const { return LexingRawMode; }
-
- /// \brief Return the preprocessor object for this lexer.
- Preprocessor *getPP() const { return PP; }
-
- FileID getFileID() const {
- assert(PP &&
- "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
- return FID;
- }
-
- /// \brief Number of SLocEntries before lexing the file.
- unsigned getInitialNumSLocEntries() const {
- return InitialNumSLocEntries;
- }
-
- /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
- /// getFileID(), this only works for lexers with attached preprocessors.
- const FileEntry *getFileEntry() const;
-
- /// \brief Iterator that traverses the current stack of preprocessor
- /// conditional directives (\#if/\#ifdef/\#ifndef).
- typedef SmallVectorImpl<PPConditionalInfo>::const_iterator
- conditional_iterator;
-
- conditional_iterator conditional_begin() const {
- return ConditionalStack.begin();
- }
- conditional_iterator conditional_end() const {
- return ConditionalStack.end();
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
deleted file mode 100644
index 963d95d..0000000
--- a/include/clang/Lex/PreprocessorOptions.h
+++ /dev/null
@@ -1,185 +0,0 @@
-//===--- PreprocessorOptions.h ----------------------------------*- 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_LEX_PREPROCESSOROPTIONS_H_
-#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
-
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
-#include <cassert>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace llvm {
- class MemoryBuffer;
-}
-
-namespace clang {
-
-class Preprocessor;
-class LangOptions;
-
-/// \brief Enumerate the kinds of standard library that
-enum ObjCXXARCStandardLibraryKind {
- ARCXX_nolib,
- /// \brief libc++
- ARCXX_libcxx,
- /// \brief libstdc++
- ARCXX_libstdcxx
-};
-
-/// PreprocessorOptions - This class is used for passing the various options
-/// used in preprocessor initialization to InitializePreprocessor().
-class PreprocessorOptions : public RefCountedBase<PreprocessorOptions> {
-public:
- std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
- std::vector<std::string> Includes;
- std::vector<std::string> MacroIncludes;
-
- /// \brief Initialize the preprocessor with the compiler and target specific
- /// predefines.
- unsigned UsePredefines : 1;
-
- /// \brief Whether we should maintain a detailed record of all macro
- /// definitions and expansions.
- unsigned DetailedRecord : 1;
-
- /// 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.
- std::vector<std::string> ChainedIncludes;
-
- /// \brief When true, disables most of the normal validation performed on
- /// precompiled headers.
- bool DisablePCHValidation;
-
- /// \brief When true, a PCH with compiler errors will not be rejected.
- bool AllowPCHWithCompilerErrors;
-
- /// \brief Dump declarations that are deserialized from PCH, for testing.
- bool DumpDeserializedPCHDecls;
-
- /// \brief 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
- /// 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;
-
- /// The implicit PTH input included at the start of the translation unit, or
- /// empty.
- std::string ImplicitPTHInclude;
-
- /// If given, a PTH cache file to use for speeding up header parsing.
- std::string TokenCache;
-
- /// \brief 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;
-
- /// \brief 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
- /// 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)
- /// the buffers associated with remapped files.
- ///
- /// This flag defaults to false; it can be set true only through direct
- /// manipulation of the compiler invocation object, in cases where the
- /// compiler invocation and its buffers will be reused.
- bool RetainRemappedFileBuffers;
-
- /// \brief 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;
-
- /// \brief Records the set of modules
- class FailedModulesSet : public RefCountedBase<FailedModulesSet> {
- llvm::StringSet<> Failed;
-
- public:
- bool hasAlreadyFailed(StringRef module) {
- return Failed.count(module) > 0;
- }
-
- void addFailed(StringRef module) {
- Failed.insert(module);
- }
- };
-
- /// \brief 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,
- /// other instances will see that the module has failed and won't try to
- /// build it again.
- IntrusiveRefCntPtr<FailedModulesSet> FailedModules;
-
-public:
- PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
- DisablePCHValidation(false),
- AllowPCHWithCompilerErrors(false),
- DumpDeserializedPCHDecls(false),
- PrecompiledPreambleBytes(0, true),
- RemappedFilesKeepOriginalName(true),
- RetainRemappedFileBuffers(false),
- ObjCXXARCStandardLibrary(ARCXX_nolib) { }
-
- void addMacroDef(StringRef Name) { Macros.emplace_back(Name, false); }
- void addMacroUndef(StringRef Name) { Macros.emplace_back(Name, true); }
- void addRemappedFile(StringRef From, StringRef To) {
- RemappedFiles.emplace_back(From, To);
- }
-
- void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) {
- RemappedFileBuffers.emplace_back(From, To);
- }
-
- void clearRemappedFiles() {
- RemappedFiles.clear();
- RemappedFileBuffers.clear();
- }
-
- /// \brief Reset any options that are not considered when building a
- /// module.
- void resetNonModularOptions() {
- Includes.clear();
- MacroIncludes.clear();
- ChainedIncludes.clear();
- DumpDeserializedPCHDecls = false;
- ImplicitPCHInclude.clear();
- ImplicitPTHInclude.clear();
- TokenCache.clear();
- RetainRemappedFileBuffers = true;
- PrecompiledPreambleBytes.first = 0;
- PrecompiledPreambleBytes.second = 0;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h
deleted file mode 100644
index a3d6096..0000000
--- a/include/clang/Lex/ScratchBuffer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===--- ScratchBuffer.h - Scratch space for forming tokens -----*- 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 ScratchBuffer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_SCRATCHBUFFER_H
-#define LLVM_CLANG_LEX_SCRATCHBUFFER_H
-
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
- class SourceManager;
-
-/// ScratchBuffer - This class exposes a simple interface for the dynamic
-/// construction of tokens. This is used for builtin macros (e.g. __LINE__) as
-/// well as token pasting, etc.
-class ScratchBuffer {
- SourceManager &SourceMgr;
- char *CurBuffer;
- SourceLocation BufferStartLoc;
- unsigned BytesUsed;
-public:
- ScratchBuffer(SourceManager &SM);
-
- /// getToken - Splat the specified text into a temporary MemoryBuffer and
- /// return a SourceLocation that refers to the token. This is just like the
- /// previous method, but returns a location that indicates the physloc of the
- /// token.
- SourceLocation getToken(const char *Buf, unsigned Len, const char *&DestPtr);
-
-private:
- void AllocScratchBuffer(unsigned RequestLen);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
deleted file mode 100644
index 7ba22b2..0000000
--- a/include/clang/Lex/Token.h
+++ /dev/null
@@ -1,328 +0,0 @@
-//===--- Token.h - Token interface ------------------------------*- 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 Token interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_TOKEN_H
-#define LLVM_CLANG_LEX_TOKEN_H
-
-#include "clang/Basic/OperatorKinds.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/TemplateKinds.h"
-#include "clang/Basic/TokenKinds.h"
-#include "llvm/ADT/StringRef.h"
-#include <cstdlib>
-
-namespace clang {
-
-class IdentifierInfo;
-
-/// Token - This structure provides full information about a lexed token.
-/// It is not intended to be space efficient, it is intended to return as much
-/// information as possible about each returned token. This is expected to be
-/// compressed into a smaller form if memory footprint is important.
-///
-/// The parser can create a special "annotation token" representing a stream of
-/// tokens that were parsed and semantically resolved, e.g.: "foo::MyClass<int>"
-/// can be represented by a single typename annotation token that carries
-/// information about the SourceRange of the tokens and the type object.
-class Token {
- /// The location of the token. This is actually a SourceLocation.
- unsigned Loc;
-
- // Conceptually these next two fields could be in a union. However, this
- // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical
- // routine. Keeping as separate members with casts until a more beautiful fix
- // presents itself.
-
- /// UintData - This holds either the length of the token text, when
- /// a normal token, or the end of the SourceRange when an annotation
- /// token.
- unsigned UintData;
-
- /// PtrData - This is a union of four different pointer types, which depends
- /// on what type of token this is:
- /// Identifiers, keywords, etc:
- /// This is an IdentifierInfo*, which contains the uniqued identifier
- /// spelling.
- /// Literals: isLiteral() returns true.
- /// This is a pointer to the start of the token in a text buffer, which
- /// may be dirty (have trigraphs / escaped newlines).
- /// Annotations (resolved type names, C++ scopes, etc): isAnnotation().
- /// This is a pointer to sema-specific data for the annotation token.
- /// Eof:
- // This is a pointer to a Decl.
- /// Other:
- /// This is null.
- void *PtrData;
-
- /// Kind - The actual flavor of token this is.
- tok::TokenKind Kind;
-
- /// Flags - Bits we track about this token, members of the TokenFlags enum.
- unsigned short Flags;
-public:
-
- // Various flags set per token:
- enum TokenFlags {
- StartOfLine = 0x01, // At start of line or only after whitespace
- // (considering the line after macro expansion).
- LeadingSpace = 0x02, // Whitespace exists before this token (considering
- // whitespace after macro expansion).
- DisableExpand = 0x04, // This identifier may never be macro expanded.
- NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
- LeadingEmptyMacro = 0x10, // Empty macro exists before this token.
- HasUDSuffix = 0x20, // This string or character literal has a ud-suffix.
- HasUCN = 0x40, // This identifier contains a UCN.
- IgnoredComma = 0x80, // This comma is not a macro argument separator (MS).
- StringifiedInMacro = 0x100, // This string or character literal is formed by
- // macro stringizing or charizing operator.
- };
-
- tok::TokenKind getKind() const { return Kind; }
- void setKind(tok::TokenKind K) { Kind = K; }
-
- /// is/isNot - Predicates to check if this token is a specific kind, as in
- /// "if (Tok.is(tok::l_brace)) {...}".
- bool is(tok::TokenKind K) const { return Kind == K; }
- bool isNot(tok::TokenKind K) const { return Kind != K; }
- bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
- return is(K1) || is(K2);
- }
- template <typename... Ts>
- bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, Ts... Ks) const {
- return is(K1) || isOneOf(K2, Ks...);
- }
-
- /// \brief 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
- /// constant, string, etc.
- bool isLiteral() const {
- return tok::isLiteral(getKind());
- }
-
- /// \brief 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
- /// offset in the current file.
- SourceLocation getLocation() const {
- return SourceLocation::getFromRawEncoding(Loc);
- }
- unsigned getLength() const {
- assert(!isAnnotation() && "Annotation tokens have no length field");
- return UintData;
- }
-
- void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); }
- void setLength(unsigned Len) {
- assert(!isAnnotation() && "Annotation tokens have no length field");
- UintData = Len;
- }
-
- SourceLocation getAnnotationEndLoc() const {
- assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
- return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc);
- }
- void setAnnotationEndLoc(SourceLocation L) {
- assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
- UintData = L.getRawEncoding();
- }
-
- SourceLocation getLastLoc() const {
- return isAnnotation() ? getAnnotationEndLoc() : getLocation();
- }
-
- SourceLocation getEndLoc() const {
- return isAnnotation() ? getAnnotationEndLoc()
- : getLocation().getLocWithOffset(getLength());
- }
-
- /// \brief SourceRange of the group of tokens that this annotation token
- /// represents.
- SourceRange getAnnotationRange() const {
- return SourceRange(getLocation(), getAnnotationEndLoc());
- }
- void setAnnotationRange(SourceRange R) {
- setLocation(R.getBegin());
- setAnnotationEndLoc(R.getEnd());
- }
-
- const char *getName() const { return tok::getTokenName(Kind); }
-
- /// \brief Reset all flags to cleared.
- void startToken() {
- Kind = tok::unknown;
- Flags = 0;
- PtrData = nullptr;
- UintData = 0;
- Loc = SourceLocation().getRawEncoding();
- }
-
- IdentifierInfo *getIdentifierInfo() const {
- assert(isNot(tok::raw_identifier) &&
- "getIdentifierInfo() on a tok::raw_identifier token!");
- assert(!isAnnotation() &&
- "getIdentifierInfo() on an annotation token!");
- if (isLiteral()) return nullptr;
- if (is(tok::eof)) return nullptr;
- return (IdentifierInfo*) PtrData;
- }
- void setIdentifierInfo(IdentifierInfo *II) {
- PtrData = (void*) II;
- }
-
- const void *getEofData() const {
- assert(is(tok::eof));
- return reinterpret_cast<const void *>(PtrData);
- }
- void setEofData(const void *D) {
- assert(is(tok::eof));
- assert(!PtrData);
- PtrData = const_cast<void *>(D);
- }
-
- /// getRawIdentifier - For a raw identifier token (i.e., an identifier
- /// lexed in raw mode), returns a reference to the text substring in the
- /// buffer if known.
- StringRef getRawIdentifier() const {
- assert(is(tok::raw_identifier));
- return StringRef(reinterpret_cast<const char *>(PtrData), getLength());
- }
- void setRawIdentifierData(const char *Ptr) {
- assert(is(tok::raw_identifier));
- PtrData = const_cast<char*>(Ptr);
- }
-
- /// getLiteralData - For a literal token (numeric constant, string, etc), this
- /// returns a pointer to the start of it in the text buffer if known, null
- /// otherwise.
- const char *getLiteralData() const {
- assert(isLiteral() && "Cannot get literal data of non-literal");
- return reinterpret_cast<const char*>(PtrData);
- }
- void setLiteralData(const char *Ptr) {
- assert(isLiteral() && "Cannot set literal data of non-literal");
- PtrData = const_cast<char*>(Ptr);
- }
-
- void *getAnnotationValue() const {
- assert(isAnnotation() && "Used AnnotVal on non-annotation token");
- return PtrData;
- }
- void setAnnotationValue(void *val) {
- assert(isAnnotation() && "Used AnnotVal on non-annotation token");
- PtrData = val;
- }
-
- /// \brief Set the specified flag.
- void setFlag(TokenFlags Flag) {
- Flags |= Flag;
- }
-
- /// \brief Unset the specified flag.
- void clearFlag(TokenFlags Flag) {
- Flags &= ~Flag;
- }
-
- /// \brief Return the internal represtation of the flags.
- ///
- /// This is only intended for low-level operations such as writing tokens to
- /// disk.
- unsigned getFlags() const {
- return Flags;
- }
-
- /// \brief Set a flag to either true or false.
- void setFlagValue(TokenFlags Flag, bool Val) {
- if (Val)
- setFlag(Flag);
- else
- clearFlag(Flag);
- }
-
- /// isAtStartOfLine - Return true if this token is at the start of a line.
- ///
- bool isAtStartOfLine() const { return (Flags & StartOfLine) ? true : false; }
-
- /// \brief Return true if this token has whitespace before it.
- ///
- bool hasLeadingSpace() const { return (Flags & LeadingSpace) ? true : false; }
-
- /// \brief Return true if this identifier token should never
- /// be expanded in the future, due to C99 6.10.3.4p2.
- bool isExpandDisabled() const {
- return (Flags & DisableExpand) ? true : false;
- }
-
- /// \brief Return true if we have an ObjC keyword identifier.
- bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const;
-
- /// \brief Return the ObjC keyword kind.
- tok::ObjCKeywordKind getObjCKeywordID() const;
-
- /// \brief Return true if this token has trigraphs or escaped newlines in it.
- bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; }
-
- /// \brief Return true if this token has an empty macro before it.
- ///
- bool hasLeadingEmptyMacro() const {
- return (Flags & LeadingEmptyMacro) ? true : false;
- }
-
- /// \brief Return true if this token is a string or character literal which
- /// has a ud-suffix.
- bool hasUDSuffix() const { return (Flags & HasUDSuffix) ? true : false; }
-
- /// Returns true if this token contains a universal character name.
- bool hasUCN() const { return (Flags & HasUCN) ? true : false; }
-
- /// Returns true if this token is formed by macro by stringizing or charizing
- /// operator.
- bool stringifiedInMacro() const {
- return (Flags & StringifiedInMacro) ? true : false;
- }
-};
-
-/// \brief Information about the conditional stack (\#if directives)
-/// currently active.
-struct PPConditionalInfo {
- /// \brief Location where the conditional started.
- SourceLocation IfLoc;
-
- /// \brief 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
- /// 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,
- /// \#elif/\#else directives are not allowed.
- bool FoundElse;
-};
-
-} // end namespace clang
-
-namespace llvm {
- template <>
- struct isPodLike<clang::Token> { static const bool value = true; };
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h
deleted file mode 100644
index a2d98b0..0000000
--- a/include/clang/Lex/TokenConcatenation.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===--- TokenConcatenation.h - Token Concatenation Avoidance ---*- 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 TokenConcatenation class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_TOKENCONCATENATION_H
-#define LLVM_CLANG_LEX_TOKENCONCATENATION_H
-
-#include "clang/Basic/TokenKinds.h"
-
-namespace clang {
- class Preprocessor;
- class Token;
-
- /// TokenConcatenation class, which answers the question of
- /// "Is it safe to emit two tokens without a whitespace between them, or
- /// would that cause implicit concatenation of the tokens?"
- ///
- /// For example, it emitting two identifiers "foo" and "bar" next to each
- /// other would cause the lexer to produce one "foobar" token. Emitting "1"
- /// and ")" next to each other is safe.
- ///
- class TokenConcatenation {
- Preprocessor &PP;
-
- enum AvoidConcatInfo {
- /// By default, a token never needs to avoid concatenation. Most tokens
- /// (e.g. ',', ')', etc) don't cause a problem when concatenated.
- aci_never_avoid_concat = 0,
-
- /// aci_custom_firstchar - AvoidConcat contains custom code to handle this
- /// token's requirements, and it needs to know the first character of the
- /// token.
- aci_custom_firstchar = 1,
-
- /// aci_custom - AvoidConcat contains custom code to handle this token's
- /// requirements, but it doesn't need to know the first character of the
- /// token.
- aci_custom = 2,
-
- /// aci_avoid_equal - Many tokens cannot be safely followed by an '='
- /// character. For example, "<<" turns into "<<=" when followed by an =.
- aci_avoid_equal = 4
- };
-
- /// TokenInfo - This array contains information for each token on what
- /// action to take when avoiding concatenation of tokens in the AvoidConcat
- /// method.
- char TokenInfo[tok::NUM_TOKENS];
- public:
- TokenConcatenation(Preprocessor &PP);
-
- bool AvoidConcat(const Token &PrevPrevTok,
- const Token &PrevTok,
- const Token &Tok) const;
-
- private:
- /// IsIdentifierStringPrefix - Return true if the spelling of the token
- /// is literally 'L', 'u', 'U', or 'u8'.
- bool IsIdentifierStringPrefix(const Token &Tok) const;
- };
- } // end clang namespace
-
-#endif
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
deleted file mode 100644
index fdeed44..0000000
--- a/include/clang/Lex/TokenLexer.h
+++ /dev/null
@@ -1,205 +0,0 @@
-//===--- TokenLexer.h - Lex from a token buffer -----------------*- 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 TokenLexer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_TOKENLEXER_H
-#define LLVM_CLANG_LEX_TOKENLEXER_H
-
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
- class MacroInfo;
- class Preprocessor;
- class Token;
- class MacroArgs;
-
-/// TokenLexer - This implements a lexer that returns tokens from a macro body
-/// or token stream instead of lexing from a character buffer. This is used for
-/// macro expansion and _Pragma handling, for example.
-///
-class TokenLexer {
- /// Macro - The macro we are expanding from. This is null if expanding a
- /// token stream.
- ///
- MacroInfo *Macro;
-
- /// ActualArgs - The actual arguments specified for a function-like macro, or
- /// null. The TokenLexer owns the pointed-to object.
- MacroArgs *ActualArgs;
-
- /// PP - The current preprocessor object we are expanding for.
- ///
- Preprocessor &PP;
-
- /// Tokens - This is the pointer to an array of tokens that the macro is
- /// defined to, with arguments expanded for function-like macros. If this is
- /// a token stream, these are the tokens we are returning. This points into
- /// the macro definition we are lexing from, a cache buffer that is owned by
- /// the preprocessor, or some other buffer that we may or may not own
- /// (depending on OwnsTokens).
- /// Note that if it points into Preprocessor's cache buffer, the Preprocessor
- /// may update the pointer as needed.
- const Token *Tokens;
- friend class Preprocessor;
-
- /// NumTokens - This is the length of the Tokens array.
- ///
- unsigned NumTokens;
-
- /// CurToken - This is the next token that Lex will return.
- ///
- unsigned CurToken;
-
- /// ExpandLocStart/End - The source location range where this macro was
- /// expanded.
- SourceLocation ExpandLocStart, ExpandLocEnd;
-
- /// \brief 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
- /// "source location address space".
- unsigned MacroStartSLocOffset;
-
- /// \brief Location of the macro definition.
- SourceLocation MacroDefStart;
- /// \brief Length of the macro definition.
- unsigned MacroDefLength;
-
- /// Lexical information about the expansion point of the macro: the identifier
- /// that the macro expanded from had these properties.
- bool AtStartOfLine : 1;
- bool HasLeadingSpace : 1;
-
- // NextTokGetsSpace - When this is true, the next token appended to the
- // output list during function argument expansion will get a leading space,
- // regardless of whether it had one to begin with or not. This is used for
- // placemarker support. If still true after function argument expansion, the
- // leading space will be applied to the first token following the macro
- // expansion.
- bool NextTokGetsSpace : 1;
-
- /// OwnsTokens - This is true if this TokenLexer allocated the Tokens
- /// array, and thus needs to free it when destroyed. For simple object-like
- /// macros (for example) we just point into the token buffer of the macro
- /// definition, we don't make a copy of it.
- bool OwnsTokens : 1;
-
- /// DisableMacroExpansion - This is true when tokens lexed from the TokenLexer
- /// should not be subject to further macro expansion.
- bool DisableMacroExpansion : 1;
-
- TokenLexer(const TokenLexer &) = delete;
- void operator=(const TokenLexer &) = delete;
-public:
- /// Create a TokenLexer for the specified macro with the specified actual
- /// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
- /// ILEnd specifies the location of the ')' for a function-like macro or the
- /// identifier for an object-like macro.
- TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
- MacroArgs *ActualArgs, Preprocessor &pp)
- : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
- Init(Tok, ILEnd, MI, ActualArgs);
- }
-
- /// Init - Initialize this TokenLexer to expand from the specified macro
- /// with the specified argument information. Note that this ctor takes
- /// ownership of the ActualArgs pointer. ILEnd specifies the location of the
- /// ')' for a function-like macro or the identifier for an object-like macro.
- void Init(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
- MacroArgs *ActualArgs);
-
- /// Create a TokenLexer for the specified token stream. If 'OwnsTokens' is
- /// specified, this takes ownership of the tokens and delete[]'s them when
- /// the token lexer is empty.
- TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion,
- bool ownsTokens, Preprocessor &pp)
- : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
- Init(TokArray, NumToks, DisableExpansion, ownsTokens);
- }
-
- /// Init - Initialize this TokenLexer with the specified token stream.
- /// This does not take ownership of the specified token vector.
- ///
- /// DisableExpansion is true when macro expansion of tokens lexed from this
- /// stream should be disabled.
- void Init(const Token *TokArray, unsigned NumToks,
- bool DisableMacroExpansion, bool OwnsTokens);
-
- ~TokenLexer() { destroy(); }
-
- /// isNextTokenLParen - If the next token lexed will pop this macro off the
- /// expansion stack, return 2. If the next unexpanded token is a '(', return
- /// 1, otherwise return 0.
- unsigned isNextTokenLParen() const;
-
- /// Lex - Lex and return a token from this macro stream.
- bool Lex(Token &Tok);
-
- /// isParsingPreprocessorDirective - Return true if we are in the middle of a
- /// preprocessor directive.
- bool isParsingPreprocessorDirective() const;
-
-private:
- void destroy();
-
- /// isAtEnd - Return true if the next lex call will pop this macro off the
- /// include stack.
- bool isAtEnd() const {
- return CurToken == NumTokens;
- }
-
- /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
- /// operator. Read the ## and RHS, and paste the LHS/RHS together. If there
- /// are is another ## after it, chomp it iteratively. Return the result as
- /// Tok. If this returns true, the caller should immediately return the
- /// token.
- bool PasteTokens(Token &Tok);
-
- /// Expand the arguments of a function-like macro so that we can quickly
- /// return preexpanded tokens from Tokens.
- void ExpandFunctionArguments();
-
- /// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes
- /// together to form a comment that comments out everything in the current
- /// macro, other active macros, and anything left on the current physical
- /// source line of the expanded buffer. Handle this by returning the
- /// 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
- /// 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
- /// tokens to their new expanded locations.
- ///
- /// \param ArgIdSpellLoc the location of the macro argument id inside the
- /// macro definition.
- void updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc,
- Token *begin_tokens, Token *end_tokens);
-
- /// Remove comma ahead of __VA_ARGS__, if present, according to compiler
- /// dialect settings. Returns true if the comma is removed.
- bool MaybeRemoveCommaBeforeVaArgs(SmallVectorImpl<Token> &ResultToks,
- bool HasPasteOperator,
- MacroInfo *Macro, unsigned MacroArgNo,
- Preprocessor &PP);
-
- void PropagateLineStartLeadingSpaceInfo(Token &Result);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Makefile b/include/clang/Makefile
deleted file mode 100644
index 5ba2dd2..0000000
--- a/include/clang/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-CLANG_LEVEL := ../..
-DIRS := AST Basic Driver Parse Sema Serialization
-
-include $(CLANG_LEVEL)/Makefile
-
-install-local::
- $(Echo) Installing Clang include files
- $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
- $(Verb) if test -d "$(PROJ_SRC_DIR)" ; then \
- cd $(PROJ_SRC_DIR)/.. && \
- for hdr in `find clang -type f \
- '(' -name LICENSE.TXT \
- -o -name '*.def' \
- -o -name '*.h' \
- -o -name '*.inc' \
- ')' -print \
- | grep -v CVS | grep -v .svn | grep -v .dir` ; do \
- instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \
- if test \! -d "$$instdir" ; then \
- $(EchoCmd) Making install directory $$instdir ; \
- $(MKDIR) $$instdir ;\
- fi ; \
- $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
- done ; \
- fi
-ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
- $(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include/clang" ; then \
- cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
- for hdr in `find clang -type f \
- '(' -name LICENSE.TXT \
- -o -name '*.def' \
- -o -name '*.h' \
- -o -name '*.inc' \
- ')' -print \
- | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
- instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \
- if test \! -d "$$instdir" ; then \
- $(EchoCmd) Making install directory $$instdir ; \
- $(MKDIR) $$instdir ;\
- fi ; \
- $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
- done ; \
- fi
-endif
diff --git a/include/clang/Parse/CMakeLists.txt b/include/clang/Parse/CMakeLists.txt
deleted file mode 100644
index ec75f7b9..0000000
--- a/include/clang/Parse/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-clang_tablegen(AttrParserStringSwitches.inc -gen-clang-attr-parser-string-switches
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrParserStringSwitches)
diff --git a/include/clang/Parse/Makefile b/include/clang/Parse/Makefile
deleted file mode 100644
index c477019..0000000
--- a/include/clang/Parse/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-CLANG_LEVEL := ../../..
-TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrParserStringSwitches.inc
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/AttrParserStringSwitches.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang parser-related attribute string switches"
- $(Verb) $(ClangTableGen) -gen-clang-attr-parser-string-switches -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h
deleted file mode 100644
index 21f9701..0000000
--- a/include/clang/Parse/ParseAST.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===--- ParseAST.h - Define the ParseAST method ----------------*- 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 clang::ParseAST method.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_PARSEAST_H
-#define LLVM_CLANG_PARSE_PARSEAST_H
-
-#include "clang/Basic/LangOptions.h"
-
-namespace clang {
- class Preprocessor;
- class ASTConsumer;
- class ASTContext;
- class CodeCompleteConsumer;
- class Sema;
-
- /// \brief Parse the entire file specified, notifying the ASTConsumer as
- /// the file is parsed.
- ///
- /// This operation inserts the parsed decls into the translation
- /// unit held by Ctx.
- ///
- /// \param TUKind The kind of translation unit being parsed.
- ///
- /// \param CompletionConsumer If given, an object to consume code completion
- /// results.
- void ParseAST(Preprocessor &pp, ASTConsumer *C,
- ASTContext &Ctx, bool PrintStats = false,
- TranslationUnitKind TUKind = TU_Complete,
- CodeCompleteConsumer *CompletionConsumer = nullptr,
- bool SkipFunctionBodies = false);
-
- /// \brief Parse the main file known to the preprocessor, producing an
- /// abstract syntax tree.
- void ParseAST(Sema &S, bool PrintStats = false,
- bool SkipFunctionBodies = false);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h
deleted file mode 100644
index f3a7f3b..0000000
--- a/include/clang/Parse/ParseDiagnostic.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- DiagnosticParse.h - Diagnostics for libparse -----------*- 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_PARSE_PARSEDIAGNOSTIC_H
-#define LLVM_CLANG_PARSE_PARSEDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define PARSESTART
-#include "clang/Basic/DiagnosticParseKinds.inc"
-#undef DIAG
- NUM_BUILTIN_PARSE_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
deleted file mode 100644
index 82b7798..0000000
--- a/include/clang/Parse/Parser.h
+++ /dev/null
@@ -1,2593 +0,0 @@
-//===--- Parser.h - C Language Parser ---------------------------*- 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 Parser interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_PARSER_H
-#define LLVM_CLANG_PARSE_PARSER_H
-
-#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Basic/OperatorPrecedence.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Lex/CodeCompletionHandler.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/LoopHint.h"
-#include "clang/Sema/Sema.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/SaveAndRestore.h"
-#include <memory>
-#include <stack>
-
-namespace clang {
- class PragmaHandler;
- class Scope;
- class BalancedDelimiterTracker;
- class CorrectionCandidateCallback;
- class DeclGroupRef;
- class DiagnosticBuilder;
- class Parser;
- class ParsingDeclRAIIObject;
- class ParsingDeclSpec;
- class ParsingDeclarator;
- class ParsingFieldDeclarator;
- class ColonProtectionRAIIObject;
- class InMessageExpressionRAIIObject;
- class PoisonSEHIdentifiersRAIIObject;
- class VersionTuple;
- class OMPClause;
- class ObjCTypeParamList;
- class ObjCTypeParameter;
-
-/// Parser - This implements a parser for the C family of languages. After
-/// parsing units of the grammar, productions are invoked to handle whatever has
-/// been read.
-///
-class Parser : public CodeCompletionHandler {
- friend class ColonProtectionRAIIObject;
- friend class InMessageExpressionRAIIObject;
- friend class PoisonSEHIdentifiersRAIIObject;
- friend class ObjCDeclContextSwitch;
- friend class ParenBraceBracketBalancer;
- friend class BalancedDelimiterTracker;
-
- Preprocessor &PP;
-
- /// Tok - The current token we are peeking ahead. All parsing methods assume
- /// that this is valid.
- Token Tok;
-
- // PrevTokLocation - The location of the token we previously
- // consumed. This token is used for diagnostics where we expected to
- // see a token following another token (e.g., the ';' at the end of
- // a statement).
- SourceLocation PrevTokLocation;
-
- unsigned short ParenCount, BracketCount, BraceCount;
-
- /// Actions - These are the callbacks we invoke as we parse various constructs
- /// in the file.
- Sema &Actions;
-
- DiagnosticsEngine &Diags;
-
- /// ScopeCache - Cache scopes to reduce malloc traffic.
- enum { ScopeCacheSize = 16 };
- unsigned NumCachedScopes;
- Scope *ScopeCache[ScopeCacheSize];
-
- /// Identifiers used for SEH handling in Borland. These are only
- /// allowed in particular circumstances
- // __except block
- IdentifierInfo *Ident__exception_code,
- *Ident___exception_code,
- *Ident_GetExceptionCode;
- // __except filter expression
- IdentifierInfo *Ident__exception_info,
- *Ident___exception_info,
- *Ident_GetExceptionInfo;
- // __finally
- IdentifierInfo *Ident__abnormal_termination,
- *Ident___abnormal_termination,
- *Ident_AbnormalTermination;
-
- /// Contextual keywords for Microsoft extensions.
- IdentifierInfo *Ident__except;
- mutable IdentifierInfo *Ident_sealed;
-
- /// Ident_super - IdentifierInfo for "super", to support fast
- /// comparison.
- IdentifierInfo *Ident_super;
- /// Ident_vector, Ident_bool - cached IdentifierInfos for "vector" and
- /// "bool" fast comparison. Only present if AltiVec or ZVector are enabled.
- IdentifierInfo *Ident_vector;
- IdentifierInfo *Ident_bool;
- /// Ident_pixel - cached IdentifierInfos for "pixel" fast comparison.
- /// Only present if AltiVec enabled.
- IdentifierInfo *Ident_pixel;
-
- /// Objective-C contextual keywords.
- mutable IdentifierInfo *Ident_instancetype;
-
- /// \brief Identifier for "introduced".
- IdentifierInfo *Ident_introduced;
-
- /// \brief Identifier for "deprecated".
- IdentifierInfo *Ident_deprecated;
-
- /// \brief Identifier for "obsoleted".
- IdentifierInfo *Ident_obsoleted;
-
- /// \brief Identifier for "unavailable".
- IdentifierInfo *Ident_unavailable;
-
- /// \brief Identifier for "message".
- IdentifierInfo *Ident_message;
-
- /// C++0x contextual keywords.
- mutable IdentifierInfo *Ident_final;
- mutable IdentifierInfo *Ident_override;
-
- // C++ type trait keywords that can be reverted to identifiers and still be
- // used as type traits.
- llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;
-
- std::unique_ptr<PragmaHandler> AlignHandler;
- std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
- std::unique_ptr<PragmaHandler> OptionsHandler;
- std::unique_ptr<PragmaHandler> PackHandler;
- std::unique_ptr<PragmaHandler> MSStructHandler;
- std::unique_ptr<PragmaHandler> UnusedHandler;
- std::unique_ptr<PragmaHandler> WeakHandler;
- std::unique_ptr<PragmaHandler> RedefineExtnameHandler;
- std::unique_ptr<PragmaHandler> FPContractHandler;
- std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
- std::unique_ptr<PragmaHandler> OpenMPHandler;
- std::unique_ptr<PragmaHandler> MSCommentHandler;
- std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
- std::unique_ptr<PragmaHandler> MSPointersToMembers;
- std::unique_ptr<PragmaHandler> MSVtorDisp;
- std::unique_ptr<PragmaHandler> MSInitSeg;
- std::unique_ptr<PragmaHandler> MSDataSeg;
- std::unique_ptr<PragmaHandler> MSBSSSeg;
- std::unique_ptr<PragmaHandler> MSConstSeg;
- std::unique_ptr<PragmaHandler> MSCodeSeg;
- std::unique_ptr<PragmaHandler> MSSection;
- std::unique_ptr<PragmaHandler> MSRuntimeChecks;
- std::unique_ptr<PragmaHandler> OptimizeHandler;
- std::unique_ptr<PragmaHandler> LoopHintHandler;
- std::unique_ptr<PragmaHandler> UnrollHintHandler;
- std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
-
- std::unique_ptr<CommentHandler> CommentSemaHandler;
-
- /// Whether the '>' token acts as an operator or not. This will be
- /// true except when we are parsing an expression within a C++
- /// template argument list, where the '>' closes the template
- /// argument list.
- bool GreaterThanIsOperator;
-
- /// ColonIsSacred - When this is false, we aggressively try to recover from
- /// code like "foo : bar" as if it were a typo for "foo :: bar". This is not
- /// safe in case statements and a few other things. This is managed by the
- /// ColonProtectionRAIIObject RAII object.
- bool ColonIsSacred;
-
- /// \brief When true, we are directly inside an Objective-C message
- /// send expression.
- ///
- /// This is managed by the \c InMessageExpressionRAIIObject class, and
- /// should not be set directly.
- bool InMessageExpression;
-
- /// The "depth" of the template parameters currently being parsed.
- unsigned TemplateParameterDepth;
-
- /// \brief RAII class that manages the template parameter depth.
- class TemplateParameterDepthRAII {
- unsigned &Depth;
- unsigned AddedLevels;
- public:
- explicit TemplateParameterDepthRAII(unsigned &Depth)
- : Depth(Depth), AddedLevels(0) {}
-
- ~TemplateParameterDepthRAII() {
- Depth -= AddedLevels;
- }
-
- void operator++() {
- ++Depth;
- ++AddedLevels;
- }
- void addDepth(unsigned D) {
- Depth += D;
- AddedLevels += D;
- }
- unsigned getDepth() const { return Depth; }
- };
-
- /// Factory object for creating AttributeList objects.
- AttributeFactory AttrFactory;
-
- /// \brief 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.
- SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
-
- IdentifierInfo *getSEHExceptKeyword();
-
- /// True if we are within an Objective-C container while parsing C-like decls.
- ///
- /// This is necessary because Sema thinks we have left the container
- /// to parse the C-like decls, meaning Actions.getObjCDeclContext() will
- /// be NULL.
- bool ParsingInObjCContainer;
-
- bool SkipFunctionBodies;
-
-public:
- Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
- ~Parser() override;
-
- const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
- const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
- Preprocessor &getPreprocessor() const { return PP; }
- Sema &getActions() const { return Actions; }
- AttributeFactory &getAttrFactory() { return AttrFactory; }
-
- const Token &getCurToken() const { return Tok; }
- Scope *getCurScope() const { return Actions.getCurScope(); }
- void incrementMSManglingNumber() const {
- return Actions.incrementMSManglingNumber();
- }
-
- Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
-
- // Type forwarding. All of these are statically 'void*', but they may all be
- // different actual classes based on the actions in place.
- typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
- typedef OpaquePtr<TemplateName> TemplateTy;
-
- typedef SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
-
- typedef Sema::FullExprArg FullExprArg;
-
- // Parsing methods.
-
- /// Initialize - Warm up the parser.
- ///
- void Initialize();
-
- /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
- /// the EOF was encountered.
- bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
- bool ParseTopLevelDecl() {
- DeclGroupPtrTy Result;
- return ParseTopLevelDecl(Result);
- }
-
- /// ConsumeToken - Consume the current 'peek token' and lex the next one.
- /// This does not work with special tokens: string literals, code completion
- /// and balanced tokens must be handled using the specific consume methods.
- /// Returns the location of the consumed token.
- SourceLocation ConsumeToken() {
- assert(!isTokenSpecial() &&
- "Should consume special tokens with Consume*Token");
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
-
- bool TryConsumeToken(tok::TokenKind Expected) {
- if (Tok.isNot(Expected))
- return false;
- assert(!isTokenSpecial() &&
- "Should consume special tokens with Consume*Token");
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return true;
- }
-
- bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
- if (!TryConsumeToken(Expected))
- return false;
- Loc = PrevTokLocation;
- return true;
- }
-
- /// Retrieve the underscored keyword (_Nonnull, _Nullable) that corresponds
- /// to the given nullability kind.
- IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability) {
- return Actions.getNullabilityKeyword(nullability);
- }
-
-private:
- //===--------------------------------------------------------------------===//
- // Low-Level token peeking and consumption methods.
- //
-
- /// isTokenParen - Return true if the cur token is '(' or ')'.
- bool isTokenParen() const {
- return Tok.getKind() == tok::l_paren || Tok.getKind() == 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;
- }
- /// isTokenBrace - Return true if the cur token is '{' or '}'.
- bool isTokenBrace() const {
- return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
- }
- /// isTokenStringLiteral - True if this token is a string-literal.
- bool isTokenStringLiteral() const {
- return tok::isStringLiteral(Tok.getKind());
- }
- /// isTokenSpecial - True if this token requires special consumption methods.
- bool isTokenSpecial() const {
- return isTokenStringLiteral() || isTokenParen() || isTokenBracket() ||
- isTokenBrace() || Tok.is(tok::code_completion);
- }
-
- /// \brief 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
- /// token the current token.
- void UnconsumeToken(Token &Consumed) {
- Token Next = Tok;
- PP.EnterToken(Consumed);
- PP.Lex(Tok);
- PP.EnterToken(Next);
- }
-
- /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
- /// current token type. This should only be used in cases where the type of
- /// the token really isn't known, e.g. in error recovery.
- SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
- if (isTokenParen())
- return ConsumeParen();
- if (isTokenBracket())
- return ConsumeBracket();
- if (isTokenBrace())
- return ConsumeBrace();
- if (isTokenStringLiteral())
- return ConsumeStringToken();
- if (Tok.is(tok::code_completion))
- return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
- : handleUnexpectedCodeCompletionToken();
- return ConsumeToken();
- }
-
- /// ConsumeParen - This consume method keeps the paren count up-to-date.
- ///
- SourceLocation ConsumeParen() {
- assert(isTokenParen() && "wrong consume method");
- if (Tok.getKind() == tok::l_paren)
- ++ParenCount;
- else if (ParenCount)
- --ParenCount; // Don't let unbalanced )'s drive the count negative.
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
-
- /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
- ///
- SourceLocation ConsumeBracket() {
- assert(isTokenBracket() && "wrong consume method");
- if (Tok.getKind() == tok::l_square)
- ++BracketCount;
- else if (BracketCount)
- --BracketCount; // Don't let unbalanced ]'s drive the count negative.
-
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
-
- /// ConsumeBrace - This consume method keeps the brace count up-to-date.
- ///
- SourceLocation ConsumeBrace() {
- assert(isTokenBrace() && "wrong consume method");
- if (Tok.getKind() == tok::l_brace)
- ++BraceCount;
- else if (BraceCount)
- --BraceCount; // Don't let unbalanced }'s drive the count negative.
-
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
-
- /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
- /// and returning the token kind. This method is specific to strings, as it
- /// handles string literal concatenation, as per C99 5.1.1.2, translation
- /// phase #6.
- SourceLocation ConsumeStringToken() {
- assert(isTokenStringLiteral() &&
- "Should only consume string literals with this method");
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
-
- /// \brief 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
- /// desired, such as token caching or completion with lookahead.
- SourceLocation ConsumeCodeCompletionToken() {
- assert(Tok.is(tok::code_completion));
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
-
- ///\ brief When we are consuming a code-completion token without having
- /// matched specific position in the grammar, provide code-completion results
- /// based on context.
- ///
- /// \returns the source location of the code-completion token.
- SourceLocation handleUnexpectedCodeCompletionToken();
-
- /// \brief Abruptly cut off parsing; mainly used when we have reached the
- /// code-completion point.
- void cutOffParsing() {
- if (PP.isCodeCompletionEnabled())
- PP.setCodeCompletionReached();
- // Cut off parsing by acting as if we reached the end-of-file.
- Tok.setKind(tok::eof);
- }
-
- /// \brief Determine if we're at the end of the file or at a transition
- /// between modules.
- bool isEofOrEom() {
- tok::TokenKind Kind = Tok.getKind();
- return Kind == tok::eof || Kind == tok::annot_module_begin ||
- Kind == tok::annot_module_end || Kind == tok::annot_module_include;
- }
-
- /// \brief Initialize all pragma handlers.
- void initializePragmaHandlers();
-
- /// \brief Destroy and reset all pragma handlers.
- void resetPragmaHandlers();
-
- /// \brief Handle the annotation token produced for #pragma unused(...)
- void HandlePragmaUnused();
-
- /// \brief Handle the annotation token produced for
- /// #pragma GCC visibility...
- void HandlePragmaVisibility();
-
- /// \brief Handle the annotation token produced for
- /// #pragma pack...
- void HandlePragmaPack();
-
- /// \brief Handle the annotation token produced for
- /// #pragma ms_struct...
- void HandlePragmaMSStruct();
-
- /// \brief Handle the annotation token produced for
- /// #pragma comment...
- void HandlePragmaMSComment();
-
- void HandlePragmaMSPointersToMembers();
-
- void HandlePragmaMSVtorDisp();
-
- void HandlePragmaMSPragma();
- bool HandlePragmaMSSection(StringRef PragmaName,
- SourceLocation PragmaLocation);
- bool HandlePragmaMSSegment(StringRef PragmaName,
- SourceLocation PragmaLocation);
- bool HandlePragmaMSInitSeg(StringRef PragmaName,
- SourceLocation PragmaLocation);
-
- /// \brief Handle the annotation token produced for
- /// #pragma align...
- void HandlePragmaAlign();
-
- /// \brief Handle the annotation token produced for
- /// #pragma weak id...
- void HandlePragmaWeak();
-
- /// \brief Handle the annotation token produced for
- /// #pragma weak id = id...
- void HandlePragmaWeakAlias();
-
- /// \brief Handle the annotation token produced for
- /// #pragma redefine_extname...
- void HandlePragmaRedefineExtname();
-
- /// \brief Handle the annotation token produced for
- /// #pragma STDC FP_CONTRACT...
- void HandlePragmaFPContract();
-
- /// \brief Handle the annotation token produced for
- /// #pragma OPENCL EXTENSION...
- void HandlePragmaOpenCLExtension();
-
- /// \brief Handle the annotation token produced for
- /// #pragma clang __debug captured
- StmtResult HandlePragmaCaptured();
-
- /// \brief Handle the annotation token produced for
- /// #pragma clang loop and #pragma unroll.
- bool HandlePragmaLoopHint(LoopHint &Hint);
-
- /// GetLookAheadToken - This peeks ahead N tokens and returns that token
- /// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
- /// returns the token after Tok, etc.
- ///
- /// Note that this differs from the Preprocessor's LookAhead method, because
- /// the Parser always has one token lexed that the preprocessor doesn't.
- ///
- const Token &GetLookAheadToken(unsigned N) {
- if (N == 0 || Tok.is(tok::eof)) return Tok;
- return PP.LookAhead(N-1);
- }
-
-public:
- /// NextToken - This peeks ahead one token and returns it without
- /// consuming it.
- const Token &NextToken() {
- return PP.LookAhead(0);
- }
-
- /// getTypeAnnotation - Read a parsed type out of an annotation token.
- static ParsedType getTypeAnnotation(Token &Tok) {
- return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue());
- }
-
-private:
- static void setTypeAnnotation(Token &Tok, ParsedType T) {
- Tok.setAnnotationValue(T.getAsOpaquePtr());
- }
-
- /// \brief Read an already-translated primary expression out of an annotation
- /// token.
- static ExprResult getExprAnnotation(Token &Tok) {
- return ExprResult::getFromOpaquePointer(Tok.getAnnotationValue());
- }
-
- /// \brief Set the primary expression corresponding to the given annotation
- /// token.
- static void setExprAnnotation(Token &Tok, ExprResult ER) {
- Tok.setAnnotationValue(ER.getAsOpaquePointer());
- }
-
-public:
- // If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to
- // find a type name by attempting typo correction.
- bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false,
- bool NeedType = false);
- bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
- bool NeedType,
- CXXScopeSpec &SS,
- bool IsNewScope);
- bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
-
-private:
- enum AnnotatedNameKind {
- /// Annotation has failed and emitted an error.
- ANK_Error,
- /// The identifier is a tentatively-declared name.
- ANK_TentativeDecl,
- /// The identifier is a template name. FIXME: Add an annotation for that.
- ANK_TemplateName,
- /// The identifier can't be resolved.
- ANK_Unresolved,
- /// Annotation was successful.
- ANK_Success
- };
- AnnotatedNameKind
- TryAnnotateName(bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
-
- /// Push a tok::annot_cxxscope token onto the token stream.
- void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
-
- /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
- /// replacing them with the non-context-sensitive keywords. This returns
- /// true if the token was replaced.
- bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID,
- bool &isInvalid) {
- if (!getLangOpts().AltiVec && !getLangOpts().ZVector)
- return false;
-
- if (Tok.getIdentifierInfo() != Ident_vector &&
- Tok.getIdentifierInfo() != Ident_bool &&
- (!getLangOpts().AltiVec || Tok.getIdentifierInfo() != Ident_pixel))
- return false;
-
- return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid);
- }
-
- /// TryAltiVecVectorToken - Check for context-sensitive AltiVec vector
- /// identifier token, replacing it with the non-context-sensitive __vector.
- /// This returns true if the token was replaced.
- bool TryAltiVecVectorToken() {
- if ((!getLangOpts().AltiVec && !getLangOpts().ZVector) ||
- Tok.getIdentifierInfo() != Ident_vector) return false;
- return TryAltiVecVectorTokenOutOfLine();
- }
-
- bool TryAltiVecVectorTokenOutOfLine();
- bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID,
- bool &isInvalid);
-
- /// Returns true if the current token is the identifier 'instancetype'.
- ///
- /// Should only be used in Objective-C language modes.
- bool isObjCInstancetype() {
- assert(getLangOpts().ObjC1);
- if (!Ident_instancetype)
- Ident_instancetype = PP.getIdentifierInfo("instancetype");
- return Tok.getIdentifierInfo() == Ident_instancetype;
- }
-
- /// TryKeywordIdentFallback - For compatibility with system headers using
- /// keywords as identifiers, attempt to convert the current token to an
- /// identifier and optionally disable the keyword for the remainder of the
- /// translation unit. This returns false if the token was not replaced,
- /// otherwise emits a diagnostic and returns true.
- bool TryKeywordIdentFallback(bool DisableKeyword);
-
- /// \brief Get the TemplateIdAnnotation from the token.
- TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
-
- /// TentativeParsingAction - An object that is used as a kind of "tentative
- /// parsing transaction". It gets instantiated to mark the token position and
- /// after the token consumption is done, Commit() or Revert() is called to
- /// either "commit the consumed tokens" or revert to the previously marked
- /// token position. Example:
- ///
- /// TentativeParsingAction TPA(*this);
- /// ConsumeToken();
- /// ....
- /// TPA.Revert();
- ///
- class TentativeParsingAction {
- Parser &P;
- Token PrevTok;
- size_t PrevTentativelyDeclaredIdentifierCount;
- unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount;
- bool isActive;
-
- public:
- explicit TentativeParsingAction(Parser& p) : P(p) {
- PrevTok = P.Tok;
- PrevTentativelyDeclaredIdentifierCount =
- P.TentativelyDeclaredIdentifiers.size();
- PrevParenCount = P.ParenCount;
- PrevBracketCount = P.BracketCount;
- PrevBraceCount = P.BraceCount;
- P.PP.EnableBacktrackAtThisPos();
- isActive = true;
- }
- void Commit() {
- assert(isActive && "Parsing action was finished!");
- P.TentativelyDeclaredIdentifiers.resize(
- PrevTentativelyDeclaredIdentifierCount);
- P.PP.CommitBacktrackedTokens();
- isActive = false;
- }
- void Revert() {
- assert(isActive && "Parsing action was finished!");
- P.PP.Backtrack();
- P.Tok = PrevTok;
- P.TentativelyDeclaredIdentifiers.resize(
- PrevTentativelyDeclaredIdentifierCount);
- P.ParenCount = PrevParenCount;
- P.BracketCount = PrevBracketCount;
- P.BraceCount = PrevBraceCount;
- isActive = false;
- }
- ~TentativeParsingAction() {
- assert(!isActive && "Forgot to call Commit or Revert!");
- }
- };
- class UnannotatedTentativeParsingAction;
-
- /// ObjCDeclContextSwitch - An object used to switch context from
- /// an objective-c decl context to its enclosing decl context and
- /// back.
- class ObjCDeclContextSwitch {
- Parser &P;
- Decl *DC;
- SaveAndRestore<bool> WithinObjCContainer;
- public:
- explicit ObjCDeclContextSwitch(Parser &p)
- : P(p), DC(p.getObjCDeclContext()),
- WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
- if (DC)
- P.Actions.ActOnObjCTemporaryExitContainerContext(cast<DeclContext>(DC));
- }
- ~ObjCDeclContextSwitch() {
- if (DC)
- P.Actions.ActOnObjCReenterContainerContext(cast<DeclContext>(DC));
- }
- };
-
- /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
- /// input. If so, it is consumed and false is returned.
- ///
- /// If a trivial punctuator misspelling is encountered, a FixIt error
- /// diagnostic is issued and false is returned after recovery.
- ///
- /// If the input is malformed, this emits the specified diagnostic and true is
- /// returned.
- bool ExpectAndConsume(tok::TokenKind ExpectedTok,
- unsigned Diag = diag::err_expected,
- StringRef DiagMsg = "");
-
- /// \brief 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.
- enum ExtraSemiKind {
- OutsideFunction = 0,
- InsideStruct = 1,
- InstanceVariableList = 2,
- AfterMemberFunctionDefinition = 3
- };
-
- /// \brief Consume any extra semi-colons until the end of the line.
- void ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST = TST_unspecified);
-
-public:
- //===--------------------------------------------------------------------===//
- // Scope manipulation
-
- /// ParseScope - Introduces a new scope for parsing. The kind of
- /// scope is determined by ScopeFlags. Objects of this type should
- /// be created on the stack to coincide with the position where the
- /// parser enters the new scope, and this object's constructor will
- /// create that new scope. Similarly, once the object is destroyed
- /// the parser will exit the scope.
- class ParseScope {
- Parser *Self;
- ParseScope(const ParseScope &) = delete;
- void operator=(const ParseScope &) = delete;
-
- public:
- // ParseScope - Construct a new object to manage a scope in the
- // parser Self where the new Scope is created with the flags
- // ScopeFlags, but only when we aren't about to enter a compound statement.
- ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
- bool BeforeCompoundStmt = false)
- : Self(Self) {
- if (EnteredScope && !BeforeCompoundStmt)
- Self->EnterScope(ScopeFlags);
- else {
- if (BeforeCompoundStmt)
- Self->incrementMSManglingNumber();
-
- this->Self = nullptr;
- }
- }
-
- // Exit - Exit the scope associated with this object now, rather
- // than waiting until the object is destroyed.
- void Exit() {
- if (Self) {
- Self->ExitScope();
- Self = nullptr;
- }
- }
-
- ~ParseScope() {
- Exit();
- }
- };
-
- /// EnterScope - Start a new scope.
- void EnterScope(unsigned ScopeFlags);
-
- /// ExitScope - Pop a scope off the scope stack.
- void ExitScope();
-
-private:
- /// \brief RAII object used to modify the scope flags for the current scope.
- class ParseScopeFlags {
- Scope *CurScope;
- unsigned OldFlags;
- ParseScopeFlags(const ParseScopeFlags &) = delete;
- void operator=(const ParseScopeFlags &) = delete;
-
- public:
- ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true);
- ~ParseScopeFlags();
- };
-
- //===--------------------------------------------------------------------===//
- // Diagnostic Emission and Error recovery.
-
-public:
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
- DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
- DiagnosticBuilder Diag(unsigned DiagID) {
- return Diag(Tok, DiagID);
- }
-
-private:
- void SuggestParentheses(SourceLocation Loc, unsigned DK,
- SourceRange ParenRange);
- void CheckNestedObjCContexts(SourceLocation AtLoc);
-
-public:
-
- /// \brief 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
- StopBeforeMatch = 1 << 1,
- StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
- };
-
- friend LLVM_CONSTEXPR SkipUntilFlags operator|(SkipUntilFlags L,
- SkipUntilFlags R) {
- return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) |
- static_cast<unsigned>(R));
- }
-
- /// SkipUntil - Read tokens until we get to the specified token, then consume
- /// it (unless StopBeforeMatch is specified). Because we cannot guarantee
- /// that the token will ever occur, this skips to the next token, or to some
- /// likely good stopping point. If Flags has StopAtSemi flag, skipping will
- /// stop at a ';' character.
- ///
- /// If SkipUntil finds the specified token, it returns true, otherwise it
- /// returns false.
- bool SkipUntil(tok::TokenKind T,
- SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
- return SkipUntil(llvm::makeArrayRef(T), Flags);
- }
- bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2,
- SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
- tok::TokenKind TokArray[] = {T1, T2};
- return SkipUntil(TokArray, Flags);
- }
- bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3,
- SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
- tok::TokenKind TokArray[] = {T1, T2, T3};
- return SkipUntil(TokArray, Flags);
- }
- bool SkipUntil(ArrayRef<tok::TokenKind> Toks,
- SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0));
-
- /// SkipMalformedDecl - Read tokens until we get to some likely good stopping
- /// point for skipping past a simple-declaration.
- void SkipMalformedDecl();
-
-private:
- //===--------------------------------------------------------------------===//
- // Lexing and parsing of C++ inline methods.
-
- struct ParsingClass;
-
- /// [class.mem]p1: "... the class is regarded as complete within
- /// - function bodies
- /// - default arguments
- /// - exception-specifications (TODO: C++0x)
- /// - and brace-or-equal-initializers for non-static data members
- /// (including such things in nested classes)."
- /// LateParsedDeclarations build the tree of those elements so they can
- /// be parsed after parsing the top-level class.
- class LateParsedDeclaration {
- public:
- virtual ~LateParsedDeclaration();
-
- virtual void ParseLexedMethodDeclarations();
- virtual void ParseLexedMemberInitializers();
- virtual void ParseLexedMethodDefs();
- virtual void ParseLexedAttributes();
- };
-
- /// Inner node of the LateParsedDeclaration tree that parses
- /// all its members recursively.
- class LateParsedClass : public LateParsedDeclaration {
- public:
- LateParsedClass(Parser *P, ParsingClass *C);
- ~LateParsedClass() override;
-
- void ParseLexedMethodDeclarations() override;
- void ParseLexedMemberInitializers() override;
- void ParseLexedMethodDefs() override;
- void ParseLexedAttributes() override;
-
- private:
- Parser *Self;
- ParsingClass *Class;
- };
-
- /// Contains the lexed tokens of an attribute with arguments that
- /// may reference member variables and so need to be parsed at the
- /// end of the class declaration after parsing all other member
- /// member declarations.
- /// FIXME: Perhaps we should change the name of LateParsedDeclaration to
- /// LateParsedTokens.
- struct LateParsedAttribute : public LateParsedDeclaration {
- Parser *Self;
- CachedTokens Toks;
- IdentifierInfo &AttrName;
- SourceLocation AttrNameLoc;
- SmallVector<Decl*, 2> Decls;
-
- explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
- SourceLocation Loc)
- : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
-
- void ParseLexedAttributes() override;
-
- void addDecl(Decl *D) { Decls.push_back(D); }
- };
-
- // A list of late-parsed attributes. Used by ParseGNUAttributes.
- class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
- public:
- LateParsedAttrList(bool PSoon = false) : ParseSoon(PSoon) { }
-
- bool parseSoon() { return ParseSoon; }
-
- private:
- bool ParseSoon; // Are we planning to parse these shortly after creation?
- };
-
- /// Contains the lexed tokens of a member function definition
- /// which needs to be parsed at the end of the class declaration
- /// after parsing all other member declarations.
- struct LexedMethod : public LateParsedDeclaration {
- Parser *Self;
- Decl *D;
- CachedTokens Toks;
-
- /// \brief 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;
-
- explicit LexedMethod(Parser* P, Decl *MD)
- : Self(P), D(MD), TemplateScope(false) {}
-
- void ParseLexedMethodDefs() override;
- };
-
- /// LateParsedDefaultArgument - Keeps track of a parameter that may
- /// have a default argument that cannot be parsed yet because it
- /// occurs within a member function declaration inside the class
- /// (C++ [class.mem]p2).
- struct LateParsedDefaultArgument {
- explicit LateParsedDefaultArgument(Decl *P,
- CachedTokens *Toks = nullptr)
- : Param(P), Toks(Toks) { }
-
- /// Param - The parameter declaration for this parameter.
- Decl *Param;
-
- /// Toks - The sequence of tokens that comprises the default
- /// argument expression, not including the '=' or the terminating
- /// ')' or ','. This will be NULL for parameters that have no
- /// default argument.
- CachedTokens *Toks;
- };
-
- /// LateParsedMethodDeclaration - A method declaration inside a class that
- /// contains at least one entity whose parsing needs to be delayed
- /// until the class itself is completely-defined, such as a default
- /// argument (C++ [class.mem]p2).
- struct LateParsedMethodDeclaration : public LateParsedDeclaration {
- explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
- : Self(P), Method(M), TemplateScope(false),
- ExceptionSpecTokens(nullptr) {}
-
- void ParseLexedMethodDeclarations() override;
-
- Parser* Self;
-
- /// Method - The method declaration.
- Decl *Method;
-
- /// \brief Whether this member function had an associated template
- /// scope. When true, D is a template declaration.
- /// othewise, it is a member function declaration.
- bool TemplateScope;
-
- /// DefaultArgs - Contains the parameters of the function and
- /// their default arguments. At least one of the parameters will
- /// have a default argument, but all of the parameters of the
- /// method will be stored so that they can be reintroduced into
- /// scope at the appropriate times.
- SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
-
- /// \brief The set of tokens that make up an exception-specification that
- /// has not yet been parsed.
- CachedTokens *ExceptionSpecTokens;
- };
-
- /// LateParsedMemberInitializer - An initializer for a non-static class data
- /// member whose parsing must to be delayed until the class is completely
- /// defined (C++11 [class.mem]p2).
- struct LateParsedMemberInitializer : public LateParsedDeclaration {
- LateParsedMemberInitializer(Parser *P, Decl *FD)
- : Self(P), Field(FD) { }
-
- void ParseLexedMemberInitializers() override;
-
- Parser *Self;
-
- /// Field - The field declaration.
- Decl *Field;
-
- /// CachedTokens - The sequence of tokens that comprises the initializer,
- /// including any leading '='.
- CachedTokens Toks;
- };
-
- /// LateParsedDeclarationsContainer - During parsing of a top (non-nested)
- /// C++ class, its method declarations that contain parts that won't be
- /// parsed until after the definition is completed (C++ [class.mem]p2),
- /// the method declarations and possibly attached inline definitions
- /// will be stored here with the tokens that will be parsed to create those
- /// entities.
- typedef SmallVector<LateParsedDeclaration*,2> LateParsedDeclarationsContainer;
-
- /// \brief 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 {
- ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface)
- : TopLevelClass(TopLevelClass), TemplateScope(false),
- IsInterface(IsInterface), TagOrTemplate(TagOrTemplate) { }
-
- /// \brief 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
- /// scope. When true, TagOrTemplate is a template declaration;
- /// othewise, it is a tag declaration.
- bool TemplateScope : 1;
-
- /// \brief Whether this class is an __interface.
- bool IsInterface : 1;
-
- /// \brief The class or class template whose definition we are parsing.
- Decl *TagOrTemplate;
-
- /// LateParsedDeclarations - Method declarations, inline definitions and
- /// nested classes that contain pieces whose parsing will be delayed until
- /// the top-level class is fully defined.
- LateParsedDeclarationsContainer LateParsedDeclarations;
- };
-
- /// \brief 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;
-
- ParsingClass &getCurrentClass() {
- assert(!ClassStack.empty() && "No lexed method stacks!");
- return *ClassStack.top();
- }
-
- /// \brief RAII object used to manage the parsing of a class definition.
- class ParsingClassDefinition {
- Parser &P;
- bool Popped;
- Sema::ParsingClassState State;
-
- public:
- ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass,
- bool IsInterface)
- : P(P), Popped(false),
- State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) {
- }
-
- /// \brief Pop this class of the stack.
- void Pop() {
- assert(!Popped && "Nested class has already been popped");
- Popped = true;
- P.PopParsingClass(State);
- }
-
- ~ParsingClassDefinition() {
- if (!Popped)
- P.PopParsingClass(State);
- }
- };
-
- /// \brief Contains information about any template-specific
- /// information that has been parsed prior to parsing declaration
- /// specifiers.
- struct ParsedTemplateInfo {
- ParsedTemplateInfo()
- : Kind(NonTemplate), TemplateParams(nullptr), TemplateLoc() { }
-
- ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
- bool isSpecialization,
- bool lastParameterListWasEmpty = false)
- : Kind(isSpecialization? ExplicitSpecialization : Template),
- TemplateParams(TemplateParams),
- LastParameterListWasEmpty(lastParameterListWasEmpty) { }
-
- explicit ParsedTemplateInfo(SourceLocation ExternLoc,
- SourceLocation TemplateLoc)
- : Kind(ExplicitInstantiation), TemplateParams(nullptr),
- ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
- LastParameterListWasEmpty(false){ }
-
- /// \brief The kind of template we are parsing.
- enum {
- /// \brief We are not parsing a template at all.
- NonTemplate = 0,
- /// \brief We are parsing a template declaration.
- Template,
- /// \brief We are parsing an explicit specialization.
- ExplicitSpecialization,
- /// \brief We are parsing an explicit instantiation.
- ExplicitInstantiation
- } Kind;
-
- /// \brief The template parameter lists, for template declarations
- /// and explicit specializations.
- TemplateParameterLists *TemplateParams;
-
- /// \brief The location of the 'extern' keyword, if any, for an explicit
- /// instantiation
- SourceLocation ExternLoc;
-
- /// \brief The location of the 'template' keyword, for an explicit
- /// instantiation.
- SourceLocation TemplateLoc;
-
- /// \brief Whether the last template parameter list was empty.
- bool LastParameterListWasEmpty;
-
- SourceRange getSourceRange() const LLVM_READONLY;
- };
-
- void LexTemplateFunctionForLateParsing(CachedTokens &Toks);
- void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT);
-
- static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT);
- static void LateTemplateParserCleanupCallback(void *P);
-
- Sema::ParsingClassState
- PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
- void DeallocateParsedClasses(ParsingClass *Class);
- void PopParsingClass(Sema::ParsingClassState);
-
- enum CachedInitKind {
- CIK_DefaultArgument,
- CIK_DefaultInitializer
- };
-
- NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
- AttributeList *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,
- bool EnterScope, bool OnDefinition);
- void ParseLexedAttribute(LateParsedAttribute &LA,
- bool EnterScope, bool OnDefinition);
- void ParseLexedMethodDeclarations(ParsingClass &Class);
- void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
- void ParseLexedMethodDefs(ParsingClass &Class);
- void ParseLexedMethodDef(LexedMethod &LM);
- void ParseLexedMemberInitializers(ParsingClass &Class);
- void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
- void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod);
- bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
- bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK);
- bool ConsumeAndStoreConditional(CachedTokens &Toks);
- bool ConsumeAndStoreUntil(tok::TokenKind T1,
- CachedTokens &Toks,
- bool StopAtSemi = true,
- bool ConsumeFinalToken = true) {
- return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken);
- }
- bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
- CachedTokens &Toks,
- bool StopAtSemi = true,
- bool ConsumeFinalToken = true);
-
- //===--------------------------------------------------------------------===//
- // C99 6.9: External Definitions.
- struct ParsedAttributesWithRange : ParsedAttributes {
- ParsedAttributesWithRange(AttributeFactory &factory)
- : ParsedAttributes(factory) {}
-
- SourceRange Range;
- };
-
- DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
- ParsingDeclSpec *DS = nullptr);
- bool isDeclarationAfterDeclarator();
- bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
- DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
- ParsedAttributesWithRange &attrs,
- ParsingDeclSpec *DS = nullptr,
- AccessSpecifier AS = AS_none);
- DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
- ParsingDeclSpec &DS,
- AccessSpecifier AS);
-
- void SkipFunctionBody();
- Decl *ParseFunctionDefinition(ParsingDeclarator &D,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- LateParsedAttrList *LateParsedAttrs = nullptr);
- void ParseKNRParamDeclarations(Declarator &D);
- // EndLoc, if non-NULL, is filled with the location of the last token of
- // the simple-asm.
- ExprResult ParseSimpleAsm(SourceLocation *EndLoc = nullptr);
- ExprResult ParseAsmStringLiteral();
-
- // Objective-C External Declarations
- void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
- DeclGroupPtrTy ParseObjCAtDirectives();
- DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
- Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
- ParsedAttributes &prefixAttrs);
- class ObjCTypeParamListScope;
- ObjCTypeParamList *parseObjCTypeParamList();
- ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs(
- ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
- SmallVectorImpl<IdentifierLocPair> &protocolIdents,
- SourceLocation &rAngleLoc, bool mayBeProtocolList = true);
-
- void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,
- BalancedDelimiterTracker &T,
- SmallVectorImpl<Decl *> &AllIvarDecls,
- bool RBraceMissing);
- void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
- tok::ObjCKeywordKind visibility,
- SourceLocation atLoc);
- bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P,
- SmallVectorImpl<SourceLocation> &PLocs,
- bool WarnOnDeclarations,
- bool ForObjCContainer,
- SourceLocation &LAngleLoc,
- SourceLocation &EndProtoLoc,
- bool consumeLastToken);
-
- /// Parse the first angle-bracket-delimited clause for an
- /// Objective-C object or object pointer type, which may be either
- /// type arguments or protocol qualifiers.
- void parseObjCTypeArgsOrProtocolQualifiers(
- ParsedType baseType,
- SourceLocation &typeArgsLAngleLoc,
- SmallVectorImpl<ParsedType> &typeArgs,
- SourceLocation &typeArgsRAngleLoc,
- SourceLocation &protocolLAngleLoc,
- SmallVectorImpl<Decl *> &protocols,
- SmallVectorImpl<SourceLocation> &protocolLocs,
- SourceLocation &protocolRAngleLoc,
- bool consumeLastToken,
- bool warnOnIncompleteProtocols);
-
- /// Parse either Objective-C type arguments or protocol qualifiers; if the
- /// former, also parse protocol qualifiers afterward.
- void parseObjCTypeArgsAndProtocolQualifiers(
- ParsedType baseType,
- SourceLocation &typeArgsLAngleLoc,
- SmallVectorImpl<ParsedType> &typeArgs,
- SourceLocation &typeArgsRAngleLoc,
- SourceLocation &protocolLAngleLoc,
- SmallVectorImpl<Decl *> &protocols,
- SmallVectorImpl<SourceLocation> &protocolLocs,
- SourceLocation &protocolRAngleLoc,
- bool consumeLastToken);
-
- /// Parse a protocol qualifier type such as '<NSCopying>', which is
- /// an anachronistic way of writing 'id<NSCopying>'.
- TypeResult parseObjCProtocolQualifierType(SourceLocation &rAngleLoc);
-
- /// Parse Objective-C type arguments and protocol qualifiers, extending the
- /// current type with the parsed result.
- TypeResult parseObjCTypeArgsAndProtocolQualifiers(SourceLocation loc,
- ParsedType type,
- bool consumeLastToken,
- SourceLocation &endLoc);
-
- void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
- Decl *CDecl);
- DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
- ParsedAttributes &prefixAttrs);
-
- struct ObjCImplParsingDataRAII {
- Parser &P;
- Decl *Dcl;
- bool HasCFunction;
- typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
- LateParsedObjCMethodContainer LateParsedObjCMethods;
-
- ObjCImplParsingDataRAII(Parser &parser, Decl *D)
- : P(parser), Dcl(D), HasCFunction(false) {
- P.CurParsedObjCImpl = this;
- Finished = false;
- }
- ~ObjCImplParsingDataRAII();
-
- void finish(SourceRange AtEnd);
- bool isFinished() const { return Finished; }
-
- private:
- bool Finished;
- };
- ObjCImplParsingDataRAII *CurParsedObjCImpl;
- void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
-
- DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc);
- DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
- Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
- Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
- Decl *ParseObjCPropertyDynamic(SourceLocation atLoc);
-
- IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation);
- // Definitions for Objective-c context sensitive keywords recognition.
- enum ObjCTypeQual {
- objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
- objc_nonnull, objc_nullable, objc_null_unspecified,
- objc_NumQuals
- };
- IdentifierInfo *ObjCTypeQuals[objc_NumQuals];
-
- bool isTokIdentifier_in() const;
-
- ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, Declarator::TheContext Ctx,
- ParsedAttributes *ParamAttrs);
- void ParseObjCMethodRequirement();
- Decl *ParseObjCMethodPrototype(
- tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
- bool MethodDefinition = true);
- Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
- tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
- bool MethodDefinition=true);
- void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
-
- Decl *ParseObjCMethodDefinition();
-
-public:
- //===--------------------------------------------------------------------===//
- // C99 6.5: Expressions.
-
- /// TypeCastState - State whether an expression is or may be a type cast.
- enum TypeCastState {
- NotTypeCast = 0,
- MaybeTypeCast,
- IsTypeCast
- };
-
- ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast);
- ExprResult ParseConstantExpression(TypeCastState isTypeCast = NotTypeCast);
- ExprResult ParseConstraintExpression();
- // Expr that doesn't include commas.
- ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast);
-
- ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
- unsigned &NumLineToksConsumed,
- void *Info,
- bool IsUnevaluated);
-
-private:
- ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
-
- ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
-
- ExprResult ParseRHSOfBinaryExpression(ExprResult LHS,
- prec::Level MinPrec);
- ExprResult ParseCastExpression(bool isUnaryExpression,
- bool isAddressOfOperand,
- bool &NotCastExpr,
- TypeCastState isTypeCast);
- ExprResult ParseCastExpression(bool isUnaryExpression,
- bool isAddressOfOperand = false,
- TypeCastState isTypeCast = NotTypeCast);
-
- /// Returns true if the next token cannot start an expression.
- bool isNotExpressionStart();
-
- /// Returns true if the next token would start a postfix-expression
- /// suffix.
- bool isPostfixExpressionSuffixStart() {
- tok::TokenKind K = Tok.getKind();
- return (K == tok::l_square || K == tok::l_paren ||
- K == tok::period || K == tok::arrow ||
- K == tok::plusplus || K == tok::minusminus);
- }
-
- ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
- ExprResult ParseUnaryExprOrTypeTraitExpression();
- ExprResult ParseBuiltinPrimaryExpression();
-
- ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
- bool &isCastExpr,
- ParsedType &CastTy,
- SourceRange &CastRange);
-
- typedef SmallVector<Expr*, 20> ExprListTy;
- typedef SmallVector<SourceLocation, 20> CommaLocsTy;
-
- /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
- bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
- SmallVectorImpl<SourceLocation> &CommaLocs,
- std::function<void()> Completer = nullptr);
-
- /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
- /// used for misc language extensions.
- bool ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs,
- SmallVectorImpl<SourceLocation> &CommaLocs);
-
-
- /// ParenParseOption - Control what ParseParenExpression will parse.
- enum ParenParseOption {
- SimpleExpr, // Only parse '(' expression ')'
- CompoundStmt, // Also allow '(' compound-statement ')'
- CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
- CastExpr // Also allow '(' type-name ')' <anything>
- };
- ExprResult ParseParenExpression(ParenParseOption &ExprType,
- bool stopIfCastExpr,
- bool isTypeCast,
- ParsedType &CastTy,
- SourceLocation &RParenLoc);
-
- ExprResult ParseCXXAmbiguousParenExpression(
- ParenParseOption &ExprType, ParsedType &CastTy,
- BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt);
- ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
-
- ExprResult ParseGenericSelectionExpression();
-
- ExprResult ParseObjCBoolLiteral();
-
- ExprResult ParseFoldExpression(ExprResult LHS, BalancedDelimiterTracker &T);
-
- //===--------------------------------------------------------------------===//
- // C++ Expressions
- ExprResult tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOperand,
- Token &Replacement);
- ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
-
- bool areTokensAdjacent(const Token &A, const Token &B);
-
- void CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectTypePtr,
- bool EnteringContext, IdentifierInfo &II,
- CXXScopeSpec &SS);
-
- bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
- ParsedType ObjectType,
- bool EnteringContext,
- bool *MayBePseudoDestructor = nullptr,
- bool IsTypename = false,
- IdentifierInfo **LastII = nullptr);
-
- void CheckForLParenAfterColonColon();
-
- //===--------------------------------------------------------------------===//
- // C++0x 5.1.2: Lambda expressions
-
- // [...] () -> type {...}
- ExprResult ParseLambdaExpression();
- ExprResult TryParseLambdaExpression();
- Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro,
- bool *SkippedInits = nullptr);
- bool TryParseLambdaIntroducer(LambdaIntroducer &Intro);
- ExprResult ParseLambdaExpressionAfterIntroducer(
- LambdaIntroducer &Intro);
-
- //===--------------------------------------------------------------------===//
- // C++ 5.2p1: C++ Casts
- ExprResult ParseCXXCasts();
-
- //===--------------------------------------------------------------------===//
- // C++ 5.2p1: C++ Type Identification
- ExprResult ParseCXXTypeid();
-
- //===--------------------------------------------------------------------===//
- // C++ : Microsoft __uuidof Expression
- ExprResult ParseCXXUuidof();
-
- //===--------------------------------------------------------------------===//
- // C++ 5.2.4: C++ Pseudo-Destructor Expressions
- ExprResult ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
- tok::TokenKind OpKind,
- CXXScopeSpec &SS,
- ParsedType ObjectType);
-
- //===--------------------------------------------------------------------===//
- // C++ 9.3.2: C++ 'this' pointer
- ExprResult ParseCXXThis();
-
- //===--------------------------------------------------------------------===//
- // C++ 15: C++ Throw Expression
- ExprResult ParseThrowExpression();
-
- ExceptionSpecificationType tryParseExceptionSpecification(
- bool Delayed,
- SourceRange &SpecificationRange,
- SmallVectorImpl<ParsedType> &DynamicExceptions,
- SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
- ExprResult &NoexceptExpr,
- CachedTokens *&ExceptionSpecTokens);
-
- // EndLoc is filled with the location of the last token of the specification.
- ExceptionSpecificationType ParseDynamicExceptionSpecification(
- SourceRange &SpecificationRange,
- SmallVectorImpl<ParsedType> &Exceptions,
- SmallVectorImpl<SourceRange> &Ranges);
-
- //===--------------------------------------------------------------------===//
- // C++0x 8: Function declaration trailing-return-type
- TypeResult ParseTrailingReturnType(SourceRange &Range);
-
- //===--------------------------------------------------------------------===//
- // C++ 2.13.5: C++ Boolean Literals
- ExprResult ParseCXXBoolLiteral();
-
- //===--------------------------------------------------------------------===//
- // C++ 5.2.3: Explicit type conversion (functional notation)
- ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
-
- /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
- /// This should only be called when the current token is known to be part of
- /// simple-type-specifier.
- void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
-
- bool ParseCXXTypeSpecifierSeq(DeclSpec &DS);
-
- //===--------------------------------------------------------------------===//
- // C++ 5.3.4 and 5.3.5: C++ new and delete
- bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr*> &Exprs,
- Declarator &D);
- void ParseDirectNewDeclarator(Declarator &D);
- ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
- ExprResult ParseCXXDeleteExpression(bool UseGlobal,
- SourceLocation Start);
-
- //===--------------------------------------------------------------------===//
- // C++ if/switch/while condition expression.
- bool ParseCXXCondition(ExprResult &ExprResult, Decl *&DeclResult,
- SourceLocation Loc, bool ConvertToBoolean);
-
- //===--------------------------------------------------------------------===//
- // C++ Coroutines
-
- ExprResult ParseCoyieldExpression();
-
- //===--------------------------------------------------------------------===//
- // C99 6.7.8: Initialization.
-
- /// ParseInitializer
- /// initializer: [C99 6.7.8]
- /// assignment-expression
- /// '{' ...
- ExprResult ParseInitializer() {
- if (Tok.isNot(tok::l_brace))
- return ParseAssignmentExpression();
- return ParseBraceInitializer();
- }
- bool MayBeDesignationStart();
- ExprResult ParseBraceInitializer();
- ExprResult ParseInitializerWithPotentialDesignator();
-
- //===--------------------------------------------------------------------===//
- // clang Expressions
-
- ExprResult ParseBlockLiteralExpression(); // ^{...}
-
- //===--------------------------------------------------------------------===//
- // Objective-C Expressions
- ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
- ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
- ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
- ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
- ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
- ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
- bool isSimpleObjCMessageExpression();
- ExprResult ParseObjCMessageExpression();
- ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
- SourceLocation SuperLoc,
- ParsedType ReceiverType,
- Expr *ReceiverExpr);
- ExprResult ParseAssignmentExprWithObjCMessageExprStart(
- SourceLocation LBracloc, SourceLocation SuperLoc,
- ParsedType ReceiverType, Expr *ReceiverExpr);
- bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
-
- //===--------------------------------------------------------------------===//
- // C99 6.8: Statements and Blocks.
-
- /// A SmallVector of statements, with stack size 32 (as that is the only one
- /// used.)
- typedef SmallVector<Stmt*, 32> StmtVector;
- /// A SmallVector of expressions, with stack size 12 (the maximum used.)
- typedef SmallVector<Expr*, 12> ExprVector;
- /// A SmallVector of types.
- typedef SmallVector<ParsedType, 12> TypeVector;
-
- StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr);
- StmtResult
- ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement,
- SourceLocation *TrailingElseLoc = nullptr);
- StmtResult ParseStatementOrDeclarationAfterAttributes(
- StmtVector &Stmts,
- bool OnlyStatement,
- SourceLocation *TrailingElseLoc,
- ParsedAttributesWithRange &Attrs);
- StmtResult ParseExprStatement();
- StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs);
- StmtResult ParseCaseStatement(bool MissingCase = false,
- ExprResult Expr = ExprResult());
- StmtResult ParseDefaultStatement();
- StmtResult ParseCompoundStatement(bool isStmtExpr = false);
- StmtResult ParseCompoundStatement(bool isStmtExpr,
- unsigned ScopeFlags);
- void ParseCompoundStatementLeadingPragmas();
- StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
- bool ParseParenExprOrCondition(ExprResult &ExprResult,
- Decl *&DeclResult,
- SourceLocation Loc,
- bool ConvertToBoolean);
- StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
- StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
- StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
- StmtResult ParseDoStatement();
- StmtResult ParseForStatement(SourceLocation *TrailingElseLoc);
- StmtResult ParseGotoStatement();
- StmtResult ParseContinueStatement();
- StmtResult ParseBreakStatement();
- StmtResult ParseReturnStatement();
- StmtResult ParseAsmStatement(bool &msAsm);
- StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
- StmtResult ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
- SourceLocation *TrailingElseLoc,
- ParsedAttributesWithRange &Attrs);
-
- /// \brief Describes the behavior that should be taken for an __if_exists
- /// block.
- enum IfExistsBehavior {
- /// \brief Parse the block; this code is always used.
- IEB_Parse,
- /// \brief Skip the block entirely; this code is never used.
- IEB_Skip,
- /// \brief 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
- /// __if_not_exists block.
- struct IfExistsCondition {
- /// \brief The location of the initial keyword.
- SourceLocation KeywordLoc;
- /// \brief Whether this is an __if_exists block (rather than an
- /// __if_not_exists block).
- bool IsIfExists;
-
- /// \brief Nested-name-specifier preceding the name.
- CXXScopeSpec SS;
-
- /// \brief The name we're looking for.
- UnqualifiedId Name;
-
- /// \brief The behavior of this __if_exists or __if_not_exists block
- /// should.
- IfExistsBehavior Behavior;
- };
-
- bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result);
- void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
- void ParseMicrosoftIfExistsExternalDeclaration();
- void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
- AccessSpecifier& CurAS);
- bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
- bool &InitExprsOk);
- bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
- SmallVectorImpl<Expr *> &Constraints,
- SmallVectorImpl<Expr *> &Exprs);
-
- //===--------------------------------------------------------------------===//
- // C++ 6: Statements and Blocks
-
- StmtResult ParseCXXTryBlock();
- StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false);
- StmtResult ParseCXXCatchBlock(bool FnCatch = false);
-
- //===--------------------------------------------------------------------===//
- // MS: SEH Statements and Blocks
-
- StmtResult ParseSEHTryBlock();
- StmtResult ParseSEHExceptBlock(SourceLocation Loc);
- StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
- StmtResult ParseSEHLeaveStatement();
-
- //===--------------------------------------------------------------------===//
- // Objective-C Statements
-
- StmtResult ParseObjCAtStatement(SourceLocation atLoc);
- StmtResult ParseObjCTryStmt(SourceLocation atLoc);
- StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
- StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
- StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc);
-
-
- //===--------------------------------------------------------------------===//
- // C99 6.7: Declarations.
-
- /// 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 {
- DSC_normal, // normal context
- DSC_class, // class context, enables 'friend'
- DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
- DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
- DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
- DSC_top_level, // top-level/namespace declaration context
- DSC_template_type_arg, // template type argument context
- DSC_objc_method_result, // ObjC method result context, enables 'instancetype'
- DSC_condition // condition declaration context
- };
-
- /// Is this a context in which we are parsing just a type-specifier (or
- /// trailing-type-specifier)?
- static bool isTypeSpecifier(DeclSpecContext DSC) {
- switch (DSC) {
- case DSC_normal:
- case DSC_class:
- case DSC_top_level:
- case DSC_objc_method_result:
- case DSC_condition:
- return false;
-
- case DSC_template_type_arg:
- case DSC_type_specifier:
- case DSC_trailing:
- case DSC_alias_declaration:
- return true;
- }
- llvm_unreachable("Missing DeclSpecContext case");
- }
-
- /// Information on a C++0x for-range-initializer found while parsing a
- /// declaration which turns out to be a for-range-declaration.
- struct ForRangeInit {
- SourceLocation ColonLoc;
- ExprResult RangeExpr;
-
- bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
- };
-
- DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs);
- DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
- SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs,
- bool RequireSemi,
- ForRangeInit *FRI = nullptr);
- bool MightBeDeclarator(unsigned Context);
- DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
- SourceLocation *DeclEnd = nullptr,
- ForRangeInit *FRI = nullptr);
- Decl *ParseDeclarationAfterDeclarator(Declarator &D,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
- bool ParseAsmAttributesAfterDeclarator(Declarator &D);
- Decl *ParseDeclarationAfterDeclaratorAndAttributes(
- Declarator &D,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- ForRangeInit *FRI = nullptr);
- Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);
- Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
-
- /// \brief 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.
- bool trySkippingFunctionBody();
-
- bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
- 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);
-
- void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
- Declarator::TheContext Context);
-
- void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
- const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS, DeclSpecContext DSC);
- void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl);
- void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
- Decl *TagDecl);
-
- void ParseStructDeclaration(
- ParsingDeclSpec &DS,
- llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback);
-
- bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
- bool isTypeSpecifierQualifier();
- bool isTypeQualifier() const;
-
- /// isKnownToBeTypeSpecifier - Return true if we know that the specified token
- /// is definitely a type-specifier. Return false if it isn't part of a type
- /// 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
- /// 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() {
- if (getLangOpts().CPlusPlus)
- return isCXXDeclarationSpecifier() == TPResult::True;
- return isDeclarationSpecifier(true);
- }
-
- /// isDeclarationStatement - Disambiguates between a declaration or an
- /// expression statement, when parsing function bodies.
- /// Returns true for declaration, false for expression.
- bool isDeclarationStatement() {
- if (getLangOpts().CPlusPlus)
- return isCXXDeclarationStatement();
- return isDeclarationSpecifier(true);
- }
-
- /// isForInitDeclaration - Disambiguates between a declaration or an
- /// expression in the context of the C 'clause-1' or the C++
- // 'for-init-statement' part of a 'for' statement.
- /// Returns true for declaration, false for expression.
- bool isForInitDeclaration() {
- if (getLangOpts().CPlusPlus)
- return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
- return isDeclarationSpecifier(true);
- }
-
- /// \brief 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
- /// class message that appears to be missing the open bracket '['.
- bool isStartOfObjCClassMessageMissingOpenBracket();
-
- /// \brief 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);
-
- /// \brief Specifies the context in which type-id/expression
- /// disambiguation will occur.
- enum TentativeCXXTypeIdContext {
- TypeIdInParens,
- TypeIdUnambiguous,
- TypeIdAsTemplateArgument
- };
-
-
- /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
- /// whether the parens contain an expression or a type-id.
- /// Returns true for a type-id and false for an expression.
- bool isTypeIdInParens(bool &isAmbiguous) {
- if (getLangOpts().CPlusPlus)
- return isCXXTypeId(TypeIdInParens, isAmbiguous);
- isAmbiguous = false;
- return isTypeSpecifierQualifier();
- }
- bool isTypeIdInParens() {
- bool isAmbiguous;
- return isTypeIdInParens(isAmbiguous);
- }
-
- /// \brief 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() {
- bool IsAmbiguous;
- if (getLangOpts().CPlusPlus)
- return isCXXTypeId(TypeIdUnambiguous, IsAmbiguous);
- return isTypeSpecifierQualifier();
- }
-
- /// isCXXDeclarationStatement - C++-specialized function that disambiguates
- /// between a declaration or an expression statement, when parsing function
- /// bodies. Returns true for declaration, false for expression.
- bool isCXXDeclarationStatement();
-
- /// isCXXSimpleDeclaration - C++-specialized function that disambiguates
- /// between a simple-declaration or an expression-statement.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- /// Returns false if the statement is disambiguated as expression.
- bool isCXXSimpleDeclaration(bool AllowForRangeDecl);
-
- /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
- /// a constructor-style initializer, when parsing declaration statements.
- /// Returns true for function declarator and false for constructor-style
- /// initializer. Sets 'IsAmbiguous' to true to indicate that this declaration
- /// might be a constructor-style initializer.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr);
-
- /// isCXXConditionDeclaration - Disambiguates between a declaration or an
- /// expression for a condition of a if/switch/while/for statement.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- bool isCXXConditionDeclaration();
-
- bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous);
- bool isCXXTypeId(TentativeCXXTypeIdContext Context) {
- bool isAmbiguous;
- return isCXXTypeId(Context, isAmbiguous);
- }
-
- /// TPResult - Used as the result value for functions whose purpose is to
- /// disambiguate C++ constructs by "tentatively parsing" them.
- enum class TPResult {
- True, False, Ambiguous, Error
- };
-
- /// \brief 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++).
- ///
- /// This routine does not attempt to resolve any of the trick cases, e.g.,
- /// those involving lookup of identifiers.
- ///
- /// \returns \c TPR_true if this token starts an expression, \c TPR_false if
- /// this token starts a type-specifier-seq, or \c TPR_ambiguous if it cannot
- /// tell.
- TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind);
-
- /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a
- /// declaration specifier, TPResult::False if it is not,
- /// TPResult::Ambiguous if it could be either a decl-specifier or a
- /// function-style cast, and TPResult::Error if a parsing error was
- /// encountered. If it could be a braced C++11 function-style cast, returns
- /// BracedCastResult.
- /// Doesn't consume tokens.
- TPResult
- isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False,
- bool *HasMissingTypename = nullptr);
-
- /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
- /// \c TPResult::Ambiguous, determine whether the decl-specifier would be
- /// a type-specifier other than a cv-qualifier.
- bool isCXXDeclarationSpecifierAType();
-
- /// \brief 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);
-
- // "Tentative parsing" functions, used for disambiguation. If a parsing error
- // is encountered they will return TPResult::Error.
- // Returning TPResult::True/False indicates that the ambiguity was
- // resolved and tentative parsing may stop. TPResult::Ambiguous indicates
- // that more tentative parsing is necessary for disambiguation.
- // They all consume tokens, so backtracking should be used after calling them.
-
- TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl);
- TPResult TryParseTypeofSpecifier();
- TPResult TryParseProtocolQualifiers();
- TPResult TryParsePtrOperatorSeq();
- TPResult TryParseOperatorId();
- TPResult TryParseInitDeclaratorList();
- TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
- TPResult
- TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr,
- bool VersusTemplateArg = false);
- TPResult TryParseFunctionDeclarator();
- TPResult TryParseBracketDeclarator();
- TPResult TryConsumeDeclarationSpecifier();
-
-public:
- TypeResult ParseTypeName(SourceRange *Range = nullptr,
- Declarator::TheContext Context
- = Declarator::TypeNameContext,
- AccessSpecifier AS = AS_none,
- Decl **OwnedType = nullptr,
- ParsedAttributes *Attrs = nullptr);
-
-private:
- void ParseBlockId(SourceLocation CaretLoc);
-
- // Check for the start of a C++11 attribute-specifier-seq in a context where
- // an attribute is not allowed.
- bool CheckProhibitedCXX11Attribute() {
- assert(Tok.is(tok::l_square));
- if (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))
- return false;
- return DiagnoseProhibitedCXX11Attribute();
- }
- bool DiagnoseProhibitedCXX11Attribute();
- void CheckMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
- SourceLocation CorrectLocation) {
- if (!getLangOpts().CPlusPlus11)
- return;
- if ((Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
- Tok.isNot(tok::kw_alignas))
- return;
- DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation);
- }
- void DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
- SourceLocation CorrectLocation);
-
- void handleDeclspecAlignBeforeClassKey(ParsedAttributesWithRange &Attrs,
- DeclSpec &DS, Sema::TagUseKind TUK);
-
- void ProhibitAttributes(ParsedAttributesWithRange &attrs) {
- if (!attrs.Range.isValid()) return;
- DiagnoseProhibitedAttributes(attrs);
- attrs.clear();
- }
- void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs);
-
- // Forbid C++11 attributes that appear on certain syntactic
- // locations which standard permits but we don't supported yet,
- // for example, attributes appertain to decl specifiers.
- void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs);
-
- /// \brief Skip C++11 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 attributes that appear in syntactic
- /// locations where attributes are not allowed.
- void DiagnoseAndSkipCXX11Attributes();
-
- /// \brief 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.
- unsigned
- ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs, SourceLocation *EndLoc,
- IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
-
- void MaybeParseGNUAttributes(Declarator &D,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.is(tok::kw___attribute)) {
- ParsedAttributes attrs(AttrFactory);
- SourceLocation endLoc;
- ParseGNUAttributes(attrs, &endLoc, LateAttrs, &D);
- D.takeAttributes(attrs, endLoc);
- }
- }
- void MaybeParseGNUAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.is(tok::kw___attribute))
- ParseGNUAttributes(attrs, endLoc, LateAttrs);
- }
- void ParseGNUAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr,
- Declarator *D = nullptr);
- void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs,
- SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax,
- Declarator *D);
- IdentifierLoc *ParseIdentifierLoc();
-
- void MaybeParseCXX11Attributes(Declarator &D) {
- if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
- ParsedAttributesWithRange attrs(AttrFactory);
- SourceLocation endLoc;
- ParseCXX11Attributes(attrs, &endLoc);
- D.takeAttributes(attrs, endLoc);
- }
- }
- void MaybeParseCXX11Attributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr) {
- if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
- ParsedAttributesWithRange attrsWithRange(AttrFactory);
- ParseCXX11Attributes(attrsWithRange, endLoc);
- attrs.takeAllFrom(attrsWithRange);
- }
- }
- void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
- SourceLocation *endLoc = nullptr,
- bool OuterMightBeMessageSend = false) {
- if (getLangOpts().CPlusPlus11 &&
- isCXX11AttributeSpecifier(false, OuterMightBeMessageSend))
- ParseCXX11Attributes(attrs, endLoc);
- }
-
- void ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
- SourceLocation *EndLoc = nullptr);
- void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
- SourceLocation *EndLoc = nullptr);
- /// \brief Parses a C++-style attribute argument list. Returns true if this
- /// results in adding an attribute to the ParsedAttributes list.
- bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs, SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc);
-
- IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc);
-
- void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr) {
- if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
- ParseMicrosoftAttributes(attrs, endLoc);
- }
- void ParseMicrosoftAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr);
- void MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
- SourceLocation *End = nullptr) {
- const auto &LO = getLangOpts();
- if (LO.DeclSpecKeyword && Tok.is(tok::kw___declspec))
- ParseMicrosoftDeclSpecs(Attrs, End);
- }
- void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
- SourceLocation *End = nullptr);
- bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs);
- void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
- void DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
- SourceLocation SkipExtendedMicrosoftTypeAttributes();
- void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
- void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
- void ParseOpenCLAttributes(ParsedAttributes &attrs);
- void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
- void ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs);
-
- VersionTuple ParseVersionTuple(SourceRange &Range);
- void ParseAvailabilityAttribute(IdentifierInfo &Availability,
- SourceLocation AvailabilityLoc,
- ParsedAttributes &attrs,
- SourceLocation *endLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
-
- void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
- SourceLocation ObjCBridgeRelatedLoc,
- ParsedAttributes &attrs,
- SourceLocation *endLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
-
- void ParseTypeTagForDatatypeAttribute(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,
- AttributeList::Syntax Syntax);
-
- void ParseTypeofSpecifier(DeclSpec &DS);
- SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
- void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
- SourceLocation StartLoc,
- SourceLocation EndLoc);
- void ParseUnderlyingTypeSpecifier(DeclSpec &DS);
- void ParseAtomicSpecifier(DeclSpec &DS);
-
- ExprResult ParseAlignArgument(SourceLocation Start,
- SourceLocation &EllipsisLoc);
- void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
- SourceLocation *endLoc = nullptr);
-
- VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
- VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
- return isCXX11VirtSpecifier(Tok);
- }
- void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface,
- SourceLocation FriendLoc);
-
- bool isCXX11FinalKeyword() const;
-
- /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
- /// enter a new C++ declarator scope and exit it when the function is
- /// finished.
- class DeclaratorScopeObj {
- Parser &P;
- CXXScopeSpec &SS;
- bool EnteredScope;
- bool CreatedScope;
- public:
- DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
- : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
-
- void EnterDeclaratorScope() {
- assert(!EnteredScope && "Already entered the scope!");
- assert(SS.isSet() && "C++ scope was not set!");
-
- CreatedScope = true;
- P.EnterScope(0); // Not a decl scope.
-
- if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.getCurScope(), SS))
- EnteredScope = true;
- }
-
- ~DeclaratorScopeObj() {
- if (EnteredScope) {
- assert(SS.isSet() && "C++ scope was cleared ?");
- P.Actions.ActOnCXXExitDeclaratorScope(P.getCurScope(), SS);
- }
- if (CreatedScope)
- P.ExitScope();
- }
- };
-
- /// ParseDeclarator - Parse and verify a newly-initialized declarator.
- void ParseDeclarator(Declarator &D);
- /// A function that parses a variant of direct-declarator.
- typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
- void ParseDeclaratorInternal(Declarator &D,
- DirectDeclParseFunction DirectDeclParser);
-
- enum AttrRequirements {
- AR_NoAttributesParsed = 0, ///< No attributes are diagnosed.
- AR_GNUAttributesParsedAndRejected = 1 << 0, ///< Diagnose GNU attributes.
- AR_GNUAttributesParsed = 1 << 1,
- AR_CXX11AttributesParsed = 1 << 2,
- AR_DeclspecAttributesParsed = 1 << 3,
- AR_AllAttributesParsed = AR_GNUAttributesParsed |
- AR_CXX11AttributesParsed |
- AR_DeclspecAttributesParsed,
- AR_VendorAttributesParsed = AR_GNUAttributesParsed |
- AR_DeclspecAttributesParsed
- };
-
- void ParseTypeQualifierListOpt(DeclSpec &DS,
- unsigned AttrReqs = AR_AllAttributesParsed,
- bool AtomicAllowed = true,
- bool IdentifierRequired = false);
- void ParseDirectDeclarator(Declarator &D);
- void ParseParenDeclarator(Declarator &D);
- void ParseFunctionDeclarator(Declarator &D,
- ParsedAttributes &attrs,
- BalancedDelimiterTracker &Tracker,
- bool IsAmbiguous,
- bool RequiresArg = false);
- bool ParseRefQualifier(bool &RefQualifierIsLValueRef,
- SourceLocation &RefQualifierLoc);
- bool isFunctionDeclaratorIdentifierList();
- void ParseFunctionDeclaratorIdentifierList(
- Declarator &D,
- SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
- void ParseParameterDeclarationClause(
- Declarator &D,
- ParsedAttributes &attrs,
- SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
- SourceLocation &EllipsisLoc);
- void ParseBracketDeclarator(Declarator &D);
- void ParseMisplacedBracketDeclarator(Declarator &D);
-
- //===--------------------------------------------------------------------===//
- // C++ 7: Declarations [dcl.dcl]
-
- /// The kind of attribute specifier we have found.
- enum CXX11AttributeKind {
- /// This is not an attribute specifier.
- CAK_NotAttributeSpecifier,
- /// This should be treated as an attribute-specifier.
- CAK_AttributeSpecifier,
- /// The next tokens are '[[', but this is not an attribute-specifier. This
- /// is ill-formed by C++11 [dcl.attr.grammar]p6.
- CAK_InvalidAttributeSpecifier
- };
- CXX11AttributeKind
- isCXX11AttributeSpecifier(bool Disambiguate = false,
- bool OuterMightBeMessageSend = false);
-
- void DiagnoseUnexpectedNamespace(NamedDecl *Context);
-
- DeclGroupPtrTy ParseNamespace(unsigned 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,
- BalancedDelimiterTracker &Tracker);
- Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
- Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
- const ParsedTemplateInfo &TemplateInfo,
- SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs,
- Decl **OwnedType = nullptr);
- Decl *ParseUsingDirective(unsigned Context,
- SourceLocation UsingLoc,
- SourceLocation &DeclEnd,
- ParsedAttributes &attrs);
- Decl *ParseUsingDeclaration(unsigned Context,
- const ParsedTemplateInfo &TemplateInfo,
- SourceLocation UsingLoc,
- SourceLocation &DeclEnd,
- AccessSpecifier AS = AS_none,
- Decl **OwnedType = nullptr);
- Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
- Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
- SourceLocation AliasLoc, IdentifierInfo *Alias,
- SourceLocation &DeclEnd);
-
- //===--------------------------------------------------------------------===//
- // C++ 9: classes [class] and C structs/unions.
- bool isValidAfterTypeSpecifier(bool CouldBeBitfield);
- void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
- DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS, bool EnteringContext,
- DeclSpecContext DSC,
- ParsedAttributesWithRange &Attributes);
- void SkipCXXMemberSpecification(SourceLocation StartLoc,
- SourceLocation AttrFixitLoc,
- unsigned TagType,
- Decl *TagDecl);
- void ParseCXXMemberSpecification(SourceLocation StartLoc,
- SourceLocation AttrFixitLoc,
- ParsedAttributesWithRange &Attrs,
- unsigned TagType,
- Decl *TagDecl);
- ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
- SourceLocation &EqualLoc);
- bool ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
- VirtSpecifiers &VS,
- ExprResult &BitfieldSize,
- LateParsedAttrList &LateAttrs);
- void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D,
- VirtSpecifiers &VS);
- DeclGroupPtrTy ParseCXXClassMemberDeclaration(
- AccessSpecifier AS, AttributeList *Attr,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
- DeclGroupPtrTy ParseCXXClassMemberDeclarationWithPragmas(
- AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs,
- DeclSpec::TST TagType, Decl *TagDecl);
- void ParseConstructorInitializer(Decl *ConstructorDecl);
- MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
- void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
- Decl *ThisDecl);
-
- //===--------------------------------------------------------------------===//
- // C++ 10: Derived classes [class.derived]
- TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
- SourceLocation &EndLocation);
- void ParseBaseClause(Decl *ClassDecl);
- BaseResult ParseBaseSpecifier(Decl *ClassDecl);
- AccessSpecifier getAccessSpecifierIfPresent() const;
-
- bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- bool EnteringContext,
- ParsedType ObjectType,
- UnqualifiedId &Id,
- bool AssumeTemplateId);
- bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
- ParsedType ObjectType,
- UnqualifiedId &Result);
-
- //===--------------------------------------------------------------------===//
- // OpenMP: Directives and clauses.
- /// \brief Parses declarative OpenMP directives.
- DeclGroupPtrTy ParseOpenMPDeclarativeDirective();
- /// \brief Parses simple list of variables.
- ///
- /// \param Kind Kind of the directive.
- /// \param [out] VarList List of referenced variables.
- /// \param AllowScopeSpecifier true, if the variables can have fully
- /// qualified names.
- ///
- bool ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
- SmallVectorImpl<Expr *> &VarList,
- bool AllowScopeSpecifier);
- /// \brief Parses declarative or executable directive.
- ///
- /// \param StandAloneAllowed true if allowed stand-alone directives,
- /// false - otherwise
- ///
- StmtResult
- ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed);
- /// \brief 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.
- /// \param FirstClause true, if this is the first clause of a kind \a CKind
- /// in current directive.
- ///
- OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind,
- OpenMPClauseKind CKind, bool FirstClause);
- /// \brief Parses clause with a single expression of a kind \a Kind.
- ///
- /// \param Kind Kind of current clause.
- ///
- OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind);
- /// \brief Parses simple clause of a kind \a Kind.
- ///
- /// \param Kind Kind of current clause.
- ///
- OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind);
- /// \brief Parses clause with a single expression and an additional argument
- /// of a kind \a Kind.
- ///
- /// \param Kind Kind of current clause.
- ///
- OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind);
- /// \brief Parses clause without any additional arguments.
- ///
- /// \param Kind Kind of current clause.
- ///
- OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind);
- /// \brief Parses clause with the list of variables of a kind \a Kind.
- ///
- /// \param Kind Kind of current clause.
- ///
- OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
- OpenMPClauseKind Kind);
-
-public:
- bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
- bool AllowDestructorName,
- bool AllowConstructorName,
- ParsedType ObjectType,
- SourceLocation& TemplateKWLoc,
- UnqualifiedId &Result);
-
-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,
- SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs);
- Decl *ParseSingleDeclarationAfterTemplate(
- unsigned Context,
- const ParsedTemplateInfo &TemplateInfo,
- ParsingDeclRAIIObject &DiagsFromParams,
- SourceLocation &DeclEnd,
- AccessSpecifier AS=AS_none,
- AttributeList *AccessAttrs = nullptr);
- bool ParseTemplateParameters(unsigned Depth,
- SmallVectorImpl<Decl*> &TemplateParams,
- SourceLocation &LAngleLoc,
- SourceLocation &RAngleLoc);
- bool ParseTemplateParameterList(unsigned Depth,
- SmallVectorImpl<Decl*> &TemplateParams);
- bool isStartOfTemplateTypeParameter();
- Decl *ParseTemplateParameter(unsigned Depth, unsigned Position);
- Decl *ParseTypeParameter(unsigned Depth, unsigned Position);
- Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
- Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
- void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
- SourceLocation CorrectLoc,
- bool AlreadyHasEllipsis,
- bool IdentifierHasName);
- void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
- Declarator &D);
- // C++ 14.3: Template arguments [temp.arg]
- typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
-
- bool ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
- bool ConsumeLastToken,
- bool ObjCGenericList);
- bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
- SourceLocation TemplateNameLoc,
- const CXXScopeSpec &SS,
- bool ConsumeLastToken,
- SourceLocation &LAngleLoc,
- TemplateArgList &TemplateArgs,
- SourceLocation &RAngleLoc);
-
- bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
- CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- UnqualifiedId &TemplateName,
- bool AllowTypeAnnotation = true);
- void AnnotateTemplateIdTokenAsType();
- bool IsTemplateArgumentList(unsigned Skip = 0);
- bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
- ParsedTemplateArgument ParseTemplateTemplateArgument();
- ParsedTemplateArgument ParseTemplateArgument();
- Decl *ParseExplicitInstantiation(unsigned Context,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- SourceLocation &DeclEnd,
- AccessSpecifier AS = AS_none);
-
- //===--------------------------------------------------------------------===//
- // Modules
- DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc);
- bool parseMisplacedModuleImport();
- bool tryParseMisplacedModuleImport() {
- tok::TokenKind Kind = Tok.getKind();
- if (Kind == tok::annot_module_begin || Kind == tok::annot_module_end ||
- Kind == tok::annot_module_include)
- return parseMisplacedModuleImport();
- return false;
- }
-
- //===--------------------------------------------------------------------===//
- // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
- ExprResult ParseTypeTrait();
-
- //===--------------------------------------------------------------------===//
- // Embarcadero: Arary and Expression Traits
- ExprResult ParseArrayTypeTrait();
- ExprResult ParseExpressionTrait();
-
- //===--------------------------------------------------------------------===//
- // Preprocessor code-completion pass-through
- void CodeCompleteDirective(bool InConditional) override;
- void CodeCompleteInConditionalExclusion() override;
- void CodeCompleteMacroName(bool IsDefinition) override;
- void CodeCompletePreprocessorExpression() override;
- void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo,
- unsigned ArgumentIndex) override;
- void CodeCompleteNaturalLanguage() override;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Rewrite/Core/DeltaTree.h b/include/clang/Rewrite/Core/DeltaTree.h
deleted file mode 100644
index fbffb38..0000000
--- a/include/clang/Rewrite/Core/DeltaTree.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===--- DeltaTree.h - B-Tree for Rewrite Delta tracking --------*- 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 DeltaTree class.
-//
-//===----------------------------------------------------------------------===//
-
-#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
- /// features. B-Trees are generally more memory and cache efficient than
- /// binary trees, because they store multiple keys/values in each node. This
- /// implements a key/value mapping from index to delta, and allows fast lookup
- /// on index. However, an added (important) bonus is that it can also
- /// efficiently tell us the full accumulated delta for a specific file offset
- /// 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();
-
- /// getDeltaAt - Return the accumulated delta at the specified file offset.
- /// This includes all insertions or delections that occurred *before* the
- /// specified file index.
- int getDeltaAt(unsigned FileIndex) const;
-
- /// AddDelta - When a change is made that shifts around the text buffer,
- /// this method is used to record that info. It inserts a delta of 'Delta'
- /// into the current DeltaTree at offset FileIndex.
- void AddDelta(unsigned FileIndex, int Delta);
- };
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h
deleted file mode 100644
index dafdf51..0000000
--- a/include/clang/Rewrite/Core/HTMLRewrite.h
+++ /dev/null
@@ -1,81 +0,0 @@
-//==- HTMLRewrite.h - Translate source code into prettified HTML ---*- 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 set of functions used for translating source code
-// into beautified HTML.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITE_CORE_HTMLREWRITE_H
-#define LLVM_CLANG_REWRITE_CORE_HTMLREWRITE_H
-
-#include "clang/Basic/SourceLocation.h"
-#include <string>
-
-namespace clang {
-
-class Rewriter;
-class RewriteBuffer;
-class Preprocessor;
-
-namespace html {
-
- /// HighlightRange - Highlight a range in the source code with the specified
- /// start/end tags. B/E must be in the same file. This ensures that
- /// 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);
-
- /// 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.
- /// This ensures that start/end tags are placed at the start/end of each line
- /// if the range is multiline.
- inline void HighlightRange(Rewriter &R, SourceRange Range,
- const char *StartTag, const char *EndTag) {
- HighlightRange(R, Range.getBegin(), Range.getEnd(), StartTag, EndTag);
- }
-
- /// HighlightRange - This is the same as the above method, but takes
- /// decomposed file locations.
- void HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
- const char *BufferStart,
- const char *StartTag, const char *EndTag);
-
- /// EscapeText - HTMLize a specified file so that special characters are
- /// are translated so that they are not interpreted as HTML tags.
- void EscapeText(Rewriter& R, FileID FID,
- bool EscapeSpaces = false, bool ReplaceTabs = false);
-
- /// EscapeText - HTMLized the provided string so that special characters
- /// in 's' are not interpreted as HTML tags. Unlike the version of
- /// EscapeText that rewrites a file, this version by default replaces tabs
- /// with spaces.
- std::string EscapeText(StringRef s,
- bool EscapeSpaces = false, bool ReplaceTabs = false);
-
- void AddLineNumbers(Rewriter& R, FileID FID);
-
- void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
- const char *title = nullptr);
-
- /// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
- /// information about keywords, comments, etc.
- void SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP);
-
- /// HighlightMacros - This uses the macro table state from the end of the
- /// file, to reexpand macros and insert (into the HTML) information about the
- /// macro expansions. This won't be perfectly perfect, but it will be
- /// reasonably close.
- void HighlightMacros(Rewriter &R, FileID FID, const Preprocessor &PP);
-
-} // end html namespace
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Rewrite/Core/RewriteBuffer.h b/include/clang/Rewrite/Core/RewriteBuffer.h
deleted file mode 100644
index d69c69b..0000000
--- a/include/clang/Rewrite/Core/RewriteBuffer.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//===--- RewriteBuffer.h - Buffer rewriting interface -----------*- 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_REWRITE_CORE_REWRITEBUFFER_H
-#define LLVM_CLANG_REWRITE_CORE_REWRITEBUFFER_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Rewrite/Core/DeltaTree.h"
-#include "clang/Rewrite/Core/RewriteRope.h"
-#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
-/// RewriteBuffer captures the modified text itself as well as information used
-/// to map between SourceLocation's in the original input and offsets in the
-/// RewriteBuffer. For example, if text is inserted into the buffer, any
-/// 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;
- iterator begin() const { return Buffer.begin(); }
- iterator end() const { return Buffer.end(); }
- unsigned size() const { return Buffer.size(); }
-
- /// Initialize - Start this rewrite buffer out with a copy of the unmodified
- /// input buffer.
- void Initialize(const char *BufStart, const char *BufEnd) {
- Buffer.assign(BufStart, BufEnd);
- }
- void Initialize(StringRef Input) {
- Initialize(Input.begin(), Input.end());
- }
-
- /// \brief 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
- /// Rewriter::overwriteChangedFiles() instead.
- ///
- /// The original buffer is not actually changed.
- raw_ostream &write(raw_ostream &Stream) const;
-
- /// RemoveText - Remove the specified text.
- void RemoveText(unsigned OrigOffset, unsigned Size,
- bool removeLineIfEmpty = false);
-
- /// 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);
-
-
- /// InsertTextBefore - Insert some text before the specified point, where the
- /// offset in the buffer is specified relative to the original
- /// SourceBuffer. The text is inserted before the specified location. This is
- /// method is the same as InsertText with "InsertAfter == false".
- void InsertTextBefore(unsigned OrigOffset, StringRef Str) {
- InsertText(OrigOffset, Str, false);
- }
-
- /// InsertTextAfter - 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 InsertTextAfter(unsigned OrigOffset, StringRef Str) {
- InsertText(OrigOffset, Str);
- }
-
- /// ReplaceText - This method replaces a range of characters in the input
- /// buffer with a new string. This is effectively a combined "remove/insert"
- /// operation.
- void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
- StringRef NewStr);
-
-private: // Methods only usable by Rewriter.
-
- /// 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
- /// position where text is inserted, the location returned will be after any
- /// inserted text at the position.
- unsigned getMappedOffset(unsigned OrigOffset,
- bool AfterInserts = false) const{
- return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset;
- }
-
- /// AddInsertDelta - When an insertion is made at a position, this
- /// method is used to record that information.
- void AddInsertDelta(unsigned OrigOffset, int Change) {
- return Deltas.AddDelta(2*OrigOffset, Change);
- }
-
- /// AddReplaceDelta - When a replacement/deletion is made at a position, this
- /// method is used to record that information.
- void AddReplaceDelta(unsigned OrigOffset, int Change) {
- return Deltas.AddDelta(2*OrigOffset+1, Change);
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
deleted file mode 100644
index 5002554..0000000
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ /dev/null
@@ -1,214 +0,0 @@
-//===--- RewriteRope.h - Rope specialized for rewriter ----------*- 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 RewriteRope class, which is a powerful string class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
-#define LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
-
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
-#include <cassert>
-#include <cstddef>
-#include <cstring>
-#include <iterator>
-
-namespace clang {
- //===--------------------------------------------------------------------===//
- // RopeRefCountString Class
- //===--------------------------------------------------------------------===//
-
- /// RopeRefCountString - This struct is allocated with 'new char[]' from the
- /// heap, and represents a reference counted chunk of string data. When its
- /// ref count drops to zero, it is delete[]'d. This is primarily managed
- /// through the RopePiece class below.
- struct RopeRefCountString {
- unsigned RefCount;
- char Data[1]; // Variable sized.
-
- void Retain() { ++RefCount; }
-
- void Release() {
- assert(RefCount > 0 && "Reference count is already zero.");
- if (--RefCount == 0)
- delete [] (char*)this;
- }
- };
-
- //===--------------------------------------------------------------------===//
- // RopePiece Class
- //===--------------------------------------------------------------------===//
-
- /// RopePiece - This class represents a view into a RopeRefCountString object.
- /// This allows references to string data to be efficiently chopped up and
- /// moved around without having to push around the string data itself.
- ///
- /// For example, we could have a 1M RopePiece and want to insert something
- /// into the middle of it. To do this, we split it into two RopePiece objects
- /// that both refer to the same underlying RopeRefCountString (just with
- /// 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) {}
-
- RopePiece(llvm::IntrusiveRefCntPtr<RopeRefCountString> Str, unsigned Start,
- unsigned End)
- : StrData(std::move(Str)), StartOffs(Start), EndOffs(End) {}
-
- const char &operator[](unsigned Offset) const {
- return StrData->Data[Offset+StartOffs];
- }
- char &operator[](unsigned Offset) {
- return StrData->Data[Offset+StartOffs];
- }
-
- unsigned size() const { return EndOffs-StartOffs; }
- };
-
- //===--------------------------------------------------------------------===//
- // RopePieceBTreeIterator Class
- //===--------------------------------------------------------------------===//
-
- /// RopePieceBTreeIterator - This class provides read-only forward iteration
- /// over bytes that are in a RopePieceBTree. This first iterates over bytes
- /// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
- /// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
- 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;
- /// CurPiece - The current RopePiece in the B+Tree node that we're
- /// inspecting.
- const RopePiece *CurPiece;
- /// CurChar - The current byte in the RopePiece we are pointing to.
- unsigned CurChar;
- public:
- // begin iterator.
- RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
- // end iterator
- RopePieceBTreeIterator()
- : CurNode(nullptr), CurPiece(nullptr), CurChar(0) {}
-
- char operator*() const {
- return (*CurPiece)[CurChar];
- }
-
- bool operator==(const RopePieceBTreeIterator &RHS) const {
- return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
- }
- bool operator!=(const RopePieceBTreeIterator &RHS) const {
- return !operator==(RHS);
- }
-
- RopePieceBTreeIterator& operator++() { // Preincrement
- if (CurChar+1 < CurPiece->size())
- ++CurChar;
- else
- MoveToNextPiece();
- return *this;
- }
- inline RopePieceBTreeIterator operator++(int) { // Postincrement
- RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
- }
-
- llvm::StringRef piece() const {
- return llvm::StringRef(&(*CurPiece)[0], CurPiece->size());
- }
-
- void MoveToNextPiece();
- };
-
- //===--------------------------------------------------------------------===//
- // RopePieceBTree Class
- //===--------------------------------------------------------------------===//
-
- class RopePieceBTree {
- void /*RopePieceBTreeNode*/ *Root;
- void operator=(const RopePieceBTree &) = delete;
- public:
- RopePieceBTree();
- RopePieceBTree(const RopePieceBTree &RHS);
- ~RopePieceBTree();
-
- typedef RopePieceBTreeIterator iterator;
- iterator begin() const { return iterator(Root); }
- iterator end() const { return iterator(); }
- unsigned size() const;
- unsigned empty() const { return size() == 0; }
-
- void clear();
-
- void insert(unsigned Offset, const RopePiece &R);
-
- void erase(unsigned Offset, unsigned NumBytes);
- };
-
- //===--------------------------------------------------------------------===//
- // RewriteRope Class
- //===--------------------------------------------------------------------===//
-
-/// RewriteRope - A powerful string class. This class supports extremely
-/// efficient insertions and deletions into the middle of it, even for
-/// ridiculously long strings.
-class RewriteRope {
- RopePieceBTree Chunks;
-
- /// 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 };
-
-public:
- RewriteRope() : AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {}
- RewriteRope(const RewriteRope &RHS)
- : Chunks(RHS.Chunks), AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {
- }
-
- typedef RopePieceBTree::iterator iterator;
- typedef RopePieceBTree::iterator const_iterator;
- iterator begin() const { return Chunks.begin(); }
- iterator end() const { return Chunks.end(); }
- unsigned size() const { return Chunks.size(); }
-
- void clear() {
- Chunks.clear();
- }
-
- void assign(const char *Start, const char *End) {
- clear();
- if (Start != End)
- Chunks.insert(0, MakeRopeString(Start, End));
- }
-
- void insert(unsigned Offset, const char *Start, const char *End) {
- assert(Offset <= size() && "Invalid position to insert!");
- if (Start == End) return;
- Chunks.insert(Offset, MakeRopeString(Start, End));
- }
-
- void erase(unsigned Offset, unsigned NumBytes) {
- assert(Offset+NumBytes <= size() && "Invalid region to erase!");
- if (NumBytes == 0) return;
- Chunks.erase(Offset, NumBytes);
- }
-
-private:
- RopePiece MakeRopeString(const char *Start, const char *End);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h
deleted file mode 100644
index 800372e..0000000
--- a/include/clang/Rewrite/Core/Rewriter.h
+++ /dev/null
@@ -1,195 +0,0 @@
-//===--- Rewriter.h - Code rewriting interface ------------------*- 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 Rewriter class, which is used for code
-// transformations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITE_CORE_REWRITER_H
-#define LLVM_CLANG_REWRITE_CORE_REWRITER_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Rewrite/Core/RewriteBuffer.h"
-#include <cstring>
-#include <map>
-#include <string>
-
-namespace clang {
- 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;
- std::map<FileID, RewriteBuffer> RewriteBuffers;
-public:
- struct RewriteOptions {
- /// \brief 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
- /// 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
- /// also remove the empty line (false by default).
- bool RemoveLineIfEmpty;
-
- RewriteOptions()
- : IncludeInsertsAtBeginOfRange(true),
- IncludeInsertsAtEndOfRange(true),
- RemoveLineIfEmpty(false) { }
- };
-
- typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator;
- typedef std::map<FileID, RewriteBuffer>::const_iterator const_buffer_iterator;
-
- explicit Rewriter(SourceManager &SM, const LangOptions &LO)
- : SourceMgr(&SM), LangOpts(&LO) {}
- explicit Rewriter() : SourceMgr(nullptr), LangOpts(nullptr) {}
-
- void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
- SourceMgr = &SM;
- LangOpts = &LO;
- }
- SourceManager &getSourceMgr() const { return *SourceMgr; }
- const LangOptions &getLangOpts() const { return *LangOpts; }
-
- /// isRewritable - Return true if this location is a raw file location, which
- /// is rewritable. Locations from macros, etc are not rewritable.
- static bool isRewritable(SourceLocation Loc) {
- return Loc.isFileID();
- }
-
- /// getRangeSize - Return the size in bytes of the specified range if they
- /// are in the same file. If not, this returns -1.
- int getRangeSize(SourceRange Range,
- RewriteOptions opts = RewriteOptions()) const;
- int getRangeSize(const CharSourceRange &Range,
- RewriteOptions opts = RewriteOptions()) const;
-
- /// getRewrittenText - Return the rewritten form of the text in the specified
- /// range. If the start or end of the range was unrewritable or if they are
- /// 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
- /// original buffer. This method returns true (and does nothing) if the input
- /// location was not rewritable, false otherwise.
- ///
- /// \param indentNewLines if true new lines in the string are indented
- /// using the indentation of the source line in position \p Loc.
- bool InsertText(SourceLocation Loc, StringRef Str,
- bool InsertAfter = true, bool indentNewLines = false);
-
- /// InsertTextAfter - Insert the specified string at the specified location in
- /// the original buffer. This method returns true (and does nothing) if
- /// the input location was not rewritable, false otherwise. Text is
- /// inserted after any other text that has been previously inserted
- /// at the some point (the default behavior for InsertText).
- bool InsertTextAfter(SourceLocation Loc, StringRef Str) {
- return InsertText(Loc, Str);
- }
-
- /// \brief Insert the specified string after the token in the
- /// specified location.
- bool InsertTextAfterToken(SourceLocation Loc, StringRef Str);
-
- /// InsertText - Insert the specified string at the specified location in the
- /// original buffer. This method returns true (and does nothing) if the input
- /// location was not rewritable, false otherwise. Text is
- /// inserted before any other text that has been previously inserted
- /// at the some point.
- bool InsertTextBefore(SourceLocation Loc, StringRef Str) {
- return InsertText(Loc, Str, false);
- }
-
- /// RemoveText - Remove the specified text region.
- bool RemoveText(SourceLocation Start, unsigned Length,
- RewriteOptions opts = RewriteOptions());
-
- /// \brief 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.
- bool RemoveText(SourceRange range, RewriteOptions opts = RewriteOptions()) {
- return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
- }
-
- /// ReplaceText - This method replaces a range of characters in the input
- /// buffer with a new string. This is effectively a combined "remove/insert"
- /// operation.
- bool ReplaceText(SourceLocation Start, unsigned OrigLength,
- StringRef NewStr);
-
- /// ReplaceText - This method replaces a range of characters in the input
- /// buffer with a new string. This is effectively a combined "remove/insert"
- /// operation.
- bool ReplaceText(SourceRange range, StringRef NewStr) {
- return ReplaceText(range.getBegin(), getRangeSize(range), NewStr);
- }
-
- /// ReplaceText - This method replaces a range of characters in the input
- /// buffer with a new string. This is effectively a combined "remove/insert"
- /// operation.
- bool ReplaceText(SourceRange range, SourceRange replacementRange);
-
- /// \brief 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.
- bool IncreaseIndentation(CharSourceRange range, SourceLocation parentIndent);
- bool IncreaseIndentation(SourceRange range, SourceLocation parentIndent) {
- return IncreaseIndentation(CharSourceRange::getTokenRange(range),
- parentIndent);
- }
-
- /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
- /// buffer, and allows you to write on it directly. This is useful if you
- /// want efficient low-level access to apis for scribbling on one specific
- /// FileID's buffer.
- RewriteBuffer &getEditBuffer(FileID FID);
-
- /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
- /// If no modification has been made to it, return null.
- const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
- std::map<FileID, RewriteBuffer>::const_iterator I =
- RewriteBuffers.find(FID);
- return I == RewriteBuffers.end() ? nullptr : &I->second;
- }
-
- // Iterators over rewrite buffers.
- buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
- buffer_iterator buffer_end() { return RewriteBuffers.end(); }
- const_buffer_iterator buffer_begin() const { return RewriteBuffers.begin(); }
- const_buffer_iterator buffer_end() const { return RewriteBuffers.end(); }
-
- /// overwriteChangedFiles - Save all changed files to disk.
- ///
- /// Returns true if any files were not saved successfully.
- /// Outputs diagnostics via the source manager's diagnostic engine
- /// in case of an error.
- bool overwriteChangedFiles();
-
-private:
- unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h
deleted file mode 100644
index 0f71e81..0000000
--- a/include/clang/Rewrite/Core/TokenRewriter.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===--- TokenRewriter.h - Token-based Rewriter -----------------*- 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 TokenRewriter class, which is used for code
-// transformations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITE_CORE_TOKENREWRITER_H
-#define LLVM_CLANG_REWRITE_CORE_TOKENREWRITER_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/Token.h"
-#include <list>
-#include <map>
-#include <memory>
-
-namespace clang {
- class LangOptions;
- class ScratchBuffer;
-
- class TokenRewriter {
- /// TokenList - This is the list of raw tokens that make up this file. Each
- /// of these tokens has a unique SourceLocation, which is a FileID.
- std::list<Token> TokenList;
-
- /// TokenRefTy - This is the type used to refer to a token in the TokenList.
- typedef std::list<Token>::iterator TokenRefTy;
-
- /// TokenAtLoc - This map indicates which token exists at a specific
- /// SourceLocation. Since each token has a unique SourceLocation, this is a
- /// one to one map. The token can return its own location directly, to map
- /// backwards.
- 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();
-
- typedef std::list<Token>::const_iterator token_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);
- }
-
- private:
- /// RemapIterator - Convert from token_iterator (a const iterator) to
- /// TokenRefTy (a non-const iterator).
- TokenRefTy RemapIterator(token_iterator I);
-
- /// AddToken - Add the specified token into the Rewriter before the other
- /// position.
- TokenRefTy AddToken(const Token &T, TokenRefTy Where);
- };
-
-
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Rewrite/Frontend/ASTConsumers.h b/include/clang/Rewrite/Frontend/ASTConsumers.h
deleted file mode 100644
index c9df889..0000000
--- a/include/clang/Rewrite/Frontend/ASTConsumers.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// AST Consumers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITE_FRONTEND_ASTCONSUMERS_H
-#define LLVM_CLANG_REWRITE_FRONTEND_ASTCONSUMERS_H
-
-#include "clang/Basic/LLVM.h"
-#include <memory>
-#include <string>
-
-namespace clang {
-
-class ASTConsumer;
-class DiagnosticsEngine;
-class LangOptions;
-class Preprocessor;
-
-// ObjC rewriter: attempts to rewrite ObjC constructs into pure C code.
-// This is considered experimental, and only works with Apple's ObjC runtime.
-std::unique_ptr<ASTConsumer>
-CreateObjCRewriter(const std::string &InFile, raw_ostream *OS,
- DiagnosticsEngine &Diags, const LangOptions &LOpts,
- bool SilenceRewriteMacroWarning);
-std::unique_ptr<ASTConsumer>
-CreateModernObjCRewriter(const std::string &InFile, raw_ostream *OS,
- DiagnosticsEngine &Diags, const LangOptions &LOpts,
- bool SilenceRewriteMacroWarning, bool LineInfo);
-
-/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
-/// HTML with syntax highlighting suitable for viewing in a web-browser.
-std::unique_ptr<ASTConsumer> CreateHTMLPrinter(raw_ostream *OS,
- Preprocessor &PP,
- bool SyntaxHighlight = true,
- bool HighlightMacros = true);
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
deleted file mode 100644
index 3b1b31e..0000000
--- a/include/clang/Rewrite/Frontend/FixItRewriter.h
+++ /dev/null
@@ -1,132 +0,0 @@
-//===--- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a diagnostic client adaptor that performs rewrites as
-// suggested by code modification hints attached to diagnostics. It
-// 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/SourceLocation.h"
-#include "clang/Edit/EditedSource.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-
-namespace clang {
-
-class SourceManager;
-class FileEntry;
-
-class FixItOptions {
-public:
- FixItOptions() : InPlace(false), FixWhatYouCan(false),
- FixOnlyWarnings(false), Silent(false) { }
-
- virtual ~FixItOptions();
-
- /// \brief 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;
-
- /// \brief Whether to abort fixing a file when not all errors could be fixed.
- bool FixWhatYouCan;
-
- /// \brief Whether to only fix warnings and not errors.
- bool FixOnlyWarnings;
-
- /// \brief 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;
-};
-
-class FixItRewriter : public DiagnosticConsumer {
- /// \brief The diagnostics machinery.
- DiagnosticsEngine &Diags;
-
- edit::EditedSource Editor;
-
- /// \brief The rewriter used to perform the various code
- /// modifications.
- Rewriter Rewrite;
-
- /// \brief 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
- /// the original.
- FixItOptions *FixItOpts;
-
- /// \brief The number of rewriter failures.
- unsigned NumFailures;
-
- /// \brief Whether the previous diagnostic was not passed to the consumer.
- bool PrevDiagSilenced;
-
-public:
- typedef Rewriter::buffer_iterator iterator;
-
- /// \brief Initialize a new fix-it rewriter.
- FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
- const LangOptions &LangOpts, FixItOptions *FixItOpts);
-
- /// \brief Destroy the fix-it rewriter.
- ~FixItRewriter() override;
-
- /// \brief Check whether there are modifications for a given file.
- bool IsModified(FileID ID) const {
- return Rewrite.getRewriteBufferFor(ID) != nullptr;
- }
-
- // 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.
- ///
- /// \returns true if there was an error, false otherwise.
- bool WriteFixedFile(FileID ID, raw_ostream &OS);
-
- /// \brief 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);
-
- /// IncludeInDiagnosticCounts - This method (whose default implementation
- /// returns true) indicates whether the diagnostics handled by this
- /// DiagnosticConsumer should be included in the number of diagnostics
- /// reported by DiagnosticsEngine.
- bool IncludeInDiagnosticCounts() const override;
-
- /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
- /// capturing it to a log as needed.
- void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) override;
-
- /// \brief Emit a diagnostic via the adapted diagnostic client.
- void Diag(SourceLocation Loc, unsigned DiagID);
-};
-
-}
-
-#endif
diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h
deleted file mode 100644
index 6c290e4..0000000
--- a/include/clang/Rewrite/Frontend/FrontendActions.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===-- FrontendActions.h - Useful Frontend Actions -------------*- 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_REWRITE_FRONTEND_FRONTENDACTIONS_H
-#define LLVM_CLANG_REWRITE_FRONTEND_FRONTENDACTIONS_H
-
-#include "clang/Frontend/FrontendAction.h"
-
-namespace clang {
-class FixItRewriter;
-class FixItOptions;
-
-//===----------------------------------------------------------------------===//
-// AST Consumer Actions
-//===----------------------------------------------------------------------===//
-
-class HTMLPrintAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-class FixItAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<FixItRewriter> Rewriter;
- std::unique_ptr<FixItOptions> FixItOpts;
-
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
- bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename) override;
-
- void EndSourceFileAction() override;
-
- bool hasASTFileSupport() const override { return false; }
-
-public:
- FixItAction();
- ~FixItAction() override;
-};
-
-/// \brief Emits changes to temporary files and uses them for the original
-/// frontend action.
-class FixItRecompile : public WrapperFrontendAction {
-public:
- FixItRecompile(FrontendAction *WrappedAction)
- : WrapperFrontendAction(WrappedAction) {}
-
-protected:
- bool BeginInvocation(CompilerInstance &CI) override;
-};
-
-class RewriteObjCAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-class RewriteMacrosAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-};
-
-class RewriteTestAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-};
-
-class RewriteIncludesAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Rewrite/Frontend/Rewriters.h b/include/clang/Rewrite/Frontend/Rewriters.h
deleted file mode 100644
index 3ad76df..0000000
--- a/include/clang/Rewrite/Frontend/Rewriters.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===--- Rewriters.h - Rewriter implementations -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header contains miscellaneous utilities for various front-end actions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITE_FRONTEND_REWRITERS_H
-#define LLVM_CLANG_REWRITE_FRONTEND_REWRITERS_H
-
-#include "clang/Basic/LLVM.h"
-
-namespace clang {
-class Preprocessor;
-class PreprocessorOutputOptions;
-
-/// RewriteMacrosInInput - Implement -rewrite-macros mode.
-void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS);
-
-/// DoRewriteTest - A simple test for the TokenRewriter class.
-void DoRewriteTest(Preprocessor &PP, raw_ostream *OS);
-
-/// RewriteIncludesInInput - Implement -frewrite-includes mode.
-void RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
- const PreprocessorOutputOptions &Opts);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h
deleted file mode 100644
index 64dd2d3..0000000
--- a/include/clang/Sema/AnalysisBasedWarnings.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//=- AnalysisBasedWarnings.h - Sema warnings based on libAnalysis -*- 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 AnalysisBasedWarnings, a worker object used by Sema
-// that issues warnings based on dataflow-analysis.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H
-#define LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H
-
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-
-class BlockExpr;
-class Decl;
-class FunctionDecl;
-class ObjCMethodDecl;
-class QualType;
-class Sema;
-namespace sema {
- class FunctionScopeInfo;
-}
-
-namespace sema {
-
-class AnalysisBasedWarnings {
-public:
- class Policy {
- friend class AnalysisBasedWarnings;
- // The warnings to run.
- unsigned enableCheckFallThrough : 1;
- unsigned enableCheckUnreachable : 1;
- unsigned enableThreadSafetyAnalysis : 1;
- unsigned enableConsumedAnalysis : 1;
- public:
- Policy();
- void disableCheckFallThrough() { enableCheckFallThrough = 0; }
- };
-
-private:
- Sema &S;
- Policy DefaultPolicy;
-
- enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 };
- llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD;
-
- /// \name Statistics
- /// @{
-
- /// \brief Number of function CFGs built and analyzed.
- unsigned NumFunctionsAnalyzed;
-
- /// \brief Number of functions for which the CFG could not be successfully
- /// built.
- unsigned NumFunctionsWithBadCFGs;
-
- /// \brief Total number of blocks across all CFGs.
- unsigned NumCFGBlocks;
-
- /// \brief Largest number of CFG blocks for a single function analyzed.
- unsigned MaxCFGBlocksPerFunction;
-
- /// \brief Total number of CFGs with variables analyzed for uninitialized
- /// uses.
- unsigned NumUninitAnalysisFunctions;
-
- /// \brief Total number of variables analyzed for uninitialized uses.
- unsigned NumUninitAnalysisVariables;
-
- /// \brief Max number of variables analyzed for uninitialized uses in a single
- /// function.
- unsigned MaxUninitAnalysisVariablesPerFunction;
-
- /// \brief Total number of block visits during uninitialized use analysis.
- unsigned NumUninitAnalysisBlockVisits;
-
- /// \brief Max number of block visits during uninitialized use analysis of
- /// a single function.
- unsigned MaxUninitAnalysisBlockVisitsPerFunction;
-
- /// @}
-
-public:
- AnalysisBasedWarnings(Sema &s);
-
- void IssueWarnings(Policy P, FunctionScopeInfo *fscope,
- const Decl *D, const BlockExpr *blkExpr);
-
- Policy getDefaultPolicy() { return DefaultPolicy; }
-
- void PrintStats() const;
-};
-
-}} // end namespace clang::sema
-
-#endif
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
deleted file mode 100644
index e32781d..0000000
--- a/include/clang/Sema/AttributeList.h
+++ /dev/null
@@ -1,863 +0,0 @@
-//===--- AttributeList.h - Parsed attribute sets ----------------*- 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 AttributeList class, which is used to collect
-// parsed attributes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
-#define LLVM_CLANG_SEMA_ATTRIBUTELIST_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/Support/Allocator.h"
-#include <cassert>
-
-namespace clang {
- class ASTContext;
- class IdentifierInfo;
- class Expr;
-
-/// \brief 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.
- SourceLocation KeywordLoc;
-
- /// \brief The version number at which the change occurred.
- VersionTuple Version;
-
- /// \brief The source range covering the version number.
- SourceRange VersionRange;
-
- /// \brief Determine whether this availability change is valid.
- bool isValid() const { return !Version.empty(); }
-};
-
-/// \brief Wraps an identifier and optional source location for the identifier.
-struct IdentifierLoc {
- SourceLocation Loc;
- IdentifierInfo *Ident;
-
- static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
- 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;
-
-/// AttributeList - Represents a syntactic attribute.
-///
-/// For a GNU attribute, there are four forms of this construct:
-///
-/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
-/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
-/// 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
-public:
- /// The style used to specify an attribute.
- enum Syntax {
- /// __attribute__((...))
- AS_GNU,
- /// [[...]]
- AS_CXX11,
- /// __declspec(...)
- AS_Declspec,
- /// __ptr16, alignas(...), etc.
- AS_Keyword,
- /// Context-sensitive version of a keyword attribute.
- AS_ContextSensitiveKeyword,
- /// #pragma ...
- AS_Pragma
- };
-
-private:
- IdentifierInfo *AttrName;
- IdentifierInfo *ScopeName;
- SourceRange AttrRange;
- SourceLocation ScopeLoc;
- SourceLocation EllipsisLoc;
-
- /// The number of expression arguments this attribute has.
- /// The expressions themselves are stored after the object.
- unsigned NumArgs : 15;
-
- /// Corresponds to the Syntax enum.
- unsigned SyntaxUsed : 3;
-
- /// True if already diagnosed as invalid.
- mutable unsigned Invalid : 1;
-
- /// True if this attribute was used as a type attribute.
- mutable unsigned UsedAsTypeAttr : 1;
-
- /// True if this has the extra information associated with an
- /// availability attribute.
- unsigned IsAvailability : 1;
-
- /// True if this has extra information associated with a
- /// type_tag_for_datatype attribute.
- unsigned IsTypeTagForDatatype : 1;
-
- /// True if this has extra information associated with a
- /// Microsoft __delcspec(property) attribute.
- unsigned IsProperty : 1;
-
- /// True if this has a ParsedType
- unsigned HasParsedType : 1;
-
- unsigned AttrKind : 8;
-
- /// \brief 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 {
- return reinterpret_cast<ArgsUnion const *>(this + 1);
- }
-
- enum AvailabilitySlot {
- IntroducedSlot, DeprecatedSlot, ObsoletedSlot
- };
-
- /// Availability information is stored immediately following the arguments,
- /// if any, at the end of the object.
- AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
- return reinterpret_cast<AvailabilityChange*>(getArgsBuffer()
- + NumArgs)[index];
- }
- const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
- return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer()
- + NumArgs)[index];
- }
-
-public:
- struct TypeTagForDatatypeData {
- ParsedType *MatchingCType;
- unsigned LayoutCompatible : 1;
- unsigned MustBeNull : 1;
- };
- struct PropertyData {
- IdentifierInfo *GetterId, *SetterId;
- PropertyData(IdentifierInfo *getterId, IdentifierInfo *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;
-
- /// 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), NextInPosition(nullptr), NextInPool(nullptr) {
- 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)
- : 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),
- UnavailableLoc(unavailable), MessageExpr(messageExpr),
- NextInPosition(nullptr), NextInPool(nullptr) {
- ArgsUnion PVal(Parm);
- memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
- new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
- new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
- AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
- }
-
- /// 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),
- NextInPosition(nullptr), NextInPool(nullptr) {
- ArgsVector Args;
- Args.push_back(Parm1);
- Args.push_back(Parm2);
- Args.push_back(Parm3);
- memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion));
- AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
- }
-
- /// 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),
- NextInPosition(nullptr), NextInPool(nullptr) {
- ArgsUnion PVal(ArgKind);
- memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
- new (&ExtraData.MatchingCType) ParsedType(matchingCType);
- ExtraData.LayoutCompatible = layoutCompatible;
- ExtraData.MustBeNull = mustBeNull;
- AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
- }
-
- /// Constructor for attributes with a single type argument.
- AttributeList(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),
- IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
- NextInPosition(nullptr), NextInPool(nullptr) {
- 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),
- NextInPosition(nullptr), NextInPool(nullptr) {
- new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
- AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
- }
-
- friend class AttributePool;
- friend class AttributeFactory;
-
-public:
- enum Kind {
- #define PARSED_ATTR(NAME) AT_##NAME,
- #include "clang/Sema/AttrParsedAttrList.inc"
- #undef PARSED_ATTR
- IgnoredAttribute,
- UnknownAttribute
- };
-
- IdentifierInfo *getName() const { return AttrName; }
- SourceLocation getLoc() const { return AttrRange.getBegin(); }
- SourceRange getRange() const { return AttrRange; }
-
- bool hasScope() const { return ScopeName; }
- IdentifierInfo *getScopeName() const { return ScopeName; }
- SourceLocation getScopeLoc() const { return ScopeLoc; }
-
- bool hasParsedType() const { return HasParsedType; }
-
- /// Is this the Microsoft __declspec(property) attribute?
- bool isDeclspecPropertyAttribute() const {
- return IsProperty;
- }
-
- bool isAlignasAttribute() const {
- // FIXME: Use a better mechanism to determine this.
- return getKind() == AT_Aligned && isKeywordAttribute();
- }
-
- bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
- bool isCXX11Attribute() const {
- return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
- }
- bool isKeywordAttribute() const {
- return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
- }
-
- bool isContextSensitiveKeywordAttribute() const {
- return SyntaxUsed == AS_ContextSensitiveKeyword;
- }
-
- bool isInvalid() const { return Invalid; }
- void setInvalid(bool b = true) const { Invalid = b; }
-
- bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
- void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
-
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
-
- Kind getKind() const { return Kind(AttrKind); }
- 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; }
-
- /// getArg - Return the specified argument.
- ArgsUnion getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return getArgsBuffer()[Arg];
- }
-
- bool isArgExpr(unsigned Arg) const {
- return Arg < NumArgs && getArg(Arg).is<Expr*>();
- }
- Expr *getArgAsExpr(unsigned Arg) const {
- return getArg(Arg).get<Expr*>();
- }
-
- bool isArgIdent(unsigned Arg) const {
- return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
- }
- IdentifierLoc *getArgAsIdent(unsigned Arg) const {
- return getArg(Arg).get<IdentifierLoc*>();
- }
-
- const AvailabilityChange &getAvailabilityIntroduced() const {
- assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilitySlot(IntroducedSlot);
- }
-
- const AvailabilityChange &getAvailabilityDeprecated() const {
- assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilitySlot(DeprecatedSlot);
- }
-
- const AvailabilityChange &getAvailabilityObsoleted() const {
- assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilitySlot(ObsoletedSlot);
- }
-
- SourceLocation getUnavailableLoc() const {
- assert(getKind() == AT_Availability && "Not an availability attribute");
- return UnavailableLoc;
- }
-
- const Expr * getMessageExpr() const {
- assert(getKind() == AT_Availability && "Not an availability attribute");
- return MessageExpr;
- }
-
- const ParsedType &getMatchingCType() const {
- assert(getKind() == AT_TypeTagForDatatype &&
- "Not a type_tag_for_datatype attribute");
- return *getTypeTagForDatatypeDataSlot().MatchingCType;
- }
-
- bool getLayoutCompatible() const {
- assert(getKind() == AT_TypeTagForDatatype &&
- "Not a type_tag_for_datatype attribute");
- return getTypeTagForDatatypeDataSlot().LayoutCompatible;
- }
-
- bool getMustBeNull() const {
- assert(getKind() == AT_TypeTagForDatatype &&
- "Not a type_tag_for_datatype attribute");
- return getTypeTagForDatatypeDataSlot().MustBeNull;
- }
-
- const ParsedType &getTypeArg() const {
- assert(HasParsedType && "Not a type attribute");
- return getTypeBuffer();
- }
-
- const PropertyData &getPropertyData() const {
- assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
- return getPropertyDataBuffer();
- }
-
- /// \brief 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;
-
- bool isTargetSpecificAttr() const;
- bool isTypeAttr() const;
-
- bool hasCustomParsing() const;
- unsigned getMinArgs() const;
- unsigned getMaxArgs() const;
- bool hasVariadicArg() const;
- bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
- bool diagnoseLangOpts(class Sema &S) const;
- bool existsInTarget(const TargetInfo &Target) const;
- bool isKnownToGCC() const;
-
- /// \brief 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
- /// a Spelling enumeration, the value UINT_MAX is returned.
- unsigned getSemanticSpelling() const;
-};
-
-/// A factory, from which one makes pools, from which one creates
-/// individual attributes which are deallocated with the pool.
-///
-/// Note that it's tolerably cheap to create and destroy one of
-/// these as long as you don't actually allocate anything in it.
-class AttributeFactory {
-public:
- enum {
- /// The required allocation size of an availability attribute,
- /// which we want to ensure is a multiple of sizeof(void*).
- AvailabilityAllocSize =
- sizeof(AttributeList)
- + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
- sizeof(ArgsUnion) - 1)
- / sizeof(void*) * sizeof(void*)),
- TypeTagForDatatypeAllocSize =
- sizeof(AttributeList)
- + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
- sizeof(ArgsUnion) - 1)
- / sizeof(void*) * sizeof(void*),
- PropertyAllocSize =
- sizeof(AttributeList)
- + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
- / sizeof(void*) * sizeof(void*)
- };
-
-private:
- enum {
- /// The number of free lists we want to be sure to support
- /// inline. This is just enough that availability attributes
- /// don't surpass it. It's actually very unlikely we'll see an
- /// 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*)
- };
-
- llvm::BumpPtrAllocator Alloc;
-
- /// Free lists. The index is determined by the following formula:
- /// (size - sizeof(AttributeList)) / sizeof(void*)
- SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
-
- // The following are the private interface used by AttributePool.
- friend class AttributePool;
-
- /// Allocate an attribute of the given size.
- void *allocate(size_t size);
-
- /// 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);
-
-public:
- AttributeFactory();
- ~AttributeFactory();
-};
-
-class AttributePool {
- AttributeFactory &Factory;
- AttributeList *Head;
-
- 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;
- return attr;
- }
-
- void takePool(AttributeList *pool);
-
-public:
- /// Create a new pool for a factory.
- AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
-
- AttributePool(const AttributePool &) = delete;
-
- /// Move the given pool's allocations to this pool.
- AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
- pool.Head = nullptr;
- }
-
- AttributeFactory &getFactory() const { return Factory; }
-
- void clear() {
- if (Head) {
- Factory.reclaimPool(Head);
- Head = nullptr;
- }
- }
-
- /// 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) {
- void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- Param, introduced, deprecated,
- obsoleted, unavailable, MessageExpr,
- syntax));
- }
-
- 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);
- 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) {
- 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) {
- void *memory = allocate(AttributeFactory::PropertyAllocSize);
- return add(new (memory) AttributeList(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 {
-public:
- ParsedAttributes(AttributeFactory &factory)
- : pool(factory), list(nullptr) {
- }
-
- ParsedAttributes(const ParsedAttributes &) = delete;
-
- AttributePool &getPool() const { return pool; }
-
- bool empty() const { return list == nullptr; }
-
- void add(AttributeList *newAttr) {
- assert(newAttr);
- assert(newAttr->getNext() == nullptr);
- newAttr->setNext(list);
- list = newAttr;
- }
-
- void addAll(AttributeList *newList) {
- if (!newList) return;
-
- AttributeList *lastInNewList = newList;
- while (AttributeList *next = lastInNewList->getNext())
- lastInNewList = next;
-
- lastInNewList->setNext(list);
- list = newList;
- }
-
- void set(AttributeList *newList) {
- list = newList;
- }
-
- void takeAllFrom(ParsedAttributes &attrs) {
- addAll(attrs.list);
- attrs.list = nullptr;
- pool.takeAllFrom(attrs.pool);
- }
-
- void clear() { list = nullptr; pool.clear(); }
- AttributeList *getList() const { return list; }
-
- /// 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; }
-
- /// 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);
- 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) {
- AttributeList *attr =
- pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
- deprecated, obsoleted, unavailable, MessageExpr, syntax);
- add(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);
- 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);
- 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);
- return attr;
- }
-
- /// Add microsoft __delspec(property) attribute.
- AttributeList *
- addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- AttributeList::Syntax syntaxUsed) {
- AttributeList *attr =
- pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
- getterId, setterId, syntaxUsed);
- add(attr);
- return attr;
- }
-
-private:
- mutable AttributePool pool;
- AttributeList *list;
-};
-
-/// These constants match the enumerated choices of
-/// err_attribute_argument_n_type and err_attribute_argument_type.
-enum AttributeArgumentNType {
- AANT_ArgumentIntOrBool,
- AANT_ArgumentIntegerConstant,
- AANT_ArgumentString,
- AANT_ArgumentIdentifier
-};
-
-/// These constants match the enumerated choices of
-/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
-enum AttributeDeclKind {
- ExpectedFunction,
- ExpectedUnion,
- ExpectedVariableOrFunction,
- ExpectedFunctionOrMethod,
- ExpectedParameter,
- ExpectedFunctionMethodOrBlock,
- ExpectedFunctionMethodOrClass,
- ExpectedFunctionMethodOrParameter,
- ExpectedClass,
- ExpectedEnum,
- ExpectedVariable,
- ExpectedMethod,
- ExpectedVariableFunctionOrLabel,
- ExpectedFieldOrGlobalVar,
- ExpectedStruct,
- ExpectedVariableOrTypedef,
- ExpectedTLSVar,
- ExpectedVariableOrField,
- ExpectedVariableFieldOrTag,
- ExpectedTypeOrNamespace,
- ExpectedObjectiveCInterface,
- ExpectedMethodOrProperty,
- ExpectedStructOrUnion,
- ExpectedStructOrUnionOrClass,
- ExpectedType,
- ExpectedObjCInstanceMethod,
- ExpectedObjCInterfaceDeclInitMethod,
- ExpectedFunctionVariableOrClass,
- ExpectedObjectiveCProtocol,
- ExpectedFunctionGlobalVarMethodOrProperty,
- ExpectedStructOrUnionOrTypedef,
- ExpectedStructOrTypedef,
- ExpectedObjectiveCInterfaceOrProtocol,
- ExpectedKernelFunction,
- ExpectedFunctionWithProtoType
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/CMakeLists.txt b/include/clang/Sema/CMakeLists.txt
deleted file mode 100644
index 5a48b90..0000000
--- a/include/clang/Sema/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-clang_tablegen(AttrTemplateInstantiate.inc -gen-clang-attr-template-instantiate
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrTemplateInstantiate)
-
-clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrParsedAttrList)
-
-clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrParsedAttrKinds)
-
-clang_tablegen(AttrSpellingListIndex.inc -gen-clang-attr-spelling-index
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrSpellingListIndex)
-
-clang_tablegen(AttrParsedAttrImpl.inc -gen-clang-attr-parsed-attr-impl
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrParsedAttrImpl)
diff --git a/include/clang/Sema/CXXFieldCollector.h b/include/clang/Sema/CXXFieldCollector.h
deleted file mode 100644
index 6685751..0000000
--- a/include/clang/Sema/CXXFieldCollector.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides CXXFieldCollector that is used during parsing & semantic
-// analysis of C++ classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
-#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- class FieldDecl;
-
-/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
-/// C++ classes.
-class CXXFieldCollector {
- /// Fields - Contains all FieldDecls collected during parsing of a C++
- /// class. When a nested class is entered, its fields are appended to the
- /// fields of its parent class, when it is exited its fields are removed.
- SmallVector<FieldDecl*, 32> Fields;
-
- /// FieldCount - Each entry represents the number of fields collected during
- /// the parsing of a C++ class. When a nested class is entered, a new field
- /// count is pushed, when it is exited, the field count is popped.
- SmallVector<size_t, 4> FieldCount;
-
- // Example:
- //
- // class C {
- // int x,y;
- // class NC {
- // int q;
- // // At this point, Fields contains [x,y,q] decls and FieldCount contains
- // // [2,1].
- // };
- // int z;
- // // At this point, Fields contains [x,y,z] decls and FieldCount contains
- // // [3].
- // };
-
-public:
- /// StartClass - Called by Sema::ActOnStartCXXClassDef.
- void StartClass() { FieldCount.push_back(0); }
-
- /// Add - Called by Sema::ActOnCXXMemberDeclarator.
- void Add(FieldDecl *D) {
- Fields.push_back(D);
- ++FieldCount.back();
- }
-
- /// getCurNumField - The number of fields added to the currently parsed class.
- size_t getCurNumFields() const {
- assert(!FieldCount.empty() && "no currently-parsed class");
- return FieldCount.back();
- }
-
- /// getCurFields - Pointer to array of fields added to the currently parsed
- /// class.
- FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
-
- /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
- void FinishClass() {
- Fields.resize(Fields.size() - getCurNumFields());
- FieldCount.pop_back();
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
deleted file mode 100644
index 9702273..0000000
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ /dev/null
@@ -1,976 +0,0 @@
-//===---- CodeCompleteConsumer.h - Code Completion Interface ----*- 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 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/Type.h"
-#include "clang/Sema/CodeCompleteOptions.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-#include <string>
-
-namespace clang {
-
-class Decl;
-
-/// \brief Default priority values for code-completion results based
-/// on their kind.
-enum {
- /// \brief Priority for the next initialization in a constructor initializer
- /// list.
- CCP_NextInitializer = 7,
- /// \brief 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.
- CCP_SuperCompletion = 20,
- /// \brief Priority for a declaration that is in the local scope.
- CCP_LocalDeclaration = 34,
- /// \brief 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
- /// categories).
- CCP_Keyword = 40,
- /// \brief Priority for a code pattern.
- CCP_CodePattern = 40,
- /// \brief Priority for a non-type declaration.
- CCP_Declaration = 50,
- /// \brief Priority for a type.
- CCP_Type = CCP_Declaration,
- /// \brief Priority for a constant value (e.g., enumerator).
- CCP_Constant = 65,
- /// \brief Priority for a preprocessor macro.
- CCP_Macro = 70,
- /// \brief Priority for a nested-name-specifier.
- CCP_NestedNameSpecifier = 75,
- /// \brief 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.
- CCP_ObjC_cmd = CCP_Unlikely
-};
-
-/// \brief 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.
- CCD_InBaseClass = 2,
- /// \brief 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
- /// 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
- /// "BOOL" is preferred.
- CCD_bool_in_ObjC = 1,
-
- /// \brief 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.
- CCD_MethodAsProperty = 2
-};
-
-/// \brief 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
- /// matches the type we expect.
- CCF_ExactTypeMatch = 4,
- /// \brief 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
-/// "similar" types for code completion.
-enum SimplifiedTypeClass {
- STC_Arithmetic,
- STC_Array,
- STC_Block,
- STC_Function,
- STC_ObjectiveC,
- STC_Other,
- STC_Pointer,
- STC_Record,
- STC_Void
-};
-
-/// \brief 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
-/// 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
-/// with the given name.
-///
-/// \param MacroName The name of the macro.
-///
-/// \param LangOpts Options describing the current language dialect.
-///
-/// \param PreferredTypeIsPointer Whether the preferred type for the context
-/// of this macro is a pointer type.
-unsigned getMacroUsagePriority(StringRef MacroName,
- const LangOptions &LangOpts,
- bool PreferredTypeIsPointer = false);
-
-/// \brief 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
-/// code-completion consumer can process the results accordingly.
-class CodeCompletionContext {
-public:
- enum Kind {
- /// \brief An unspecified code-completion context.
- CCC_Other,
- /// \brief An unspecified code-completion context where we should also add
- /// macro completions.
- CCC_OtherWithMacros,
- /// \brief 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,
- /// protocol, or category interface.
- CCC_ObjCInterface,
- /// \brief Code completion occurred within an Objective-C implementation
- /// or category implementation.
- CCC_ObjCImplementation,
- /// \brief 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.
- CCC_ClassStructUnion,
- /// \brief 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.
- CCC_Expression,
- /// \brief 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
- /// 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
- /// 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
- /// 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
- /// an enumeration name.
- CCC_EnumTag,
- /// \brief Code completion occurred after the "union" keyword, to indicate
- /// a union name.
- CCC_UnionTag,
- /// \brief 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.
- CCC_ObjCProtocolName,
- /// \brief Code completion occurred where a namespace or namespace alias
- /// is expected.
- CCC_Namespace,
- /// \brief Code completion occurred where a type name is expected.
- CCC_Type,
- /// \brief Code completion occurred where a new name is expected.
- CCC_Name,
- /// \brief 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.
- CCC_MacroName,
- /// \brief 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.
- CCC_PreprocessorExpression,
- /// \brief Code completion occurred where a preprocessor directive is
- /// expected.
- CCC_PreprocessorDirective,
- /// \brief 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.
- CCC_SelectorName,
- /// \brief Code completion within a type-qualifier list.
- CCC_TypeQualifiers,
- /// \brief 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
- /// expected.
- CCC_ObjCInstanceMessage,
- /// \brief Code completion where an Objective-C class message is expected.
- CCC_ObjCClassMessage,
- /// \brief 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.
- CCC_ObjCCategoryName,
- /// \brief An unknown context, in which we are recovering from a parsing
- /// error and don't know which completions we should give.
- CCC_Recovery
- };
-
-private:
- enum Kind Kind;
-
- /// \brief 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.
- QualType BaseType;
-
- /// \brief The identifiers for Objective-C selector parts.
- ArrayRef<IdentifierInfo *> SelIdents;
-
-public:
- /// \brief Construct a new code-completion context of the given kind.
- CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(None) { }
-
- /// \brief Construct a new code-completion context of the given kind.
- CodeCompletionContext(enum Kind Kind, 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)
- BaseType = T;
- else
- PreferredType = T;
- }
-
- /// \brief Retrieve the kind of code-completion context.
- enum Kind getKind() const { return Kind; }
-
- /// \brief 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
- /// expression.
- QualType getBaseType() const { return BaseType; }
-
- /// \brief Retrieve the Objective-C selector identifiers.
- ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; }
-
- /// \brief Determines whether we want C++ constructors as results within this
- /// context.
- bool wantConstructorResults() const;
-};
-
-
-/// \brief 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
-/// used. For example, the code completion string for a function would show
-/// the syntax to call it, including the parentheses, placeholders for the
-/// arguments, etc.
-class CodeCompletionString {
-public:
- /// \brief 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
- /// 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.,
- /// parentheses or a comma in a function call.
- CK_Text,
- /// \brief 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
- /// call argument.
- CK_Placeholder,
- /// \brief 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
- /// functions and methods, the return type.
- CK_ResultType,
- /// \brief 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 ('(').
- CK_LeftParen,
- /// \brief A right parenthesis (')').
- CK_RightParen,
- /// \brief A left bracket ('[').
- CK_LeftBracket,
- /// \brief A right bracket (']').
- CK_RightBracket,
- /// \brief A left brace ('{').
- CK_LeftBrace,
- /// \brief A right brace ('}').
- CK_RightBrace,
- /// \brief A left angle bracket ('<').
- CK_LeftAngle,
- /// \brief A right angle bracket ('>').
- CK_RightAngle,
- /// \brief A comma separator (',').
- CK_Comma,
- /// \brief A colon (':').
- CK_Colon,
- /// \brief A semicolon (';').
- CK_SemiColon,
- /// \brief An '=' sign.
- CK_Equal,
- /// \brief Horizontal whitespace (' ').
- CK_HorizontalSpace,
- /// \brief Vertical whitespace ('\\n' or '\\r\\n', depending on the
- /// platform).
- CK_VerticalSpace
- };
-
- /// \brief One piece of the code completion string.
- struct Chunk {
- /// \brief The kind of data stored in this piece of the code completion
- /// string.
- ChunkKind Kind;
-
- union {
- /// \brief 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 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) { }
-
- explicit Chunk(ChunkKind Kind, const char *Text = "");
-
- /// \brief Create a new text chunk.
- static Chunk CreateText(const char *Text);
-
- /// \brief Create a new optional chunk.
- static Chunk CreateOptional(CodeCompletionString *Optional);
-
- /// \brief Create a new placeholder chunk.
- static Chunk CreatePlaceholder(const char *Placeholder);
-
- /// \brief Create a new informative chunk.
- static Chunk CreateInformative(const char *Informative);
-
- /// \brief Create a new result type chunk.
- static Chunk CreateResultType(const char *ResultType);
-
- /// \brief Create a new current-parameter chunk.
- static Chunk CreateCurrentParameter(const char *CurrentParameter);
- };
-
-private:
- /// \brief The number of chunks stored in this string.
- unsigned NumChunks : 16;
-
- /// \brief The number of annotations for this code-completion result.
- unsigned NumAnnotations : 16;
-
- /// \brief The priority of this code-completion string.
- unsigned Priority : 16;
-
- /// \brief The availability of this code-completion result.
- unsigned Availability : 2;
-
- /// \brief The name of the parent context.
- StringRef ParentName;
-
- /// \brief 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,
- const char **Annotations, unsigned NumAnnotations,
- StringRef ParentName,
- const char *BriefComment);
- ~CodeCompletionString() = default;
-
- friend class CodeCompletionBuilder;
- friend class CodeCompletionResult;
-
-public:
- typedef const Chunk *iterator;
- iterator begin() const { return reinterpret_cast<const Chunk *>(this + 1); }
- iterator end() const { return begin() + NumChunks; }
- bool empty() const { return NumChunks == 0; }
- unsigned size() const { return NumChunks; }
-
- const Chunk &operator[](unsigned I) const {
- assert(I < size() && "Chunk index out-of-range");
- return begin()[I];
- }
-
- /// \brief Returns the text in the TypedText chunk.
- const char *getTypedText() const;
-
- /// \brief Retrieve the priority of this code completion result.
- unsigned getPriority() const { return Priority; }
-
- /// \brief Retrieve the availability of this code completion result.
- unsigned getAvailability() const { return Availability; }
-
- /// \brief Retrieve the number of annotations for this code completion result.
- unsigned getAnnotationCount() const;
-
- /// \brief Retrieve the annotation string specified by \c AnnotationNr.
- const char *getAnnotation(unsigned AnnotationNr) const;
-
- /// \brief Retrieve the name of the parent context.
- StringRef getParentContextName() const {
- return ParentName;
- }
-
- const char *getBriefComment() const {
- return BriefComment;
- }
-
- /// \brief 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.
-class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
-public:
- /// \brief Copy the given string into this allocator.
- const char *CopyString(const Twine &String);
-};
-
-/// \brief Allocator for a cached set of global code completions.
-class GlobalCodeCompletionAllocator
- : public CodeCompletionAllocator,
- public RefCountedBase<GlobalCodeCompletionAllocator>
-{
-
-};
-
-class CodeCompletionTUInfo {
- llvm::DenseMap<const DeclContext *, StringRef> ParentNames;
- IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> AllocatorRef;
-
-public:
- explicit CodeCompletionTUInfo(
- IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator)
- : AllocatorRef(Allocator) { }
-
- IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> getAllocatorRef() const {
- return AllocatorRef;
- }
- CodeCompletionAllocator &getAllocator() const {
- assert(AllocatorRef);
- return *AllocatorRef;
- }
-
- StringRef getParentName(const DeclContext *DC);
-};
-
-} // end namespace clang
-
-namespace llvm {
- template <> struct isPodLike<clang::CodeCompletionString::Chunk> {
- static const bool value = true;
- };
-}
-
-namespace clang {
-
-/// \brief A builder class used to construct new code-completion strings.
-class CodeCompletionBuilder {
-public:
- typedef CodeCompletionString::Chunk Chunk;
-
-private:
- CodeCompletionAllocator &Allocator;
- CodeCompletionTUInfo &CCTUInfo;
- unsigned Priority;
- CXAvailabilityKind Availability;
- StringRef ParentName;
- const char *BriefComment;
-
- /// \brief The chunks stored in this string.
- SmallVector<Chunk, 4> Chunks;
-
- SmallVector<const char *, 2> Annotations;
-
-public:
- CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo)
- : Allocator(Allocator), CCTUInfo(CCTUInfo),
- Priority(0), Availability(CXAvailability_Available),
- BriefComment(nullptr) { }
-
- CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo,
- unsigned Priority, CXAvailabilityKind Availability)
- : Allocator(Allocator), CCTUInfo(CCTUInfo),
- Priority(Priority), Availability(Availability),
- BriefComment(nullptr) { }
-
- /// \brief 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.
- ///
- /// This operation can only be performed once.
- CodeCompletionString *TakeString();
-
- /// \brief Add a new typed-text chunk.
- void AddTypedTextChunk(const char *Text);
-
- /// \brief Add a new text chunk.
- void AddTextChunk(const char *Text);
-
- /// \brief Add a new optional chunk.
- void AddOptionalChunk(CodeCompletionString *Optional);
-
- /// \brief Add a new placeholder chunk.
- void AddPlaceholderChunk(const char *Placeholder);
-
- /// \brief Add a new informative chunk.
- void AddInformativeChunk(const char *Text);
-
- /// \brief Add a new result-type chunk.
- void AddResultTypeChunk(const char *ResultType);
-
- /// \brief Add a new current-parameter chunk.
- void AddCurrentParameterChunk(const char *CurrentParameter);
-
- /// \brief 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.
- 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.
-class CodeCompletionResult {
-public:
- /// \brief 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.
- };
-
- /// \brief 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;
-
- union {
- /// \brief 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
- /// describes the completion text to insert.
- CodeCompletionString *Pattern;
-
- /// \brief When Kind == RK_Macro, the identifier that refers to a macro.
- const IdentifierInfo *Macro;
- };
-
- /// \brief The priority of this particular code-completion result.
- unsigned Priority;
-
- /// \brief Specifies which parameter (of a function, Objective-C method,
- /// macro, etc.) we should start with when formatting the result.
- unsigned StartParameter;
-
- /// \brief The kind of result stored here.
- ResultKind Kind;
-
- /// \brief The cursor kind that describes this result.
- CXCursorKind CursorKind;
-
- /// \brief The availability of this result.
- CXAvailabilityKind Availability;
-
- /// \brief Whether this result is hidden by another name.
- bool Hidden : 1;
-
- /// \brief Whether this result was found via lookup into a base class.
- bool QualifierIsInformative : 1;
-
- /// \brief 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
- /// method, etc.) should be considered "informative".
- bool AllParametersAreInformative : 1;
-
- /// \brief 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.
- /// When \c QualifierIsInformative, the nested-name-specifier is
- /// informative rather than required.
- NestedNameSpecifier *Qualifier;
-
- /// \brief 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) {
- computeCursorKindAndAvailability(Accessible);
- }
-
- /// \brief 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.
- 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.
- 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)
- {
- }
-
- /// \brief Build a result that refers to a pattern with an associated
- /// declaration.
- CodeCompletionResult(CodeCompletionString *Pattern, 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) {
- computeCursorKindAndAvailability();
- }
-
- /// \brief Retrieve the declaration stored in this result.
- const NamedDecl *getDeclaration() const {
- assert(Kind == RK_Declaration && "Not a declaration result");
- return Declaration;
- }
-
- /// \brief 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
- /// this result into a program.
- ///
- /// \param S The semantic analysis that created the result.
- ///
- /// \param Allocator The allocator that will be used to allocate the
- /// string itself.
- CodeCompletionString *CreateCodeCompletionString(Sema &S,
- const CodeCompletionContext &CCContext,
- CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo,
- bool IncludeBriefComments);
- CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx,
- Preprocessor &PP,
- const CodeCompletionContext &CCContext,
- CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo,
- bool IncludeBriefComments);
-
-private:
- void computeCursorKindAndAvailability(bool Accessible = true);
-};
-
-bool operator<(const CodeCompletionResult &X, const CodeCompletionResult &Y);
-
-inline bool operator>(const CodeCompletionResult &X,
- const CodeCompletionResult &Y) {
- return Y < X;
-}
-
-inline bool operator<=(const CodeCompletionResult &X,
- const CodeCompletionResult &Y) {
- return !(Y < X);
-}
-
-inline bool operator>=(const CodeCompletionResult &X,
- const CodeCompletionResult &Y) {
- return !(X < Y);
-}
-
-
-raw_ostream &operator<<(raw_ostream &OS,
- const CodeCompletionString &CCS);
-
-/// \brief 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
- /// binary.
- bool OutputIsBinary;
-
-public:
- class OverloadCandidate {
- public:
- /// \brief Describes the type of overload candidate.
- enum CandidateKind {
- /// \brief The candidate is a function declaration.
- CK_Function,
- /// \brief The candidate is a function template.
- CK_FunctionTemplate,
- /// \brief 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.
- CandidateKind Kind;
-
- union {
- /// \brief The function overload candidate, available when
- /// Kind == CK_Function.
- FunctionDecl *Function;
-
- /// \brief The function template overload candidate, available when
- /// Kind == CK_FunctionTemplate.
- FunctionTemplateDecl *FunctionTemplate;
-
- /// \brief 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) { }
-
- OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
- : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) { }
-
- OverloadCandidate(const FunctionType *Type)
- : Kind(CK_FunctionType), Type(Type) { }
-
- /// \brief Determine the kind of overload candidate.
- CandidateKind getKind() const { return Kind; }
-
- /// \brief Retrieve the function overload candidate or the templated
- /// function declaration for a function template.
- FunctionDecl *getFunction() const;
-
- /// \brief 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
- /// function is stored.
- const FunctionType *getFunctionType() const;
-
- /// \brief Create a new code-completion string that describes the function
- /// signature of this overload candidate.
- CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
- Sema &S,
- CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo,
- bool IncludeBriefComments) const;
- };
-
- CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
- bool OutputIsBinary)
- : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary)
- { }
-
- /// \brief 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.
- bool includeCodePatterns() const {
- return CodeCompleteOpts.IncludeCodePatterns;
- }
-
- /// \brief Whether to include global (top-level) declaration results.
- bool includeGlobals() const {
- return CodeCompleteOpts.IncludeGlobals;
- }
-
- /// \brief 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.
- bool isOutputBinary() const { return OutputIsBinary; }
-
- /// \brief Deregisters and destroys this code-completion consumer.
- virtual ~CodeCompleteConsumer();
-
- /// \name Code-completion callbacks
- //@{
- /// \brief Process the finalized code-completion results.
- virtual void ProcessCodeCompleteResults(Sema &S,
- CodeCompletionContext Context,
- CodeCompletionResult *Results,
- unsigned NumResults) { }
-
- /// \param S the semantic-analyzer object for which code-completion is being
- /// done.
- ///
- /// \param CurrentArg the index of the current argument.
- ///
- /// \param Candidates an array of overload candidates.
- ///
- /// \param NumCandidates the number of overload candidates
- virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
- OverloadCandidate *Candidates,
- unsigned NumCandidates) { }
- //@}
-
- /// \brief 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
-/// receives in a simple format.
-class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
- /// \brief The raw output stream.
- raw_ostream &OS;
-
- CodeCompletionTUInfo CCTUInfo;
-
-public:
- /// \brief 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(new GlobalCodeCompletionAllocator) {}
-
- /// \brief Prints the finalized code-completion results.
- void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
- CodeCompletionResult *Results,
- unsigned NumResults) override;
-
- void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
- OverloadCandidate *Candidates,
- unsigned NumCandidates) override;
-
- CodeCompletionAllocator &getAllocator() override {
- return CCTUInfo.getAllocator();
- }
-
- CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h
deleted file mode 100644
index fc7713c..0000000
--- a/include/clang/Sema/CodeCompleteOptions.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//===---- CodeCompleteOptions.h - Code Completion Options -------*- 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_SEMA_CODECOMPLETEOPTIONS_H
-#define LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H
-
-namespace clang {
-
-/// Options controlling the behavior of code completion.
-class CodeCompleteOptions {
-public:
- /// Show macros in code completion results.
- unsigned IncludeMacros : 1;
-
- /// Show code patterns in code completion results.
- unsigned IncludeCodePatterns : 1;
-
- /// Show top-level decls in code completion results.
- unsigned IncludeGlobals : 1;
-
- /// Show brief documentation comments in code completion results.
- unsigned IncludeBriefComments : 1;
-
- CodeCompleteOptions() :
- IncludeMacros(0),
- IncludeCodePatterns(0),
- IncludeGlobals(1),
- IncludeBriefComments(0)
- { }
-};
-
-} // namespace clang
-
-#endif
-
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
deleted file mode 100644
index e9fdb70..0000000
--- a/include/clang/Sema/DeclSpec.h
+++ /dev/null
@@ -1,2313 +0,0 @@
-//===--- DeclSpec.h - Parsed declaration specifiers -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file defines the classes used to store parsed information about
-/// declaration-specifiers and declarators.
-///
-/// \verbatim
-/// static const int volatile x, *y, *(*(*z)[10])(const void *x);
-/// ------------------------- - -- ---------------------------
-/// declaration-specifiers \ | /
-/// declarators
-/// \endverbatim
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_DECLSPEC_H
-#define LLVM_CLANG_SEMA_DECLSPEC_H
-
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/Basic/ExceptionSpecificationType.h"
-#include "clang/Basic/Lambda.h"
-#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 "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
- class ASTContext;
- class CXXRecordDecl;
- class TypeLoc;
- class LangOptions;
- class IdentifierInfo;
- class NamespaceAliasDecl;
- class NamespaceDecl;
- class ObjCDeclSpec;
- class Sema;
- class Declarator;
- struct TemplateIdAnnotation;
-
-/// \brief Represents a C++ nested-name-specifier or a global scope specifier.
-///
-/// These can be in 3 states:
-/// 1) Not present, identified by isEmpty()
-/// 2) Present, identified by isNotEmpty()
-/// 2.a) Valid, identified by isValid()
-/// 2.b) Invalid, identified by isInvalid().
-///
-/// isSet() is deprecated because it mostly corresponded to "valid" but was
-/// often used as if it meant "present".
-///
-/// The actual scope is described by getScopeRep().
-class CXXScopeSpec {
- SourceRange Range;
- NestedNameSpecifierLocBuilder Builder;
-
-public:
- SourceRange getRange() const { return Range; }
- void setRange(SourceRange R) { Range = R; }
- void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); }
- void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); }
- SourceLocation getBeginLoc() const { return Range.getBegin(); }
- SourceLocation getEndLoc() const { return Range.getEnd(); }
-
- /// \brief Retrieve the representation of the nested-name-specifier.
- NestedNameSpecifier *getScopeRep() const {
- return Builder.getRepresentation();
- }
-
- /// \brief 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
- /// resides.
- ///
- /// \param TemplateKWLoc The location of the 'template' keyword, if present.
- ///
- /// \param TL The TypeLoc that describes the type preceding the '::'.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
- SourceLocation ColonColonLoc);
-
- /// \brief 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
- /// resides.
- ///
- /// \param Identifier The identifier.
- ///
- /// \param IdentifierLoc The location of the identifier.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, IdentifierInfo *Identifier,
- SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
-
- /// \brief 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
- /// resides.
- ///
- /// \param Namespace The namespace.
- ///
- /// \param NamespaceLoc The location of the namespace name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceDecl *Namespace,
- SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
-
- /// \brief 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
- /// resides.
- ///
- /// \param Alias The namespace alias.
- ///
- /// \param AliasLoc The location of the namespace alias
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc, SourceLocation ColonColonLoc);
-
- /// \brief 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'
- /// nested-name-specifier.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param RD The declaration of the class in which nested-name-specifier
- /// appeared.
- ///
- /// \param SuperLoc The location of the '__super' keyword.
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
- SourceLocation SuperLoc, SourceLocation ColonColonLoc);
-
- /// \brief Make a new nested-name-specifier from incomplete source-location
- /// information.
- ///
- /// FIXME: This routine should be used very, very rarely, in cases where we
- /// need to synthesize a nested-name-specifier. Most code should instead use
- /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
- void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
- SourceRange R);
-
- /// \brief Adopt an existing nested-name-specifier (with source-range
- /// information).
- void Adopt(NestedNameSpecifierLoc Other);
-
- /// \brief 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
- /// in this nested name specifier.
- ///
- /// For example, the location of \c bar
- /// in
- /// \verbatim
- /// \::foo::bar<0>::
- /// ^~~
- /// \endverbatim
- SourceLocation getLastQualifierNameLoc() const;
-
- /// No scope specifier.
- bool isEmpty() const { return !Range.isValid(); }
- /// A scope specifier is present, but may be valid or invalid.
- bool isNotEmpty() const { return !isEmpty(); }
-
- /// An error occurred during parsing of the scope specifier.
- bool isInvalid() const { return isNotEmpty() && getScopeRep() == nullptr; }
- /// 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.
- void SetInvalid(SourceRange R) {
- assert(R.isValid() && "Must have a valid source range");
- if (Range.getBegin().isInvalid())
- Range.setBegin(R.getBegin());
- Range.setEnd(R.getEnd());
- Builder.Clear();
- }
-
- /// Deprecated. Some call sites intend isNotEmpty() while others intend
- /// isValid().
- bool isSet() const { return getScopeRep() != nullptr; }
-
- void clear() {
- Range = SourceRange();
- Builder.Clear();
- }
-
- /// \brief 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
- /// information.
- unsigned location_size() const { return Builder.getBuffer().second; }
-};
-
-/// \brief 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
- /// \note The order of these enumerators is important for diagnostics.
- enum SCS {
- SCS_unspecified = 0,
- SCS_typedef,
- SCS_extern,
- SCS_static,
- SCS_auto,
- SCS_register,
- SCS_private_extern,
- SCS_mutable
- };
-
- // Import thread storage class specifier enumeration and constants.
- // These can be combined with SCS_extern and SCS_static.
- typedef ThreadStorageClassSpecifier TSCS;
- static const TSCS TSCS_unspecified = clang::TSCS_unspecified;
- static const TSCS TSCS___thread = clang::TSCS___thread;
- static const TSCS TSCS_thread_local = clang::TSCS_thread_local;
- static const TSCS TSCS__Thread_local = clang::TSCS__Thread_local;
-
- // Import type specifier width enumeration and constants.
- typedef TypeSpecifierWidth TSW;
- static const TSW TSW_unspecified = clang::TSW_unspecified;
- static const TSW TSW_short = clang::TSW_short;
- static const TSW TSW_long = clang::TSW_long;
- static const TSW TSW_longlong = clang::TSW_longlong;
-
- enum TSC {
- TSC_unspecified,
- TSC_imaginary,
- TSC_complex
- };
-
- // Import type specifier sign enumeration and constants.
- typedef TypeSpecifierSign TSS;
- static const TSS TSS_unspecified = clang::TSS_unspecified;
- static const TSS TSS_signed = clang::TSS_signed;
- static const TSS TSS_unsigned = clang::TSS_unsigned;
-
- // Import type specifier type enumeration and constants.
- typedef TypeSpecifierType TST;
- static const TST TST_unspecified = clang::TST_unspecified;
- 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_char16 = clang::TST_char16;
- static const TST TST_char32 = clang::TST_char32;
- static const TST TST_int = clang::TST_int;
- static const TST TST_int128 = clang::TST_int128;
- static const TST TST_half = clang::TST_half;
- static const TST TST_float = clang::TST_float;
- static const TST TST_double = clang::TST_double;
- static const TST TST_bool = clang::TST_bool;
- static const TST TST_decimal32 = clang::TST_decimal32;
- static const TST TST_decimal64 = clang::TST_decimal64;
- static const TST TST_decimal128 = clang::TST_decimal128;
- static const TST TST_enum = clang::TST_enum;
- static const TST TST_union = clang::TST_union;
- static const TST TST_struct = clang::TST_struct;
- static const TST TST_interface = clang::TST_interface;
- static const TST TST_class = clang::TST_class;
- static const TST TST_typename = clang::TST_typename;
- static const TST TST_typeofType = clang::TST_typeofType;
- static const TST TST_typeofExpr = clang::TST_typeofExpr;
- static const TST TST_decltype = clang::TST_decltype;
- static const TST TST_decltype_auto = clang::TST_decltype_auto;
- static const TST TST_underlyingType = clang::TST_underlyingType;
- static const TST TST_auto = clang::TST_auto;
- static const TST TST_auto_type = clang::TST_auto_type;
- static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
- static const TST TST_atomic = clang::TST_atomic;
- static const TST TST_error = clang::TST_error;
-
- // type-qualifiers
- enum TQ { // NOTE: These flags must be kept in sync with Qualifiers::TQ.
- TQ_unspecified = 0,
- TQ_const = 1,
- TQ_restrict = 2,
- TQ_volatile = 4,
- // This has no corresponding Qualifiers::TQ value, because it's not treated
- // as a qualifier in our type system.
- TQ_atomic = 8
- };
-
- /// ParsedSpecifiers - Flags to query which specifiers were applied. This is
- /// returned by getParsedSpecifiers.
- enum ParsedSpecifiers {
- PQ_None = 0,
- PQ_StorageClassSpecifier = 1,
- PQ_TypeSpecifier = 2,
- PQ_TypeQualifier = 4,
- PQ_FunctionSpecifier = 8
- };
-
-private:
- // storage-class-specifier
- /*SCS*/unsigned StorageClassSpec : 3;
- /*TSCS*/unsigned ThreadStorageClassSpec : 2;
- unsigned SCS_extern_in_linkage_spec : 1;
-
- // type-specifier
- /*TSW*/unsigned TypeSpecWidth : 2;
- /*TSC*/unsigned TypeSpecComplex : 2;
- /*TSS*/unsigned TypeSpecSign : 2;
- /*TST*/unsigned TypeSpecType : 6;
- unsigned TypeAltiVecVector : 1;
- unsigned TypeAltiVecPixel : 1;
- unsigned TypeAltiVecBool : 1;
- unsigned TypeSpecOwned : 1;
-
- // type-qualifiers
- unsigned TypeQualifiers : 4; // Bitwise OR of TQ.
-
- // function-specifier
- unsigned FS_inline_specified : 1;
- unsigned FS_forceinline_specified: 1;
- unsigned FS_virtual_specified : 1;
- unsigned FS_explicit_specified : 1;
- unsigned FS_noreturn_specified : 1;
-
- // friend-specifier
- unsigned Friend_specified : 1;
-
- // constexpr-specifier
- unsigned Constexpr_specified : 1;
-
- // concept-specifier
- unsigned Concept_specified : 1;
-
- union {
- UnionParsedType TypeRep;
- Decl *DeclRep;
- Expr *ExprRep;
- };
-
- // attributes.
- ParsedAttributes Attrs;
-
- // Scope specifier for the type spec, if applicable.
- CXXScopeSpec TypeScope;
-
- // SourceLocation info. These are null if the item wasn't specified or if
- // the setting was synthesized.
- SourceRange Range;
-
- SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc;
- SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
- /// 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
- /// TSTNameLoc provides source range info for tag types.
- SourceLocation TSTNameLoc;
- SourceRange TypeofParensRange;
- SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc;
- SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc;
- SourceLocation FS_forceinlineLoc;
- SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc, ConceptLoc;
-
- WrittenBuiltinSpecs writtenBS;
- void SaveWrittenBuiltinSpecs();
-
- ObjCDeclSpec *ObjCQualifiers;
-
- static bool isTypeRep(TST T) {
- return (T == TST_typename || T == TST_typeofType ||
- T == TST_underlyingType || T == TST_atomic);
- }
- static bool isExprRep(TST T) {
- return (T == TST_typeofExpr || T == TST_decltype);
- }
-
- DeclSpec(const DeclSpec &) = delete;
- void operator=(const DeclSpec &) = delete;
-public:
- static bool isDeclRep(TST T) {
- return (T == TST_enum || T == TST_struct ||
- T == TST_interface || T == TST_union ||
- T == TST_class);
- }
-
- DeclSpec(AttributeFactory &attrFactory)
- : StorageClassSpec(SCS_unspecified),
- ThreadStorageClassSpec(TSCS_unspecified),
- SCS_extern_in_linkage_spec(false),
- TypeSpecWidth(TSW_unspecified),
- TypeSpecComplex(TSC_unspecified),
- TypeSpecSign(TSS_unspecified),
- TypeSpecType(TST_unspecified),
- TypeAltiVecVector(false),
- TypeAltiVecPixel(false),
- TypeAltiVecBool(false),
- TypeSpecOwned(false),
- TypeQualifiers(TQ_unspecified),
- FS_inline_specified(false),
- FS_forceinline_specified(false),
- FS_virtual_specified(false),
- FS_explicit_specified(false),
- FS_noreturn_specified(false),
- Friend_specified(false),
- Constexpr_specified(false),
- Concept_specified(false),
- Attrs(attrFactory),
- writtenBS(),
- ObjCQualifiers(nullptr) {
- }
-
- // storage-class-specifier
- SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; }
- TSCS getThreadStorageClassSpec() const {
- return (TSCS)ThreadStorageClassSpec;
- }
- bool isExternInLinkageSpec() const { return SCS_extern_in_linkage_spec; }
- void setExternInLinkageSpec(bool Value) {
- SCS_extern_in_linkage_spec = Value;
- }
-
- SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
- SourceLocation getThreadStorageClassSpecLoc() const {
- return ThreadStorageClassSpecLoc;
- }
-
- void ClearStorageClassSpecs() {
- StorageClassSpec = DeclSpec::SCS_unspecified;
- ThreadStorageClassSpec = DeclSpec::TSCS_unspecified;
- SCS_extern_in_linkage_spec = false;
- StorageClassSpecLoc = SourceLocation();
- ThreadStorageClassSpecLoc = SourceLocation();
- }
-
- void ClearTypeSpecType() {
- TypeSpecType = DeclSpec::TST_unspecified;
- TypeSpecOwned = false;
- TSTLoc = SourceLocation();
- }
-
- // type-specifier
- TSW getTypeSpecWidth() const { return (TSW)TypeSpecWidth; }
- TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; }
- TSS getTypeSpecSign() const { return (TSS)TypeSpecSign; }
- TST getTypeSpecType() const { return (TST)TypeSpecType; }
- bool isTypeAltiVecVector() const { return TypeAltiVecVector; }
- bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; }
- bool isTypeAltiVecBool() const { return TypeAltiVecBool; }
- bool isTypeSpecOwned() const { return TypeSpecOwned; }
- bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); }
-
- ParsedType getRepAsType() const {
- assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type");
- return TypeRep;
- }
- Decl *getRepAsDecl() const {
- assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl");
- return DeclRep;
- }
- Expr *getRepAsExpr() const {
- assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr");
- return ExprRep;
- }
- CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
- const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
-
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
-
- SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
- SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
- SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
- SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
- SourceLocation getAltiVecLoc() const { return AltiVecLoc; }
-
- SourceLocation getTypeSpecTypeNameLoc() const {
- assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename);
- return TSTNameLoc;
- }
-
- SourceRange getTypeofParensRange() const { return TypeofParensRange; }
- void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
-
- bool containsPlaceholderType() const {
- return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type ||
- TypeSpecType == TST_decltype_auto);
- }
-
- bool hasTagDefinition() const;
-
- /// \brief 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);
- static const char *getSpecifierName(DeclSpec::TSS S);
- static const char *getSpecifierName(DeclSpec::TSC C);
- static const char *getSpecifierName(DeclSpec::TSW W);
- static const char *getSpecifierName(DeclSpec::SCS S);
- static const char *getSpecifierName(DeclSpec::TSCS S);
-
- // type-qualifiers
-
- /// getTypeQualifiers - Return a set of TQs.
- unsigned getTypeQualifiers() const { return TypeQualifiers; }
- SourceLocation getConstSpecLoc() const { return TQ_constLoc; }
- SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
- SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
- SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; }
-
- /// \brief Clear out all of the type qualifiers.
- void ClearTypeQualifiers() {
- TypeQualifiers = 0;
- TQ_constLoc = SourceLocation();
- TQ_restrictLoc = SourceLocation();
- TQ_volatileLoc = SourceLocation();
- TQ_atomicLoc = SourceLocation();
- }
-
- // function-specifier
- bool isInlineSpecified() const {
- return FS_inline_specified | FS_forceinline_specified;
- }
- SourceLocation getInlineSpecLoc() const {
- return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc;
- }
-
- bool isVirtualSpecified() const { return FS_virtual_specified; }
- SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; }
-
- bool isExplicitSpecified() const { return FS_explicit_specified; }
- SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; }
-
- bool isNoreturnSpecified() const { return FS_noreturn_specified; }
- SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; }
-
- void ClearFunctionSpecs() {
- FS_inline_specified = false;
- FS_inlineLoc = SourceLocation();
- FS_forceinline_specified = false;
- FS_forceinlineLoc = SourceLocation();
- FS_virtual_specified = false;
- FS_virtualLoc = SourceLocation();
- FS_explicit_specified = false;
- FS_explicitLoc = SourceLocation();
- FS_noreturn_specified = false;
- FS_noreturnLoc = SourceLocation();
- }
-
- /// \brief Return true if any type-specifier has been found.
- bool hasTypeSpecifier() const {
- return getTypeSpecType() != DeclSpec::TST_unspecified ||
- getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
- getTypeSpecComplex() != DeclSpec::TSC_unspecified ||
- getTypeSpecSign() != DeclSpec::TSS_unspecified;
- }
-
- /// \brief Return a bitmask of which flavors of specifiers this
- /// DeclSpec includes.
- unsigned getParsedSpecifiers() const;
-
- /// isEmpty - Return true if this declaration specifier is completely empty:
- /// no tokens were parsed in the production of it.
- bool isEmpty() const {
- return getParsedSpecifiers() == DeclSpec::PQ_None;
- }
-
- void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); }
- void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); }
-
- /// These methods set the specified attribute of the DeclSpec and
- /// return false if there was no error. If an error occurs (for
- /// example, if we tried to set "auto" on a spec with "extern"
- /// already set), they return true and set PrevSpec and DiagID
- /// such that
- /// Diag(Loc, DiagID) << PrevSpec;
- /// will yield a useful result.
- ///
- /// TODO: use a more general approach that still allows these
- /// diagnostics to be ignored when desired.
- bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID,
- const PrintingPolicy &Policy);
- bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID);
- bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, const PrintingPolicy &Policy);
- bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, const PrintingPolicy &Policy);
- bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, ParsedType Rep,
- const PrintingPolicy &Policy);
- bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, Decl *Rep, bool Owned,
- const PrintingPolicy &Policy);
- bool SetTypeSpecType(TST T, SourceLocation TagKwLoc,
- SourceLocation TagNameLoc, const char *&PrevSpec,
- unsigned &DiagID, ParsedType Rep,
- const PrintingPolicy &Policy);
- bool SetTypeSpecType(TST T, SourceLocation TagKwLoc,
- SourceLocation TagNameLoc, const char *&PrevSpec,
- unsigned &DiagID, Decl *Rep, bool Owned,
- const PrintingPolicy &Policy);
-
- bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, Expr *Rep,
- const PrintingPolicy &policy);
- bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID,
- const PrintingPolicy &Policy);
- bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID,
- const PrintingPolicy &Policy);
- bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID,
- const PrintingPolicy &Policy);
- bool SetTypeSpecError();
- void UpdateDeclRep(Decl *Rep) {
- assert(isDeclRep((TST) TypeSpecType));
- DeclRep = Rep;
- }
- void UpdateTypeRep(ParsedType Rep) {
- assert(isTypeRep((TST) TypeSpecType));
- TypeRep = Rep;
- }
- void UpdateExprRep(Expr *Rep) {
- assert(isExprRep((TST) TypeSpecType));
- ExprRep = Rep;
- }
-
- bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, const LangOptions &Lang);
-
- bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
-
- bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool SetConceptSpec(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
-
- bool isFriendSpecified() const { return Friend_specified; }
- SourceLocation getFriendSpecLoc() const { return FriendLoc; }
-
- bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); }
- SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; }
-
- bool isConstexprSpecified() const { return Constexpr_specified; }
- SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
-
- bool isConceptSpecified() const { return Concept_specified; }
- SourceLocation getConceptSpecLoc() const { return ConceptLoc; }
-
- void ClearConstexprSpec() {
- Constexpr_specified = false;
- ConstexprLoc = SourceLocation();
- }
-
- void ClearConceptSpec() {
- Concept_specified = false;
- ConceptLoc = SourceLocation();
- }
-
- AttributePool &getAttributePool() const {
- return Attrs.getPool();
- }
-
- /// \brief Concatenates two attribute lists.
- ///
- /// The GCC attribute syntax allows for the following:
- ///
- /// \code
- /// short __attribute__(( unused, deprecated ))
- /// int __attribute__(( may_alias, aligned(16) )) var;
- /// \endcode
- ///
- /// This declares 4 attributes using 2 lists. The following syntax is
- /// also allowed and equivalent to the previous declaration.
- ///
- /// \code
- /// short __attribute__((unused)) __attribute__((deprecated))
- /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
- /// \endcode
- ///
- void addAttributes(AttributeList *AL) {
- Attrs.addAll(AL);
- }
-
- bool hasAttributes() const { return !Attrs.empty(); }
-
- ParsedAttributes &getAttributes() { return Attrs; }
- const ParsedAttributes &getAttributes() const { return Attrs; }
-
- void takeAttributesFrom(ParsedAttributes &attrs) {
- Attrs.takeAllFrom(attrs);
- }
-
- /// Finish - This does final analysis of the declspec, issuing diagnostics for
- /// things like "_Imaginary" (lacking an FP type). After calling this method,
- /// DeclSpec is guaranteed self-consistent, even if an error occurred.
- void Finish(Sema &S, const PrintingPolicy &Policy);
-
- const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
- return writtenBS;
- }
-
- ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; }
- void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; }
-
- /// \brief 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
-/// Objective-C.
-class ObjCDeclSpec {
-public:
- /// ObjCDeclQualifier - Qualifier used on types in method
- /// declarations. Not all combinations are sensible. Parameters
- /// can be one of { in, out, inout } with one of { bycopy, byref }.
- /// Returns can either be { oneway } or not.
- ///
- /// This should be kept in sync with Decl::ObjCDeclQualifier.
- enum ObjCDeclQualifier {
- DQ_None = 0x0,
- DQ_In = 0x1,
- DQ_Inout = 0x2,
- DQ_Out = 0x4,
- DQ_Bycopy = 0x8,
- DQ_Byref = 0x10,
- DQ_Oneway = 0x20,
- DQ_CSNullability = 0x40
- };
-
- /// PropertyAttributeKind - list of property attributes.
- enum ObjCPropertyAttributeKind {
- DQ_PR_noattr = 0x0,
- DQ_PR_readonly = 0x01,
- DQ_PR_getter = 0x02,
- DQ_PR_assign = 0x04,
- DQ_PR_readwrite = 0x08,
- DQ_PR_retain = 0x10,
- DQ_PR_copy = 0x20,
- DQ_PR_nonatomic = 0x40,
- DQ_PR_setter = 0x80,
- DQ_PR_atomic = 0x100,
- DQ_PR_weak = 0x200,
- DQ_PR_strong = 0x400,
- DQ_PR_unsafe_unretained = 0x800,
- DQ_PR_nullability = 0x1000,
- DQ_PR_null_resettable = 0x2000
- };
-
- ObjCDeclSpec()
- : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
- Nullability(0), GetterName(nullptr), SetterName(nullptr) { }
-
- ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
- void setObjCDeclQualifier(ObjCDeclQualifier DQVal) {
- objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal);
- }
- void clearObjCDeclQualifier(ObjCDeclQualifier DQVal) {
- objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier & ~DQVal);
- }
-
- ObjCPropertyAttributeKind getPropertyAttributes() const {
- return ObjCPropertyAttributeKind(PropertyAttributes);
- }
- void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) {
- PropertyAttributes =
- (ObjCPropertyAttributeKind)(PropertyAttributes | PRVal);
- }
-
- NullabilityKind getNullability() const {
- assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
- (getPropertyAttributes() & DQ_PR_nullability)) &&
- "Objective-C declspec doesn't have nullability");
- return static_cast<NullabilityKind>(Nullability);
- }
-
- SourceLocation getNullabilityLoc() const {
- assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
- (getPropertyAttributes() & DQ_PR_nullability)) &&
- "Objective-C declspec doesn't have nullability");
- return NullabilityLoc;
- }
-
- void setNullability(SourceLocation loc, NullabilityKind kind) {
- assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
- (getPropertyAttributes() & DQ_PR_nullability)) &&
- "Set the nullability declspec or property attribute first");
- Nullability = static_cast<unsigned>(kind);
- NullabilityLoc = loc;
- }
-
- const IdentifierInfo *getGetterName() const { return GetterName; }
- IdentifierInfo *getGetterName() { return GetterName; }
- void setGetterName(IdentifierInfo *name) { GetterName = name; }
-
- const IdentifierInfo *getSetterName() const { return SetterName; }
- IdentifierInfo *getSetterName() { return SetterName; }
- void setSetterName(IdentifierInfo *name) { SetterName = name; }
-
-private:
- // FIXME: These two are unrelated and mutually exclusive. So perhaps
- // we can put them in a union to reflect their mutual exclusivity
- // (space saving is negligible).
- ObjCDeclQualifier objcDeclQualifier : 7;
-
- // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
- unsigned PropertyAttributes : 14;
-
- unsigned Nullability : 2;
-
- SourceLocation NullabilityLoc;
-
- IdentifierInfo *GetterName; // getter name or NULL if no getter
- IdentifierInfo *SetterName; // setter name or NULL if no setter
-};
-
-/// \brief 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
- } Kind;
-
- struct OFI {
- /// \brief The kind of overloaded operator.
- OverloadedOperatorKind Operator;
-
- /// \brief The source locations of the individual tokens that name
- /// the operator, e.g., the "new", "[", and "]" tokens in
- /// operator new [].
- ///
- /// Different operators have different numbers of tokens in their name,
- /// up to three. Any remaining source locations in this array will be
- /// set to an invalid value for operators with fewer than three tokens.
- unsigned SymbolLocations[3];
- };
-
- /// \brief Anonymous union that holds extra data associated with the
- /// parsed unqualified-id.
- union {
- /// \brief 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
- /// that we parsed.
- struct OFI OperatorFunctionId;
-
- /// \brief When Kind == IK_ConversionFunctionId, the type that the
- /// conversion function names.
- UnionParsedType ConversionFunctionId;
-
- /// \brief 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
- /// class-name.
- UnionParsedType DestructorName;
-
- /// \brief 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,
- /// 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.
- SourceLocation EndLocation;
-
- UnqualifiedId() : Kind(IK_Identifier), Identifier(nullptr) { }
-
- /// \brief Clear out this unqualified-id, setting it to default (invalid)
- /// state.
- void clear() {
- Kind = IK_Identifier;
- Identifier = nullptr;
- StartLocation = SourceLocation();
- EndLocation = SourceLocation();
- }
-
- /// \brief 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.
- bool isInvalid() const { return !isValid(); }
-
- /// \brief Determine what kind of name we have.
- IdKind getKind() const { return Kind; }
- void setKind(IdKind kind) { Kind = kind; }
-
- /// \brief 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;
- Identifier = const_cast<IdentifierInfo *>(Id);
- StartLocation = EndLocation = IdLoc;
- }
-
- /// \brief Specify that this unqualified-id was parsed as an
- /// operator-function-id.
- ///
- /// \param OperatorLoc the location of the 'operator' keyword.
- ///
- /// \param Op the overloaded operator.
- ///
- /// \param SymbolLocations the locations of the individual operator symbols
- /// in the operator.
- void setOperatorFunctionId(SourceLocation OperatorLoc,
- OverloadedOperatorKind Op,
- SourceLocation SymbolLocations[3]);
-
- /// \brief Specify that this unqualified-id was parsed as a
- /// conversion-function-id.
- ///
- /// \param OperatorLoc the location of the 'operator' keyword.
- ///
- /// \param Ty the type to which this conversion function is converting.
- ///
- /// \param EndLoc the location of the last token that makes up the type name.
- void setConversionFunctionId(SourceLocation OperatorLoc,
- ParsedType Ty,
- SourceLocation EndLoc) {
- Kind = IK_ConversionFunctionId;
- StartLocation = OperatorLoc;
- EndLocation = EndLoc;
- ConversionFunctionId = Ty;
- }
-
- /// \brief Specific that this unqualified-id was parsed as a
- /// literal-operator-id.
- ///
- /// \param Id the parsed identifier.
- ///
- /// \param OpLoc the location of the 'operator' keyword.
- ///
- /// \param IdLoc the location of the identifier.
- void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
- SourceLocation IdLoc) {
- Kind = IK_LiteralOperatorId;
- Identifier = const_cast<IdentifierInfo *>(Id);
- StartLocation = OpLoc;
- EndLocation = IdLoc;
- }
-
- /// \brief Specify that this unqualified-id was parsed as a constructor name.
- ///
- /// \param ClassType the class type referred to by the constructor name.
- ///
- /// \param ClassNameLoc the location of the class name.
- ///
- /// \param EndLoc the location of the last token that makes up the type name.
- void setConstructorName(ParsedType ClassType,
- SourceLocation ClassNameLoc,
- SourceLocation EndLoc) {
- Kind = IK_ConstructorName;
- StartLocation = ClassNameLoc;
- EndLocation = EndLoc;
- ConstructorName = ClassType;
- }
-
- /// \brief 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
- /// template-id. This UnqualifiedId instance will take ownership of the
- /// \p TemplateId and will free it on destruction.
- void setConstructorTemplateId(TemplateIdAnnotation *TemplateId);
-
- /// \brief Specify that this unqualified-id was parsed as a destructor name.
- ///
- /// \param TildeLoc the location of the '~' that introduces the destructor
- /// name.
- ///
- /// \param ClassType the name of the class referred to by the destructor name.
- void setDestructorName(SourceLocation TildeLoc,
- ParsedType ClassType,
- SourceLocation EndLoc) {
- Kind = IK_DestructorName;
- StartLocation = TildeLoc;
- EndLocation = EndLoc;
- DestructorName = ClassType;
- }
-
- /// \brief 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 Return the source range that covers this unqualified-id.
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(StartLocation, EndLocation);
- }
- SourceLocation getLocStart() const LLVM_READONLY { return StartLocation; }
- SourceLocation getLocEnd() const LLVM_READONLY { return EndLocation; }
-};
-
-/// \brief 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
-/// declarator that is parsed.
-///
-/// This is intended to be a small value object.
-struct DeclaratorChunk {
- enum {
- Pointer, Reference, Array, Function, BlockPointer, MemberPointer, Paren
- } Kind;
-
- /// Loc - The place where this type was defined.
- SourceLocation Loc;
- /// EndLoc - If valid, the place where this chunck ends.
- SourceLocation EndLoc;
-
- SourceRange getSourceRange() const {
- if (EndLoc.isInvalid())
- return SourceRange(Loc, Loc);
- return SourceRange(Loc, EndLoc);
- }
-
- struct TypeInfoCommon {
- AttributeList *AttrList;
- };
-
- struct PointerTypeInfo : TypeInfoCommon {
- /// The type qualifiers: const/volatile/restrict/atomic.
- unsigned TypeQuals : 4;
-
- /// The location of the const-qualifier, if any.
- unsigned ConstQualLoc;
-
- /// The location of the volatile-qualifier, if any.
- unsigned VolatileQualLoc;
-
- /// The location of the restrict-qualifier, if any.
- unsigned RestrictQualLoc;
-
- /// The location of the _Atomic-qualifier, if any.
- unsigned AtomicQualLoc;
-
- void destroy() {
- }
- };
-
- struct ReferenceTypeInfo : TypeInfoCommon {
- /// The type qualifier: restrict. [GNU] C++ extension
- bool HasRestrict : 1;
- /// True if this is an lvalue reference, false if it's an rvalue reference.
- bool LValueRef : 1;
- void destroy() {
- }
- };
-
- struct ArrayTypeInfo : TypeInfoCommon {
- /// The type qualifiers for the array: const/volatile/restrict/_Atomic.
- unsigned TypeQuals : 4;
-
- /// True if this dimension included the 'static' keyword.
- bool hasStatic : 1;
-
- /// True if this dimension was [*]. In this case, NumElts is null.
- bool isStar : 1;
-
- /// This is the size of the array, or null if [] or [*] was specified.
- /// Since the parser is multi-purpose, and we don't want to impose a root
- /// expression class on all clients, NumElts is untyped.
- Expr *NumElts;
-
- void destroy() {}
- };
-
- /// ParamInfo - An array of paraminfo objects is allocated whenever a function
- /// declarator is parsed. There are two interesting styles of parameters
- /// here:
- /// K&R-style identifier lists and parameter type lists. K&R-style identifier
- /// lists will have information about the identifier, but no type information.
- /// Parameter type lists will have type info (if the actions module provides
- /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
- struct ParamInfo {
- IdentifierInfo *Ident;
- SourceLocation IdentLoc;
- Decl *Param;
-
- /// DefaultArgTokens - When the parameter's default argument
- /// cannot be parsed immediately (because it occurs within the
- /// declaration of a member function), it will be stored here as a
- /// sequence of tokens to be parsed once the class definition is
- /// complete. Non-NULL indicates that there is a default argument.
- CachedTokens *DefaultArgTokens;
-
- ParamInfo() {}
- ParamInfo(IdentifierInfo *ident, SourceLocation iloc,
- Decl *param,
- CachedTokens *DefArgTokens = nullptr)
- : Ident(ident), IdentLoc(iloc), Param(param),
- DefaultArgTokens(DefArgTokens) {}
- };
-
- struct TypeAndRange {
- ParsedType Ty;
- SourceRange Range;
- };
-
- struct FunctionTypeInfo : TypeInfoCommon {
- /// 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.
- unsigned hasPrototype : 1;
-
- /// isVariadic - If this function has a prototype, and if that
- /// proto ends with ',...)', this is true. When true, EllipsisLoc
- /// contains the location of the ellipsis.
- unsigned isVariadic : 1;
-
- /// Can this declaration be a constructor-style initializer?
- unsigned isAmbiguous : 1;
-
- /// \brief Whether the ref-qualifier (if any) is an lvalue reference.
- /// Otherwise, it's an rvalue reference.
- unsigned RefQualifierIsLValueRef : 1;
-
- /// The type qualifiers: const/volatile/restrict.
- /// The qualifier bitmask values are the same as in QualType.
- unsigned TypeQuals : 3;
-
- /// ExceptionSpecType - An ExceptionSpecificationType value.
- unsigned ExceptionSpecType : 4;
-
- /// DeleteParams - If this is true, we need to delete[] Params.
- unsigned DeleteParams : 1;
-
- /// HasTrailingReturnType - If this is true, a trailing return type was
- /// specified.
- unsigned HasTrailingReturnType : 1;
-
- /// The location of the left parenthesis in the source.
- unsigned LParenLoc;
-
- /// When isVariadic is true, the location of the ellipsis in the source.
- unsigned EllipsisLoc;
-
- /// The location of the right parenthesis in the source.
- unsigned RParenLoc;
-
- /// NumParams - This is the number of formal parameters specified by the
- /// declarator.
- unsigned NumParams;
-
- /// NumExceptions - This is the number of types in the dynamic-exception-
- /// decl, if the function has one.
- unsigned NumExceptions;
-
- /// \brief 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.
- ///
- /// If this is an invalid location, there is no const-qualifier.
- unsigned ConstQualifierLoc;
-
- /// \brief 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.
- ///
- /// 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
- /// any.
- unsigned MutableLoc;
-
- /// \brief The beginning location of the exception specification, if any.
- unsigned ExceptionSpecLocBeg;
-
- /// \brief 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
- /// describe the parameters specified by this function declarator. null if
- /// there are no parameters specified.
- ParamInfo *Params;
-
- union {
- /// \brief 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
- /// function, if it has one.
- Expr *NoexceptExpr;
-
- /// \brief Pointer to the cached tokens for an exception-specification
- /// that has not yet been parsed.
- CachedTokens *ExceptionSpecTokens;
- };
-
- /// \brief If HasTrailingReturnType is true, this is the trailing return
- /// type specified.
- UnionParsedType TrailingReturnType;
-
- /// \brief Reset the parameter list to having zero parameters.
- ///
- /// This is used in various places for error recovery.
- void freeParams() {
- for (unsigned I = 0; I < NumParams; ++I) {
- delete Params[I].DefaultArgTokens;
- Params[I].DefaultArgTokens = nullptr;
- }
- if (DeleteParams) {
- delete[] Params;
- DeleteParams = false;
- }
- NumParams = 0;
- }
-
- void destroy() {
- if (DeleteParams)
- delete[] Params;
- if (getExceptionSpecType() == EST_Dynamic)
- delete[] Exceptions;
- else if (getExceptionSpecType() == EST_Unparsed)
- delete ExceptionSpecTokens;
- }
-
- /// isKNRPrototype - Return true if this is a K&R style identifier list,
- /// like "void foo(a,b,c)". In a function definition, this will be followed
- /// by the parameter type definitions.
- bool isKNRPrototype() const { return !hasPrototype && NumParams != 0; }
-
- SourceLocation getLParenLoc() const {
- return SourceLocation::getFromRawEncoding(LParenLoc);
- }
-
- SourceLocation getEllipsisLoc() const {
- return SourceLocation::getFromRawEncoding(EllipsisLoc);
- }
-
- SourceLocation getRParenLoc() const {
- return SourceLocation::getFromRawEncoding(RParenLoc);
- }
-
- SourceLocation getExceptionSpecLocBeg() const {
- return SourceLocation::getFromRawEncoding(ExceptionSpecLocBeg);
- }
-
- SourceLocation getExceptionSpecLocEnd() const {
- return SourceLocation::getFromRawEncoding(ExceptionSpecLocEnd);
- }
-
- SourceRange getExceptionSpecRange() const {
- return SourceRange(getExceptionSpecLocBeg(), getExceptionSpecLocEnd());
- }
-
- /// \brief 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.
- SourceLocation getConstQualifierLoc() const {
- return SourceLocation::getFromRawEncoding(ConstQualifierLoc);
- }
-
- /// \brief 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.
- SourceLocation getRestrictQualifierLoc() const {
- return SourceLocation::getFromRawEncoding(RestrictQualifierLoc);
- }
-
- /// \brief Retrieve the location of the 'mutable' qualifier, if any.
- SourceLocation getMutableLoc() const {
- return SourceLocation::getFromRawEncoding(MutableLoc);
- }
-
- /// \brief Determine whether this function declaration contains a
- /// ref-qualifier.
- bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); }
-
- /// \brief 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.
- ExceptionSpecificationType getExceptionSpecType() const {
- return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
- }
-
- /// \brief 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.
- ParsedType getTrailingReturnType() const { return TrailingReturnType; }
- };
-
- struct BlockPointerTypeInfo : TypeInfoCommon {
- /// For now, sema will catch these as invalid.
- /// The type qualifiers: const/volatile/restrict/_Atomic.
- unsigned TypeQuals : 4;
-
- void destroy() {
- }
- };
-
- struct MemberPointerTypeInfo : TypeInfoCommon {
- /// The type qualifiers: const/volatile/restrict/_Atomic.
- unsigned TypeQuals : 4;
- // CXXScopeSpec has a constructor, so it can't be a direct member.
- // So we need some pointer-aligned storage and a bit of trickery.
- union {
- void *Aligner;
- char Mem[sizeof(CXXScopeSpec)];
- } ScopeMem;
- CXXScopeSpec &Scope() {
- return *reinterpret_cast<CXXScopeSpec*>(ScopeMem.Mem);
- }
- const CXXScopeSpec &Scope() const {
- return *reinterpret_cast<const CXXScopeSpec*>(ScopeMem.Mem);
- }
- void destroy() {
- Scope().~CXXScopeSpec();
- }
- };
-
- union {
- TypeInfoCommon Common;
- PointerTypeInfo Ptr;
- ReferenceTypeInfo Ref;
- ArrayTypeInfo Arr;
- FunctionTypeInfo Fun;
- BlockPointerTypeInfo Cls;
- MemberPointerTypeInfo Mem;
- };
-
- void destroy() {
- switch (Kind) {
- case DeclaratorChunk::Function: return Fun.destroy();
- case DeclaratorChunk::Pointer: return Ptr.destroy();
- case DeclaratorChunk::BlockPointer: return Cls.destroy();
- case DeclaratorChunk::Reference: return Ref.destroy();
- case DeclaratorChunk::Array: return Arr.destroy();
- case DeclaratorChunk::MemberPointer: return Mem.destroy();
- case DeclaratorChunk::Paren: return;
- }
- }
-
- /// \brief If there are attributes applied to this declaratorchunk, return
- /// them.
- const AttributeList *getAttrs() const {
- return Common.AttrList;
- }
-
- AttributeList *&getAttrListRef() {
- return Common.AttrList;
- }
-
- /// \brief Return a DeclaratorChunk for a pointer.
- static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
- SourceLocation ConstQualLoc,
- SourceLocation VolatileQualLoc,
- SourceLocation RestrictQualLoc,
- SourceLocation AtomicQualLoc) {
- DeclaratorChunk I;
- I.Kind = Pointer;
- I.Loc = Loc;
- I.Ptr.TypeQuals = TypeQuals;
- I.Ptr.ConstQualLoc = ConstQualLoc.getRawEncoding();
- I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding();
- I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding();
- I.Ptr.AtomicQualLoc = AtomicQualLoc.getRawEncoding();
- I.Ptr.AttrList = nullptr;
- return I;
- }
-
- /// \brief Return a DeclaratorChunk for a reference.
- static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
- bool lvalue) {
- DeclaratorChunk I;
- I.Kind = Reference;
- 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.
- static DeclaratorChunk getArray(unsigned TypeQuals,
- bool isStatic, bool isStar, Expr *NumElts,
- SourceLocation LBLoc, SourceLocation RBLoc) {
- DeclaratorChunk I;
- 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;
- I.Arr.NumElts = NumElts;
- return I;
- }
-
- /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
- /// "TheDeclarator" is the declarator that this will be added to.
- static DeclaratorChunk getFunction(bool HasProto,
- bool IsAmbiguous,
- SourceLocation LParenLoc,
- ParamInfo *Params, unsigned NumParams,
- SourceLocation EllipsisLoc,
- SourceLocation RParenLoc,
- unsigned TypeQuals,
- bool RefQualifierIsLvalueRef,
- SourceLocation RefQualifierLoc,
- SourceLocation ConstQualifierLoc,
- SourceLocation VolatileQualifierLoc,
- SourceLocation RestrictQualifierLoc,
- SourceLocation MutableLoc,
- ExceptionSpecificationType ESpecType,
- SourceRange ESpecRange,
- ParsedType *Exceptions,
- SourceRange *ExceptionRanges,
- unsigned NumExceptions,
- Expr *NoexceptExpr,
- CachedTokens *ExceptionSpecTokens,
- SourceLocation LocalRangeBegin,
- SourceLocation LocalRangeEnd,
- Declarator &TheDeclarator,
- TypeResult TrailingReturnType =
- TypeResult());
-
- /// \brief 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;
- }
-
- static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
- unsigned TypeQuals,
- SourceLocation Loc) {
- DeclaratorChunk I;
- I.Kind = MemberPointer;
- I.Loc = SS.getBeginLoc();
- I.EndLoc = Loc;
- I.Mem.TypeQuals = TypeQuals;
- I.Mem.AttrList = nullptr;
- new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
- return I;
- }
-
- /// \brief 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;
- }
-
- bool isParen() const {
- return Kind == Paren;
- }
-};
-
-/// \brief Described the kind of function definition (if any) provided for
-/// a function.
-enum FunctionDefinitionKind {
- FDK_Declaration,
- FDK_Definition,
- FDK_Defaulted,
- 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 {
- FileContext, // File scope declaration.
- PrototypeContext, // Within a function prototype.
- ObjCResultContext, // An ObjC method result type.
- ObjCParameterContext,// An ObjC method parameter type.
- KNRTypeListContext, // K&R type definition list for formals.
- TypeNameContext, // Abstract declarator for types.
- MemberContext, // Struct/Union field.
- BlockContext, // Declaration within a block in a function.
- ForContext, // Declaration within first part of a for loop.
- ConditionContext, // Condition declaration in a C++ if/switch/while/for.
- TemplateParamContext,// Within a template parameter list.
- CXXNewContext, // C++ new-expression.
- CXXCatchContext, // C++ catch exception-declaration
- ObjCCatchContext, // Objective-C catch exception-declaration
- BlockLiteralContext, // Block literal declarator.
- LambdaExprContext, // Lambda-expression declarator.
- LambdaExprParameterContext, // Lambda-expression parameter declarator.
- ConversionIdContext, // C++ conversion-type-id.
- TrailingReturnContext, // C++11 trailing-type-specifier.
- TemplateTypeArgContext, // Template type argument.
- AliasDeclContext, // C++11 alias-declaration.
- AliasTemplateContext // C++11 alias-declaration template.
- };
-
-private:
- const DeclSpec &DS;
- CXXScopeSpec SS;
- UnqualifiedId Name;
- SourceRange Range;
-
- /// \brief Where we are parsing this declarator.
- TheContext Context;
-
- /// DeclTypeInfo - This holds each type that the declarator includes as it is
- /// parsed. This is pushed from the identifier out, which means that element
- /// #0 will be the most closely bound to the identifier, and
- /// DeclTypeInfo.back() will be the least closely bound.
- SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
-
- /// InvalidType - Set by Sema::GetTypeForDeclarator().
- bool InvalidType : 1;
-
- /// GroupingParens - Set by Parser::ParseParenDeclarator().
- bool GroupingParens : 1;
-
- /// FunctionDefinition - Is this Declarator for a function or member
- /// definition and, if so, what kind?
- ///
- /// Actually a FunctionDefinitionKind.
- unsigned FunctionDefinition : 2;
-
- /// \brief Is this Declarator a redeclaration?
- bool Redeclaration : 1;
-
- /// Attrs - Attributes.
- ParsedAttributes Attrs;
-
- /// \brief The asm label, if specified.
- Expr *AsmLabel;
-
- /// InlineParams - This is a local array used for the first function decl
- /// chunk to avoid going to the heap for the common case when we have one
- /// function chunk in the declarator.
- DeclaratorChunk::ParamInfo InlineParams[16];
- bool InlineParamsUsed;
-
- /// \brief true if the declaration is preceded by \c __extension__.
- unsigned Extension : 1;
-
- /// Indicates whether this is an Objective-C instance variable.
- unsigned ObjCIvar : 1;
-
- /// Indicates whether this is an Objective-C 'weak' property.
- unsigned ObjCWeakProperty : 1;
-
- /// \brief 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
- /// this declarator as a parameter pack.
- SourceLocation EllipsisLoc;
-
- friend struct DeclaratorChunk;
-
-public:
- Declarator(const DeclSpec &ds, TheContext C)
- : DS(ds), Range(ds.getSourceRange()), Context(C),
- InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
- GroupingParens(false), FunctionDefinition(FDK_Declaration),
- Redeclaration(false),
- Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
- InlineParamsUsed(false), Extension(false), ObjCIvar(false),
- ObjCWeakProperty(false) {
- }
-
- ~Declarator() {
- clear();
- }
- /// getDeclSpec - Return the declaration-specifier that this declarator was
- /// declared with.
- const DeclSpec &getDeclSpec() const { return DS; }
-
- /// getMutableDeclSpec - Return a non-const version of the DeclSpec. This
- /// should be used with extreme care: declspecs can often be shared between
- /// multiple declarators, so mutating the DeclSpec affects all of the
- /// Declarators. This should only be done when the declspec is known to not
- /// be shared or when in error recovery etc.
- DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); }
-
- AttributePool &getAttributePool() const {
- return Attrs.getPool();
- }
-
- /// getCXXScopeSpec - Return the C++ scope specifier (global scope or
- /// nested-name-specifier) that is part of the declarator-id.
- const CXXScopeSpec &getCXXScopeSpec() const { return SS; }
- CXXScopeSpec &getCXXScopeSpec() { return SS; }
-
- /// \brief Retrieve the name specified by this declarator.
- UnqualifiedId &getName() { return Name; }
-
- TheContext getContext() const { return Context; }
-
- bool isPrototypeContext() const {
- return (Context == PrototypeContext ||
- Context == ObjCParameterContext ||
- Context == ObjCResultContext ||
- Context == LambdaExprParameterContext);
- }
-
- /// \brief 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(); }
-
- void SetSourceRange(SourceRange R) { Range = R; }
- /// SetRangeBegin - Set the start of the source range to Loc, unless it's
- /// invalid.
- void SetRangeBegin(SourceLocation Loc) {
- if (!Loc.isInvalid())
- Range.setBegin(Loc);
- }
- /// SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
- void SetRangeEnd(SourceLocation Loc) {
- if (!Loc.isInvalid())
- Range.setEnd(Loc);
- }
- /// ExtendWithDeclSpec - Extend the declarator source range to include the
- /// given declspec, unless its location is invalid. Adopts the range start if
- /// the current range start is invalid.
- void ExtendWithDeclSpec(const DeclSpec &DS) {
- SourceRange SR = DS.getSourceRange();
- if (Range.getBegin().isInvalid())
- Range.setBegin(SR.getBegin());
- if (!SR.getEnd().isInvalid())
- Range.setEnd(SR.getEnd());
- }
-
- /// \brief Reset the contents of this Declarator.
- void clear() {
- SS.clear();
- Name.clear();
- Range = DS.getSourceRange();
-
- for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
- DeclTypeInfo[i].destroy();
- DeclTypeInfo.clear();
- Attrs.clear();
- AsmLabel = nullptr;
- InlineParamsUsed = false;
- ObjCIvar = false;
- ObjCWeakProperty = false;
- CommaLoc = SourceLocation();
- EllipsisLoc = SourceLocation();
- }
-
- /// mayOmitIdentifier - Return true if the identifier is either optional or
- /// not allowed. This is true for typenames, prototypes, and template
- /// parameter lists.
- bool mayOmitIdentifier() const {
- switch (Context) {
- case FileContext:
- case KNRTypeListContext:
- case MemberContext:
- case BlockContext:
- case ForContext:
- case ConditionContext:
- return false;
-
- case TypeNameContext:
- 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:
- return true;
- }
- llvm_unreachable("unknown context kind!");
- }
-
- /// mayHaveIdentifier - Return true if the identifier is either optional or
- /// required. This is true for normal declarators and prototypes, but not
- /// typenames.
- bool mayHaveIdentifier() const {
- switch (Context) {
- case FileContext:
- case KNRTypeListContext:
- case MemberContext:
- case BlockContext:
- case ForContext:
- case ConditionContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case TemplateParamContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- return true;
-
- case TypeNameContext:
- case CXXNewContext:
- case AliasDeclContext:
- case AliasTemplateContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case BlockLiteralContext:
- case LambdaExprContext:
- case ConversionIdContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
- return false;
- }
- llvm_unreachable("unknown context kind!");
- }
-
- /// diagnoseIdentifier - Return true if the identifier is prohibited and
- /// should be diagnosed (because it cannot be anything else).
- bool diagnoseIdentifier() const {
- switch (Context) {
- case FileContext:
- case KNRTypeListContext:
- case MemberContext:
- case BlockContext:
- case ForContext:
- case ConditionContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case TemplateParamContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- case TypeNameContext:
- case ConversionIdContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case BlockLiteralContext:
- case CXXNewContext:
- case LambdaExprContext:
- return false;
-
- case AliasDeclContext:
- case AliasTemplateContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
- return true;
- }
- llvm_unreachable("unknown context kind!");
- }
-
- /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be
- /// followed by a C++ direct initializer, e.g. "int x(1);".
- bool mayBeFollowedByCXXDirectInit() const {
- if (hasGroupingParens()) return false;
-
- if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
- return false;
-
- if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern &&
- Context != FileContext)
- return false;
-
- // Special names can't have direct initializers.
- if (Name.getKind() != UnqualifiedId::IK_Identifier)
- return false;
-
- switch (Context) {
- case FileContext:
- case BlockContext:
- case ForContext:
- return true;
-
- case 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 CXXNewContext:
- case AliasDeclContext:
- case AliasTemplateContext:
- case BlockLiteralContext:
- case LambdaExprContext:
- case ConversionIdContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
- return false;
- }
- llvm_unreachable("unknown context kind!");
- }
-
- /// isPastIdentifier - Return true if we have parsed beyond the point where
- /// the
- bool isPastIdentifier() const { return Name.isValid(); }
-
- /// hasName - Whether this declarator has a name, which might be an
- /// identifier (accessible via getIdentifier()) or some kind of
- /// special C++ name (constructor, destructor, etc.).
- bool hasName() const {
- return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier;
- }
-
- IdentifierInfo *getIdentifier() const {
- if (Name.getKind() == UnqualifiedId::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.
- void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) {
- Name.setIdentifier(Id, IdLoc);
- }
-
- /// 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,
- SourceLocation EndLoc) {
- DeclTypeInfo.push_back(TI);
- DeclTypeInfo.back().getAttrListRef() = attrs.getList();
- getAttributePool().takeAllFrom(attrs.getPool());
-
- if (!EndLoc.isInvalid())
- SetRangeEnd(EndLoc);
- }
-
- /// \brief 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.
- unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); }
-
- /// Return the specified TypeInfo from this declarator. TypeInfo #0 is
- /// closest to the identifier.
- const DeclaratorChunk &getTypeObject(unsigned i) const {
- assert(i < DeclTypeInfo.size() && "Invalid type chunk");
- return DeclTypeInfo[i];
- }
- DeclaratorChunk &getTypeObject(unsigned i) {
- assert(i < DeclTypeInfo.size() && "Invalid type chunk");
- return DeclTypeInfo[i];
- }
-
- typedef SmallVectorImpl<DeclaratorChunk>::const_iterator type_object_iterator;
- typedef llvm::iterator_range<type_object_iterator> type_object_range;
-
- /// Returns the range of type objects, from the identifier outwards.
- type_object_range type_objects() const {
- return type_object_range(DeclTypeInfo.begin(), DeclTypeInfo.end());
- }
-
- void DropFirstTypeObject() {
- assert(!DeclTypeInfo.empty() && "No type chunks to drop.");
- DeclTypeInfo.front().destroy();
- DeclTypeInfo.erase(DeclTypeInfo.begin());
- }
-
- /// Return the innermost (closest to the declarator) chunk of this
- /// declarator that is not a parens chunk, or null if there are no
- /// non-parens chunks.
- const DeclaratorChunk *getInnermostNonParenChunk() const {
- for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
- if (!DeclTypeInfo[i].isParen())
- return &DeclTypeInfo[i];
- }
- return nullptr;
- }
-
- /// Return the outermost (furthest from the declarator) chunk of
- /// this declarator that is not a parens chunk, or null if there are
- /// no non-parens chunks.
- const DeclaratorChunk *getOutermostNonParenChunk() const {
- for (unsigned i = DeclTypeInfo.size(), i_end = 0; i != i_end; --i) {
- if (!DeclTypeInfo[i-1].isParen())
- return &DeclTypeInfo[i-1];
- }
- return nullptr;
- }
-
- /// isArrayOfUnknownBound - This method returns true if the declarator
- /// is a declarator for an array of unknown bound (looking through
- /// parentheses).
- bool isArrayOfUnknownBound() const {
- const DeclaratorChunk *chunk = getInnermostNonParenChunk();
- return (chunk && chunk->Kind == DeclaratorChunk::Array &&
- !chunk->Arr.NumElts);
- }
-
- /// isFunctionDeclarator - This method returns true if the declarator
- /// is a function declarator (looking through parentheses).
- /// If true is returned, then the reference type parameter idx is
- /// assigned with the index of the declaration chunk.
- bool isFunctionDeclarator(unsigned& idx) const {
- for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
- switch (DeclTypeInfo[i].Kind) {
- case DeclaratorChunk::Function:
- idx = i;
- return true;
- case DeclaratorChunk::Paren:
- continue;
- case DeclaratorChunk::Pointer:
- case DeclaratorChunk::Reference:
- case DeclaratorChunk::Array:
- case DeclaratorChunk::BlockPointer:
- case DeclaratorChunk::MemberPointer:
- return false;
- }
- llvm_unreachable("Invalid type chunk");
- }
- return false;
- }
-
- /// isFunctionDeclarator - Once this declarator is fully parsed and formed,
- /// this method returns true if the identifier is a function declarator
- /// (looking through parentheses).
- bool isFunctionDeclarator() const {
- unsigned index;
- return isFunctionDeclarator(index);
- }
-
- /// getFunctionTypeInfo - Retrieves the function type info object
- /// (looking through parentheses).
- DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() {
- assert(isFunctionDeclarator() && "Not a function declarator!");
- unsigned index = 0;
- isFunctionDeclarator(index);
- return DeclTypeInfo[index].Fun;
- }
-
- /// getFunctionTypeInfo - Retrieves the function type info object
- /// (looking through parentheses).
- const DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() const {
- return const_cast<Declarator*>(this)->getFunctionTypeInfo();
- }
-
- /// \brief 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
- /// isn't a function declarator, if the type specifier refers to a function
- /// type. This routine checks for both cases.
- bool isDeclarationOfFunction() const;
-
- /// \brief 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:
- return true;
-
- case ForContext:
- case ConditionContext:
- case KNRTypeListContext:
- case TypeNameContext:
- 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:
- return false;
- }
- llvm_unreachable("unknown context kind!");
- }
-
- /// \brief Return true if a function declarator at this position would be a
- /// function declaration.
- bool isFunctionDeclaratorAFunctionDeclaration() const {
- if (!isFunctionDeclarationContext())
- return false;
-
- for (unsigned I = 0, N = getNumTypeObjects(); I != N; ++I)
- if (getTypeObject(I).Kind != DeclaratorChunk::Paren)
- return false;
-
- return true;
- }
-
- /// takeAttributes - Takes attributes from the given parsed-attributes
- /// set and add them to this declarator.
- ///
- /// These examples both add 3 attributes to "var":
- /// short int var __attribute__((aligned(16),common,deprecated));
- /// short int x, __attribute__((aligned(16)) var
- /// __attribute__((common,deprecated));
- ///
- /// Also extends the range of the declarator.
- void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) {
- Attrs.takeAllFrom(attrs);
-
- if (!lastLoc.isInvalid())
- SetRangeEnd(lastLoc);
- }
-
- const AttributeList *getAttributes() const { return Attrs.getList(); }
- AttributeList *getAttributes() { return Attrs.getList(); }
-
- AttributeList *&getAttrListRef() { return Attrs.getListRef(); }
-
- /// hasAttributes - do we contain any attributes?
- bool hasAttributes() const {
- if (getAttributes() || getDeclSpec().hasAttributes()) return true;
- for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
- if (getTypeObject(i).getAttrs())
- return true;
- return false;
- }
-
- /// \brief 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();
- }
- }
-
- void setAsmLabel(Expr *E) { AsmLabel = E; }
- Expr *getAsmLabel() const { return AsmLabel; }
-
- void setExtension(bool Val = true) { Extension = Val; }
- bool getExtension() const { return Extension; }
-
- void setObjCIvar(bool Val = true) { ObjCIvar = Val; }
- bool isObjCIvar() const { return ObjCIvar; }
-
- void setObjCWeakProperty(bool Val = true) { ObjCWeakProperty = Val; }
- bool isObjCWeakProperty() const { return ObjCWeakProperty; }
-
- void setInvalidType(bool Val = true) { InvalidType = Val; }
- bool isInvalidType() const {
- return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error;
- }
-
- void setGroupingParens(bool flag) { GroupingParens = flag; }
- bool hasGroupingParens() const { return GroupingParens; }
-
- bool isFirstDeclarator() const { return !CommaLoc.isValid(); }
- SourceLocation getCommaLoc() const { return CommaLoc; }
- void setCommaLoc(SourceLocation CL) { CommaLoc = CL; }
-
- bool hasEllipsis() const { return EllipsisLoc.isValid(); }
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; }
-
- void setFunctionDefinitionKind(FunctionDefinitionKind Val) {
- FunctionDefinition = Val;
- }
-
- bool isFunctionDefinition() const {
- return getFunctionDefinitionKind() != FDK_Declaration;
- }
-
- FunctionDefinitionKind getFunctionDefinitionKind() const {
- return (FunctionDefinitionKind)FunctionDefinition;
- }
-
- /// Returns true if this declares a real member and not a friend.
- bool isFirstDeclarationOfMember() {
- return getContext() == MemberContext && !getDeclSpec().isFriendSpecified();
- }
-
- /// Returns true if this declares a static member. This cannot be called on a
- /// declarator outside of a MemberContext because we won't know until
- /// redeclaration time if the decl is static.
- bool isStaticMember();
-
- /// Returns true if this declares a constructor or a destructor.
- bool isCtorOrDtor();
-
- void setRedeclaration(bool Val) { Redeclaration = Val; }
- bool isRedeclaration() const { return Redeclaration; }
-};
-
-/// \brief 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) { }
-};
-
-/// \brief Represents a C++11 virt-specifier-seq.
-class VirtSpecifiers {
-public:
- enum Specifier {
- VS_None = 0,
- VS_Override = 1,
- VS_Final = 2,
- VS_Sealed = 4
- };
-
- VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { }
-
- bool SetSpecifier(Specifier VS, SourceLocation Loc,
- const char *&PrevSpec);
-
- bool isUnset() const { return Specifiers == 0; }
-
- bool isOverrideSpecified() const { return Specifiers & VS_Override; }
- SourceLocation getOverrideLoc() const { return VS_overrideLoc; }
-
- bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed); }
- bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; }
- SourceLocation getFinalLoc() const { return VS_finalLoc; }
-
- void clear() { Specifiers = 0; }
-
- static const char *getSpecifierName(Specifier VS);
-
- SourceLocation getFirstLocation() const { return FirstLocation; }
- SourceLocation getLastLocation() const { return LastLocation; }
- Specifier getLastSpecifier() const { return LastSpecifier; }
-
-private:
- unsigned Specifiers;
- Specifier LastSpecifier;
-
- SourceLocation VS_overrideLoc, VS_finalLoc;
- SourceLocation FirstLocation;
- SourceLocation LastLocation;
-};
-
-enum class LambdaCaptureInitKind {
- NoInit, //!< [a]
- CopyInit, //!< [a = b], [a = {b}]
- DirectInit, //!< [a(b)]
- ListInit //!< [a{b}]
-};
-
-/// \brief Represents a complete lambda introducer.
-struct LambdaIntroducer {
- /// \brief An individual capture in a lambda introducer.
- struct LambdaCapture {
- LambdaCaptureKind Kind;
- SourceLocation Loc;
- IdentifierInfo *Id;
- SourceLocation EllipsisLoc;
- LambdaCaptureInitKind InitKind;
- ExprResult Init;
- ParsedType InitCaptureType;
- LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
- IdentifierInfo *Id, SourceLocation EllipsisLoc,
- LambdaCaptureInitKind InitKind, ExprResult Init,
- ParsedType InitCaptureType)
- : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc),
- InitKind(InitKind), Init(Init), InitCaptureType(InitCaptureType) {}
- };
-
- SourceRange Range;
- SourceLocation DefaultLoc;
- LambdaCaptureDefault Default;
- SmallVector<LambdaCapture, 4> Captures;
-
- LambdaIntroducer()
- : Default(LCD_None) {}
-
- /// \brief Append a capture in a lambda introducer.
- void addCapture(LambdaCaptureKind Kind,
- SourceLocation Loc,
- IdentifierInfo* Id,
- SourceLocation EllipsisLoc,
- LambdaCaptureInitKind InitKind,
- ExprResult Init,
- ParsedType InitCaptureType) {
- Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init,
- InitCaptureType));
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
deleted file mode 100644
index 155b3aa..0000000
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ /dev/null
@@ -1,305 +0,0 @@
-//===--- DelayedDiagnostic.h - Delayed declarator diagnostics ---*- 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 classes clang::DelayedDiagnostic and
-/// clang::AccessedEntity.
-///
-/// DelayedDiangostic is used to record diagnostics that are being
-/// conditionally produced during declarator parsing. Certain kinds of
-/// 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/Sema/Sema.h"
-
-namespace clang {
-namespace sema {
-
-/// A declaration being accessed, together with information about how
-/// it was accessed.
-class AccessedEntity {
-public:
- /// A member declaration found through lookup. The target is the
- /// member.
- enum MemberNonce { Member };
-
- /// A hierarchy (base-to-derived or derived-to-base) conversion.
- /// 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) {
- }
-
- AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
- BaseNonce _,
- CXXRecordDecl *BaseClass,
- CXXRecordDecl *DerivedClass,
- AccessSpecifier Access)
- : Access(Access), IsMember(false),
- Target(BaseClass),
- NamingClass(DerivedClass),
- Diag(0, Allocator) {
- }
-
- bool isQuiet() const { return Diag.getDiagID() == 0; }
-
- AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
-
- // These apply to member decls...
- NamedDecl *getTargetDecl() const { return Target; }
- CXXRecordDecl *getNamingClass() const { return NamingClass; }
-
- // ...and these apply to hierarchy conversions.
- CXXRecordDecl *getBaseClass() const {
- assert(!IsMember); return cast<CXXRecordDecl>(Target);
- }
- CXXRecordDecl *getDerivedClass() const { return NamingClass; }
-
- /// Retrieves the base object type, important when accessing
- /// an instance member.
- QualType getBaseObjectType() const { return BaseObjectType; }
-
- /// Sets a diagnostic to be performed. The diagnostic is given
- /// four (additional) arguments:
- /// %0 - 0 if the entity was private, 1 if protected
- /// %1 - the DeclarationName of the entity
- /// %2 - the TypeDecl type of the naming class
- /// %3 - the TypeDecl type of the declaring class
- void setDiag(const PartialDiagnostic &PDiag) {
- assert(isQuiet() && "partial diagnostic already defined");
- Diag = PDiag;
- }
- PartialDiagnostic &setDiag(unsigned DiagID) {
- assert(isQuiet() && "partial diagnostic already defined");
- assert(DiagID && "creating null diagnostic");
- Diag.Reset(DiagID);
- return Diag;
- }
- const PartialDiagnostic &getDiag() const {
- return Diag;
- }
-
-private:
- unsigned Access : 2;
- unsigned IsMember : 1;
- NamedDecl *Target;
- CXXRecordDecl *NamingClass;
- QualType BaseObjectType;
- PartialDiagnostic Diag;
-};
-
-/// A diagnostic message which has been conditionally emitted pending
-/// the complete parsing of the current declaration.
-class DelayedDiagnostic {
-public:
- enum DDKind { Deprecation, Unavailable, Access, ForbiddenType };
-
- unsigned char Kind; // actually a DDKind
- bool Triggered;
-
- SourceLocation Loc;
-
- void Destroy();
-
- static DelayedDiagnostic makeAvailability(Sema::AvailabilityDiagnostic AD,
- SourceLocation Loc,
- const NamedDecl *D,
- const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
- StringRef Msg,
- bool ObjCPropertyAccess);
-
-
- static DelayedDiagnostic makeAccess(SourceLocation Loc,
- const AccessedEntity &Entity) {
- DelayedDiagnostic DD;
- DD.Kind = Access;
- DD.Triggered = false;
- DD.Loc = Loc;
- new (&DD.getAccessData()) AccessedEntity(Entity);
- return DD;
- }
-
- static DelayedDiagnostic makeForbiddenType(SourceLocation loc,
- unsigned diagnostic,
- QualType type,
- unsigned argument) {
- DelayedDiagnostic DD;
- DD.Kind = ForbiddenType;
- DD.Triggered = false;
- DD.Loc = loc;
- DD.ForbiddenTypeData.Diagnostic = diagnostic;
- DD.ForbiddenTypeData.OperandType = type.getAsOpaquePtr();
- DD.ForbiddenTypeData.Argument = argument;
- return DD;
- }
-
- AccessedEntity &getAccessData() {
- assert(Kind == Access && "Not an access diagnostic.");
- return *reinterpret_cast<AccessedEntity*>(AccessData);
- }
- const AccessedEntity &getAccessData() const {
- assert(Kind == Access && "Not an access diagnostic.");
- return *reinterpret_cast<const AccessedEntity*>(AccessData);
- }
-
- const NamedDecl *getDeprecationDecl() const {
- assert((Kind == Deprecation || Kind == Unavailable) &&
- "Not a deprecation diagnostic.");
- return DeprecationData.Decl;
- }
-
- StringRef getDeprecationMessage() const {
- assert((Kind == Deprecation || Kind == Unavailable) &&
- "Not a deprecation diagnostic.");
- return StringRef(DeprecationData.Message,
- DeprecationData.MessageLen);
- }
-
- /// The diagnostic ID to emit. Used like so:
- /// Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
- /// << diag.getForbiddenTypeOperand()
- /// << diag.getForbiddenTypeArgument();
- unsigned getForbiddenTypeDiagnostic() const {
- assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
- return ForbiddenTypeData.Diagnostic;
- }
-
- unsigned getForbiddenTypeArgument() const {
- assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
- return ForbiddenTypeData.Argument;
- }
-
- QualType getForbiddenTypeOperand() const {
- assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
- return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType);
- }
-
- const ObjCInterfaceDecl *getUnknownObjCClass() const {
- return DeprecationData.UnknownObjCClass;
- }
-
- const ObjCPropertyDecl *getObjCProperty() const {
- return DeprecationData.ObjCProperty;
- }
-
- bool getObjCPropertyAccess() const {
- return DeprecationData.ObjCPropertyAccess;
- }
-
-private:
-
- struct DD {
- const NamedDecl *Decl;
- const ObjCInterfaceDecl *UnknownObjCClass;
- const ObjCPropertyDecl *ObjCProperty;
- const char *Message;
- size_t MessageLen;
- bool ObjCPropertyAccess;
- };
-
- struct FTD {
- unsigned Diagnostic;
- unsigned Argument;
- void *OperandType;
- };
-
- union {
- /// Deprecation
- struct DD DeprecationData;
- struct FTD ForbiddenTypeData;
-
- /// Access control.
- char AccessData[sizeof(AccessedEntity)];
- };
-};
-
-/// \brief 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(DelayedDiagnosticPool &&Other)
- : Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) {
- Other.Diagnostics.clear();
- }
- DelayedDiagnosticPool &operator=(DelayedDiagnosticPool &&Other) {
- Parent = Other.Parent;
- Diagnostics = std::move(Other.Diagnostics);
- Other.Diagnostics.clear();
- return *this;
- }
-
- const DelayedDiagnosticPool *getParent() const { return Parent; }
-
- /// Does this pool, or any of its ancestors, contain any diagnostics?
- bool empty() const {
- return (Diagnostics.empty() && (!Parent || Parent->empty()));
- }
-
- /// Add a diagnostic to this pool.
- void add(const DelayedDiagnostic &diag) {
- Diagnostics.push_back(diag);
- }
-
- /// Steal the diagnostics from the given pool.
- void steal(DelayedDiagnosticPool &pool) {
- if (pool.Diagnostics.empty()) return;
-
- if (Diagnostics.empty()) {
- Diagnostics = std::move(pool.Diagnostics);
- } else {
- Diagnostics.append(pool.pool_begin(), pool.pool_end());
- }
- pool.Diagnostics.clear();
- }
-
- typedef SmallVectorImpl<DelayedDiagnostic>::const_iterator pool_iterator;
- pool_iterator pool_begin() const { return Diagnostics.begin(); }
- pool_iterator pool_end() const { return Diagnostics.end(); }
- bool pool_empty() const { return Diagnostics.empty(); }
-};
-
-}
-
-/// Add a diagnostic to the current delay pool.
-inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
- assert(shouldDelayDiagnostics() && "trying to delay without pool");
- CurPool->add(diag);
-}
-
-
-}
-
-#endif
diff --git a/include/clang/Sema/Designator.h b/include/clang/Sema/Designator.h
deleted file mode 100644
index 55603fe..0000000
--- a/include/clang/Sema/Designator.h
+++ /dev/null
@@ -1,210 +0,0 @@
-//===--- Designator.h - Initialization Designator ---------------*- 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 interfaces used to represent designators (a la
-// C99 designated initializers) during parsing.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
-#define LLVM_CLANG_SEMA_DESIGNATOR_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-class Expr;
-class IdentifierInfo;
-class Sema;
-
-/// Designator - A designator in a C99 designated initializer.
-///
-/// This class is a discriminated union which holds the various
-/// different sorts of designators possible. A Designation is an array of
-/// these. An example of a designator are things like this:
-/// [8] .field [47] // C99 designation: 3 designators
-/// [8 ... 47] field: // GNU extensions: 2 designators
-/// These occur in initializers, e.g.:
-/// int a[10] = {2, 4, [8]=9, 10};
-///
-class Designator {
-public:
- enum DesignatorKind {
- FieldDesignator, ArrayDesignator, ArrayRangeDesignator
- };
-private:
- DesignatorKind Kind;
-
- struct FieldDesignatorInfo {
- const IdentifierInfo *II;
- unsigned DotLoc;
- unsigned NameLoc;
- };
- struct ArrayDesignatorInfo {
- Expr *Index;
- unsigned LBracketLoc;
- mutable unsigned RBracketLoc;
- };
- struct ArrayRangeDesignatorInfo {
- Expr *Start, *End;
- unsigned LBracketLoc, EllipsisLoc;
- mutable unsigned RBracketLoc;
- };
-
- union {
- FieldDesignatorInfo FieldInfo;
- ArrayDesignatorInfo ArrayInfo;
- ArrayRangeDesignatorInfo ArrayRangeInfo;
- };
-
-public:
-
- DesignatorKind getKind() const { return Kind; }
- bool isFieldDesignator() const { return Kind == FieldDesignator; }
- bool isArrayDesignator() const { return Kind == ArrayDesignator; }
- bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
-
- const IdentifierInfo *getField() const {
- assert(isFieldDesignator() && "Invalid accessor");
- return FieldInfo.II;
- }
-
- SourceLocation getDotLoc() const {
- assert(isFieldDesignator() && "Invalid accessor");
- return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
- }
-
- SourceLocation getFieldLoc() const {
- assert(isFieldDesignator() && "Invalid accessor");
- return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
- }
-
- Expr *getArrayIndex() const {
- assert(isArrayDesignator() && "Invalid accessor");
- return ArrayInfo.Index;
- }
-
- Expr *getArrayRangeStart() const {
- assert(isArrayRangeDesignator() && "Invalid accessor");
- return ArrayRangeInfo.Start;
- }
- Expr *getArrayRangeEnd() const {
- assert(isArrayRangeDesignator() && "Invalid accessor");
- return ArrayRangeInfo.End;
- }
-
- SourceLocation getLBracketLoc() const {
- assert((isArrayDesignator() || isArrayRangeDesignator()) &&
- "Invalid accessor");
- if (isArrayDesignator())
- return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
- else
- return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
- }
-
- SourceLocation getRBracketLoc() const {
- assert((isArrayDesignator() || isArrayRangeDesignator()) &&
- "Invalid accessor");
- if (isArrayDesignator())
- return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
- else
- return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
- }
-
- SourceLocation getEllipsisLoc() const {
- assert(isArrayRangeDesignator() && "Invalid accessor");
- return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
- }
-
- static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
- SourceLocation NameLoc) {
- Designator D;
- D.Kind = FieldDesignator;
- D.FieldInfo.II = II;
- D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
- D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
- return D;
- }
-
- static Designator getArray(Expr *Index,
- SourceLocation LBracketLoc) {
- Designator D;
- D.Kind = ArrayDesignator;
- D.ArrayInfo.Index = Index;
- D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
- D.ArrayInfo.RBracketLoc = 0;
- return D;
- }
-
- static Designator getArrayRange(Expr *Start,
- Expr *End,
- SourceLocation LBracketLoc,
- SourceLocation EllipsisLoc) {
- Designator D;
- D.Kind = ArrayRangeDesignator;
- D.ArrayRangeInfo.Start = Start;
- D.ArrayRangeInfo.End = End;
- D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
- D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
- D.ArrayRangeInfo.RBracketLoc = 0;
- return D;
- }
-
- void setRBracketLoc(SourceLocation RBracketLoc) const {
- assert((isArrayDesignator() || isArrayRangeDesignator()) &&
- "Invalid accessor");
- if (isArrayDesignator())
- ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
- else
- ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
- }
-
- /// ClearExprs - Null out any expression references, which prevents
- /// them from being 'delete'd later.
- void ClearExprs(Sema &Actions) {}
-
- /// FreeExprs - Release any unclaimed memory for the expressions in
- /// this designator.
- void FreeExprs(Sema &Actions) {}
-};
-
-
-/// Designation - Represent a full designation, which is a sequence of
-/// designators. This class is mostly a helper for InitListDesignations.
-class Designation {
- /// Designators - The actual designators for this initializer.
- SmallVector<Designator, 2> Designators;
-
-public:
- /// AddDesignator - Add a designator to the end of this list.
- void AddDesignator(Designator D) {
- Designators.push_back(D);
- }
-
- bool empty() const { return Designators.empty(); }
-
- unsigned getNumDesignators() const { return Designators.size(); }
- const Designator &getDesignator(unsigned Idx) const {
- assert(Idx < Designators.size());
- return Designators[Idx];
- }
-
- /// ClearExprs - Null out any expression references, which prevents them from
- /// being 'delete'd later.
- void ClearExprs(Sema &Actions) {}
-
- /// FreeExprs - Release any unclaimed memory for the expressions in this
- /// designation.
- void FreeExprs(Sema &Actions) {}
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
deleted file mode 100644
index 97f78f4..0000000
--- a/include/clang/Sema/ExternalSemaSource.h
+++ /dev/null
@@ -1,229 +0,0 @@
-//===--- ExternalSemaSource.h - External Sema Interface ---------*- 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 ExternalSemaSource interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_EXTERNALSEMASOURCE_H
-#define LLVM_CLANG_SEMA_EXTERNALSEMASOURCE_H
-
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/Type.h"
-#include "clang/Sema/TypoCorrection.h"
-#include "clang/Sema/Weak.h"
-#include "llvm/ADT/MapVector.h"
-#include <utility>
-
-namespace llvm {
-template <class T, unsigned n> class SmallSetVector;
-}
-
-namespace clang {
-
-class CXXConstructorDecl;
-class CXXDeleteExpr;
-class CXXRecordDecl;
-class DeclaratorDecl;
-class LookupResult;
-struct ObjCMethodList;
-class Scope;
-class Sema;
-class TypedefNameDecl;
-class ValueDecl;
-class VarDecl;
-struct LateParsedTemplate;
-
-/// \brief A simple structure that captures a vtable use for the purposes of
-/// the \c ExternalSemaSource.
-struct ExternalVTableUse {
- CXXRecordDecl *Record;
- SourceLocation Location;
- bool DefinitionRequired;
-};
-
-/// \brief An abstract interface that should be implemented by
-/// external AST sources that also provide information for semantic
-/// analysis.
-class ExternalSemaSource : public ExternalASTSource {
-public:
- ExternalSemaSource() {
- ExternalASTSource::SemaSource = true;
- }
-
- ~ExternalSemaSource() override;
-
- /// \brief 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.
- virtual void ForgetSema() {}
-
- /// \brief Load the contents of the global method pool for a given
- /// selector.
- virtual void ReadMethodPool(Selector Sel);
-
- /// \brief 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
- /// internal linkage, or used but not defined internal functions.
- virtual void ReadUndefinedButUsed(
- llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
-
- virtual void ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &);
-
- /// \brief Do last resort, unqualified lookup on a LookupResult that
- /// Sema cannot find.
- ///
- /// \param R a LookupResult that is being recovered.
- ///
- /// \param S the Scope of the identifier occurrence.
- ///
- /// \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
- /// source.
- ///
- /// The external source should append its own tentative definitions to the
- /// given vector of tentative definitions. Note that this routine may be
- /// invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- virtual void ReadTentativeDefinitions(
- SmallVectorImpl<VarDecl *> &TentativeDefs) {}
-
- /// \brief 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
- /// given vector of declarations. Note that this routine may be
- /// invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- virtual void ReadUnusedFileScopedDecls(
- SmallVectorImpl<const DeclaratorDecl *> &Decls) {}
-
- /// \brief Read the set of delegating constructors known to the
- /// external Sema source.
- ///
- /// The external source should append its own delegating constructors to the
- /// given vector of declarations. Note that this routine may be
- /// invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- virtual void ReadDelegatingConstructors(
- SmallVectorImpl<CXXConstructorDecl *> &Decls) {}
-
- /// \brief 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
- /// the given vector of declarations. Note that this routine may be
- /// invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {}
-
- /// \brief 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
- /// be invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- virtual void ReadUnusedLocalTypedefNameCandidates(
- llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {}
-
- /// \brief Read the set of referenced selectors known to the
- /// external Sema source.
- ///
- /// The external source should append its own referenced selectors to the
- /// given vector of selectors. Note that this routine
- /// may be invoked multiple times; the external source should take care not
- /// to introduce the same selectors repeatedly.
- virtual void ReadReferencedSelectors(
- SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {}
-
- /// \brief Read the set of weak, undeclared identifiers known to the
- /// external Sema source.
- ///
- /// The external source should append its own weak, undeclared identifiers to
- /// the given vector. Note that this routine may be invoked multiple times;
- /// the external source should take care not to introduce the same identifiers
- /// repeatedly.
- virtual void ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) {}
-
- /// \brief 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
- /// Sema source.
- ///
- /// The external source should append its own pending instantiations to the
- /// given vector. Note that this routine may be invoked multiple times; the
- /// external source should take care not to introduce the same instantiations
- /// repeatedly.
- virtual void ReadPendingInstantiations(
- SmallVectorImpl<std::pair<ValueDecl *,
- SourceLocation> > &Pending) {}
-
- /// \brief 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
- /// external source should take care not to introduce the same map entries
- /// repeatedly.
- virtual void ReadLateParsedTemplates(
- llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {}
-
- /// \copydoc Sema::CorrectTypo
- /// \note LookupKind must correspond to a valid Sema::LookupNameKind
- ///
- /// ExternalSemaSource::CorrectTypo is always given the first chance to
- /// correct a typo (really, to offer suggestions to repair a failed lookup).
- /// It will even be called when SpellChecking is turned off or after a
- /// fatal error has already been detected.
- virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
- int LookupKind, Scope *S, CXXScopeSpec *SS,
- CorrectionCandidateCallback &CCC,
- DeclContext *MemberContext,
- bool EnteringContext,
- const ObjCObjectPointerType *OPT) {
- return TypoCorrection();
- }
-
- /// \brief 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
- /// provided
- ///
- /// \param T the \c QualType that should have been complete at \p Loc
- ///
- /// \return true if a diagnostic was produced, false otherwise.
- virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
- QualType T) {
- return false;
- }
-
- // isa/cast/dyn_cast support
- static bool classof(const ExternalASTSource *Source) {
- return Source->SemaSource;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
deleted file mode 100644
index a07834f..0000000
--- a/include/clang/Sema/IdentifierResolver.h
+++ /dev/null
@@ -1,213 +0,0 @@
-//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- 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 IdentifierResolver class, which is used for lexical
-// scoped lookup, based on declaration names.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
-#define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-class ASTContext;
-class Decl;
-class DeclContext;
-class DeclarationName;
-class ExternalPreprocessorSource;
-class NamedDecl;
-class Preprocessor;
-class Scope;
-
-/// IdentifierResolver - Keeps track of shadowed decls on enclosing
-/// 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;
-
- inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
- inline DeclsTy::iterator decls_end() { return Decls.end(); }
-
- void AddDecl(NamedDecl *D) { Decls.push_back(D); }
-
- /// RemoveDecl - Remove the decl from the scope chain.
- /// 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.
- void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) {
- Decls.insert(Pos, D);
- }
-
- private:
- DeclsTy Decls;
- };
-
-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;
-
- /// Ptr - There are 3 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 & 0x3 == 0x1)
- /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
- /// declaration contexts too. (Ptr & 0x3 == 0x3)
- uintptr_t Ptr;
- typedef IdDeclInfo::DeclsTy::iterator BaseIter;
-
- /// 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) {
- Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
- }
-
- bool isIterator() const { return (Ptr & 0x1); }
-
- BaseIter getIterator() const {
- assert(isIterator() && "Ptr not an iterator!");
- return reinterpret_cast<BaseIter>(Ptr & ~0x3);
- }
-
- friend class IdentifierResolver;
-
- void incrementSlowCase();
- public:
- iterator() : Ptr(0) {}
-
- NamedDecl *operator*() const {
- if (isIterator())
- return *getIterator();
- else
- return reinterpret_cast<NamedDecl*>(Ptr);
- }
-
- bool operator==(const iterator &RHS) const {
- return Ptr == RHS.Ptr;
- }
- bool operator!=(const iterator &RHS) const {
- return Ptr != RHS.Ptr;
- }
-
- // Preincrement.
- iterator& operator++() {
- if (!isIterator()) // common case.
- Ptr = 0;
- else
- incrementSlowCase();
- return *this;
- }
-
- uintptr_t getAsOpaqueValue() const { return Ptr; }
-
- static iterator getFromOpaqueValue(uintptr_t P) {
- iterator Result;
- Result.Ptr = P;
- return Result;
- }
- };
-
- /// begin - Returns an iterator for decls with the name 'Name'.
- iterator begin(DeclarationName Name);
-
- /// end - Returns an iterator that has 'finished'.
- iterator end() {
- return iterator();
- }
-
- /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
- /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
- /// true if 'D' belongs to the given declaration context.
- ///
- /// \param AllowInlineNamespace If \c true, we are checking whether a prior
- /// declaration is in scope in a declaration that requires a prior
- /// declaration (because it is either explicitly qualified or is a
- /// template instantiation or specialization). In this case, a
- /// declaration is in scope if it's in the inline namespace set of the
- /// context.
- bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr,
- bool AllowInlineNamespace = false) const;
-
- /// AddDecl - Link the decl to its shadowed decl chain.
- void AddDecl(NamedDecl *D);
-
- /// RemoveDecl - Unlink the decl from its shadowed decl chain.
- /// The decl must already be part of the decl chain.
- void RemoveDecl(NamedDecl *D);
-
- /// \brief 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
- /// (or a redeclaration of it) hasn't already been added.
- ///
- /// \param D The externally-produced declaration to add.
- ///
- /// \param Name The name of the externally-produced declaration.
- ///
- /// \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;
-
- class IdDeclInfoMap;
- IdDeclInfoMap *IdDeclInfos;
-
- void updatingIdentifier(IdentifierInfo &II);
- void readingIdentifier(IdentifierInfo &II);
-
- /// FETokenInfo contains a Decl pointer if lower bit == 0.
- static inline bool isDeclPtr(void *Ptr) {
- return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
- }
-
- /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
- static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
- assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
- && "Ptr not a IdDeclInfo* !");
- return reinterpret_cast<IdDeclInfo*>(
- reinterpret_cast<uintptr_t>(Ptr) & ~0x1
- );
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
deleted file mode 100644
index d4f57b7..0000000
--- a/include/clang/Sema/Initialization.h
+++ /dev/null
@@ -1,1145 +0,0 @@
-//===--- Initialization.h - Semantic Analysis for Initializers --*- 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 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/Type.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Sema/Overload.h"
-#include "clang/Sema/Ownership.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-
-namespace clang {
-
-class CXXBaseSpecifier;
-class DeclaratorDecl;
-class DeclaratorInfo;
-class FieldDecl;
-class FunctionDecl;
-class ParmVarDecl;
-class Sema;
-class TypeLoc;
-class VarDecl;
-class ObjCMethodDecl;
-
-/// \brief Describes an entity that is being initialized.
-class InitializedEntity {
-public:
- /// \brief Specifies the kind of entity being initialized.
- enum EntityKind {
- /// \brief The entity being initialized is a variable.
- EK_Variable,
- /// \brief The entity being initialized is a function parameter.
- EK_Parameter,
- /// \brief The entity being initialized is the result of a function call.
- EK_Result,
- /// \brief 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
- /// subobject.
- EK_Member,
- /// \brief The entity being initialized is an element of an array.
- EK_ArrayElement,
- /// \brief 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.
- EK_Temporary,
- /// \brief The entity being initialized is a base member subobject.
- EK_Base,
- /// \brief The initialization is being done by a delegating constructor.
- EK_Delegating,
- /// \brief 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 copied-in c++ object.
- EK_BlockElement,
- /// \brief 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
- /// variable in a lambda.
- EK_LambdaCapture,
- /// \brief The entity being initialized is the initializer for a compound
- /// literal.
- EK_CompoundLiteralInit,
- /// \brief The entity being implicitly initialized back to the formal
- /// result type.
- EK_RelatedResult,
- /// \brief The entity being initialized is a function parameter; function
- /// is member of group of audited CF APIs.
- EK_Parameter_CF_Audited
-
- // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
- // 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.
- EntityKind Kind;
-
- /// \brief If non-NULL, the parent entity in which this
- /// initialization occurs.
- const InitializedEntity *Parent;
-
- /// \brief 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;
-
- struct LN {
- /// \brief 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
- /// named return value optimization (NRVO).
- bool NRVO;
- };
-
- struct C {
- /// \brief The name of the variable being captured by an EK_LambdaCapture.
- IdentifierInfo *VarID;
-
- /// \brief The source location at which the capture occurs.
- unsigned Location;
- };
-
- union {
- /// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or
- /// FieldDecl, respectively.
- DeclaratorDecl *VariableOrMember;
-
- /// \brief 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
- /// low bit indicating whether the parameter is "consumed".
- uintptr_t Parameter;
-
- /// \brief 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
- /// 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
- /// EK_ComplexElement, the index of the array or vector element being
- /// initialized.
- unsigned Index;
-
- struct C Capture;
- };
-
- InitializedEntity() : ManglingNumber(0) {}
-
- /// \brief Create the initialization entity for a variable.
- InitializedEntity(VarDecl *Var)
- : Kind(EK_Variable), Parent(nullptr), Type(Var->getType()),
- ManglingNumber(0), VariableOrMember(Var) { }
-
- /// \brief 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)
- {
- LocAndNRVO.Location = Loc.getRawEncoding();
- LocAndNRVO.NRVO = NRVO;
- }
-
- /// \brief Create the initialization entity for a member subobject.
- InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent)
- : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
- ManglingNumber(0), VariableOrMember(Member) { }
-
- /// \brief 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.
- InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
- : Kind(EK_LambdaCapture), Parent(nullptr), Type(FieldType),
- ManglingNumber(0)
- {
- Capture.VarID = VarID;
- Capture.Location = Loc.getRawEncoding();
- }
-
-public:
- /// \brief Create the initialization entity for a variable.
- static InitializedEntity InitializeVariable(VarDecl *Var) {
- return InitializedEntity(Var);
- }
-
- /// \brief Create the initialization entity for a parameter.
- static InitializedEntity InitializeParameter(ASTContext &Context,
- ParmVarDecl *Parm) {
- return InitializeParameter(Context, Parm, Parm->getType());
- }
-
- /// \brief Create the initialization entity for a parameter, but use
- /// another type.
- static InitializedEntity InitializeParameter(ASTContext &Context,
- ParmVarDecl *Parm,
- QualType Type) {
- bool Consumed = (Context.getLangOpts().ObjCAutoRefCount &&
- Parm->hasAttr<NSConsumedAttr>());
-
- InitializedEntity Entity;
- Entity.Kind = EK_Parameter;
- Entity.Type =
- Context.getVariableArrayDecayedType(Type.getUnqualifiedType());
- Entity.Parent = nullptr;
- Entity.Parameter
- = (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm));
- return Entity;
- }
-
- /// \brief Create the initialization entity for a parameter that is
- /// only known by its type.
- static InitializedEntity InitializeParameter(ASTContext &Context,
- QualType Type,
- bool Consumed) {
- InitializedEntity Entity;
- Entity.Kind = EK_Parameter;
- Entity.Type = Context.getVariableArrayDecayedType(Type);
- Entity.Parent = nullptr;
- Entity.Parameter = (Consumed);
- return Entity;
- }
-
- /// \brief 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 InitializeBlock(SourceLocation BlockVarLoc,
- QualType Type, bool NRVO) {
- return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO);
- }
-
- /// \brief 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.
- static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
- return InitializedEntity(EK_New, NewLoc, Type);
- }
-
- /// \brief Create the initialization entity for a temporary.
- static InitializedEntity InitializeTemporary(QualType Type) {
- InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
- Result.TypeInfo = nullptr;
- return Result;
- }
-
- /// \brief Create the initialization entity for a temporary.
- static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) {
- InitializedEntity Result(EK_Temporary, SourceLocation(),
- TypeInfo->getType());
- Result.TypeInfo = TypeInfo;
- return Result;
- }
-
- /// \brief Create the initialization entity for a related result.
- static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD,
- QualType Type) {
- InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type);
- Result.MethodDecl = MD;
- return Result;
- }
-
-
- /// \brief Create the initialization entity for a base class subobject.
- static InitializedEntity InitializeBase(ASTContext &Context,
- const CXXBaseSpecifier *Base,
- bool IsInheritedVirtualBase);
-
- /// \brief 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.
- static InitializedEntity
- InitializeMember(FieldDecl *Member,
- const InitializedEntity *Parent = nullptr) {
- return InitializedEntity(Member, Parent);
- }
-
- /// \brief Create the initialization entity for a member subobject.
- static InitializedEntity
- InitializeMember(IndirectFieldDecl *Member,
- const InitializedEntity *Parent = nullptr) {
- return InitializedEntity(Member->getAnonField(), Parent);
- }
-
- /// \brief 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 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.
- static InitializedEntity InitializeCompoundLiteralInit(TypeSourceInfo *TSI) {
- InitializedEntity Result(EK_CompoundLiteralInit, SourceLocation(),
- TSI->getType());
- Result.TypeInfo = TSI;
- return Result;
- }
-
-
- /// \brief Determine the kind of initialization.
- EntityKind getKind() const { return Kind; }
-
- /// \brief 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.
- QualType getType() const { return Type; }
-
- /// \brief Retrieve complete type-source information for the object being
- /// constructed, if known.
- TypeSourceInfo *getTypeSourceInfo() const {
- if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit)
- return TypeInfo;
-
- return nullptr;
- }
-
- /// \brief Retrieve the name of the entity being initialized.
- DeclarationName getName() const;
-
- /// \brief Retrieve the variable, parameter, or field being
- /// initialized.
- DeclaratorDecl *getDecl() const;
-
- /// \brief Retrieve the ObjectiveC method being initialized.
- ObjCMethodDecl *getMethodDecl() const { return MethodDecl; }
-
- /// \brief Determine whether this initialization allows the named return
- /// value optimization, which also applies to thrown objects.
- bool allowsNRVO() const;
-
- bool isParameterKind() const {
- return (getKind() == EK_Parameter ||
- getKind() == EK_Parameter_CF_Audited);
- }
- /// \brief Determine whether this initialization consumes the
- /// parameter.
- bool isParameterConsumed() const {
- assert(isParameterKind() && "Not a parameter");
- return (Parameter & 1);
- }
-
- /// \brief 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.
- bool isInheritedVirtualBase() const {
- assert(getKind() == EK_Base && "Not a base specifier");
- return Base & 0x1;
- }
-
- /// \brief 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
- /// 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
- /// 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
- /// 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.
- StringRef getCapturedVarName() const {
- assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
- return Capture.VarID->getName();
- }
- /// \brief 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!");
- return SourceLocation::getFromRawEncoding(Capture.Location);
- }
-
- void setParameterCFAudited() {
- Kind = EK_Parameter_CF_Audited;
- }
-
- unsigned allocateManglingNumber() const { return ++ManglingNumber; }
-
- /// Dump a representation of the initialized entity to standard error,
- /// for debugging purposes.
- void dump() const;
-
-private:
- unsigned dumpImpl(raw_ostream &OS) const;
-};
-
-/// \brief 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.
- enum InitKind {
- IK_Direct, ///< Direct initialization
- IK_DirectList, ///< Direct list-initialization
- IK_Copy, ///< Copy initialization
- IK_Default, ///< Default initialization
- IK_Value ///< Value initialization
- };
-
-private:
- /// \brief 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
- };
-
- /// \brief The kind of initialization being performed.
- InitKind Kind : 8;
-
- /// \brief The context of the initialization.
- InitContext Context : 8;
-
- /// \brief 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)
- {
- Locations[0] = Loc1;
- Locations[1] = Loc2;
- Locations[2] = Loc3;
- }
-
-public:
- /// \brief Create a direct initialization.
- static InitializationKind CreateDirect(SourceLocation InitLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- return InitializationKind(IK_Direct, IC_Normal,
- InitLoc, LParenLoc, RParenLoc);
- }
-
- static InitializationKind CreateDirectList(SourceLocation 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
- /// 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.
- static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
- SourceRange TypeRange,
- bool InitList) {
- // C++ cast syntax doesn't permit init lists, but C compound literals are
- // exactly that.
- return InitializationKind(InitList ? IK_DirectList : IK_Direct,
- IC_CStyleCast, StartLoc, TypeRange.getBegin(),
- TypeRange.getEnd());
- }
-
- /// \brief Create a direct initialization for a functional cast.
- static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
- bool InitList) {
- return InitializationKind(InitList ? IK_DirectList : IK_Direct,
- IC_FunctionalCast, TypeRange.getBegin(),
- TypeRange.getBegin(), TypeRange.getEnd());
- }
-
- /// \brief Create a copy initialization.
- static InitializationKind CreateCopy(SourceLocation InitLoc,
- SourceLocation EqualLoc,
- bool AllowExplicitConvs = false) {
- return InitializationKind(IK_Copy,
- AllowExplicitConvs? IC_ExplicitConvs : IC_Normal,
- InitLoc, EqualLoc, EqualLoc);
- }
-
- /// \brief Create a default initialization.
- static InitializationKind CreateDefault(SourceLocation InitLoc) {
- return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
- }
-
- /// \brief Create a value initialization.
- static InitializationKind CreateValue(SourceLocation InitLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc,
- bool isImplicit = false) {
- return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
- InitLoc, LParenLoc, RParenLoc);
- }
-
- /// \brief Determine the initialization kind.
- InitKind getKind() const {
- return Kind;
- }
-
- /// \brief 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.
- bool isCStyleOrFunctionalCast() const {
- return Context >= IC_CStyleCast;
- }
-
- /// \brief Determine whether this is a C-style cast.
- bool isCStyleCast() const {
- return Context == IC_CStyleCast;
- }
-
- /// \brief Determine whether this is a functional-style cast.
- bool isFunctionalCast() const {
- return Context == IC_FunctionalCast;
- }
-
- /// \brief 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.
- SourceLocation getLocation() const { return Locations[0]; }
-
- /// \brief 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
- /// (if present).
- SourceLocation getEqualLoc() const {
- assert(Kind == IK_Copy && "Only copy initialization has an '='");
- return Locations[1];
- }
-
- bool isCopyInit() const { return Kind == IK_Copy; }
-
- /// \brief 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
- /// 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;
- }
-
- /// \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");
- return SourceRange(Locations[1], Locations[2]);
- }
-};
-
-/// \brief 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.
- enum SequenceKind {
- /// \brief A failed initialization sequence. The failure kind tells what
- /// happened.
- FailedSequence = 0,
-
- /// \brief 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.
- NormalSequence
- };
-
- /// \brief Describes the kind of a particular step in an initialization
- /// sequence.
- enum StepKind {
- /// \brief Resolve the address of an overloaded function to a specific
- /// function declaration.
- SK_ResolveAddressOfOverloadedFunction,
- /// \brief Perform a derived-to-base cast, producing an rvalue.
- SK_CastDerivedToBaseRValue,
- /// \brief Perform a derived-to-base cast, producing an xvalue.
- SK_CastDerivedToBaseXValue,
- /// \brief Perform a derived-to-base cast, producing an lvalue.
- SK_CastDerivedToBaseLValue,
- /// \brief Reference binding to an lvalue.
- SK_BindReference,
- /// \brief Reference binding to a temporary.
- SK_BindReferenceToTemporary,
- /// \brief 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 Perform a user-defined conversion, either via a conversion
- /// function or via a constructor.
- SK_UserConversion,
- /// \brief Perform a qualification conversion, producing an rvalue.
- SK_QualificationConversionRValue,
- /// \brief Perform a qualification conversion, producing an xvalue.
- SK_QualificationConversionXValue,
- /// \brief Perform a qualification conversion, producing an lvalue.
- SK_QualificationConversionLValue,
- /// \brief Perform a conversion adding _Atomic to a type.
- SK_AtomicConversion,
- /// \brief Perform a load from a glvalue, producing an rvalue.
- SK_LValueToRValue,
- /// \brief Perform an implicit conversion sequence.
- SK_ConversionSequence,
- /// \brief Perform an implicit conversion sequence without narrowing.
- SK_ConversionSequenceNoNarrowing,
- /// \brief Perform list-initialization without a constructor.
- SK_ListInitialization,
- /// \brief Unwrap the single-element initializer list for a reference.
- SK_UnwrapInitList,
- /// \brief Rewrap the single-element initializer list for a reference.
- SK_RewrapInitList,
- /// \brief Perform initialization via a constructor.
- SK_ConstructorInitialization,
- /// \brief Perform initialization via a constructor, taking arguments from
- /// a single InitListExpr.
- SK_ConstructorInitializationFromList,
- /// \brief Zero-initialize the object
- SK_ZeroInitialization,
- /// \brief C assignment
- SK_CAssignment,
- /// \brief Initialization by string
- SK_StringInit,
- /// \brief An initialization that "converts" an Objective-C object
- /// (not a point to an object) to another Objective-C object type.
- SK_ObjCObjectConversion,
- /// \brief Array initialization (from an array rvalue).
- /// This is a GNU C extension.
- SK_ArrayInit,
- /// \brief Array initialization from a parenthesized initializer list.
- /// This is a GNU C++ extension.
- SK_ParenthesizedArrayInit,
- /// \brief Pass an object by indirect copy-and-restore.
- SK_PassByIndirectCopyRestore,
- /// \brief Pass an object by indirect restore.
- SK_PassByIndirectRestore,
- /// \brief Produce an Objective-C object pointer.
- SK_ProduceObjCObject,
- /// \brief Construct a std::initializer_list from an initializer list.
- SK_StdInitializerList,
- /// \brief Perform initialization via a constructor taking a single
- /// std::initializer_list argument.
- SK_StdInitializerListConstructorCall,
- /// \brief Initialize an OpenCL sampler from an integer.
- SK_OCLSamplerInit,
- /// \brief Passing zero to a function where OpenCL event_t is expected.
- SK_OCLZeroEvent
- };
-
- /// \brief A single step in the initialization sequence.
- class Step {
- public:
- /// \brief The kind of conversion or initialization step we are taking.
- StepKind Kind;
-
- // \brief The type that results from this initialization.
- QualType Type;
-
- struct F {
- bool HadMultipleCandidates;
- FunctionDecl *Function;
- DeclAccessPair FoundDecl;
- };
-
- union {
- /// \brief 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,
- /// the constructor to be called.
- ///
- /// Always a FunctionDecl, plus a Boolean flag telling if it was
- /// selected from an overloaded set having size greater than 1.
- /// For conversion decls, the naming class is the source type.
- /// For construct decls, the naming class is the target type.
- struct F Function;
-
- /// \brief When Kind = SK_ConversionSequence, the implicit conversion
- /// sequence.
- ImplicitConversionSequence *ICS;
-
- /// \brief When Kind = SK_RewrapInitList, the syntactic form of the
- /// wrapping list.
- InitListExpr *WrappingSyntacticList;
- };
-
- void Destroy();
- };
-
-private:
- /// \brief The kind of initialization sequence computed.
- enum SequenceKind SequenceKind;
-
- /// \brief Steps taken by this initialization.
- SmallVector<Step, 4> Steps;
-
-public:
- /// \brief Describes why initialization failed.
- enum FailureKind {
- /// \brief Too many initializers provided for a reference.
- FK_TooManyInitsForReference,
- /// \brief Array must be initialized with an initializer list.
- FK_ArrayNeedsInitList,
- /// \brief 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
- /// wide string literal.
- FK_ArrayNeedsInitListOrWideStringLiteral,
- /// \brief Initializing a wide char array with narrow string literal.
- FK_NarrowStringIntoWideCharArray,
- /// \brief Initializing char array with wide string literal.
- FK_WideStringIntoCharArray,
- /// \brief Initializing wide char array with incompatible wide string
- /// literal.
- FK_IncompatWideStringIntoWideChar,
- /// \brief Array type mismatch.
- FK_ArrayTypeMismatch,
- /// \brief Non-constant array initializer
- FK_NonConstantArrayInit,
- /// \brief Cannot resolve the address of an overloaded function.
- FK_AddressOfOverloadFailed,
- /// \brief Overloading due to reference initialization failed.
- FK_ReferenceInitOverloadFailed,
- /// \brief Non-const lvalue reference binding to a temporary.
- FK_NonConstLValueReferenceBindingToTemporary,
- /// \brief Non-const lvalue reference binding to an lvalue of unrelated
- /// type.
- FK_NonConstLValueReferenceBindingToUnrelated,
- /// \brief Rvalue reference binding to an lvalue.
- FK_RValueReferenceBindingToLValue,
- /// \brief Reference binding drops qualifiers.
- FK_ReferenceInitDropsQualifiers,
- /// \brief Reference binding failed.
- FK_ReferenceInitFailed,
- /// \brief Implicit conversion failed.
- FK_ConversionFailed,
- /// \brief Implicit conversion failed.
- FK_ConversionFromPropertyFailed,
- /// \brief Too many initializers for scalar
- FK_TooManyInitsForScalar,
- /// \brief Reference initialization from an initializer list
- FK_ReferenceBindingToInitList,
- /// \brief Initialization of some unused destination type with an
- /// initializer list.
- FK_InitListBadDestinationType,
- /// \brief Overloading for a user-defined conversion failed.
- FK_UserConversionOverloadFailed,
- /// \brief Overloading for initialization by constructor failed.
- FK_ConstructorOverloadFailed,
- /// \brief Overloading for list-initialization by constructor failed.
- FK_ListConstructorOverloadFailed,
- /// \brief Default-initialization of a 'const' object.
- FK_DefaultInitOfConst,
- /// \brief Initialization of an incomplete type.
- FK_Incomplete,
- /// \brief Variable-length array must not have an initializer.
- FK_VariableLengthArrayHasInitializer,
- /// \brief List initialization failed at some point.
- FK_ListInitializationFailed,
- /// \brief 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
- /// having its address taken.
- FK_AddressOfUnaddressableFunction,
- /// \brief List-copy-initialization chose an explicit constructor.
- FK_ExplicitConstructor
- };
-
-private:
- /// \brief The reason why initialization failed.
- FailureKind Failure;
-
- /// \brief The failed result of overload resolution.
- OverloadingResult FailedOverloadResult;
-
- /// \brief The candidate set created when initialization failed.
- OverloadCandidateSet FailedCandidateSet;
-
- /// \brief The incomplete type that caused a failure.
- QualType FailedIncompleteType;
-
- /// \brief 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
- /// zero initialzations if Fixit was applied.
- void SetZeroInitializationFixit(const std::string& Fixit, SourceLocation L) {
- ZeroInitializationFixit = Fixit;
- ZeroInitializationFixitLoc = L;
- }
-
-private:
-
- /// \brief 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
- /// record of the steps required to perform the initialization.
- ///
- /// The generated initialization sequence will either contain enough
- /// information to diagnose
- ///
- /// \param S the semantic analysis object.
- ///
- /// \param Entity the entity being initialized.
- ///
- /// \param Kind the kind of initialization being performed.
- ///
- /// \param Args the argument(s) provided for initialization.
- ///
- /// \param TopLevelOfInitList true if we are initializing from an expression
- /// at the top level inside an initializer list. This disallows
- /// narrowing conversions in C++11 onwards.
- InitializationSequence(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- MultiExprArg Args,
- bool TopLevelOfInitList = false);
- void InitializeFrom(Sema &S, const InitializedEntity &Entity,
- const InitializationKind &Kind, MultiExprArg Args,
- bool TopLevelOfInitList);
-
- ~InitializationSequence();
-
- /// \brief Perform the actual initialization of the given entity based on
- /// the computed initialization sequence.
- ///
- /// \param S the semantic analysis object.
- ///
- /// \param Entity the entity being initialized.
- ///
- /// \param Kind the kind of initialization being performed.
- ///
- /// \param Args the argument(s) provided for initialization, ownership of
- /// which is transferred into the routine.
- ///
- /// \param ResultType if non-NULL, will be set to the type of the
- /// initialized object, which is the type of the declaration in most
- /// cases. However, when the initialized object is a variable of
- /// incomplete array type and the initializer is an initializer
- /// list, this type will be set to the completed array type.
- ///
- /// \returns an expression that performs the actual object initialization, if
- /// the initialization is well-formed. Otherwise, emits diagnostics
- /// and returns an invalid expression.
- ExprResult Perform(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- MultiExprArg Args,
- QualType *ResultType = nullptr);
-
- /// \brief Diagnose an potentially-invalid initialization sequence.
- ///
- /// \returns true if the initialization sequence was ill-formed,
- /// false otherwise.
- bool Diagnose(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- ArrayRef<Expr *> Args);
-
- /// \brief Determine the kind of initialization sequence computed.
- enum SequenceKind getKind() const { return SequenceKind; }
-
- /// \brief Set the kind of sequence computed.
- void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
-
- /// \brief Determine whether the initialization sequence is valid.
- explicit operator bool() const { return !Failed(); }
-
- /// \brief Determine whether the initialization sequence is invalid.
- bool Failed() const { return SequenceKind == FailedSequence; }
-
- typedef SmallVectorImpl<Step>::const_iterator step_iterator;
- step_iterator step_begin() const { return Steps.begin(); }
- step_iterator step_end() const { return Steps.end(); }
-
- /// \brief 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.
- bool isAmbiguous() const;
-
- /// \brief 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
- /// narrowing conversion, defined by C++0x [dcl.init.list]p7.
- ///
- /// If this function returns true, *isInitializerConstant will be set to
- /// describe whether *Initializer was a constant expression. If
- /// *isInitializerConstant is set to true, *ConstantValue will be set to the
- /// evaluated value of *Initializer.
- bool endsWithNarrowing(ASTContext &Ctx, const Expr *Initializer,
- bool *isInitializerConstant,
- APValue *ConstantValue) const;
-
- /// \brief 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
- /// resolves.
- void AddAddressOverloadResolutionStep(FunctionDecl *Function,
- DeclAccessPair Found,
- bool HadMultipleCandidates);
-
- /// \brief 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.
- ///
- /// \param Category Indicates whether the result will be treated as an
- /// rvalue, an xvalue, or an lvalue.
- void AddDerivedToBaseCastStep(QualType BaseType,
- ExprValueKind Category);
-
- /// \brief 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
- /// to a temporary of the same class type.
- ///
- /// This extraneous copy only occurs during reference binding in
- /// C++98/03, where we are permitted (but not required) to introduce
- /// an extra copy. At a bare minimum, we must check that we could
- /// call the copy constructor, and produce a diagnostic if the copy
- /// constructor is inaccessible or no copy constructor matches.
- //
- /// \param T The type of the temporary being created.
- void AddExtraneousCopyToTemporary(QualType T);
-
- /// \brief 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
- /// given type.
- void AddQualificationConversionStep(QualType Ty,
- ExprValueKind Category);
-
- /// \brief 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.
- ///
- /// 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.
- void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
- QualType T, bool TopLevelOfInitList = false);
-
- /// \brief Add a list-initialization step.
- void AddListInitializationStep(QualType T);
-
- /// \brief Add a constructor-initialization step.
- ///
- /// \param FromInitList The constructor call is syntactically an initializer
- /// list.
- /// \param AsInitList The constructor is called as an init list constructor.
- void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
- AccessSpecifier Access,
- QualType T,
- bool HadMultipleCandidates,
- bool FromInitList, bool AsInitList);
-
- /// \brief Add a zero-initialization step.
- void AddZeroInitializationStep(QualType T);
-
- /// \brief 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.
- void AddStringInitStep(QualType T);
-
- /// \brief Add an Objective-C object conversion step, which is
- /// always a no-op.
- void AddObjCObjectConversionStep(QualType T);
-
- /// \brief Add an array initialization step.
- void AddArrayInitStep(QualType T);
-
- /// \brief Add a parenthesized array initialization step.
- void AddParenthesizedArrayInitStep(QualType T);
-
- /// \brief 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
- /// retaining it).
- void AddProduceObjCObjectStep(QualType T);
-
- /// \brief 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
- /// constant.
- void AddOCLSamplerInitStep(QualType T);
-
- /// \brief Add a step to initialize an OpenCL event_t from a NULL
- /// constant.
- void AddOCLZeroEventStep(QualType T);
-
- /// \brief 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.
- void SetFailed(FailureKind Failure) {
- SequenceKind = FailedSequence;
- this->Failure = Failure;
- assert((Failure != FK_Incomplete || !FailedIncompleteType.isNull()) &&
- "Incomplete type failure requires a type!");
- }
-
- /// \brief 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
- /// resolution fails.
- OverloadCandidateSet &getFailedCandidateSet() {
- return FailedCandidateSet;
- }
-
- /// \brief 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
- /// incomplete type.
- void setIncompleteTypeFailure(QualType IncompleteType) {
- FailedIncompleteType = IncompleteType;
- SetFailed(FK_Incomplete);
- }
-
- /// \brief Determine why initialization failed.
- FailureKind getFailureKind() const {
- assert(Failed() && "Not an initialization failure!");
- return Failure;
- }
-
- /// \brief 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
- /// standard error, for debugging purposes.
- void dump() const;
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_INITIALIZATION_H
diff --git a/include/clang/Sema/LocInfoType.h b/include/clang/Sema/LocInfoType.h
deleted file mode 100644
index 63dfa72..0000000
--- a/include/clang/Sema/LocInfoType.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===--- LocInfoType.h - Parsed Type with Location 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 LocInfoType class, which holds a type and its
-// source-location information.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_LOCINFOTYPE_H
-#define LLVM_CLANG_SEMA_LOCINFOTYPE_H
-
-#include "clang/AST/Type.h"
-
-namespace clang {
-
-class TypeSourceInfo;
-
-/// \brief 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
-/// and Sema, when we want to preserve type source info for a parsed type.
-/// It will not participate in the type system semantics in any way.
-class LocInfoType : public Type {
- enum {
- // The last number that can fit in Type's TC.
- // Avoids conflict with an existing Type class.
- LocInfo = Type::TypeLast + 1
- };
-
- TypeSourceInfo *DeclInfo;
-
- LocInfoType(QualType ty, TypeSourceInfo *TInfo)
- : Type((TypeClass)LocInfo, ty, ty->isDependentType(),
- ty->isInstantiationDependentType(),
- ty->isVariablyModifiedType(),
- ty->containsUnexpandedParameterPack()),
- DeclInfo(TInfo) {
- assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?");
- }
- friend class Sema;
-
-public:
- QualType getType() const { return getCanonicalTypeInternal(); }
- TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; }
-
- void getAsStringInternal(std::string &Str,
- const PrintingPolicy &Policy) const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == (TypeClass)LocInfo;
- }
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_LOCINFOTYPE_H
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
deleted file mode 100644
index 87c40f0..0000000
--- a/include/clang/Sema/Lookup.h
+++ /dev/null
@@ -1,760 +0,0 @@
-//===--- Lookup.h - Classes for name lookup ---------------------*- 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 LookupResult class, which is integral to
-// Sema's name-lookup subsystem.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_LOOKUP_H
-#define LLVM_CLANG_SEMA_LOOKUP_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/Sema/Sema.h"
-
-namespace clang {
-
-/// @brief 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),
-/// a single declaration, a set of overloaded functions, or an
-/// ambiguity. Use the getKind() method to determine which of these
-/// results occurred for a given lookup.
-class LookupResult {
-public:
- enum LookupResultKind {
- /// @brief No entity found met the criteria.
- NotFound = 0,
-
- /// @brief 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
- /// criteria. getFoundDecl() will return this declaration.
- Found,
-
- /// @brief Name lookup found a set of overloaded functions that
- /// met the criteria.
- FoundOverloaded,
-
- /// @brief 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
- /// getAmbiguityKind to figure out what kind of ambiguity
- /// we have.
- Ambiguous
- };
-
- enum AmbiguityKind {
- /// Name lookup results in an ambiguity because multiple
- /// entities that meet the lookup criteria were found in
- /// subobjects of different types. For example:
- /// @code
- /// struct A { void f(int); }
- /// struct B { void f(double); }
- /// struct C : A, B { };
- /// void test(C c) {
- /// c.f(0); // error: A::f and B::f come from subobjects of different
- /// // types. overload resolution is not performed.
- /// }
- /// @endcode
- AmbiguousBaseSubobjectTypes,
-
- /// Name lookup results in an ambiguity because multiple
- /// nonstatic entities that meet the lookup criteria were found
- /// in different subobjects of the same type. For example:
- /// @code
- /// struct A { int x; };
- /// struct B : A { };
- /// struct C : A { };
- /// struct D : B, C { };
- /// int test(D d) {
- /// return d.x; // error: 'x' is found in two A subobjects (of B and C)
- /// }
- /// @endcode
- AmbiguousBaseSubobjects,
-
- /// Name lookup results in an ambiguity because multiple definitions
- /// of entity that meet the lookup criteria were found in different
- /// declaration contexts.
- /// @code
- /// namespace A {
- /// int i;
- /// namespace B { int i; }
- /// int test() {
- /// using namespace B;
- /// return i; // error 'i' is found in namespace A and A::B
- /// }
- /// }
- /// @endcode
- AmbiguousReference,
-
- /// Name lookup results in an ambiguity because an entity with a
- /// tag name was hidden by an entity with an ordinary name from
- /// a different context.
- /// @code
- /// namespace A { struct Foo {}; }
- /// namespace B { void Foo(); }
- /// namespace C {
- /// using namespace A;
- /// using namespace B;
- /// }
- /// void test() {
- /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
- /// // different namespace
- /// }
- /// @endcode
- AmbiguousTagHiding
- };
-
- /// A little identifier for flagging temporary lookup results.
- enum TemporaryToken {
- Temporary
- };
-
- typedef UnresolvedSetImpl::iterator 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),
- HideTags(true),
- Diagnose(Redecl == Sema::NotForRedeclaration),
- AllowHidden(false),
- Shadowed(false)
- {
- configure();
- }
-
- // TODO: consider whether this constructor should be restricted to take
- // as input a const IndentifierInfo* (instead of Name),
- // forcing other cases towards the constructor taking a DNInfo.
- 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),
- HideTags(true),
- Diagnose(Redecl == Sema::NotForRedeclaration),
- AllowHidden(false),
- Shadowed(false)
- {
- configure();
- }
-
- /// Creates a temporary lookup result, initializing its core data
- /// 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),
- HideTags(Other.HideTags),
- Diagnose(false),
- AllowHidden(Other.AllowHidden),
- Shadowed(false)
- {}
-
- ~LookupResult() {
- if (Diagnose) diagnose();
- if (Paths) deletePaths(Paths);
- }
-
- /// Gets the name info to look up.
- const DeclarationNameInfo &getLookupNameInfo() const {
- return NameInfo;
- }
-
- /// \brief Sets the name info to look up.
- void setLookupNameInfo(const DeclarationNameInfo &NameInfo) {
- this->NameInfo = NameInfo;
- }
-
- /// Gets the name to look up.
- DeclarationName getLookupName() const {
- return NameInfo.getName();
- }
-
- /// \brief Sets the name to look up.
- void setLookupName(DeclarationName Name) {
- NameInfo.setName(Name);
- }
-
- /// Gets the kind of lookup to perform.
- Sema::LookupNameKind getLookupKind() const {
- return LookupKind;
- }
-
- /// True if this lookup is just looking for an existing declaration.
- bool isForRedeclaration() const {
- return Redecl;
- }
-
- /// \brief 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
- /// declarations, such as those in modules that have not yet been imported.
- bool isHiddenDeclarationVisible(NamedDecl *ND) const {
- return AllowHidden ||
- (isForRedeclaration() && ND->isExternallyVisible());
- }
-
- /// Sets whether tag declarations should be hidden by non-tag
- /// declarations during resolution. The default is true.
- void setHideTags(bool Hide) {
- HideTags = Hide;
- }
-
- bool isAmbiguous() const {
- return getResultKind() == Ambiguous;
- }
-
- /// Determines if this names a single result which is not an
- /// unresolved value using decl. If so, it is safe to call
- /// getFoundDecl().
- bool isSingleResult() const {
- return getResultKind() == Found;
- }
-
- /// Determines if the results are overloaded.
- bool isOverloadedResult() const {
- return getResultKind() == FoundOverloaded;
- }
-
- bool isUnresolvableResult() const {
- return getResultKind() == FoundUnresolvedValue;
- }
-
- LookupResultKind getResultKind() const {
- assert(sanity());
- return ResultKind;
- }
-
- AmbiguityKind getAmbiguityKind() const {
- assert(isAmbiguous());
- return Ambiguity;
- }
-
- const UnresolvedSetImpl &asUnresolvedSet() const {
- return Decls;
- }
-
- iterator begin() const { return iterator(Decls.begin()); }
- iterator end() const { return iterator(Decls.end()); }
-
- /// \brief Return true if no decls were found
- bool empty() const { return Decls.empty(); }
-
- /// \brief 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
- /// program.
- static bool isVisible(Sema &SemaRef, NamedDecl *D) {
- // If this declaration is not hidden, it's visible.
- if (!D->isHidden())
- return true;
-
- // During template instantiation, we can refer to hidden declarations, if
- // they were visible in any module along the path of instantiation.
- return isVisibleSlow(SemaRef, D);
- }
-
- /// \brief Retrieve the accepted (re)declaration of the given declaration,
- /// if there is one.
- NamedDecl *getAcceptableDecl(NamedDecl *D) const {
- if (!D->isInIdentifierNamespace(IDNS))
- return nullptr;
-
- if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D))
- return D;
-
- return getAcceptableDeclSlow(D);
- }
-
-private:
- static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D);
- NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const;
-
-public:
- /// \brief Returns the identifier namespace mask for this lookup.
- unsigned getIdentifierNamespace() const {
- return IDNS;
- }
-
- /// \brief 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
- /// class which was looked into to find these results.
- ///
- /// C++0x [class.access.base]p5:
- /// The access to a member is affected by the class in which the
- /// member is named. This naming class is the class in which the
- /// member name was looked up and found. [Note: this class can be
- /// explicit, e.g., when a qualified-id is used, or implicit,
- /// e.g., when a class member access operator (5.2.5) is used
- /// (including cases where an implicit "this->" is added). If both
- /// a class member access operator and a qualified-id are used to
- /// name the member (as in p->T::m), the class naming the member
- /// is the class named by the nested-name-specifier of the
- /// qualified-id (that is, T). -- end note ]
- ///
- /// This is set by the lookup routines when they find results in a class.
- CXXRecordDecl *getNamingClass() const {
- return NamingClass;
- }
-
- /// \brief Sets the 'naming class' for this lookup.
- void setNamingClass(CXXRecordDecl *Record) {
- NamingClass = Record;
- }
-
- /// \brief 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.
- void setBaseObjectType(QualType T) {
- BaseObjectType = T;
- }
-
- /// \brief 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.
- /// 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
- /// 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
- /// 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,
- /// 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
- /// declaration that lookup ignored.
- bool isShadowed() const { return Shadowed; }
-
- /// \brief 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
- /// 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
- /// removals has been performed.
- void resolveKindAfterFilter() {
- if (Decls.empty()) {
- if (ResultKind != NotFoundInCurrentInstantiation)
- ResultKind = NotFound;
-
- if (Paths) {
- deletePaths(Paths);
- Paths = nullptr;
- }
- } else {
- AmbiguityKind SavedAK;
- bool WasAmbiguous = false;
- if (ResultKind == Ambiguous) {
- SavedAK = Ambiguity;
- WasAmbiguous = true;
- }
- ResultKind = Found;
- resolveKind();
-
- // If we didn't make the lookup unambiguous, restore the old
- // ambiguity kind.
- if (ResultKind == Ambiguous) {
- (void)WasAmbiguous;
- assert(WasAmbiguous);
- Ambiguity = SavedAK;
- } else if (Paths) {
- deletePaths(Paths);
- Paths = nullptr;
- }
- }
- }
-
- template <class DeclClass>
- DeclClass *getAsSingle() const {
- if (getResultKind() != Found) return nullptr;
- return dyn_cast<DeclClass>(getFoundDecl());
- }
-
- /// \brief Fetch the unique decl found by this lookup. Asserts
- /// that one was found.
- ///
- /// This is intended for users who have examined the result kind
- /// and are certain that there is only one result.
- NamedDecl *getFoundDecl() const {
- assert(getResultKind() == Found
- && "getFoundDecl called on non-unique result");
- return (*begin())->getUnderlyingDecl();
- }
-
- /// Fetches a representative decl. Useful for lazy diagnostics.
- NamedDecl *getRepresentativeDecl() const {
- assert(!Decls.empty() && "cannot get representative of empty set");
- return *begin();
- }
-
- /// \brief 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
- /// 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
- /// 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
- /// 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.
- void clear() {
- ResultKind = NotFound;
- Decls.clear();
- if (Paths) deletePaths(Paths);
- Paths = nullptr;
- NamingClass = nullptr;
- Shadowed = false;
- }
-
- /// \brief Clears out any current state and re-initializes for a
- /// different kind of lookup.
- void clear(Sema::LookupNameKind Kind) {
- clear();
- LookupKind = Kind;
- configure();
- }
-
- /// \brief Change this lookup's redeclaration kind.
- void setRedeclarationKind(Sema::RedeclarationKind RK) {
- Redecl = RK;
- configure();
- }
-
- void print(raw_ostream &);
-
- /// Suppress the diagnostics that would normally fire because of this
- /// lookup. This happens during (e.g.) redeclaration lookups.
- void suppressDiagnostics() {
- Diagnose = false;
- }
-
- /// Determines whether this lookup is suppressing diagnostics.
- bool isSuppressingDiagnostics() const {
- return !Diagnose;
- }
-
- /// Sets a 'context' source range.
- void setContextRange(SourceRange SR) {
- NameContextRange = SR;
- }
-
- /// Gets the source range of the context of this name; for C++
- /// qualified lookups, this is the source range of the scope
- /// specifier.
- SourceRange getContextRange() const {
- return NameContextRange;
- }
-
- /// Gets the location of the identifier. This isn't always defined:
- /// sometimes we're doing lookups on synthesized names.
- SourceLocation getNameLoc() const {
- return NameInfo.getLoc();
- }
-
- /// \brief Get the Sema object that this lookup result is searching
- /// with.
- Sema &getSema() const { return *SemaPtr; }
-
- /// A class for iterating through a result set and possibly
- /// filtering out results. The results returned are possibly
- /// sugared.
- class Filter {
- LookupResult &Results;
- LookupResult::iterator I;
- bool Changed;
- bool CalledDone;
-
- friend class LookupResult;
- Filter(LookupResult &Results)
- : Results(Results), I(Results.begin()), Changed(false), CalledDone(false)
- {}
-
- public:
- Filter(Filter &&F)
- : Results(F.Results), I(F.I), Changed(F.Changed),
- CalledDone(F.CalledDone) {
- F.CalledDone = true;
- }
- ~Filter() {
- assert(CalledDone &&
- "LookupResult::Filter destroyed without done() call");
- }
-
- bool hasNext() const {
- return I != Results.end();
- }
-
- NamedDecl *next() {
- assert(I != Results.end() && "next() called on empty filter");
- return *I++;
- }
-
- /// Restart the iteration.
- void restart() {
- I = Results.begin();
- }
-
- /// Erase the last element returned from this iterator.
- void erase() {
- Results.Decls.erase(--I);
- Changed = true;
- }
-
- /// Replaces the current entry with the given one, preserving the
- /// access bits.
- void replace(NamedDecl *D) {
- Results.Decls.replace(I-1, D);
- Changed = true;
- }
-
- /// Replaces the current entry with the given one.
- void replace(NamedDecl *D, AccessSpecifier AS) {
- Results.Decls.replace(I-1, D, AS);
- Changed = true;
- }
-
- void done() {
- assert(!CalledDone && "done() called twice");
- CalledDone = true;
-
- if (Changed)
- Results.resolveKindAfterFilter();
- }
- };
-
- /// Create a filter for this result set.
- Filter makeFilter() {
- return Filter(*this);
- }
-
- void setFindLocalExtern(bool FindLocalExtern) {
- if (FindLocalExtern)
- IDNS |= Decl::IDNS_LocalExtern;
- else
- IDNS &= ~Decl::IDNS_LocalExtern;
- }
-
-private:
- void diagnose() {
- if (isAmbiguous())
- getSema().DiagnoseAmbiguousLookup(*this);
- else if (isClassLookup() && getSema().getLangOpts().AccessControl)
- getSema().CheckLookupAccess(*this);
- }
-
- void setAmbiguous(AmbiguityKind AK) {
- ResultKind = Ambiguous;
- Ambiguity = AK;
- }
-
- void addDeclsFromBasePaths(const CXXBasePaths &P);
- void configure();
-
- // Sanity checks.
- bool sanity() const;
-
- bool sanityCheckUnresolved() const {
- for (iterator I = begin(), E = end(); I != E; ++I)
- if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl()))
- return true;
- return false;
- }
-
- static void deletePaths(CXXBasePaths *);
-
- // Results.
- LookupResultKind ResultKind;
- AmbiguityKind Ambiguity; // ill-defined unless ambiguous
- UnresolvedSet<8> Decls;
- CXXBasePaths *Paths;
- CXXRecordDecl *NamingClass;
- QualType BaseObjectType;
-
- // Parameters.
- Sema *SemaPtr;
- DeclarationNameInfo NameInfo;
- SourceRange NameContextRange;
- Sema::LookupNameKind LookupKind;
- unsigned IDNS; // set by configure()
-
- bool Redecl;
-
- /// \brief True if tag declarations should be hidden if non-tags
- /// are present
- bool HideTags;
-
- bool Diagnose;
-
- /// \brief True if we should allow hidden declarations to be 'visible'.
- bool AllowHidden;
-
- /// \brief 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;
-};
-
-/// \brief 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
-/// Sema::LookupVisibleDecls(), each of which should override the \c
-/// FoundDecl() function to process declarations as they are found.
-class VisibleDeclConsumer {
-public:
- /// \brief Destroys the visible declaration consumer.
- virtual ~VisibleDeclConsumer();
-
- /// \brief 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
- /// declaration visible from the current scope or context.
- ///
- /// \param ND the declaration found.
- ///
- /// \param Hiding a declaration that hides the declaration \p ND,
- /// or NULL if no such declaration exists.
- ///
- /// \param Ctx the original context from which the lookup started.
- ///
- /// \param InBaseClass whether this declaration was found in base
- /// class of the context we searched.
- virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
- bool InBaseClass) = 0;
-};
-
-/// \brief A class for storing results from argument-dependent lookup.
-class ADLResult {
-private:
- /// A map from canonical decls to the 'most recent' decl.
- llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
-
-public:
- /// Adds a new ADL candidate to this map.
- void insert(NamedDecl *D);
-
- /// Removes any data associated with a given decl.
- void erase(NamedDecl *D) {
- Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
- }
-
- class iterator
- : public llvm::iterator_adaptor_base<
- iterator, llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator,
- std::forward_iterator_tag, NamedDecl *> {
- friend class ADLResult;
-
- iterator(llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator Iter)
- : iterator_adaptor_base(std::move(Iter)) {}
-
- public:
- iterator() {}
-
- value_type operator*() const { return I->second; }
- };
-
- iterator begin() { return iterator(Decls.begin()); }
- iterator end() { return iterator(Decls.end()); }
-};
-
-}
-
-#endif
diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Sema/LoopHint.h
deleted file mode 100644
index c8b2ee8..0000000
--- a/include/clang/Sema/LoopHint.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===--- LoopHint.h - Types for LoopHint ------------------------*- 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_SEMA_LOOPHINT_H
-#define LLVM_CLANG_SEMA_LOOPHINT_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Sema/AttributeList.h"
-#include "clang/Sema/Ownership.h"
-
-namespace clang {
-
-/// \brief Loop optimization hint for loop and unroll pragmas.
-struct LoopHint {
- // Source range of the directive.
- SourceRange Range;
- // Identifier corresponding to the name of the pragma. "loop" for
- // "#pragma clang loop" directives and "unroll" for "#pragma unroll"
- // hints.
- IdentifierLoc *PragmaNameLoc;
- // Name of the loop hint. Examples: "unroll", "vectorize". In the
- // "#pragma unroll" and "#pragma nounroll" cases, this is identical to
- // PragmaNameLoc.
- IdentifierLoc *OptionLoc;
- // Identifier for the hint state argument. If null, then the state is
- // default value such as for "#pragma unroll".
- IdentifierLoc *StateLoc;
- // Expression for the hint argument if it exists, null otherwise.
- Expr *ValueExpr;
-
- LoopHint()
- : PragmaNameLoc(nullptr), OptionLoc(nullptr), StateLoc(nullptr),
- ValueExpr(nullptr) {}
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_LOOPHINT_H
diff --git a/include/clang/Sema/Makefile b/include/clang/Sema/Makefile
deleted file mode 100644
index 799f789..0000000
--- a/include/clang/Sema/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-CLANG_LEVEL := ../../..
-TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc \
- AttrSpellingListIndex.inc AttrParsedAttrImpl.inc
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/AttrTemplateInstantiate.inc.tmp : $(TD_SRC_DIR)/Attr.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang attribute template instantiate code with tablegen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-template-instantiate -o \
- $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrParsedAttrList.inc.tmp : $(TD_SRC_DIR)/Attr.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang parsed attribute list with tablegen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-list -o \
- $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrParsedAttrKinds.inc.tmp : $(TD_SRC_DIR)/Attr.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang parsed attribute kinds with tablegen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-kinds -o \
- $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrSpellingListIndex.inc.tmp : $(TD_SRC_DIR)/Attr.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang attribute spelling list index with tablegen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-spelling-index -o \
- $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrParsedAttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang parsed attribute list impl with tablegen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-impl -o \
- $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
-
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
deleted file mode 100644
index d6daadc..0000000
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ /dev/null
@@ -1,353 +0,0 @@
-//===--- MultiplexExternalSemaSource.h - External Sema Interface-*- 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 ExternalSemaSource interface, dispatching to all clients
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_MULTIPLEXEXTERNALSEMASOURCE_H
-#define LLVM_CLANG_SEMA_MULTIPLEXEXTERNALSEMASOURCE_H
-
-#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/Sema/Weak.h"
-#include "llvm/ADT/SmallVector.h"
-#include <utility>
-
-namespace clang {
-
- class CXXConstructorDecl;
- class CXXRecordDecl;
- class DeclaratorDecl;
- struct ExternalVTableUse;
- class LookupResult;
- class NamespaceDecl;
- class Scope;
- class Sema;
- class TypedefNameDecl;
- class ValueDecl;
- class VarDecl;
-
-
-/// \brief An abstract interface that should be implemented by
-/// external AST sources that also provide information for semantic
-/// analysis.
-class MultiplexExternalSemaSource : public ExternalSemaSource {
-
-private:
- SmallVector<ExternalSemaSource *, 2> Sources; // doesn't own them.
-
-public:
-
- ///\brief Constructs a new multiplexing external sema source and appends the
- /// given element to it.
- ///
- ///\param[in] s1 - A non-null (old) ExternalSemaSource.
- ///\param[in] s2 - A non-null (new) ExternalSemaSource.
- ///
- MultiplexExternalSemaSource(ExternalSemaSource& s1, ExternalSemaSource& s2);
-
- ~MultiplexExternalSemaSource() override;
-
- ///\brief Appends new source to the source list.
- ///
- ///\param[in] source - An ExternalSemaSource.
- ///
- void addSource(ExternalSemaSource &source);
-
- //===--------------------------------------------------------------------===//
- // ExternalASTSource.
- //===--------------------------------------------------------------------===//
-
- /// \brief 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
- /// previous generation of the AST source.
- void CompleteRedeclChain(const Decl *D) override;
-
- /// \brief Resolve a selector ID into a selector.
- Selector GetExternalSelector(uint32_t ID) override;
-
- /// \brief 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
- /// a statement.
- Stmt *GetExternalDeclStmt(uint64_t Offset) override;
-
- /// \brief 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
- /// initializers themselves.
- CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override;
-
- /// \brief 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
- /// context is up to date.
- void completeVisibleDeclsMap(const DeclContext *DC) override;
-
- /// \brief 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
- /// declaration kind is one we are looking for.
- void
- FindExternalLexicalDecls(const DeclContext *DC,
- 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
- /// 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
- /// an incomplete type.
- void CompleteType(TagDecl *Tag) override;
-
- /// \brief Gives the external AST source an opportunity to complete an
- /// incomplete Objective-C class.
- ///
- /// This routine will only be invoked if the "externally completed" bit is
- /// set on the ObjCInterfaceDecl via the function
- /// \c ObjCInterfaceDecl::setExternallyCompleted().
- void CompleteType(ObjCInterfaceDecl *Class) override;
-
- /// \brief Loads comment ranges.
- void ReadComments() override;
-
- /// \brief Notify ExternalASTSource that we started deserialization of
- /// a decl or type so until FinishedDeserializing is called there may be
- /// decls that are initializing. Must be paired with FinishedDeserializing.
- void StartedDeserializing() override;
-
- /// \brief 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
- /// translation unit involving this external AST source.
- void StartTranslationUnit(ASTConsumer *Consumer) override;
-
- /// \brief Print any statistics that have been gathered regarding
- /// the external AST source.
- void PrintStats() override;
-
-
- /// \brief 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
- /// constructed. It is intended for clients who receive specific layout
- /// details rather than source code (such as LLDB). The client is expected
- /// to fill in the field offsets, base offsets, virtual base offsets, and
- /// complete object size.
- ///
- /// \param Record The record whose layout is being requested.
- ///
- /// \param Size The final size of the record, in bits.
- ///
- /// \param Alignment The final alignment of the record, in bits.
- ///
- /// \param FieldOffsets The offset of each of the fields within the record,
- /// expressed in bits. All of the fields must be provided with offsets.
- ///
- /// \param BaseOffsets The offset of each of the direct, non-virtual base
- /// classes. If any bases are not given offsets, the bases will be laid
- /// out according to the ABI.
- ///
- /// \param VirtualBaseOffsets The offset of each of the virtual base classes
- /// (either direct or not). If any bases are not given offsets, the bases will
- /// be laid out according to the ABI.
- ///
- /// \returns true if the record layout was provided, false otherwise.
- bool
- layoutRecordType(const RecordDecl *Record,
- uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
- llvm::DenseMap<const CXXRecordDecl *,
- CharUnits> &VirtualBaseOffsets) override;
-
- /// Return the amount of memory used by memory buffers, breaking down
- /// by heap-backed versus mmap'ed memory.
- void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
-
- //===--------------------------------------------------------------------===//
- // ExternalSemaSource.
- //===--------------------------------------------------------------------===//
-
- /// \brief 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.
- void ForgetSema() override;
-
- /// \brief Load the contents of the global method pool for a given
- /// selector.
- void ReadMethodPool(Selector Sel) override;
-
- /// \brief 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
- /// internal linkage, or used but not defined inline functions.
- void ReadUndefinedButUsed(
- llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override;
-
- void ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
- Exprs) override;
-
- /// \brief Do last resort, unqualified lookup on a LookupResult that
- /// Sema cannot find.
- ///
- /// \param R a LookupResult that is being recovered.
- ///
- /// \param S the Scope of the identifier occurrence.
- ///
- /// \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
- /// source.
- ///
- /// The external source should append its own tentative definitions to the
- /// given vector of tentative definitions. Note that this routine may be
- /// invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs) override;
-
- /// \brief 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
- /// given vector of declarations. Note that this routine may be
- /// invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- void ReadUnusedFileScopedDecls(
- SmallVectorImpl<const DeclaratorDecl*> &Decls) override;
-
- /// \brief Read the set of delegating constructors known to the
- /// external Sema source.
- ///
- /// The external source should append its own delegating constructors to the
- /// given vector of declarations. Note that this routine may be
- /// invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- void ReadDelegatingConstructors(
- SmallVectorImpl<CXXConstructorDecl*> &Decls) override;
-
- /// \brief 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
- /// the given vector of declarations. Note that this routine may be
- /// invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls) override;
-
- /// \brief 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
- /// be invoked multiple times; the external source should take care not to
- /// introduce the same declarations repeatedly.
- void ReadUnusedLocalTypedefNameCandidates(
- llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
-
- /// \brief Read the set of referenced selectors known to the
- /// external Sema source.
- ///
- /// The external source should append its own referenced selectors to the
- /// given vector of selectors. Note that this routine
- /// may be invoked multiple times; the external source should take care not
- /// to introduce the same selectors repeatedly.
- void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,
- SourceLocation> > &Sels) override;
-
- /// \brief Read the set of weak, undeclared identifiers known to the
- /// external Sema source.
- ///
- /// The external source should append its own weak, undeclared identifiers to
- /// the given vector. Note that this routine may be invoked multiple times;
- /// the external source should take care not to introduce the same identifiers
- /// repeatedly.
- void ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) override;
-
- /// \brief 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
- /// Sema source.
- ///
- /// The external source should append its own pending instantiations to the
- /// given vector. Note that this routine may be invoked multiple times; the
- /// external source should take care not to introduce the same instantiations
- /// repeatedly.
- void ReadPendingInstantiations(
- SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending) override;
-
- /// \brief 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
- /// external source should take care not to introduce the same map entries
- /// repeatedly.
- void ReadLateParsedTemplates(
- llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap)
- override;
-
- /// \copydoc ExternalSemaSource::CorrectTypo
- /// \note Returns the first nonempty correction.
- TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
- int LookupKind, Scope *S, CXXScopeSpec *SS,
- CorrectionCandidateCallback &CCC,
- DeclContext *MemberContext,
- bool EnteringContext,
- const ObjCObjectPointerType *OPT) override;
-
- /// \brief 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.
- ///
- /// \param Loc the location at which a complete type was required but not
- /// provided
- ///
- /// \param T the \c QualType that should have been complete at \p Loc
- ///
- /// \return true if a diagnostic was produced, false otherwise.
- bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
- QualType T) override;
-
- // isa/cast/dyn_cast support
- static bool classof(const MultiplexExternalSemaSource*) { return true; }
- //static bool classof(const ExternalSemaSource*) { return true; }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h
deleted file mode 100644
index b618e38..0000000
--- a/include/clang/Sema/ObjCMethodList.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===--- ObjCMethodList.h - A singly linked list of methods -----*- 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 ObjCMethodList, a singly-linked list of methods.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_OBJCMETHODLIST_H
-#define LLVM_CLANG_SEMA_OBJCMETHODLIST_H
-
-#include "llvm/ADT/PointerIntPair.h"
-
-namespace clang {
-
-class ObjCMethodDecl;
-
-/// \brief 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.
- llvm::PointerIntPair<ObjCMethodDecl *, 1> MethodAndHasMoreThanOneDecl;
- /// \brief The next list object and 2 bits for extra info.
- llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits;
-
- ObjCMethodList() { }
- ObjCMethodList(ObjCMethodDecl *M)
- : MethodAndHasMoreThanOneDecl(M, 0) {}
-
- ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); }
- unsigned getBits() const { return NextAndExtraBits.getInt(); }
- void setNext(ObjCMethodList *L) { NextAndExtraBits.setPointer(L); }
- void setBits(unsigned B) { NextAndExtraBits.setInt(B); }
-
- ObjCMethodDecl *getMethod() const {
- return MethodAndHasMoreThanOneDecl.getPointer();
- }
- void setMethod(ObjCMethodDecl *M) {
- return MethodAndHasMoreThanOneDecl.setPointer(M);
- }
-
- bool hasMoreThanOneDecl() const {
- return MethodAndHasMoreThanOneDecl.getInt();
- }
- void setHasMoreThanOneDecl(bool B) {
- return MethodAndHasMoreThanOneDecl.setInt(B);
- }
-};
-
-}
-
-#endif
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
deleted file mode 100644
index 20958b0..0000000
--- a/include/clang/Sema/Overload.h
+++ /dev/null
@@ -1,799 +0,0 @@
-//===--- Overload.h - C++ Overloading ---------------------------*- 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 data structures and types used in C++
-// overload resolution.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_OVERLOAD_H
-#define LLVM_CLANG_SEMA_OVERLOAD_H
-
-#include "clang/AST/Decl.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/Sema/SemaFixItUtils.h"
-#include "clang/Sema/TemplateDeduction.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/Allocator.h"
-
-namespace clang {
- class ASTContext;
- class CXXConstructorDecl;
- class CXXConversionDecl;
- class FunctionDecl;
- 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.
- };
-
- enum OverloadCandidateDisplayKind {
- /// Requests that all candidates be shown. Viable candidates will
- /// be printed first.
- OCD_AllCandidates,
-
- /// Requests that only viable candidates be shown.
- OCD_ViableCandidates
- };
-
- /// 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.
- 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_NoReturn_Adjustment, ///< Removal of noreturn from a type (Clang)
- 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_C_Only_Conversion, ///< Conversions allowed in C, but not C++
- ICK_Num_Conversion_Kinds, ///< The number of conversion kinds
- };
-
- /// ImplicitConversionRank - The rank of an implicit conversion
- /// kind. The enumerator values match with Table 9 of (C++
- /// 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_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*)
- };
-
- ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
-
- /// NarrowingKind - The kind of narrowing conversion being performed by a
- /// standard conversion sequence according to C++11 [dcl.init.list]p7.
- enum NarrowingKind {
- /// Not a narrowing conversion.
- NK_Not_Narrowing,
-
- /// A narrowing conversion by virtue of the source and destination types.
- NK_Type_Narrowing,
-
- /// A narrowing conversion, because a constant expression got narrowed.
- NK_Constant_Narrowing,
-
- /// A narrowing conversion, because a non-constant-expression variable might
- /// have got narrowed.
- NK_Variable_Narrowing
- };
-
- /// StandardConversionSequence - represents a standard conversion
- /// sequence (C++ 13.3.3.1.1). A standard conversion sequence
- /// contains between zero and three conversions. If a particular
- /// conversion is not needed, it will be set to the identity conversion
- /// (ICK_Identity). Note that the three conversions are
- /// specified as separate members (rather than in an array) so that
- /// we can keep the size of a standard conversion sequence to a
- /// single word.
- class StandardConversionSequence {
- public:
- /// First -- The first conversion can be an lvalue-to-rvalue
- /// conversion, array-to-pointer conversion, or
- /// function-to-pointer conversion.
- ImplicitConversionKind First : 8;
-
- /// Second - The second conversion can be an integral promotion,
- /// floating point promotion, integral conversion, floating point
- /// conversion, floating-integral conversion, pointer conversion,
- /// pointer-to-member conversion, or boolean conversion.
- ImplicitConversionKind Second : 8;
-
- /// Third - The third conversion can be a qualification conversion.
- ImplicitConversionKind Third : 8;
-
- /// \brief 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
- /// Objective-C lifetime (for automatic reference counting).
- unsigned QualificationIncludesObjCLifetime : 1;
-
- /// IncompatibleObjC - Whether this is an Objective-C conversion
- /// that we should warn about (if we actually use it).
- unsigned IncompatibleObjC : 1;
-
- /// ReferenceBinding - True when this is a reference binding
- /// (C++ [over.ics.ref]).
- unsigned ReferenceBinding : 1;
-
- /// DirectBinding - True when this is a reference binding that is a
- /// direct binding (C++ [dcl.init.ref]).
- unsigned DirectBinding : 1;
-
- /// \brief 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.
- unsigned BindsToFunctionLvalue : 1;
-
- /// \brief Whether we're binding to an rvalue.
- unsigned BindsToRvalue : 1;
-
- /// \brief 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
- /// Objective-C lifetime qualifier.
- unsigned ObjCLifetimeConversionBinding : 1;
-
- /// FromType - The type that this conversion is converting
- /// from. This is an opaque pointer that can be translated into a
- /// QualType.
- void *FromTypePtr;
-
- /// ToType - The types that this conversion is converting to in
- /// each step. This is an opaque pointer that can be translated
- /// into a QualType.
- void *ToTypePtrs[3];
-
- /// CopyConstructor - The copy constructor that is used to perform
- /// this conversion, when the conversion is actually just the
- /// initialization of an object via copy constructor. Such
- /// conversions are either identity conversions or derived-to-base
- /// conversions.
- CXXConstructorDecl *CopyConstructor;
-
- 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];
- ToTypePtrs[2] = ToTypePtrs[0];
- }
-
- 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]);
- }
-
- void setAsIdentityConversion();
-
- bool isIdentityConversion() const {
- return Second == ICK_Identity && Third == ICK_Identity;
- }
-
- ImplicitConversionRank getRank() const;
- NarrowingKind getNarrowingKind(ASTContext &Context, const Expr *Converted,
- APValue &ConstantValue,
- QualType &ConstantType) const;
- bool isPointerConversionToBool() const;
- bool isPointerConversionToVoidPointer(ASTContext& Context) const;
- void dump() const;
- };
-
- /// UserDefinedConversionSequence - Represents a user-defined
- /// conversion sequence (C++ 13.3.3.1.2).
- struct UserDefinedConversionSequence {
- /// \brief Represents the standard conversion that occurs before
- /// the actual user-defined conversion.
- ///
- /// C++11 13.3.3.1.2p1:
- /// If the user-defined conversion is specified by a constructor
- /// (12.3.1), the initial standard conversion sequence converts
- /// the source type to the type required by the argument of the
- /// constructor. If the user-defined conversion is specified by
- /// a conversion function (12.3.2), the initial standard
- /// conversion sequence converts the source type to the implicit
- /// object parameter of the conversion function.
- StandardConversionSequence Before;
-
- /// EllipsisConversion - When this is true, it means user-defined
- /// conversion sequence starts with a ... (ellipsis) conversion, instead of
- /// a standard conversion. In this case, 'Before' field must be ignored.
- // FIXME. I much rather put this as the first field. But there seems to be
- // a gcc code gen. bug which causes a crash in a test. Putting it here seems
- // to work around the crash.
- bool EllipsisConversion : 1;
-
- /// HadMultipleCandidates - When this is true, it means that the
- /// conversion function was resolved from an overloaded set having
- /// size greater than 1.
- bool HadMultipleCandidates : 1;
-
- /// After - Represents the standard conversion that occurs after
- /// the actual user-defined conversion.
- StandardConversionSequence After;
-
- /// ConversionFunction - The function that will perform the
- /// user-defined conversion. Null if the conversion is an
- /// aggregate initialization from an initializer list.
- FunctionDecl* ConversionFunction;
-
- /// \brief 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;
-
- void dump() const;
- };
-
- /// Represents an ambiguous user-defined conversion sequence.
- struct AmbiguousConversionSequence {
- typedef SmallVector<FunctionDecl*, 4> ConversionSet;
-
- void *FromTypePtr;
- void *ToTypePtr;
- char Buffer[sizeof(ConversionSet)];
-
- 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(); }
-
- ConversionSet &conversions() {
- return *reinterpret_cast<ConversionSet*>(Buffer);
- }
-
- const ConversionSet &conversions() const {
- return *reinterpret_cast<const ConversionSet*>(Buffer);
- }
-
- void addConversion(FunctionDecl *D) {
- conversions().push_back(D);
- }
-
- typedef ConversionSet::iterator iterator;
- iterator begin() { return conversions().begin(); }
- iterator end() { return conversions().end(); }
-
- typedef ConversionSet::const_iterator const_iterator;
- const_iterator begin() const { return conversions().begin(); }
- const_iterator end() const { return conversions().end(); }
-
- void construct();
- void destruct();
- void copyFrom(const AmbiguousConversionSequence &);
- };
-
- /// BadConversionSequence - Records information about an invalid
- /// conversion sequence.
- struct BadConversionSequence {
- enum FailureKind {
- no_conversion,
- unrelated_class,
- bad_qualifiers,
- lvalue_ref_to_rvalue,
- rvalue_ref_to_lvalue
- };
-
- // This can be null, e.g. for implicit object arguments.
- Expr *FromExpr;
-
- FailureKind Kind;
-
- private:
- // The type we're converting from (an opaque QualType).
- void *FromTy;
-
- // The type we're converting to (an opaque QualType).
- void *ToTy;
-
- public:
- void init(FailureKind K, Expr *From, QualType To) {
- init(K, From->getType(), To);
- FromExpr = From;
- }
- void init(FailureKind K, QualType From, QualType To) {
- Kind = K;
- FromExpr = nullptr;
- setFromType(From);
- setToType(To);
- }
-
- QualType getFromType() const { return QualType::getFromOpaquePtr(FromTy); }
- QualType getToType() const { return QualType::getFromOpaquePtr(ToTy); }
-
- void setFromExpr(Expr *E) {
- FromExpr = E;
- setFromType(E->getType());
- }
- void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); }
- void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); }
- };
-
- /// ImplicitConversionSequence - Represents an implicit conversion
- /// sequence, which may be a standard conversion sequence
- /// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2),
- /// or an ellipsis conversion sequence (C++ 13.3.3.1.3).
- class ImplicitConversionSequence {
- public:
- /// Kind - The kind of implicit conversion sequence. BadConversion
- /// specifies that there is no conversion from the source type to
- /// the target type. AmbiguousConversion represents the unique
- /// ambiguous conversion (C++0x [over.best.ics]p10).
- enum Kind {
- StandardConversion = 0,
- UserDefinedConversion,
- AmbiguousConversion,
- EllipsisConversion,
- BadConversion
- };
-
- private:
- enum {
- Uninitialized = BadConversion + 1
- };
-
- /// ConversionKind - The kind of implicit conversion sequence.
- unsigned ConversionKind : 30;
-
- /// \brief Whether the target is really a std::initializer_list, and the
- /// sequence only represents the worst element conversion.
- bool StdInitializerListElement : 1;
-
- void setKind(Kind K) {
- destruct();
- ConversionKind = K;
- }
-
- void destruct() {
- if (ConversionKind == AmbiguousConversion) Ambiguous.destruct();
- }
-
- public:
- union {
- /// When ConversionKind == StandardConversion, provides the
- /// details of the standard conversion sequence.
- StandardConversionSequence Standard;
-
- /// When ConversionKind == UserDefinedConversion, provides the
- /// details of the user-defined conversion sequence.
- UserDefinedConversionSequence UserDefined;
-
- /// When ConversionKind == AmbiguousConversion, provides the
- /// details of the ambiguous conversion.
- AmbiguousConversionSequence Ambiguous;
-
- /// When ConversionKind == BadConversion, provides the details
- /// of the bad conversion.
- BadConversionSequence Bad;
- };
-
- ImplicitConversionSequence()
- : ConversionKind(Uninitialized), StdInitializerListElement(false)
- {}
- ~ImplicitConversionSequence() {
- destruct();
- }
- ImplicitConversionSequence(const ImplicitConversionSequence &Other)
- : ConversionKind(Other.ConversionKind),
- StdInitializerListElement(Other.StdInitializerListElement)
- {
- switch (ConversionKind) {
- case Uninitialized: break;
- case StandardConversion: Standard = Other.Standard; break;
- case UserDefinedConversion: UserDefined = Other.UserDefined; break;
- case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break;
- case EllipsisConversion: break;
- case BadConversion: Bad = Other.Bad; break;
- }
- }
-
- ImplicitConversionSequence &
- operator=(const ImplicitConversionSequence &Other) {
- destruct();
- new (this) ImplicitConversionSequence(Other);
- return *this;
- }
-
- Kind getKind() const {
- assert(isInitialized() && "querying uninitialized conversion");
- return Kind(ConversionKind);
- }
-
- /// \brief Return a ranking of the implicit conversion sequence
- /// kind, where smaller ranks represent better conversion
- /// sequences.
- ///
- /// In particular, this routine gives user-defined conversion
- /// sequences and ambiguous conversion sequences the same rank,
- /// per C++ [over.best.ics]p10.
- unsigned getKindRank() const {
- switch (getKind()) {
- case StandardConversion:
- return 0;
-
- case UserDefinedConversion:
- case AmbiguousConversion:
- return 1;
-
- case EllipsisConversion:
- return 2;
-
- case BadConversion:
- return 3;
- }
-
- llvm_unreachable("Invalid ImplicitConversionSequence::Kind!");
- }
-
- bool isBad() const { return getKind() == BadConversion; }
- bool isStandard() const { return getKind() == StandardConversion; }
- bool isEllipsis() const { return getKind() == EllipsisConversion; }
- bool isAmbiguous() const { return getKind() == AmbiguousConversion; }
- bool isUserDefined() const { return getKind() == UserDefinedConversion; }
- bool isFailure() const { return isBad() || isAmbiguous(); }
-
- /// Determines whether this conversion sequence has been
- /// initialized. Most operations should never need to query
- /// uninitialized conversions and should assert as above.
- bool isInitialized() const { return ConversionKind != Uninitialized; }
-
- /// Sets this sequence as a bad conversion for an explicit argument.
- void setBad(BadConversionSequence::FailureKind Failure,
- Expr *FromExpr, QualType ToType) {
- setKind(BadConversion);
- Bad.init(Failure, FromExpr, ToType);
- }
-
- /// Sets this sequence as a bad conversion for an implicit argument.
- void setBad(BadConversionSequence::FailureKind Failure,
- QualType FromType, QualType ToType) {
- setKind(BadConversion);
- Bad.init(Failure, FromType, ToType);
- }
-
- void setStandard() { setKind(StandardConversion); }
- void setEllipsis() { setKind(EllipsisConversion); }
- void setUserDefined() { setKind(UserDefinedConversion); }
- void setAmbiguous() {
- if (ConversionKind == AmbiguousConversion) return;
- ConversionKind = AmbiguousConversion;
- Ambiguous.construct();
- }
-
- /// \brief Whether the target is really a std::initializer_list, and the
- /// sequence only represents the worst element conversion.
- bool isStdInitializerListElement() const {
- return StdInitializerListElement;
- }
-
- void setStdInitializerListElement(bool V = true) {
- StdInitializerListElement = V;
- }
-
- // The result of a comparison between implicit conversion
- // sequences. Use Sema::CompareImplicitConversionSequences to
- // actually perform the comparison.
- enum CompareKind {
- Better = -1,
- Indistinguishable = 0,
- Worse = 1
- };
-
- void DiagnoseAmbiguousConversion(Sema &S,
- SourceLocation CaretLoc,
- const PartialDiagnostic &PDiag) const;
-
- void dump() const;
- };
-
- enum OverloadFailureKind {
- ovl_fail_too_many_arguments,
- ovl_fail_too_few_arguments,
- ovl_fail_bad_conversion,
- ovl_fail_bad_deduction,
-
- /// This conversion candidate was not considered because it
- /// duplicates the work of a trivial or derived-to-base
- /// conversion.
- ovl_fail_trivial_conversion,
-
- /// This conversion candidate was not considered because it is
- /// an illegal instantiation of a constructor temploid: it is
- /// callable with one argument, we only have one argument, and
- /// its first parameter type is exactly the type of the class.
- ///
- /// Defining such a constructor directly is illegal, and
- /// template-argument deduction is supposed to ignore such
- /// instantiations, but we can still get one with the right
- /// kind of implicit instantiation.
- ovl_fail_illegal_constructor,
-
- /// This conversion candidate is not viable because its result
- /// type is not implicitly convertible to the desired type.
- ovl_fail_bad_final_conversion,
-
- /// This conversion function template specialization candidate is not
- /// viable because the final conversion was not an exact match.
- ovl_fail_final_conversion_not_exact,
-
- /// (CUDA) This candidate was not viable because the callee
- /// was not accessible from the caller's target (i.e. host->device,
- /// global->host, device->host).
- ovl_fail_bad_target,
-
- /// This candidate function was not viable because an enable_if
- /// attribute disabled it.
- ovl_fail_enable_if
- };
-
- /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
- struct OverloadCandidate {
- /// Function - The actual function that this candidate
- /// represents. When NULL, this is a built-in candidate
- /// (C++ [over.oper]) or a surrogate for a conversion to a
- /// function pointer or reference (C++ [over.call.object]).
- FunctionDecl *Function;
-
- /// FoundDecl - The original declaration that was looked up /
- /// invented / otherwise found, together with its access.
- /// Might be a UsingShadowDecl or a FunctionTemplateDecl.
- DeclAccessPair FoundDecl;
-
- // BuiltinTypes - Provides the return and parameter types of a
- // built-in overload candidate. Only valid when Function is NULL.
- struct {
- QualType ResultTy;
- QualType ParamTypes[3];
- } BuiltinTypes;
-
- /// Surrogate - The conversion function for which this candidate
- /// is a surrogate, but only if IsSurrogate is true.
- CXXConversionDecl *Surrogate;
-
- /// Conversions - The conversion sequences used to convert the
- /// function arguments to the function parameters, the pointer points to a
- /// fixed size array with NumConversions elements. The memory is owned by
- /// the OverloadCandidateSet.
- ImplicitConversionSequence *Conversions;
-
- /// The FixIt hints which can be used to fix the Bad candidate.
- ConversionFixItGenerator Fix;
-
- /// NumConversions - The number of elements in the Conversions array.
- unsigned NumConversions;
-
- /// Viable - True to indicate that this overload candidate is viable.
- bool Viable;
-
- /// IsSurrogate - True to indicate that this candidate is a
- /// surrogate for a conversion to a function pointer or reference
- /// (C++ [over.call.object]).
- bool IsSurrogate;
-
- /// IgnoreObjectArgument - True to indicate that the first
- /// argument's conversion, which for this function represents the
- /// implicit object argument, should be ignored. This will be true
- /// when the candidate is a static member function (where the
- /// implicit object argument is just a placeholder) or a
- /// non-static member function when the call doesn't have an
- /// object argument.
- bool IgnoreObjectArgument;
-
- /// FailureKind - The reason why this candidate is not viable.
- /// Actually an OverloadFailureKind.
- unsigned char FailureKind;
-
- /// \brief The number of call arguments that were explicitly provided,
- /// to be used while performing partial ordering of function templates.
- unsigned ExplicitCallArguments;
-
- union {
- DeductionFailureInfo DeductionFailure;
-
- /// FinalConversion - For a conversion function (where Function is
- /// a CXXConversionDecl), the standard conversion that occurs
- /// after the call to the overload candidate to convert the result
- /// of calling the conversion function to the required type.
- StandardConversionSequence FinalConversion;
- };
-
- /// hasAmbiguousConversion - Returns whether this overload
- /// candidate requires an ambiguous conversion or not.
- bool hasAmbiguousConversion() const {
- for (unsigned i = 0, e = NumConversions; i != e; ++i) {
- if (!Conversions[i].isInitialized()) return false;
- if (Conversions[i].isAmbiguous()) return true;
- }
- return false;
- }
-
- bool TryToFixBadConversion(unsigned Idx, Sema &S) {
- bool CanFix = Fix.tryToFixConversion(
- Conversions[Idx].Bad.FromExpr,
- Conversions[Idx].Bad.getFromType(),
- Conversions[Idx].Bad.getToType(), S);
-
- // If at least one conversion fails, the candidate cannot be fixed.
- if (!CanFix)
- Fix.clear();
-
- return CanFix;
- }
-
- unsigned getNumParams() const {
- if (IsSurrogate) {
- auto STy = Surrogate->getConversionType();
- while (STy->isPointerType() || STy->isReferenceType())
- STy = STy->getPointeeType();
- return STy->getAs<FunctionProtoType>()->getNumParams();
- }
- if (Function)
- return Function->getNumParams();
- return ExplicitCallArguments;
- }
- };
-
- /// OverloadCandidateSet - A set of overload candidates, used in C++
- /// overload resolution (C++ 13.3).
- class OverloadCandidateSet {
- public:
- enum CandidateSetKind {
- /// Normal lookup.
- CSK_Normal,
- /// Lookup for candidates for 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
- };
-
- private:
- SmallVector<OverloadCandidate, 16> Candidates;
- llvm::SmallPtrSet<Decl *, 16> Functions;
-
- // Allocator for OverloadCandidate::Conversions. We store the first few
- // elements inline to avoid allocation for small sets.
- llvm::BumpPtrAllocator ConversionSequenceAllocator;
-
- SourceLocation Loc;
- CandidateSetKind Kind;
-
- unsigned NumInlineSequences;
- llvm::AlignedCharArray<llvm::AlignOf<ImplicitConversionSequence>::Alignment,
- 16 * sizeof(ImplicitConversionSequence)> InlineSpace;
-
- OverloadCandidateSet(const OverloadCandidateSet &) = delete;
- void operator=(const OverloadCandidateSet &) = delete;
-
- void destroyCandidates();
-
- public:
- OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
- : Loc(Loc), Kind(CSK), NumInlineSequences(0) {}
- ~OverloadCandidateSet() { destroyCandidates(); }
-
- SourceLocation getLocation() const { return Loc; }
- CandidateSetKind getKind() const { return Kind; }
-
- /// \brief 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.
- void clear();
-
- typedef SmallVectorImpl<OverloadCandidate>::iterator 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
- /// to the overload set.
- OverloadCandidate &addCandidate(unsigned NumConversions = 0) {
- Candidates.push_back(OverloadCandidate());
- OverloadCandidate &C = Candidates.back();
-
- // Assign space from the inline array if there are enough free slots
- // available.
- if (NumConversions + NumInlineSequences <= 16) {
- ImplicitConversionSequence *I =
- (ImplicitConversionSequence *)InlineSpace.buffer;
- C.Conversions = &I[NumInlineSequences];
- NumInlineSequences += NumConversions;
- } else {
- // Otherwise get memory from the allocator.
- C.Conversions = ConversionSequenceAllocator
- .Allocate<ImplicitConversionSequence>(NumConversions);
- }
-
- // Construct the new objects.
- for (unsigned i = 0; i != NumConversions; ++i)
- new (&C.Conversions[i]) ImplicitConversionSequence();
-
- C.NumConversions = NumConversions;
- return C;
- }
-
- /// Find the best viable function on this overload set, if it exists.
- OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
- OverloadCandidateSet::iterator& Best,
- bool UserDefinedConversion = false);
-
- void NoteCandidates(Sema &S,
- OverloadCandidateDisplayKind OCD,
- ArrayRef<Expr *> Args,
- StringRef Opc = "",
- SourceLocation Loc = SourceLocation());
- };
-
- bool isBetterOverloadCandidate(Sema &S,
- const OverloadCandidate& Cand1,
- const OverloadCandidate& Cand2,
- SourceLocation Loc,
- bool UserDefinedConversion = false);
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
deleted file mode 100644
index 8acf9e8..0000000
--- a/include/clang/Sema/Ownership.h
+++ /dev/null
@@ -1,287 +0,0 @@
-//===--- Ownership.h - Parser ownership helpers -----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains classes for managing ownership of Stmt and Expr nodes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_OWNERSHIP_H
-#define LLVM_CLANG_SEMA_OWNERSHIP_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/PointerIntPair.h"
-
-//===----------------------------------------------------------------------===//
-// 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.
- /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like
- /// a pointer.
- ///
- /// This is a very simple POD type that wraps a pointer that the Parser
- /// doesn't know about but that Sema or another client does. The PtrTy
- /// template argument is used to make sure that "Decl" pointers are not
- /// compatible with "Type" pointers for example.
- template <class PtrTy>
- class OpaquePtr {
- void *Ptr;
- explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
-
- typedef llvm::PointerLikeTypeTraits<PtrTy> Traits;
-
- public:
- OpaquePtr() : Ptr(nullptr) {}
-
- static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
-
- /// \brief Returns plain pointer to the entity pointed by this wrapper.
- /// \tparam PointeeT Type of pointed entity.
- ///
- /// It is identical to getPtrAs<PointeeT*>.
- template <typename PointeeT> PointeeT* getPtrTo() const {
- return get();
- }
-
- /// \brief Returns pointer converted to the specified type.
- /// \tparam PtrT Result pointer type. There must be implicit conversion
- /// from PtrTy to PtrT.
- ///
- /// In contrast to getPtrTo, this method allows the return type to be
- /// a smart pointer.
- template <typename PtrT> PtrT getPtrAs() const {
- return get();
- }
-
- PtrTy get() const {
- return Traits::getFromVoidPointer(Ptr);
- }
-
- void set(PtrTy P) {
- Ptr = Traits::getAsVoidPointer(P);
- }
-
- explicit operator bool() const { return Ptr != nullptr; }
-
- void *getAsOpaquePtr() const { return Ptr; }
- static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
- };
-
- /// UnionOpaquePtr - A version of OpaquePtr suitable for membership
- /// in a union.
- template <class T> struct UnionOpaquePtr {
- void *Ptr;
-
- static UnionOpaquePtr make(OpaquePtr<T> P) {
- UnionOpaquePtr OP = { P.getAsOpaquePtr() };
- return OP;
- }
-
- OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); }
- operator OpaquePtr<T>() const { return get(); }
-
- UnionOpaquePtr &operator=(OpaquePtr<T> P) {
- Ptr = P.getAsOpaquePtr();
- return *this;
- }
- };
-}
-
-namespace llvm {
- template <class T>
- class PointerLikeTypeTraits<clang::OpaquePtr<T> > {
- public:
- 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; };
-}
-
-namespace clang {
- // Basic
- class DiagnosticBuilder;
-
- // Determines whether the low bit of the result pointer for the
- // given UID is always zero. If so, ActionResult will use that bit
- // for it's "invalid" flag.
- template<class Ptr>
- struct IsResultPtrLowBitFree {
- static const bool value = false;
- };
-
- /// ActionResult - This structure is used while parsing/acting on
- /// expressions, stmts, etc. It encapsulates both the object returned by
- /// the action, plus a sense of whether or not it is valid.
- /// When CompressInvalid is true, the "invalid" flag will be
- /// stored in the low bit of the Val pointer.
- template<class PtrTy,
- bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value>
- class ActionResult {
- PtrTy Val;
- bool Invalid;
-
- public:
- ActionResult(bool Invalid = false)
- : Val(PtrTy()), Invalid(Invalid) {}
- ActionResult(PtrTy val) : Val(val), Invalid(false) {}
- ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
-
- // These two overloads prevent void* -> bool conversions.
- ActionResult(const void *);
- ActionResult(volatile void *);
-
- bool isInvalid() const { return Invalid; }
- bool isUsable() const { return !Invalid && Val; }
- bool isUnset() const { return !Invalid && !Val; }
-
- PtrTy get() const { return Val; }
- template <typename T> T *getAs() { return static_cast<T*>(get()); }
-
- void set(PtrTy V) { Val = V; }
-
- const ActionResult &operator=(PtrTy RHS) {
- Val = RHS;
- Invalid = false;
- return *this;
- }
- };
-
- // This ActionResult partial specialization places the "invalid"
- // flag into the low bit of the pointer.
- template<typename PtrTy>
- class ActionResult<PtrTy, true> {
- // A pointer whose low bit is 1 if this result is invalid, 0
- // otherwise.
- uintptr_t PtrWithInvalid;
- typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits;
- public:
- ActionResult(bool Invalid = false)
- : 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) { }
-
- // These two overloads prevent void* -> bool conversions.
- ActionResult(const void *);
- ActionResult(volatile void *);
-
- bool isInvalid() const { return PtrWithInvalid & 0x01; }
- bool isUsable() const { return PtrWithInvalid > 0x01; }
- bool isUnset() const { return PtrWithInvalid == 0; }
-
- PtrTy get() const {
- 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) {
- void *VP = PtrTraits::getAsVoidPointer(V);
- PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
- assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
- }
-
- const ActionResult &operator=(PtrTy RHS) {
- void *VP = PtrTraits::getAsVoidPointer(RHS);
- PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
- assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
- return *this;
- }
-
- // For types where we can fit a flag in with the pointer, provide
- // conversions to/from pointer type.
- static ActionResult getFromOpaquePointer(void *P) {
- ActionResult Result;
- Result.PtrWithInvalid = (uintptr_t)P;
- return Result;
- }
- void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; }
- };
-
- /// An opaque type for threading parsed type information through the
- /// parser.
- typedef OpaquePtr<QualType> ParsedType;
- typedef UnionOpaquePtr<QualType> UnionParsedType;
-
- // We can re-use the low bit of expression, statement, base, and
- // member-initializer pointers for the "invalid" flag of
- // ActionResult.
- template<> struct IsResultPtrLowBitFree<Expr*> {
- static const bool value = true;
- };
- template<> struct IsResultPtrLowBitFree<Stmt*> {
- static const bool value = true;
- };
- template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> {
- static const bool value = true;
- };
- template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> {
- 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;
-
- typedef ActionResult<Decl*> DeclResult;
- typedef OpaquePtr<TemplateName> ParsedTemplateTy;
-
- typedef MutableArrayRef<Expr*> MultiExprArg;
- typedef MutableArrayRef<Stmt*> MultiStmtArg;
- typedef MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr;
- typedef MutableArrayRef<ParsedType> MultiTypeArg;
- typedef MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg;
-
- inline ExprResult ExprError() { return ExprResult(true); }
- inline StmtResult StmtError() { return StmtResult(true); }
-
- inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
- inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
-
- inline ExprResult ExprEmpty() { return ExprResult(false); }
- inline StmtResult StmtEmpty() { return StmtResult(false); }
-
- inline Expr *AssertSuccess(ExprResult R) {
- assert(!R.isInvalid() && "operation was asserted to never fail!");
- return R.get();
- }
-
- inline Stmt *AssertSuccess(StmtResult R) {
- assert(!R.isInvalid() && "operation was asserted to never fail!");
- return R.get();
- }
-}
-
-#endif
diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h
deleted file mode 100644
index b36425f..0000000
--- a/include/clang/Sema/ParsedTemplate.h
+++ /dev/null
@@ -1,214 +0,0 @@
-//===--- ParsedTemplate.h - Template Parsing Data Types -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides data structures that store the parsed representation of
-// templates.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
-#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
-
-#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/Ownership.h"
-#include <cassert>
-
-namespace clang {
- /// \brief Represents the parsed form of a C++ template argument.
- class ParsedTemplateArgument {
- public:
- /// \brief Describes the kind of template argument that was parsed.
- enum KindType {
- /// \brief A template type parameter, stored as a type.
- Type,
- /// \brief A non-type template parameter, stored as an expression.
- NonType,
- /// \brief A template template argument, stored as a template name.
- Template
- };
-
- /// \brief 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.
- ///
- /// \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.
- ///
- /// \param SS the C++ scope specifier that precedes the template name, if
- /// any.
- ///
- /// \param Template the template to which this template template
- /// argument refers.
- ///
- /// \param TemplateLoc the location of the template name.
- ParsedTemplateArgument(const CXXScopeSpec &SS,
- ParsedTemplateTy Template,
- SourceLocation TemplateLoc)
- : Kind(ParsedTemplateArgument::Template),
- Arg(Template.getAsOpaquePtr()),
- SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
-
- /// \brief Determine whether the given template argument is invalid.
- bool isInvalid() const { return Arg == nullptr; }
-
- /// \brief Determine what kind of template argument we have.
- KindType getKind() const { return Kind; }
-
- /// \brief 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.
- 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.
- ParsedTemplateTy getAsTemplate() const {
- assert(Kind == Template && "Not a template template argument");
- return ParsedTemplateTy::getFromOpaquePtr(Arg);
- }
-
- /// \brief Retrieve the location of the template argument.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Retrieve the nested-name-specifier that precedes the template
- /// name in a template template argument.
- const CXXScopeSpec &getScopeSpec() const {
- assert(Kind == Template &&
- "Only template template arguments can have a scope specifier");
- return SS;
- }
-
- /// \brief Retrieve the location of the ellipsis that makes a template
- /// template argument into a pack expansion.
- SourceLocation getEllipsisLoc() const {
- assert(Kind == Template &&
- "Only template template arguments can have an ellipsis");
- return EllipsisLoc;
- }
-
- /// \brief Retrieve a pack expansion of the given template template
- /// argument.
- ///
- /// \param EllipsisLoc The location of the ellipsis.
- ParsedTemplateArgument getTemplatePackExpansion(
- SourceLocation EllipsisLoc) const;
-
- private:
- KindType Kind;
-
- /// \brief The actual template argument representation, which may be
- /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an
- /// expression), or an ActionBase::TemplateTy (for a template).
- void *Arg;
-
- /// \brief The nested-name-specifier that can accompany a template template
- /// argument.
- CXXScopeSpec SS;
-
- /// \brief the location of the template argument.
- SourceLocation Loc;
-
- /// \brief 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
- /// token.
- ///
- /// A template-id annotation token contains the template declaration,
- /// template arguments, whether those template arguments were types,
- /// expressions, or template names, and the source locations for important
- /// tokens. All of the information about template arguments is allocated
- /// directly after this structure.
- struct TemplateIdAnnotation {
- /// \brief The nested-name-specifier that precedes the template name.
- CXXScopeSpec SS;
-
- /// TemplateKWLoc - The location of the template keyword within the
- /// source.
- SourceLocation TemplateKWLoc;
-
- /// TemplateNameLoc - The location of the template name within the
- /// source.
- SourceLocation TemplateNameLoc;
-
- /// FIXME: Temporarily stores the name of a specialization
- IdentifierInfo *Name;
-
- /// FIXME: Temporarily stores the overloaded operator kind.
- OverloadedOperatorKind Operator;
-
- /// The declaration of the template corresponding to the
- /// template-name.
- ParsedTemplateTy Template;
-
- /// The kind of template that Template refers to.
- TemplateNameKind Kind;
-
- /// The location of the '<' before the template argument
- /// list.
- SourceLocation LAngleLoc;
-
- /// The location of the '>' after the template argument
- /// list.
- SourceLocation RAngleLoc;
-
- /// NumArgs - The number of template arguments.
- unsigned NumArgs;
-
- /// \brief Retrieves a pointer to the template arguments
- ParsedTemplateArgument *getTemplateArgs() {
- return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
- }
-
- /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
- /// appends it to List.
- static TemplateIdAnnotation *
- Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
- TemplateIdAnnotation *TemplateId
- = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
- sizeof(ParsedTemplateArgument) * NumArgs);
- TemplateId->NumArgs = NumArgs;
-
- // Default-construct nested-name-specifier.
- new (&TemplateId->SS) CXXScopeSpec();
-
- // Default-construct parsed template arguments.
- ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
- for (unsigned I = 0; I != NumArgs; ++I)
- new (TemplateArgs + I) ParsedTemplateArgument();
-
- List.push_back(TemplateId);
- return TemplateId;
- }
-
- void Destroy() {
- SS.~CXXScopeSpec();
- free(this);
- }
- };
-
- /// Retrieves the range of the given template parameter lists.
- SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
- unsigned NumParams);
-}
-
-#endif
diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/Sema/PrettyDeclStackTrace.h
deleted file mode 100644
index ca22e64..0000000
--- a/include/clang/Sema/PrettyDeclStackTrace.h
+++ /dev/null
@@ -1,47 +0,0 @@
-//===- PrettyDeclStackTrace.h - Stack trace for decl processing -*- 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 an llvm::PrettyStackTraceEntry object for showing
-// that a particular declaration was being processed when a crash
-// occurred.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H
-#define LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/PrettyStackTrace.h"
-
-namespace clang {
-
-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;
- Decl *TheDecl;
- SourceLocation Loc;
- const char *Message;
-
-public:
- PrettyDeclStackTraceEntry(Sema &S, Decl *D, SourceLocation Loc,
- const char *Msg)
- : S(S), TheDecl(D), Loc(Loc), Message(Msg) {}
-
- void print(raw_ostream &OS) const override;
-};
-
-}
-
-#endif
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
deleted file mode 100644
index dfc6f9c..0000000
--- a/include/clang/Sema/Scope.h
+++ /dev/null
@@ -1,484 +0,0 @@
-//===--- Scope.h - Scope interface ------------------------------*- 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 Scope interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_SCOPE_H
-#define LLVM_CLANG_SEMA_SCOPE_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace llvm {
-
-class raw_ostream;
-
-}
-
-namespace clang {
-
-class Decl;
-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
- /// means that labels are set here.
- FnScope = 0x01,
-
- /// \brief 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
- /// embedded into it.
- ContinueScope = 0x04,
-
- /// \brief 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.
- ControlScope = 0x10,
-
- /// \brief The scope of a struct/union/class definition.
- ClassScope = 0x20,
-
- /// \brief 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
- /// 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
- /// parameters within a function prototype.
- FunctionPrototypeScope = 0x100,
-
- /// \brief 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
- /// \@catch statement.
- AtCatchScope = 0x400,
-
- /// \brief 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.
- SwitchScope = 0x1000,
-
- /// \brief 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.
- FnTryCatchScope = 0x4000,
-
- /// \brief This is the scope of OpenMP executable directive.
- OpenMPDirectiveScope = 0x8000,
-
- /// \brief This is the scope of some OpenMP loop directive.
- OpenMPLoopDirectiveScope = 0x10000,
-
- /// \brief 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,
-
- /// This scope corresponds to an enum.
- EnumScope = 0x40000,
-
- /// This scope corresponds to an SEH try.
- SEHTryScope = 0x80000,
-
- /// This scope corresponds to an SEH except.
- SEHExceptScope = 0x100000,
-
- /// We are currently in the filter expression of an SEH except block.
- SEHFilterScope = 0x200000,
- };
-private:
- /// The parent scope for this scope. This is null for the translation-unit
- /// scope.
- Scope *AnyParent;
-
- /// Flags - This contains a set of ScopeFlags, which indicates how the scope
- /// interrelates with other control flow statements.
- unsigned Flags;
-
- /// Depth - This is the depth of this scope. The translation-unit scope has
- /// depth 0.
- unsigned short Depth;
-
- /// \brief Declarations with static linkage are mangled with the number of
- /// scopes seen as a component.
- unsigned short MSLastManglingNumber;
-
- unsigned short MSCurManglingNumber;
-
- /// PrototypeDepth - This is the number of function prototype scopes
- /// enclosing this scope, including this scope.
- unsigned short PrototypeDepth;
-
- /// PrototypeIndex - This is the number of parameters currently
- /// declared in this scope.
- unsigned short PrototypeIndex;
-
- /// FnParent - If this scope has a parent scope that is a function body, this
- /// pointer is non-null and points to it. This is used for label processing.
- Scope *FnParent;
- Scope *MSLastManglingParent;
-
- /// BreakParent/ContinueParent - This is a direct link to the innermost
- /// BreakScope/ContinueScope which contains the contents of this scope
- /// for control flow purposes (and might be this scope itself), or null
- /// if there is no such scope.
- Scope *BreakParent, *ContinueParent;
-
- /// BlockParent - This is a direct link to the immediately containing
- /// BlockScope if this scope is not one, or null if there is none.
- Scope *BlockParent;
-
- /// TemplateParamParent - This is a direct link to the
- /// immediately containing template parameter scope. In the
- /// case of nested templates, template parameter scopes can have
- /// other template parameter scopes as parents.
- Scope *TemplateParamParent;
-
- /// DeclsInScope - This keeps track of all declarations in this scope. When
- /// the declaration is added to the scope, it is set as the current
- /// declaration for the identifier in the IdentifierTable. When the scope is
- /// 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;
- DeclSetTy DeclsInScope;
-
- /// The DeclContext with which this scope is associated. For
- /// example, the entity of a class scope is the class itself, the
- /// entity of a function scope is a function, etc.
- DeclContext *Entity;
-
- typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy;
- UsingDirectivesTy UsingDirectives;
-
- /// \brief Used to determine if errors occurred in this scope.
- DiagnosticErrorTrap ErrorTrap;
-
- /// A lattice consisting of undefined, a single NRVO candidate variable in
- /// this scope, or over-defined. The bit is true when over-defined.
- llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
-
-public:
- Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
- : ErrorTrap(Diag) {
- Init(Parent, ScopeFlags);
- }
-
- /// getFlags - Return the flags for this scope.
- ///
- unsigned getFlags() const { return Flags; }
- void setFlags(unsigned F) { Flags = 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; }
-
- const Scope *getMSLastManglingParent() const {
- return MSLastManglingParent;
- }
- Scope *getMSLastManglingParent() { return MSLastManglingParent; }
-
- /// getContinueParent - Return the closest scope that a continue statement
- /// would be affected by.
- Scope *getContinueParent() {
- return ContinueParent;
- }
-
- const Scope *getContinueParent() const {
- return const_cast<Scope*>(this)->getContinueParent();
- }
-
- /// getBreakParent - Return the closest scope that a break statement
- /// would be affected by.
- Scope *getBreakParent() {
- return BreakParent;
- }
- const Scope *getBreakParent() const {
- return const_cast<Scope*>(this)->getBreakParent();
- }
-
- Scope *getBlockParent() { return BlockParent; }
- const Scope *getBlockParent() const { return BlockParent; }
-
- Scope *getTemplateParamParent() { return TemplateParamParent; }
- const Scope *getTemplateParamParent() const { return TemplateParamParent; }
-
- /// Returns the number of function prototype scopes in this scope
- /// chain.
- unsigned getFunctionPrototypeDepth() const {
- return PrototypeDepth;
- }
-
- /// Return the number of parameters declared in this function
- /// prototype, increasing it by one for the next call.
- unsigned getNextFunctionPrototypeIndex() {
- assert(isFunctionPrototypeScope());
- return PrototypeIndex++;
- }
-
- typedef llvm::iterator_range<DeclSetTy::iterator> decl_range;
- decl_range decls() const {
- return decl_range(DeclsInScope.begin(), DeclsInScope.end());
- }
- bool decl_empty() const { return DeclsInScope.empty(); }
-
- void AddDecl(Decl *D) {
- DeclsInScope.insert(D);
- }
-
- void RemoveDecl(Decl *D) {
- DeclsInScope.erase(D);
- }
-
- void incrementMSManglingNumber() {
- if (Scope *MSLMP = getMSLastManglingParent()) {
- MSLMP->MSLastManglingNumber += 1;
- MSCurManglingNumber += 1;
- }
- }
-
- void decrementMSManglingNumber() {
- if (Scope *MSLMP = getMSLastManglingParent()) {
- MSLMP->MSLastManglingNumber -= 1;
- MSCurManglingNumber -= 1;
- }
- }
-
- unsigned getMSLastManglingNumber() const {
- if (const Scope *MSLMP = getMSLastManglingParent())
- return MSLMP->MSLastManglingNumber;
- return 1;
- }
-
- unsigned getMSCurManglingNumber() const {
- return MSCurManglingNumber;
- }
-
- /// isDeclScope - Return true if this is the scope that the specified decl is
- /// declared in.
- bool isDeclScope(Decl *D) {
- return DeclsInScope.count(D) != 0;
- }
-
- DeclContext *getEntity() const { return Entity; }
- void setEntity(DeclContext *E) { Entity = E; }
-
- bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); }
-
- bool hasUnrecoverableErrorOccurred() const {
- return ErrorTrap.hasUnrecoverableErrorOccurred();
- }
-
- /// isFunctionScope() - Return true if this scope is a function scope.
- bool isFunctionScope() const { return (getFlags() & Scope::FnScope); }
-
- /// isClassScope - Return true if this scope is a class/struct/union scope.
- bool isClassScope() const {
- return (getFlags() & Scope::ClassScope);
- }
-
- /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
- /// method scope or is inside one.
- bool isInCXXInlineMethodScope() const {
- if (const Scope *FnS = getFnParent()) {
- assert(FnS->getParent() && "TUScope not created?");
- return FnS->getParent()->isClassScope();
- }
- return false;
- }
-
- /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
- /// Objective-C method body. Note that this method is not constant time.
- bool isInObjcMethodScope() const {
- for (const Scope *S = this; S; S = S->getParent()) {
- // If this scope is an objc method scope, then we succeed.
- if (S->getFlags() & ObjCMethodScope)
- return true;
- }
- return false;
- }
-
- /// isInObjcMethodOuterScope - Return true if this scope is an
- /// Objective-C method outer most body.
- bool isInObjcMethodOuterScope() const {
- if (const Scope *S = this) {
- // If this scope is an objc method scope, then we succeed.
- if (S->getFlags() & ObjCMethodScope)
- return true;
- }
- return false;
- }
-
-
- /// isTemplateParamScope - Return true if this scope is a C++
- /// template parameter scope.
- bool isTemplateParamScope() const {
- return getFlags() & Scope::TemplateParamScope;
- }
-
- /// isFunctionPrototypeScope - Return true if this scope is a
- /// function prototype scope.
- bool isFunctionPrototypeScope() const {
- return getFlags() & Scope::FunctionPrototypeScope;
- }
-
- /// isAtCatchScope - Return true if this scope is \@catch.
- bool isAtCatchScope() const {
- return getFlags() & Scope::AtCatchScope;
- }
-
- /// isSwitchScope - Return true if this scope is a switch scope.
- bool isSwitchScope() const {
- for (const Scope *S = this; S; S = S->getParent()) {
- if (S->getFlags() & Scope::SwitchScope)
- return true;
- else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
- Scope::BlockScope | Scope::TemplateParamScope |
- Scope::FunctionPrototypeScope |
- Scope::AtCatchScope | Scope::ObjCMethodScope))
- return false;
- }
- return false;
- }
-
- /// \brief 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
- /// (for example, 'omp for', 'omp simd').
- bool isOpenMPLoopDirectiveScope() const {
- if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
- assert(isOpenMPDirectiveScope() &&
- "OpenMP loop directive scope is not a directive scope");
- return true;
- }
- return false;
- }
-
- /// \brief 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
- /// directive attached.
- bool isOpenMPLoopScope() const {
- const Scope *P = getParent();
- return P && P->isOpenMPLoopDirectiveScope();
- }
-
- /// \brief 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.
- bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
-
- /// \brief Determine whether this scope is a SEH '__except' block.
- bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }
-
- /// \brief 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.
- bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; }
-
- /// containedInPrototypeScope - Return true if this or a parent scope
- /// is a FunctionPrototypeScope.
- bool containedInPrototypeScope() const;
-
- void PushUsingDirective(UsingDirectiveDecl *UDir) {
- UsingDirectives.push_back(UDir);
- }
-
- typedef llvm::iterator_range<UsingDirectivesTy::iterator>
- using_directives_range;
-
- using_directives_range using_directives() {
- return using_directives_range(UsingDirectives.begin(),
- UsingDirectives.end());
- }
-
- void addNRVOCandidate(VarDecl *VD) {
- if (NRVO.getInt())
- return;
- if (NRVO.getPointer() == nullptr) {
- NRVO.setPointer(VD);
- return;
- }
- if (NRVO.getPointer() != VD)
- setNoNRVO();
- }
-
- void setNoNRVO() {
- NRVO.setInt(1);
- 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
- /// variables accordingly.
- ///
- void AddFlags(unsigned Flags);
-
- void dumpImpl(raw_ostream &OS) const;
- void dump() const;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
deleted file mode 100644
index d13667e..0000000
--- a/include/clang/Sema/ScopeInfo.h
+++ /dev/null
@@ -1,858 +0,0 @@
-//===--- ScopeInfo.h - Information about a semantic context -----*- 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 FunctionScopeInfo and its subclasses, which contain
-// information about a single function, block, lambda, or method body.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_SCOPEINFO_H
-#define LLVM_CLANG_SEMA_SCOPEINFO_H
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/CapturedStmt.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Sema/Ownership.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include <algorithm>
-
-namespace clang {
-
-class Decl;
-class BlockDecl;
-class CapturedDecl;
-class CXXMethodDecl;
-class FieldDecl;
-class ObjCPropertyDecl;
-class IdentifierInfo;
-class ImplicitParamDecl;
-class LabelDecl;
-class ReturnStmt;
-class Scope;
-class SwitchStmt;
-class TemplateTypeParmDecl;
-class TemplateParameterList;
-class VarDecl;
-class ObjCIvarRefExpr;
-class ObjCPropertyRefExpr;
-class ObjCMessageExpr;
-
-namespace sema {
-
-/// \brief 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
- /// with empty bodies.
- bool HasEmptyLoopBodies;
-
- void setHasEmptyLoopBodies() {
- HasEmptyLoopBodies = true;
- }
-};
-
-class PossiblyUnreachableDiag {
-public:
- PartialDiagnostic PD;
- SourceLocation Loc;
- const Stmt *stmt;
-
- PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
- const Stmt *stmt)
- : PD(PD), Loc(Loc), stmt(stmt) {}
-};
-
-/// \brief Retains information about a function, method, or block that is
-/// currently being parsed.
-class FunctionScopeInfo {
-protected:
- enum ScopeKind {
- SK_Function,
- SK_Block,
- SK_Lambda,
- SK_CapturedRegion
- };
-
-public:
- /// \brief What kind of scope we are describing.
- ///
- ScopeKind Kind : 3;
-
- /// \brief 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.
- bool HasBranchIntoScope : 1;
-
- /// \brief Whether this function contains any indirect gotos.
- bool HasIndirectGoto : 1;
-
- /// \brief Whether a statement was dropped because it was invalid.
- bool HasDroppedStmt : 1;
-
- /// A flag that is set when parsing a method that must call super's
- /// implementation, such as \c -dealloc, \c -finalize, or any method marked
- /// with \c __attribute__((objc_requires_super)).
- bool ObjCShouldCallSuper : 1;
-
- /// 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.
- bool ObjCWarnForNoDesignatedInitChain : 1;
-
- /// True when this is an initializer method not marked as a designated
- /// 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;
-
- /// First 'return' statement in the current function.
- SourceLocation FirstReturnLoc;
-
- /// First C++ 'try' statement in the current function.
- SourceLocation FirstCXXTryLoc;
-
- /// First SEH '__try' statement in the current function.
- SourceLocation FirstSEHTryLoc;
-
- /// \brief Used to determine if errors occurred in this function or block.
- DiagnosticErrorTrap ErrorTrap;
-
- /// SwitchStack - This is the current set of active switch statements in the
- /// block.
- SmallVector<SwitchStmt*, 8> SwitchStack;
-
- /// \brief 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.
- VarDecl *CoroutinePromise;
-
- /// \brief The list of coroutine control flow constructs (co_await, co_yield,
- /// co_return) that occur within the function or block. Empty if and only if
- /// this function or block is not (yet known to be) a coroutine.
- SmallVector<Stmt*, 4> CoroutineStmts;
-
- /// \brief 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
- /// 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
- /// modified in the function.
- llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams;
-
-public:
- /// Represents a simple identification of a weak object.
- ///
- /// Part of the implementation of -Wrepeated-use-of-weak.
- ///
- /// This is used to determine if two weak accesses refer to the same object.
- /// Here are some examples of how various accesses are "profiled":
- ///
- /// Access Expression | "Base" Decl | "Property" Decl
- /// :---------------: | :-----------------: | :------------------------------:
- /// self.property | self (VarDecl) | property (ObjCPropertyDecl)
- /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl)
- /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
- /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl)
- /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl)
- /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl)
- /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
- /// weakVar | 0 (known) | weakVar (VarDecl)
- /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl)
- ///
- /// Objects are identified with only two Decls to make it reasonably fast to
- /// compare them.
- class WeakObjectProfileTy {
- /// The base object decl, as described in the class documentation.
- ///
- /// The extra flag is "true" if the Base and Property are enough to uniquely
- /// identify the object in memory.
- ///
- /// \sa isExactProfile()
- typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
- 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;
-
- /// Used to find the proper base profile for a given base expression.
- static BaseInfoTy getBaseInfo(const Expr *BaseE);
-
- inline WeakObjectProfileTy();
- static inline WeakObjectProfileTy getSentinel();
-
- public:
- WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
- WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
- WeakObjectProfileTy(const DeclRefExpr *RE);
- WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
-
- const NamedDecl *getBase() const { return Base.getPointer(); }
- const NamedDecl *getProperty() const { return Property; }
-
- /// Returns true if the object base specifies a known object in memory,
- /// rather than, say, an instance variable or property of another object.
- ///
- /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
- /// considered an exact profile if \c foo is a local variable, even if
- /// another variable \c foo2 refers to the same object as \c foo.
- ///
- /// For increased precision, accesses with base variables that are
- /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
- /// be exact, though this is not true for arbitrary variables
- /// (foo.prop1.prop2).
- bool isExactProfile() const {
- return Base.getInt();
- }
-
- bool operator==(const WeakObjectProfileTy &Other) const {
- return Base == Other.Base && Property == Other.Property;
- }
-
- // For use in DenseMap.
- // We can't specialize the usual llvm::DenseMapInfo at the end of the file
- // because by that point the DenseMap in FunctionScopeInfo has already been
- // instantiated.
- class DenseMapInfo {
- 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;
- return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
- Val.Property));
- }
-
- static bool isEqual(const WeakObjectProfileTy &LHS,
- const WeakObjectProfileTy &RHS) {
- return LHS == RHS;
- }
- };
- };
-
- /// Represents a single use of a weak object.
- ///
- /// Stores both the expression and whether the access is potentially unsafe
- /// (i.e. it could potentially be warned about).
- ///
- /// 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) {}
-
- const Expr *getUseExpr() const { return Rep.getPointer(); }
- bool isUnsafe() const { return Rep.getInt(); }
- void markSafe() { Rep.setInt(false); }
-
- bool operator==(const WeakUseTy &Other) const {
- return Rep == Other.Rep;
- }
- };
-
- /// 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;
-
- /// 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;
-
-private:
- /// Used to collect all uses of weak objects in this function body.
- ///
- /// Part of the implementation of -Wrepeated-use-of-weak.
- WeakObjectUseMap WeakObjectUses;
-
-protected:
- FunctionScopeInfo(const FunctionScopeInfo&) = default;
-
-public:
- /// Record that a weak object was accessed.
- ///
- /// Part of the implementation of -Wrepeated-use-of-weak.
- template <typename ExprT>
- inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
-
- void recordUseOfWeak(const ObjCMessageExpr *Msg,
- const ObjCPropertyDecl *Prop);
-
- /// Record that a given expression is a "safe" access of a weak object (e.g.
- /// assigning it to a strong variable.)
- ///
- /// Part of the implementation of -Wrepeated-use-of-weak.
- void markSafeWeakUse(const Expr *E);
-
- const WeakObjectUseMap &getWeakObjectUses() const {
- return WeakObjectUses;
- }
-
- void setHasBranchIntoScope() {
- HasBranchIntoScope = true;
- }
-
- void setHasBranchProtectedScope() {
- HasBranchProtectedScope = true;
- }
-
- void setHasIndirectGoto() {
- HasIndirectGoto = true;
- }
-
- void setHasDroppedStmt() {
- HasDroppedStmt = true;
- }
-
- void setHasCXXTry(SourceLocation TryLoc) {
- setHasBranchProtectedScope();
- FirstCXXTryLoc = TryLoc;
- }
-
- void setHasSEHTry(SourceLocation TryLoc) {
- setHasBranchProtectedScope();
- FirstSEHTryLoc = TryLoc;
- }
-
- bool NeedsScopeChecking() const {
- return !HasDroppedStmt &&
- (HasIndirectGoto ||
- (HasBranchProtectedScope && HasBranchIntoScope));
- }
-
- FunctionScopeInfo(DiagnosticsEngine &Diag)
- : Kind(SK_Function),
- HasBranchProtectedScope(false),
- HasBranchIntoScope(false),
- HasIndirectGoto(false),
- HasDroppedStmt(false),
- ObjCShouldCallSuper(false),
- ObjCIsDesignatedInit(false),
- ObjCWarnForNoDesignatedInitChain(false),
- ObjCIsSecondaryInit(false),
- ObjCWarnForNoInitDelegation(false),
- ErrorTrap(Diag) { }
-
- virtual ~FunctionScopeInfo();
-
- /// \brief Clear out the information in this function scope, making it
- /// suitable for reuse.
- void Clear();
-};
-
-class CapturingScopeInfo : public FunctionScopeInfo {
-protected:
- CapturingScopeInfo(const CapturingScopeInfo&) = default;
-
-public:
- enum ImplicitCaptureStyle {
- ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
- ImpCap_CapturedRegion
- };
-
- ImplicitCaptureStyle ImpCaptureStyle;
-
- 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_This
- };
-
- /// The variable being captured (if we are not capturing 'this') and whether
- /// this is a nested capture.
- llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested;
-
- /// 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;
-
- /// \brief The location of the ellipsis that expands a parameter pack.
- SourceLocation EllipsisLoc;
-
- /// \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;
-
- public:
- Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
- SourceLocation Loc, SourceLocation EllipsisLoc,
- QualType CaptureType, Expr *Cpy)
- : VarAndNested(Var, IsNested),
- InitExprAndCaptureKind(Cpy, Block ? Cap_Block :
- ByRef ? Cap_ByRef : Cap_ByCopy),
- Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
-
- enum IsThisCapture { ThisCapture };
- Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
- QualType CaptureType, Expr *Cpy)
- : VarAndNested(nullptr, IsNested),
- InitExprAndCaptureKind(Cpy, Cap_This),
- Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
-
- bool isThisCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_This;
- }
- bool isVariableCapture() const {
- return InitExprAndCaptureKind.getInt() != Cap_This && !isVLATypeCapture();
- }
- bool isCopyCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_ByCopy &&
- !isVLATypeCapture();
- }
- bool isReferenceCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_ByRef;
- }
- bool isBlockCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_Block;
- }
- bool isVLATypeCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_ByCopy &&
- getVariable() == nullptr;
- }
- bool isNested() const { return VarAndNested.getInt(); }
-
- VarDecl *getVariable() const {
- return VarAndNested.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 { return CaptureType; }
-
- Expr *getInitExpr() const {
- assert(!isVLATypeCapture() && "no init expression for type capture");
- return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
- }
- };
-
- CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
- : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
- HasImplicitReturnType(false)
- {}
-
- /// 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;
-
- /// Captures - The captures.
- SmallVector<Capture, 4> Captures;
-
- /// \brief - Whether the target type of return statements in this context
- /// is deduced (e.g. a lambda or block with omitted return type).
- bool HasImplicitReturnType;
-
- /// ReturnType - The target type of return statements in this context,
- /// or null if unknown.
- QualType ReturnType;
-
- void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
- SourceLocation Loc, SourceLocation EllipsisLoc,
- QualType CaptureType, Expr *Cpy) {
- Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
- EllipsisLoc, CaptureType, Cpy));
- CaptureMap[Var] = Captures.size();
- }
-
- void addVLATypeCapture(SourceLocation Loc, QualType CaptureType) {
- Captures.push_back(Capture(/*Var*/ nullptr, /*isBlock*/ false,
- /*isByref*/ false, /*isNested*/ false, Loc,
- /*EllipsisLoc*/ SourceLocation(), CaptureType,
- /*Cpy*/ nullptr));
- }
-
- void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
- Expr *Cpy);
-
- /// \brief 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.
- Capture &getCXXThisCapture() {
- assert(isCXXThisCaptured() && "this has not been captured");
- return Captures[CXXThisCaptureIndex - 1];
- }
-
- /// \brief 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.
- bool isVLATypeCaptured(const VariableArrayType *VAT) const;
-
- /// \brief 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");
- return Captures[CaptureMap[Var] - 1];
- }
-
- const Capture &getCapture(VarDecl *Var) const {
- llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
- = CaptureMap.find(Var);
- assert(Known != CaptureMap.end() && "Variable has not been captured");
- return Captures[Known->second - 1];
- }
-
- static bool classof(const FunctionScopeInfo *FSI) {
- return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
- || FSI->Kind == SK_CapturedRegion;
- }
-};
-
-/// \brief Retains information about a block that is currently being parsed.
-class BlockScopeInfo final : public CapturingScopeInfo {
-public:
- BlockDecl *TheDecl;
-
- /// TheScope - This is the scope for the block itself, which contains
- /// arguments etc.
- Scope *TheScope;
-
- /// BlockType - The function type of the block, if one was given.
- /// Its return type may be BuiltinType::Dependent.
- QualType FunctionType;
-
- BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
- : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
- TheScope(BlockScope)
- {
- Kind = SK_Block;
- }
-
- ~BlockScopeInfo() override;
-
- static bool classof(const FunctionScopeInfo *FSI) {
- return FSI->Kind == SK_Block;
- }
-};
-
-/// \brief Retains information about a captured region.
-class CapturedRegionScopeInfo final : public CapturingScopeInfo {
-public:
- /// \brief The CapturedDecl for this statement.
- CapturedDecl *TheCapturedDecl;
- /// \brief The captured record type.
- RecordDecl *TheRecordDecl;
- /// \brief This is the enclosing scope of the captured region.
- Scope *TheScope;
- /// \brief The implicit parameter for the captured variables.
- ImplicitParamDecl *ContextParam;
- /// \brief The kind of captured region.
- CapturedRegionKind CapRegionKind;
-
- CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
- RecordDecl *RD, ImplicitParamDecl *Context,
- CapturedRegionKind K)
- : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
- TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
- ContextParam(Context), CapRegionKind(K)
- {
- Kind = SK_CapturedRegion;
- }
-
- ~CapturedRegionScopeInfo() override;
-
- /// \brief 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_OpenMP:
- return "OpenMP region";
- }
- llvm_unreachable("Invalid captured region kind!");
- }
-
- static bool classof(const FunctionScopeInfo *FSI) {
- return FSI->Kind == SK_CapturedRegion;
- }
-};
-
-class LambdaScopeInfo final : public CapturingScopeInfo {
-public:
- /// \brief The class that describes the lambda.
- CXXRecordDecl *Lambda;
-
- /// \brief The lambda's compiler-generated \c operator().
- CXXMethodDecl *CallOperator;
-
- /// \brief Source range covering the lambda introducer [...].
- SourceRange IntroducerRange;
-
- /// \brief 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
- /// explicit captures.
- unsigned NumExplicitCaptures;
-
- /// \brief Whether this is a mutable lambda.
- bool Mutable;
-
- /// \brief Whether the (empty) parameter list is explicit.
- bool ExplicitParams;
-
- /// \brief Whether any of the capture expressions requires cleanups.
- bool ExprNeedsCleanups;
-
- /// \brief Whether the lambda contains an unexpanded parameter pack.
- bool ContainsUnexpandedParameterPack;
-
- /// \brief If this is a generic lambda, use this as the depth of
- /// each 'auto' parameter, during initial AST construction.
- unsigned AutoTemplateParameterDepth;
-
- /// \brief 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
- /// parameter list, during initial AST construction.
- SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams;
-
- /// 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;
-
- /// \brief 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.
- /// 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
- /// 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;
-
- SourceLocation PotentialThisCaptureLocation;
-
- LambdaScopeInfo(DiagnosticsEngine &Diag)
- : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
- CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
- ExplicitParams(false), ExprNeedsCleanups(false),
- ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0),
- GLTemplateParameterList(nullptr) {
- Kind = SK_Lambda;
- }
-
- /// \brief Note when all explicit captures have been added.
- void finishedExplicitCaptures() {
- NumExplicitCaptures = Captures.size();
- }
-
- static bool classof(const FunctionScopeInfo *FSI) {
- return FSI->Kind == SK_Lambda;
- }
-
- ///
- /// \brief 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
- /// variables that nested lambda's - depending on their enclosing
- /// specialization - might need to capture.
- /// Consider:
- /// void f(int, int); <-- don't capture
- /// void f(const int&, double); <-- capture
- /// void foo() {
- /// const int x = 10;
- /// auto L = [=](auto a) { // capture 'x'
- /// return [=](auto b) {
- /// f(x, a); // we may or may not need to capture 'x'
- /// };
- /// };
- /// }
- void addPotentialCapture(Expr *VarExpr) {
- assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr));
- PotentiallyCapturingExprs.push_back(VarExpr);
- }
-
- 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.
- ///
- /// For generic lambdas, if a variable is named in a potentially evaluated
- /// expression, where the enclosing full expression is dependent then we
- /// must capture the variable (given a default capture).
- /// This is accomplished by recording all references to variables
- /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of
- /// PotentialCaptures. All such variables have to be captured by that lambda,
- /// except for as described below.
- /// If that variable is usable as a constant expression and is named in a
- /// manner that does not involve its odr-use (e.g. undergoes
- /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
- /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
- /// if we can determine that the full expression is not instantiation-
- /// dependent, then we can entirely avoid its capture.
- ///
- /// const int n = 0;
- /// [&] (auto x) {
- /// (void)+n + x;
- /// };
- /// Interestingly, this strategy would involve a capture of n, even though
- /// it's obviously not odr-used here, because the full-expression is
- /// instantiation-dependent. It could be useful to avoid capturing such
- /// variables, even when they are referred to in an instantiation-dependent
- /// expression, if we can unambiguously determine that they shall never be
- /// odr-used. This would involve removal of the variable-referring-expression
- /// from the array of PotentialCaptures during the lvalue-to-rvalue
- /// conversions. But per the working draft N3797, (post-chicago 2013) we must
- /// capture such variables.
- /// Before anyone is tempted to implement a strategy for not-capturing 'n',
- /// consider the insightful warning in:
- /// /cfe-commits/Week-of-Mon-20131104/092596.html
- /// "The problem is that the set of captures for a lambda is part of the ABI
- /// (since lambda layout can be made visible through inline functions and the
- /// like), and there are no guarantees as to which cases we'll manage to build
- /// an lvalue-to-rvalue conversion in, when parsing a template -- some
- /// 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));
- NonODRUsedCapturingExprs.insert(CapturingVarExpr);
- }
- bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
- assert(isa<DeclRefExpr>(CapturingVarExpr)
- || isa<MemberExpr>(CapturingVarExpr));
- return NonODRUsedCapturingExprs.count(CapturingVarExpr);
- }
- void removePotentialCapture(Expr *E) {
- PotentiallyCapturingExprs.erase(
- std::remove(PotentiallyCapturingExprs.begin(),
- PotentiallyCapturingExprs.end(), E),
- PotentiallyCapturingExprs.end());
- }
- void clearPotentialCaptures() {
- PotentiallyCapturingExprs.clear();
- PotentialThisCaptureLocation = SourceLocation();
- }
- unsigned getNumPotentialVariableCaptures() const {
- return PotentiallyCapturingExprs.size();
- }
-
- bool hasPotentialCaptures() const {
- return getNumPotentialVariableCaptures() ||
- PotentialThisCaptureLocation.isValid();
- }
-
- // When passed the index, returns the VarDecl and Expr associated
- // with the index.
- void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const;
-};
-
-FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
- : Base(nullptr, false), Property(nullptr) {}
-
-FunctionScopeInfo::WeakObjectProfileTy
-FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
- FunctionScopeInfo::WeakObjectProfileTy Result;
- Result.Base.setInt(true);
- return Result;
-}
-
-template <typename ExprT>
-void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
- assert(E);
- WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
- Uses.push_back(WeakUseTy(E, IsRead));
-}
-
-inline void
-CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
- QualType CaptureType, Expr *Cpy) {
- Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
- Cpy));
- CXXThisCaptureIndex = Captures.size();
-}
-
-} // end namespace sema
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
deleted file mode 100644
index 77d06f2..0000000
--- a/include/clang/Sema/Sema.h
+++ /dev/null
@@ -1,9265 +0,0 @@
-//===--- Sema.h - Semantic Analysis & AST Building --------------*- 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 Sema class, which performs semantic analysis and
-// builds ASTs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_SEMA_H
-#define LLVM_CLANG_SEMA_SEMA_H
-
-#include "clang/AST/Attr.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/MangleNumberingContext.h"
-#include "clang/AST/NSAPI.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/TemplateKinds.h"
-#include "clang/Basic/TypeTraits.h"
-#include "clang/Sema/AnalysisBasedWarnings.h"
-#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/Sema/IdentifierResolver.h"
-#include "clang/Sema/LocInfoType.h"
-#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/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include <deque>
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace llvm {
- class APSInt;
- template <typename ValueT> struct DenseMapInfo;
- template <typename ValueT, typename ValueInfoT> class DenseSet;
- class SmallBitVector;
- class InlineAsmIdentifierInfo;
-}
-
-namespace clang {
- class ADLResult;
- class ASTConsumer;
- class ASTContext;
- class ASTMutationListener;
- class ASTReader;
- class ASTWriter;
- class ArrayType;
- class AttributeList;
- class BlockDecl;
- class CapturedDecl;
- class CXXBasePath;
- class CXXBasePaths;
- class CXXBindTemporaryExpr;
- typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
- class CXXConstructorDecl;
- class CXXConversionDecl;
- class CXXDeleteExpr;
- class CXXDestructorDecl;
- class CXXFieldCollector;
- class CXXMemberCallExpr;
- class CXXMethodDecl;
- class CXXScopeSpec;
- class CXXTemporary;
- class CXXTryStmt;
- class CallExpr;
- class ClassTemplateDecl;
- class ClassTemplatePartialSpecializationDecl;
- class ClassTemplateSpecializationDecl;
- class VarTemplatePartialSpecializationDecl;
- class CodeCompleteConsumer;
- class CodeCompletionAllocator;
- class CodeCompletionTUInfo;
- class CodeCompletionResult;
- class Decl;
- class DeclAccessPair;
- class DeclContext;
- class DeclRefExpr;
- class DeclaratorDecl;
- class DeducedTemplateArgument;
- class DependentDiagnostic;
- class DesignatedInitExpr;
- class Designation;
- class EnableIfAttr;
- class EnumConstantDecl;
- class Expr;
- class ExtVectorType;
- class ExternalSemaSource;
- class FormatAttr;
- class FriendDecl;
- class FunctionDecl;
- class FunctionProtoType;
- class FunctionTemplateDecl;
- class ImplicitConversionSequence;
- class InitListExpr;
- class InitializationKind;
- class InitializationSequence;
- class InitializedEntity;
- class IntegerLiteral;
- class LabelStmt;
- class LambdaExpr;
- class LangOptions;
- class LocalInstantiationScope;
- class LookupResult;
- class MacroInfo;
- typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath;
- class ModuleLoader;
- class MultiLevelTemplateArgumentList;
- class NamedDecl;
- class ObjCCategoryDecl;
- class ObjCCategoryImplDecl;
- class ObjCCompatibleAliasDecl;
- class ObjCContainerDecl;
- class ObjCImplDecl;
- class ObjCImplementationDecl;
- class ObjCInterfaceDecl;
- class ObjCIvarDecl;
- template <class T> class ObjCList;
- class ObjCMessageExpr;
- class ObjCMethodDecl;
- class ObjCPropertyDecl;
- class ObjCProtocolDecl;
- class OMPThreadPrivateDecl;
- class OMPClause;
- struct OverloadCandidate;
- class OverloadCandidateSet;
- class OverloadExpr;
- class ParenListExpr;
- class ParmVarDecl;
- class Preprocessor;
- class PseudoDestructorTypeStorage;
- class PseudoObjectExpr;
- class QualType;
- class StandardConversionSequence;
- class Stmt;
- class StringLiteral;
- class SwitchStmt;
- class TemplateArgument;
- class TemplateArgumentList;
- class TemplateArgumentLoc;
- class TemplateDecl;
- class TemplateParameterList;
- class TemplatePartialOrderingContext;
- class TemplateTemplateParmDecl;
- class Token;
- class TypeAliasDecl;
- class TypedefDecl;
- class TypedefNameDecl;
- class TypeLoc;
- class TypoCorrectionConsumer;
- class UnqualifiedId;
- class UnresolvedLookupExpr;
- class UnresolvedMemberExpr;
- class UnresolvedSetImpl;
- class UnresolvedSetIterator;
- class UsingDecl;
- class UsingShadowDecl;
- class ValueDecl;
- class VarDecl;
- class VarTemplateSpecializationDecl;
- class VisibilityAttr;
- class VisibleDeclConsumer;
- class IndirectFieldDecl;
- struct DeductionFailureInfo;
- class TemplateSpecCandidateSet;
-
-namespace sema {
- class AccessedEntity;
- class BlockScopeInfo;
- class CapturedRegionScopeInfo;
- class CapturingScopeInfo;
- class CompoundScopeInfo;
- class DelayedDiagnostic;
- class DelayedDiagnosticPool;
- class FunctionScopeInfo;
- class LambdaScopeInfo;
- class PossiblyUnreachableDiag;
- class TemplateDeductionInfo;
-}
-
-namespace threadSafety {
- class BeforeSet;
- void threadSafetyCleanup(BeforeSet* Cache);
-}
-
-// FIXME: No way to easily map from TemplateTypeParmTypes to
-// TemplateTypeParmDecls, so we have this horrible PointerUnion.
-typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>,
- SourceLocation> UnexpandedParameterPack;
-
-/// Describes whether we've seen any nullability information for the given
-/// file.
-struct FileNullability {
- /// The first pointer declarator (of any pointer kind) in the file that does
- /// not have a corresponding nullability annotation.
- SourceLocation PointerLoc;
-
- /// Which kind of pointer declarator we saw.
- uint8_t PointerKind;
-
- /// Whether we saw any type nullability annotations in the given file.
- bool SawTypeNullability = false;
-};
-
-/// A mapping from file IDs to a record of whether we've seen nullability
-/// information in that file.
-class FileNullabilityMap {
- /// A mapping from file IDs to the nullability information for each file ID.
- llvm::DenseMap<FileID, FileNullability> Map;
-
- /// A single-element cache based on the file ID.
- struct {
- FileID File;
- FileNullability Nullability;
- } Cache;
-
-public:
- FileNullability &operator[](FileID file) {
- // Check the single-element cache.
- if (file == Cache.File)
- return Cache.Nullability;
-
- // It's not in the single-element cache; flush the cache if we have one.
- if (!Cache.File.isInvalid()) {
- Map[Cache.File] = Cache.Nullability;
- }
-
- // Pull this entry into the cache.
- Cache.File = file;
- Cache.Nullability = Map[file];
- return Cache.Nullability;
- }
-};
-
-/// Sema - This implements semantic analysis and AST building for C.
-class Sema {
- Sema(const Sema &) = delete;
- void operator=(const Sema &) = delete;
-
- ///\brief Source of additional semantic information.
- ExternalSemaSource *ExternalSource;
-
- ///\brief Whether Sema has generated a multiplexer and has to delete it.
- bool isMultiplexExternalSource;
-
- static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD);
-
- bool isVisibleSlow(const NamedDecl *D);
-
- bool shouldLinkPossiblyHiddenDecl(const NamedDecl *Old,
- const NamedDecl *New) {
- // We are about to link these. It is now safe to compute the linkage of
- // the new decl. If the new decl has external linkage, we will
- // link it with the hidden decl (which also has external linkage) and
- // it will keep having external linkage. If it has internal linkage, we
- // will not link it. Since it has no previous decls, it will remain
- // with internal linkage.
- return isVisible(Old) || New->isExternallyVisible();
- }
- bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New);
-
-public:
- typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
- typedef OpaquePtr<TemplateName> TemplateTy;
- typedef OpaquePtr<QualType> TypeTy;
-
- OpenCLOptions OpenCLFeatures;
- FPOptions FPFeatures;
-
- const LangOptions &LangOpts;
- Preprocessor &PP;
- ASTContext &Context;
- ASTConsumer &Consumer;
- DiagnosticsEngine &Diags;
- SourceManager &SourceMgr;
-
- /// \brief Flag indicating whether or not to collect detailed statistics.
- bool CollectStats;
-
- /// \brief 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,
- /// like in \see ActOnObjCTemporaryExitContainerContext.
- DeclContext *OriginalLexicalContext;
-
- /// VAListTagName - The declaration name corresponding to __va_list_tag.
- /// This is used as part of a hack to omit that class from ADL results.
- DeclarationName VAListTagName;
-
- /// PackContext - Manages the stack for \#pragma pack. An alignment
- /// of 0 indicates default alignment.
- void *PackContext; // Really a "PragmaPackStack*"
-
- bool MSStructPragmaOn; // True when \#pragma ms_struct on
-
- /// \brief Controls member pointer representation format under the MS ABI.
- LangOptions::PragmaMSPointersToMembersKind
- MSPointerToMemberRepresentationMethod;
-
- enum PragmaVtorDispKind {
- PVDK_Push, ///< #pragma vtordisp(push, mode)
- PVDK_Set, ///< #pragma vtordisp(mode)
- PVDK_Pop, ///< #pragma vtordisp(pop)
- PVDK_Reset ///< #pragma vtordisp()
- };
-
- enum PragmaMsStackAction {
- PSK_Reset, // #pragma ()
- PSK_Set, // #pragma ("name")
- PSK_Push, // #pragma (push[, id])
- PSK_Push_Set, // #pragma (push[, id], "name")
- PSK_Pop, // #pragma (pop[, id])
- PSK_Pop_Set, // #pragma (pop[, id], "name")
- };
-
- /// \brief 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
- /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial
- /// structors
- /// 2: Always insert vtordisps to support RTTI on partially constructed
- /// objects
- ///
- /// The stack always has at least one element in it.
- SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack;
-
- /// Stack of active SEH __finally scopes. Can be empty.
- SmallVector<Scope*, 2> CurrentSEHFinally;
-
- /// \brief Source location for newly created implicit MSInheritanceAttrs
- SourceLocation ImplicitMSInheritanceAttrLoc;
-
- template<typename ValueType>
- struct PragmaStack {
- struct Slot {
- llvm::StringRef StackSlotLabel;
- ValueType Value;
- SourceLocation PragmaLocation;
- Slot(llvm::StringRef StackSlotLabel,
- ValueType Value,
- SourceLocation PragmaLocation)
- : StackSlotLabel(StackSlotLabel), Value(Value),
- PragmaLocation(PragmaLocation) {}
- };
- void Act(SourceLocation PragmaLocation,
- PragmaMsStackAction Action,
- llvm::StringRef StackSlotLabel,
- ValueType Value);
- explicit PragmaStack(const ValueType &Value)
- : CurrentValue(Value) {}
- SmallVector<Slot, 2> Stack;
- ValueType CurrentValue;
- SourceLocation CurrentPragmaLocation;
- };
- // FIXME: We should serialize / deserialize these if they occur in a PCH (but
- // we shouldn't do so if they're in a module).
- PragmaStack<StringLiteral *> DataSegStack;
- PragmaStack<StringLiteral *> BSSSegStack;
- PragmaStack<StringLiteral *> ConstSegStack;
- PragmaStack<StringLiteral *> CodeSegStack;
-
- /// A mapping that describes the nullability we've seen in each header file.
- FileNullabilityMap NullabilityMap;
-
- /// Last section used with #pragma init_seg.
- StringLiteral *CurInitSeg;
- SourceLocation CurInitSegLoc;
-
- /// VisContext - Manages the stack for \#pragma GCC visibility.
- void *VisContext; // Really a "PragmaVisStack*"
-
- /// \brief 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.
- ///
- /// This flag is used to avoid building recovery call expressions
- /// if Sema is already doing so, which would cause infinite recursions.
- bool IsBuildingRecoveryCallExpr;
-
- /// ExprNeedsCleanups - True if the current evaluation context
- /// requires cleanups to be run at its conclusion.
- bool ExprNeedsCleanups;
-
- /// ExprCleanupObjects - This is the stack of objects requiring
- /// cleanup that are created by the current full expression. The
- /// element type here is ExprWithCleanups::Object.
- SmallVector<BlockDecl*, 8> ExprCleanupObjects;
-
- /// \brief 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
- /// of the enclosing full expression. This is cleared at the end of each
- /// full expression.
- llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
-
- /// \brief 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,
- &ExternalSemaSource::ReadExtVectorDecls, 2, 2>
- ExtVectorDeclsType;
-
- /// ExtVectorDecls - This is a list all the extended vector types. This allows
- /// us to associate a raw vector type with one of the ext_vector type names.
- /// This is only necessary for issuing pretty diagnostics.
- ExtVectorDeclsType ExtVectorDecls;
-
- /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
- std::unique_ptr<CXXFieldCollector> FieldCollector;
-
- typedef llvm::SmallSetVector<const NamedDecl*, 16> NamedDeclSetType;
-
- /// \brief Set containing all declared private fields that are not used.
- NamedDeclSetType UnusedPrivateFields;
-
- /// \brief 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
- ///
- /// This list contains class members, and locations of delete-expressions
- /// that could not be proven as to whether they mismatch with new-expression
- /// used in initializer of the field.
- typedef std::pair<SourceLocation, bool> DeleteExprLoc;
- typedef llvm::SmallVector<DeleteExprLoc, 4> DeleteLocs;
- llvm::MapVector<FieldDecl *, DeleteLocs> DeleteExprs;
-
- typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy;
-
- /// PureVirtualClassDiagSet - a set of class declarations which we have
- /// emitted a list of pure virtual functions. Used to prevent emitting the
- /// same list more than once.
- std::unique_ptr<RecordDeclSetTy> PureVirtualClassDiagSet;
-
- /// ParsingInitForAutoVars - a set of declarations with auto types for which
- /// 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.
- NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name);
-
- typedef LazyVector<VarDecl *, ExternalSemaSource,
- &ExternalSemaSource::ReadTentativeDefinitions, 2, 2>
- TentativeDefinitionsType;
-
- /// \brief 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
- /// and must warn if not used. Only contains the first declaration.
- UnusedFileScopedDeclsType UnusedFileScopedDecls;
-
- typedef LazyVector<CXXConstructorDecl *, ExternalSemaSource,
- &ExternalSemaSource::ReadDelegatingConstructors, 2, 2>
- DelegatingCtorDeclsType;
-
- /// \brief 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
- /// 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
- /// explicitly defaulted and had explicitly-specified exception
- /// specifications, along with the function type containing their
- /// user-specified exception specification. Those exception specifications
- /// were overridden with the default specifications, but we still need to
- /// check whether they are compatible with the default specification, and
- /// we can't do that until the nesting set of class definitions is complete.
- SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2>
- DelayedDefaultedMemberExceptionSpecs;
-
- typedef llvm::MapVector<const FunctionDecl *, LateParsedTemplate *>
- LateParsedTemplateMapT;
- LateParsedTemplateMapT LateParsedTemplateMap;
-
- /// \brief Callback to the parser to parse templated functions when needed.
- typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT);
- typedef void LateTemplateParserCleanupCB(void *P);
- LateTemplateParserCB *LateTemplateParser;
- LateTemplateParserCleanupCB *LateTemplateParserCleanup;
- void *OpaqueParser;
-
- void SetLateTemplateParser(LateTemplateParserCB *LTP,
- LateTemplateParserCleanupCB *LTPCleanup,
- void *P) {
- LateTemplateParser = LTP;
- LateTemplateParserCleanup = LTPCleanup;
- OpaqueParser = P;
- }
-
- class DelayedDiagnostics;
-
- class DelayedDiagnosticsState {
- sema::DelayedDiagnosticPool *SavedPool;
- friend class Sema::DelayedDiagnostics;
- };
- typedef DelayedDiagnosticsState ParsingDeclState;
- typedef DelayedDiagnosticsState ProcessingContextState;
-
- /// 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
- /// diagnostics should go.
- sema::DelayedDiagnosticPool *CurPool;
-
- public:
- DelayedDiagnostics() : CurPool(nullptr) {}
-
- /// Adds a delayed diagnostic.
- void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h
-
- /// Determines whether diagnostics should be delayed.
- bool shouldDelayDiagnostics() { return CurPool != nullptr; }
-
- /// Returns the current delayed-diagnostics pool.
- sema::DelayedDiagnosticPool *getCurrentPool() const {
- return CurPool;
- }
-
- /// Enter a new scope. Access and deprecation diagnostics will be
- /// collected in this pool.
- DelayedDiagnosticsState push(sema::DelayedDiagnosticPool &pool) {
- DelayedDiagnosticsState state;
- state.SavedPool = CurPool;
- CurPool = &pool;
- return state;
- }
-
- /// Leave a delayed-diagnostic state that was previously pushed.
- /// Do not emit any of the diagnostics. This is performed as part
- /// of the bookkeeping of popping a pool "properly".
- void popWithoutEmitting(DelayedDiagnosticsState state) {
- CurPool = state.SavedPool;
- }
-
- /// Enter a new scope where access and deprecation diagnostics are
- /// not delayed.
- DelayedDiagnosticsState pushUndelayed() {
- DelayedDiagnosticsState state;
- state.SavedPool = CurPool;
- CurPool = nullptr;
- return state;
- }
-
- /// Undo a previous pushUndelayed().
- void popUndelayed(DelayedDiagnosticsState state) {
- assert(CurPool == nullptr);
- CurPool = state.SavedPool;
- }
- } DelayedDiagnostics;
-
- /// A RAII object to temporarily push a declaration context.
- class ContextRAII {
- private:
- Sema &S;
- DeclContext *SavedContext;
- ProcessingContextState SavedContextState;
- QualType SavedCXXThisTypeOverride;
-
- public:
- ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true)
- : S(S), SavedContext(S.CurContext),
- SavedContextState(S.DelayedDiagnostics.pushUndelayed()),
- SavedCXXThisTypeOverride(S.CXXThisTypeOverride)
- {
- assert(ContextToPush && "pushing null context");
- S.CurContext = ContextToPush;
- if (NewThisContext)
- S.CXXThisTypeOverride = QualType();
- }
-
- void pop() {
- if (!SavedContext) return;
- S.CurContext = SavedContext;
- S.DelayedDiagnostics.popUndelayed(SavedContextState);
- S.CXXThisTypeOverride = SavedCXXThisTypeOverride;
- SavedContext = nullptr;
- }
-
- ~ContextRAII() {
- pop();
- }
- };
-
- /// \brief RAII object to handle the state changes required to synthesize
- /// a function body.
- class SynthesizedFunctionScope {
- Sema &S;
- Sema::ContextRAII SavedContext;
-
- public:
- SynthesizedFunctionScope(Sema &S, DeclContext *DC)
- : S(S), SavedContext(S, DC)
- {
- S.PushFunctionScope();
- S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
- }
-
- ~SynthesizedFunctionScope() {
- S.PopExpressionEvaluationContext();
- S.PopFunctionScopeInfo();
- }
- };
-
- /// WeakUndeclaredIdentifiers - Identifiers contained in
- /// \#pragma weak before declared. rare. may alias another
- /// identifier, declared or undeclared
- llvm::MapVector<IdentifierInfo *, WeakInfo> WeakUndeclaredIdentifiers;
-
- /// ExtnameUndeclaredIdentifiers - Identifiers contained in
- /// \#pragma redefine_extname before declared. Used in Solaris system headers
- /// to define functions that occur in multiple standards to call the version
- /// in the currently selected standard.
- llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*> ExtnameUndeclaredIdentifiers;
-
-
- /// \brief Load weak undeclared identifiers from the external source.
- void LoadExternalWeakUndeclaredIdentifiers();
-
- /// WeakTopLevelDecl - Translation-unit scoped declarations generated by
- /// \#pragma weak during processing of other Decls.
- /// I couldn't figure out a clean way to generate these in-line, so
- /// we store them here and handle separately -- which is a hack.
- /// It would be best to refactor this.
- SmallVector<Decl*,2> WeakTopLevelDecl;
-
- IdentifierResolver IdResolver;
-
- /// Translation Unit Scope - useful to Objective-C actions that need
- /// to lookup file scope declarations in the "ordinary" C decl namespace.
- /// For example, user-defined classes, built-in "id" type, etc.
- Scope *TUScope;
-
- /// \brief The C++ "std" namespace, where the standard library resides.
- LazyDeclPtr StdNamespace;
-
- /// \brief The C++ "std::bad_alloc" class, which is defined by the C++
- /// standard library.
- LazyDeclPtr StdBadAlloc;
-
- /// \brief 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>.
- RecordDecl *CXXTypeInfoDecl;
-
- /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files.
- RecordDecl *MSVCGuidDecl;
-
- /// \brief Caches identifiers/selectors for NSFoundation APIs.
- std::unique_ptr<NSAPI> NSAPIObj;
-
- /// \brief The declaration of the Objective-C NSNumber class.
- ObjCInterfaceDecl *NSNumberDecl;
-
- /// \brief The declaration of the Objective-C NSValue class.
- ObjCInterfaceDecl *NSValueDecl;
-
- /// \brief Pointer to NSNumber type (NSNumber *).
- QualType NSNumberPointer;
-
- /// \brief Pointer to NSValue type (NSValue *).
- QualType NSValuePointer;
-
- /// \brief The Objective-C NSNumber methods used to create NSNumber literals.
- ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods];
-
- /// \brief The declaration of the Objective-C NSString class.
- ObjCInterfaceDecl *NSStringDecl;
-
- /// \brief Pointer to NSString type (NSString *).
- QualType NSStringPointer;
-
- /// \brief The declaration of the stringWithUTF8String: method.
- ObjCMethodDecl *StringWithUTF8StringMethod;
-
- /// \brief The declaration of the valueWithBytes:objCType: method.
- ObjCMethodDecl *ValueWithBytesObjCTypeMethod;
-
- /// \brief The declaration of the Objective-C NSArray class.
- ObjCInterfaceDecl *NSArrayDecl;
-
- /// \brief The declaration of the arrayWithObjects:count: method.
- ObjCMethodDecl *ArrayWithObjectsMethod;
-
- /// \brief The declaration of the Objective-C NSDictionary class.
- ObjCInterfaceDecl *NSDictionaryDecl;
-
- /// \brief The declaration of the dictionaryWithObjects:forKeys:count: method.
- ObjCMethodDecl *DictionaryWithObjectsMethod;
-
- /// \brief id<NSCopying> type.
- QualType QIDNSCopying;
-
- /// \brief will hold 'respondsToSelector:'
- Selector RespondsToSelectorSel;
-
- /// \brief counter for internal MS Asm label names.
- unsigned MSAsmLabelNameCounter;
-
- /// A flag to remember whether the implicit forms of operator new and delete
- /// have been declared.
- bool GlobalNewDeleteDeclared;
-
- /// A flag to indicate that we're in a context that permits abstract
- /// references to fields. This is really a
- bool AllowAbstractFieldReference;
-
- /// \brief Describes how the expressions currently being parsed are
- /// evaluated at run-time, if at all.
- enum ExpressionEvaluationContext {
- /// \brief 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 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,
- /// 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,
- /// 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
- /// declarations referenced inside that expression are only used if
- /// in fact the current expression is used.
- ///
- /// This value is used when parsing default function arguments, for which
- /// we would like to provide diagnostics (e.g., passing non-POD arguments
- /// through varargs) but do not want to mark declarations as "referenced"
- /// until the default argument is used.
- PotentiallyEvaluatedIfUsed
- };
-
- /// \brief Data structure used to record current or nested
- /// expression evaluation contexts.
- struct ExpressionEvaluationContextRecord {
- /// \brief The expression evaluation context.
- ExpressionEvaluationContext Context;
-
- /// \brief Whether the enclosing context needed a cleanup.
- bool ParentNeedsCleanups;
-
- /// \brief Whether we are in a decltype expression.
- bool IsDecltype;
-
- /// \brief 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
- /// 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
- /// is indeed an unevaluated context.
- SmallVector<LambdaExpr *, 2> Lambdas;
-
- /// \brief 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
- /// and block literals within this context.
- ///
- /// This mangling information is allocated lazily, since most contexts
- /// do not have lambda expressions or block literals.
- IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering;
-
- /// \brief 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
- /// expressions for which we have deferred checking the destructor.
- SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds;
-
- ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
- unsigned NumCleanupObjects,
- bool ParentNeedsCleanups,
- Decl *ManglingContextDecl,
- bool IsDecltype)
- : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),
- IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
- NumTypos(0),
- ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }
-
- /// \brief Retrieve the mangling numbering context, used to consistently
- /// number constructs like lambdas for mangling.
- MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx);
-
- bool isUnevaluated() const {
- return Context == Unevaluated || Context == UnevaluatedAbstract;
- }
- };
-
- /// A stack of expression evaluation contexts.
- SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
-
- /// \brief Compute the mangling number context for a lambda expression or
- /// block literal.
- ///
- /// \param DC - The DeclContext containing the lambda expression or
- /// block literal.
- /// \param[out] ManglingContextDecl - Returns the ManglingContextDecl
- /// associated with the context, if relevant.
- MangleNumberingContext *getCurrentMangleNumberContext(
- const DeclContext *DC,
- Decl *&ManglingContextDecl);
-
-
- /// SpecialMemberOverloadResult - The overloading result for a special member
- /// function.
- ///
- /// This is basically a wrapper around PointerIntPair. The lowest bits of the
- /// integer are used to determine whether overload resolution succeeded.
- class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
- public:
- enum Kind {
- NoMemberOrDeleted,
- Ambiguous,
- Success
- };
-
- private:
- llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
-
- public:
- SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
- : FastFoldingSetNode(ID)
- {}
-
- CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
- void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
-
- Kind getKind() const { return static_cast<Kind>(Pair.getInt()); }
- void setKind(Kind K) { Pair.setInt(K); }
- };
-
- /// \brief A cache of special member function overload resolution results
- /// for C++ records.
- llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache;
-
- /// \brief 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.
- ///
- /// When we're processing a complete translation unit, Sema will perform
- /// end-of-translation-unit semantic tasks (such as creating
- /// initializers for tentative definitions in C) once parsing has
- /// completed. Modules and precompiled headers perform different kinds of
- /// checks.
- TranslationUnitKind TUKind;
-
- llvm::BumpPtrAllocator BumpAlloc;
-
- /// \brief 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
- /// set of instantiations of each parameter.
- ///
- /// This mapping is a temporary data structure used when parsing
- /// nested class templates or nested classes of class templates,
- /// where we might end up instantiating an inner class before the
- /// default arguments of its methods have been parsed.
- UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations;
-
- // Contains the locations of the beginning of unparsed default
- // argument locations.
- llvm::DenseMap<ParmVarDecl *, SourceLocation> UnparsedDefaultArgLocs;
-
- /// UndefinedInternals - all the used, undefined objects which require a
- /// definition in this translation unit.
- llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedButUsed;
-
- /// Obtain a sorted list of functions that are undefined but ODR-used.
- void getUndefinedButUsed(
- SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined);
-
- /// Retrieves list of suspicious delete-expressions that will be checked at
- /// the end of translation unit.
- const llvm::MapVector<FieldDecl *, DeleteLocs> &
- getMismatchingDeleteExpressions() const;
-
- typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
- typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
-
- /// Method Pool - allows efficient lookup when typechecking messages to "id".
- /// We need to maintain a list, since selectors can have differing signatures
- /// across classes. In Cocoa, this happens to be extremely uncommon (only 1%
- /// of selectors are "overloaded").
- /// At the head of the list it is recorded whether there were 0, 1, or >= 2
- /// methods inside categories with a particular selector.
- GlobalMethodPool MethodPool;
-
- /// Method selectors used in a \@selector expression. Used for implementation
- /// of -Wselector.
- llvm::MapVector<Selector, SourceLocation> ReferencedSelectors;
-
- /// Kinds of C++ special members.
- enum CXXSpecialMember {
- CXXDefaultConstructor,
- CXXCopyConstructor,
- CXXMoveConstructor,
- CXXCopyAssignment,
- CXXMoveAssignment,
- CXXDestructor,
- CXXInvalid
- };
-
- typedef std::pair<CXXRecordDecl*, CXXSpecialMember> SpecialMemberDecl;
-
- /// The C++ special members which we are currently in the process of
- /// declaring. If this process recursively triggers the declaration of the
- /// same special member, we should act as if it is not yet declared.
- llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared;
-
- void ReadMethodPool(Selector Sel);
-
- /// Private Helper predicate to check for 'self'.
- bool isSelfExpr(Expr *RExpr);
- bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method);
-
- /// \brief 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);
-
- /// Records and restores the FP_CONTRACT state on entry/exit of compound
- /// statements.
- class FPContractStateRAII {
- public:
- FPContractStateRAII(Sema& S)
- : S(S), OldFPContractState(S.FPFeatures.fp_contract) {}
- ~FPContractStateRAII() {
- S.FPFeatures.fp_contract = OldFPContractState;
- }
- private:
- Sema& S;
- bool OldFPContractState : 1;
- };
-
- /// Records and restores the vtordisp state on entry/exit of C++ method body.
- class VtorDispStackRAII {
- public:
- VtorDispStackRAII(Sema &S, bool ShouldSaveAndRestore)
- : S(S), ShouldSaveAndRestore(ShouldSaveAndRestore), OldVtorDispStack() {
- if (ShouldSaveAndRestore)
- OldVtorDispStack = S.VtorDispModeStack;
- }
- ~VtorDispStackRAII() {
- if (ShouldSaveAndRestore)
- S.VtorDispModeStack = OldVtorDispStack;
- }
- private:
- Sema &S;
- bool ShouldSaveAndRestore;
- SmallVector<MSVtorDispAttr::Mode, 2> OldVtorDispStack;
- };
-
- void addImplicitTypedef(StringRef Name, QualType T);
-
-public:
- Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
- TranslationUnitKind TUKind = TU_Complete,
- CodeCompleteConsumer *CompletionConsumer = nullptr);
- ~Sema();
-
- /// \brief Perform initialization that occurs after the parser has been
- /// initialized but before it parses anything.
- void Initialize();
-
- const LangOptions &getLangOpts() const { return LangOpts; }
- OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; }
- FPOptions &getFPOptions() { return FPFeatures; }
-
- DiagnosticsEngine &getDiagnostics() const { return Diags; }
- SourceManager &getSourceManager() const { return SourceMgr; }
- Preprocessor &getPreprocessor() const { return PP; }
- ASTContext &getASTContext() const { return Context; }
- ASTConsumer &getASTConsumer() const { return Consumer; }
- ASTMutationListener *getASTMutationListener() const;
- ExternalSemaSource* getExternalSource() const { return ExternalSource; }
-
- ///\brief 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.
- ///
- void addExternalSource(ExternalSemaSource *E);
-
- void PrintStats() const;
-
- /// \brief Helper class that creates diagnostics with optional
- /// template instantiation stacks.
- ///
- /// This class provides a wrapper around the basic DiagnosticBuilder
- /// class that emits diagnostics. SemaDiagnosticBuilder is
- /// responsible for emitting the diagnostic (as DiagnosticBuilder
- /// does) and, if the diagnostic comes from inside a template
- /// instantiation, printing the template instantiation stack as
- /// well.
- class SemaDiagnosticBuilder : public DiagnosticBuilder {
- Sema &SemaRef;
- unsigned DiagID;
-
- public:
- SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
- : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
-
- // This is a cunning lie. DiagnosticBuilder actually performs move
- // construction in its copy constructor (but due to varied uses, it's not
- // possible to conveniently express this as actual move construction). So
- // the default copy ctor here is fine, because the base class disables the
- // source anyway, so the user-defined ~SemaDiagnosticBuilder is a safe no-op
- // in that case anwyay.
- SemaDiagnosticBuilder(const SemaDiagnosticBuilder&) = default;
-
- ~SemaDiagnosticBuilder() {
- // If we aren't active, there is nothing to do.
- if (!isActive()) return;
-
- // Otherwise, we need to emit the diagnostic. First flush the underlying
- // DiagnosticBuilder data, and clear the diagnostic builder itself so it
- // won't emit the diagnostic in its own destructor.
- //
- // This seems wasteful, in that as written the DiagnosticBuilder dtor will
- // do its own needless checks to see if the diagnostic needs to be
- // emitted. However, because we take care to ensure that the builder
- // objects never escape, a sufficiently smart compiler will be able to
- // eliminate that code.
- FlushCounts();
- Clear();
-
- // Dispatch to Sema to emit the diagnostic.
- SemaRef.EmitCurrentDiagnostic(DiagID);
- }
-
- /// Teach operator<< to produce an object of the correct type.
- template<typename T>
- friend const SemaDiagnosticBuilder &operator<<(
- const SemaDiagnosticBuilder &Diag, const T &Value) {
- const DiagnosticBuilder &BaseDiag = Diag;
- BaseDiag << Value;
- return Diag;
- }
- };
-
- /// \brief 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.
- SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
-
- /// \brief 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.
- std::string
- getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const;
- std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const;
-
- /// \brief Calls \c Lexer::getLocForEndOfToken()
- SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
-
- /// \brief Retrieve the module loader associated with the preprocessor.
- ModuleLoader &getModuleLoader() const;
-
- void emitAndClearUnusedLocalTypedefWarnings();
-
- void ActOnEndOfTranslationUnit();
-
- void CheckDelegatingCtorCycles();
-
- Scope *getScopeForContext(DeclContext *Ctx);
-
- void PushFunctionScope();
- void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
- sema::LambdaScopeInfo *PushLambdaScope();
-
- /// \brief 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);
-
- void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD,
- RecordDecl *RD,
- CapturedRegionKind K);
- void
- PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr,
- const Decl *D = nullptr,
- const BlockExpr *blkExpr = nullptr);
-
- sema::FunctionScopeInfo *getCurFunction() const {
- return FunctionScopes.back();
- }
-
- sema::FunctionScopeInfo *getEnclosingFunction() const {
- if (FunctionScopes.empty())
- return nullptr;
-
- for (int e = FunctionScopes.size()-1; e >= 0; --e) {
- if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
- continue;
- return FunctionScopes[e];
- }
- return nullptr;
- }
-
- template <typename ExprT>
- void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
- if (!isUnevaluatedContext())
- getCurFunction()->recordUseOfWeak(E, IsRead);
- }
-
- void PushCompoundScope();
- void PopCompoundScope();
-
- sema::CompoundScopeInfo &getCurCompoundScope() const;
-
- bool hasAnyUnrecoverableErrorsInThisFunction() const;
-
- /// \brief Retrieve the current block, if any.
- sema::BlockScopeInfo *getCurBlock();
-
- /// \brief Retrieve the current lambda scope info, if any.
- sema::LambdaScopeInfo *getCurLambda();
-
- /// \brief Retrieve the current generic lambda info, if any.
- sema::LambdaScopeInfo *getCurGenericLambda();
-
- /// \brief Retrieve the current captured region, if any.
- sema::CapturedRegionScopeInfo *getCurCapturedRegion();
-
- /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls
- SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
-
- void ActOnComment(SourceRange Comment);
-
- //===--------------------------------------------------------------------===//
- // Type Analysis / Processing: SemaType.cpp.
- //
-
- QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs,
- const DeclSpec *DS = nullptr);
- QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA,
- const DeclSpec *DS = nullptr);
- QualType BuildPointerType(QualType T,
- SourceLocation Loc, DeclarationName Entity);
- QualType BuildReferenceType(QualType T, bool LValueRef,
- SourceLocation Loc, DeclarationName Entity);
- QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
- Expr *ArraySize, unsigned Quals,
- SourceRange Brackets, DeclarationName Entity);
- QualType BuildExtVectorType(QualType T, Expr *ArraySize,
- SourceLocation AttrLoc);
-
- bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
-
- /// \brief 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
- /// just been instantiated from a template. It therefore duplicates
- /// some of the behavior of GetTypeForDeclarator, but in a much
- /// simpler form that is only suitable for this narrow use case.
- ///
- /// \param T The return type of the function.
- ///
- /// \param ParamTypes The parameter types of the function. This array
- /// will be modified to account for adjustments to the types of the
- /// function parameters.
- ///
- /// \param Loc The location of the entity whose type involves this
- /// function type or, if there is no such entity, the location of the
- /// type that will have function type.
- ///
- /// \param Entity The name of the entity that involves the function
- /// type, if known.
- ///
- /// \param EPI Extra information about the function type. Usually this will
- /// be taken from an existing function with the same prototype.
- ///
- /// \returns A suitable function type, if there are no errors. The
- /// unqualified type will always be a FunctionProtoType.
- /// Otherwise, returns a NULL type.
- QualType BuildFunctionType(QualType T,
- MutableArrayRef<QualType> ParamTypes,
- SourceLocation Loc, DeclarationName Entity,
- const FunctionProtoType::ExtProtoInfo &EPI);
-
- QualType BuildMemberPointerType(QualType T, QualType Class,
- SourceLocation Loc,
- DeclarationName Entity);
- QualType BuildBlockPointerType(QualType T,
- SourceLocation Loc, DeclarationName Entity);
- QualType BuildParenType(QualType T);
- QualType BuildAtomicType(QualType T, SourceLocation Loc);
-
- TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
- TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
- TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
- TypeSourceInfo *ReturnTypeInfo);
-
- /// \brief Package the given type and TSI into a ParsedType.
- ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);
- DeclarationNameInfo GetNameForDeclarator(Declarator &D);
- DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name);
- static QualType GetTypeFromParser(ParsedType Ty,
- TypeSourceInfo **TInfo = nullptr);
- CanThrowResult canThrow(const Expr *E);
- const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
- const FunctionProtoType *FPT);
- void UpdateExceptionSpec(FunctionDecl *FD,
- const FunctionProtoType::ExceptionSpecInfo &ESI);
- bool CheckSpecifiedExceptionType(QualType &T, SourceRange Range);
- bool CheckDistantExceptionSpec(QualType T);
- bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
- bool CheckEquivalentExceptionSpec(
- const FunctionProtoType *Old, SourceLocation OldLoc,
- const FunctionProtoType *New, SourceLocation NewLoc);
- bool CheckEquivalentExceptionSpec(
- const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
- const FunctionProtoType *Old, SourceLocation OldLoc,
- const FunctionProtoType *New, SourceLocation NewLoc,
- bool *MissingExceptionSpecification = nullptr,
- bool *MissingEmptyExceptionSpecification = nullptr,
- bool AllowNoexceptAllMatchWithNoSpec = false,
- bool IsOperatorNew = false);
- bool CheckExceptionSpecSubset(
- const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
- const FunctionProtoType *Superset, SourceLocation SuperLoc,
- const FunctionProtoType *Subset, SourceLocation SubLoc);
- bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
- const FunctionProtoType *Target, SourceLocation TargetLoc,
- const FunctionProtoType *Source, SourceLocation SourceLoc);
-
- TypeResult ActOnTypeName(Scope *S, Declarator &D);
-
- /// \brief 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.
- struct TypeDiagnoser {
- TypeDiagnoser() {}
-
- virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0;
- virtual ~TypeDiagnoser() {}
- };
-
- static int getPrintable(int I) { return I; }
- static unsigned getPrintable(unsigned I) { return I; }
- static bool getPrintable(bool B) { return B; }
- static const char * getPrintable(const char *S) { return S; }
- static StringRef getPrintable(StringRef S) { return S; }
- static const std::string &getPrintable(const std::string &S) { return S; }
- static const IdentifierInfo *getPrintable(const IdentifierInfo *II) {
- return II;
- }
- static DeclarationName getPrintable(DeclarationName N) { return N; }
- static QualType getPrintable(QualType T) { return T; }
- static SourceRange getPrintable(SourceRange R) { return R; }
- static SourceRange getPrintable(SourceLocation L) { return L; }
- static SourceRange getPrintable(const Expr *E) { return E->getSourceRange(); }
- static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();}
-
- template <typename... Ts> class BoundTypeDiagnoser : public TypeDiagnoser {
- unsigned DiagID;
- std::tuple<const Ts &...> Args;
-
- template <std::size_t... Is>
- void emit(const SemaDiagnosticBuilder &DB,
- llvm::index_sequence<Is...>) const {
- // Apply all tuple elements to the builder in order.
- bool Dummy[] = {false, (DB << getPrintable(std::get<Is>(Args)))...};
- (void)Dummy;
- }
-
- public:
- BoundTypeDiagnoser(unsigned DiagID, const Ts &...Args)
- : TypeDiagnoser(), DiagID(DiagID), Args(Args...) {
- assert(DiagID != 0 && "no diagnostic for type diagnoser");
- }
-
- void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
- const SemaDiagnosticBuilder &DB = S.Diag(Loc, DiagID);
- emit(DB, llvm::index_sequence_for<Ts...>());
- DB << T;
- }
- };
-
-private:
- bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
- TypeDiagnoser *Diagnoser);
-
- VisibleModuleSet VisibleModules;
- llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack;
-
- Module *CachedFakeTopLevelModule;
-
-public:
- /// \brief Get the module owning an entity.
- Module *getOwningModule(Decl *Entity);
-
- /// \brief Make a merged definition of an existing hidden definition \p ND
- /// visible at the specified location.
- void makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc);
-
- bool isModuleVisible(Module *M) { return VisibleModules.isVisible(M); }
-
- /// Determine whether a declaration is visible to name lookup.
- bool isVisible(const NamedDecl *D) {
- return !D->isHidden() || isVisibleSlow(D);
- }
- bool hasVisibleMergedDefinition(NamedDecl *Def);
-
- /// Determine if \p D has a visible definition. If not, suggest a declaration
- /// that should be made visible to expose the definition.
- bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested,
- bool OnlyNeedComplete = false);
- bool hasVisibleDefinition(const NamedDecl *D) {
- NamedDecl *Hidden;
- return hasVisibleDefinition(const_cast<NamedDecl*>(D), &Hidden);
- }
-
- /// Determine if the template parameter \p D has a visible default argument.
- bool
- hasVisibleDefaultArgument(const NamedDecl *D,
- llvm::SmallVectorImpl<Module *> *Modules = nullptr);
-
- /// Determine if \p A and \p B are equivalent internal linkage declarations
- /// from different modules, and thus an ambiguity error can be downgraded to
- /// an extension warning.
- bool isEquivalentInternalLinkageDeclaration(const NamedDecl *A,
- const NamedDecl *B);
- void diagnoseEquivalentInternalLinkageDeclarations(
- SourceLocation Loc, const NamedDecl *D,
- ArrayRef<const NamedDecl *> Equiv);
-
- bool isCompleteType(SourceLocation Loc, QualType T) {
- return !RequireCompleteTypeImpl(Loc, T, nullptr);
- }
- bool RequireCompleteType(SourceLocation Loc, QualType T,
- TypeDiagnoser &Diagnoser);
- bool RequireCompleteType(SourceLocation Loc, QualType T,
- unsigned DiagID);
-
- template <typename... Ts>
- bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID,
- const Ts &...Args) {
- BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
- return RequireCompleteType(Loc, T, Diagnoser);
- }
-
- void completeExprArrayBound(Expr *E);
- bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser);
- bool RequireCompleteExprType(Expr *E, unsigned DiagID);
-
- template <typename... Ts>
- bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) {
- BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
- return RequireCompleteExprType(E, Diagnoser);
- }
-
- bool RequireLiteralType(SourceLocation Loc, QualType T,
- TypeDiagnoser &Diagnoser);
- bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID);
-
- template <typename... Ts>
- bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID,
- const Ts &...Args) {
- BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
- return RequireLiteralType(Loc, T, Diagnoser);
- }
-
- QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
- const CXXScopeSpec &SS, QualType T);
-
- QualType BuildTypeofExprType(Expr *E, SourceLocation Loc);
- /// If AsUnevaluated is false, E is treated as though it were an evaluated
- /// context, such as when building a type for decltype(auto).
- QualType BuildDecltypeType(Expr *E, SourceLocation Loc,
- bool AsUnevaluated = true);
- QualType BuildUnaryTransformType(QualType BaseType,
- UnaryTransformType::UTTKind UKind,
- SourceLocation Loc);
-
- //===--------------------------------------------------------------------===//
- // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
- //
-
- struct SkipBodyInfo {
- SkipBodyInfo() : ShouldSkip(false), Previous(nullptr) {}
- bool ShouldSkip;
- NamedDecl *Previous;
- };
-
- /// List of decls defined in a function prototype. This contains EnumConstants
- /// that incorrectly end up in translation unit scope because there is no
- /// function to pin them on. ActOnFunctionDeclarator reads this list and patches
- /// them into the FunctionDecl.
- std::vector<NamedDecl*> DeclsInPrototypeScope;
-
- DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
-
- void DiagnoseUseOfUnimplementedSelectors();
-
- bool isSimpleTypeSpecifier(tok::TokenKind Kind) const;
-
- ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, CXXScopeSpec *SS = nullptr,
- bool isClassName = false,
- bool HasTrailingDot = false,
- ParsedType ObjectType = ParsedType(),
- bool IsCtorOrDtorName = false,
- bool WantNontrivialTypeSourceInfo = false,
- IdentifierInfo **CorrectedII = nullptr);
- TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
- bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S);
- void DiagnoseUnknownTypeName(IdentifierInfo *&II,
- SourceLocation IILoc,
- Scope *S,
- CXXScopeSpec *SS,
- ParsedType &SuggestedType,
- bool AllowClassTemplates = false);
-
- /// \brief For compatibility with MSVC, we delay parsing of some default
- /// template type arguments until instantiation time. Emits a warning and
- /// returns a synthesized DependentNameType that isn't really dependent on any
- /// other template arguments.
- ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II,
- SourceLocation NameLoc);
-
- /// \brief Describes the result of the name lookup and resolution performed
- /// by \c ClassifyName().
- enum NameClassificationKind {
- NC_Unknown,
- NC_Error,
- NC_Keyword,
- NC_Type,
- NC_Expression,
- NC_NestedNameSpecifier,
- NC_TypeTemplate,
- NC_VarTemplate,
- NC_FunctionTemplate
- };
-
- class NameClassification {
- NameClassificationKind Kind;
- ExprResult Expr;
- TemplateName Template;
- ParsedType Type;
- const IdentifierInfo *Keyword;
-
- explicit NameClassification(NameClassificationKind Kind) : Kind(Kind) {}
-
- public:
- NameClassification(ExprResult Expr) : Kind(NC_Expression), Expr(Expr) {}
-
- NameClassification(ParsedType Type) : Kind(NC_Type), Type(Type) {}
-
- NameClassification(const IdentifierInfo *Keyword)
- : Kind(NC_Keyword), Keyword(Keyword) { }
-
- static NameClassification Error() {
- return NameClassification(NC_Error);
- }
-
- static NameClassification Unknown() {
- return NameClassification(NC_Unknown);
- }
-
- static NameClassification NestedNameSpecifier() {
- return NameClassification(NC_NestedNameSpecifier);
- }
-
- static NameClassification TypeTemplate(TemplateName Name) {
- NameClassification Result(NC_TypeTemplate);
- Result.Template = Name;
- return Result;
- }
-
- static NameClassification VarTemplate(TemplateName Name) {
- NameClassification Result(NC_VarTemplate);
- Result.Template = Name;
- return Result;
- }
-
- static NameClassification FunctionTemplate(TemplateName Name) {
- NameClassification Result(NC_FunctionTemplate);
- Result.Template = Name;
- return Result;
- }
-
- NameClassificationKind getKind() const { return Kind; }
-
- ParsedType getType() const {
- assert(Kind == NC_Type);
- return Type;
- }
-
- ExprResult getExpression() const {
- assert(Kind == NC_Expression);
- return Expr;
- }
-
- TemplateName getTemplateName() const {
- assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate ||
- Kind == NC_VarTemplate);
- return Template;
- }
-
- TemplateNameKind getTemplateNameKind() const {
- switch (Kind) {
- case NC_TypeTemplate:
- return TNK_Type_template;
- case NC_FunctionTemplate:
- return TNK_Function_template;
- case NC_VarTemplate:
- return TNK_Var_template;
- default:
- llvm_unreachable("unsupported name classification.");
- }
- }
- };
-
- /// \brief 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
- /// parsing. When the identifier cannot be found, this routine will attempt
- /// to correct the typo and classify based on the resulting name.
- ///
- /// \param S The scope in which we're performing name lookup.
- ///
- /// \param SS The nested-name-specifier that precedes the name.
- ///
- /// \param Name The identifier. If typo correction finds an alternative name,
- /// this pointer parameter will be updated accordingly.
- ///
- /// \param NameLoc The location of the identifier.
- ///
- /// \param NextToken The token following the identifier. Used to help
- /// disambiguate the name.
- ///
- /// \param IsAddressOfOperand True if this name is the operand of a unary
- /// address of ('&') expression, assuming it is classified as an
- /// expression.
- ///
- /// \param CCC The correction callback, if typo correction is desired.
- NameClassification
- ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name,
- SourceLocation NameLoc, const Token &NextToken,
- bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
-
- Decl *ActOnDeclarator(Scope *S, Declarator &D);
-
- NamedDecl *HandleDeclarator(Scope *S, Declarator &D,
- MultiTemplateParamsArg TemplateParameterLists);
- void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S);
- bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
- bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
- DeclarationName Name,
- SourceLocation Loc);
- void
- diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
- SourceLocation FallbackLoc,
- SourceLocation ConstQualLoc = SourceLocation(),
- SourceLocation VolatileQualLoc = SourceLocation(),
- SourceLocation RestrictQualLoc = SourceLocation(),
- SourceLocation AtomicQualLoc = SourceLocation());
-
- static bool adjustContextForLocalExternDecl(DeclContext *&DC);
- void DiagnoseFunctionSpecifiers(const DeclSpec &DS);
- void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
- void CheckShadow(Scope *S, VarDecl *D);
- void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange);
- void handleTagNumbering(const TagDecl *Tag, Scope *TagScope);
- void setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec,
- TypedefNameDecl *NewTD);
- void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D);
- NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- TypeSourceInfo *TInfo,
- LookupResult &Previous);
- NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D,
- LookupResult &Previous, bool &Redeclaration);
- NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
- TypeSourceInfo *TInfo,
- LookupResult &Previous,
- MultiTemplateParamsArg TemplateParamLists,
- bool &AddToScope);
- // Returns true if the variable declaration is a redeclaration
- bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
- void CheckVariableDeclarationType(VarDecl *NewVD);
- void CheckCompleteVariableDeclaration(VarDecl *var);
- void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
-
- NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- TypeSourceInfo *TInfo,
- LookupResult &Previous,
- MultiTemplateParamsArg TemplateParamLists,
- bool &AddToScope);
- bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
-
- bool CheckConstexprFunctionDecl(const FunctionDecl *FD);
- bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body);
-
- void DiagnoseHiddenVirtualMethods(CXXMethodDecl *MD);
- void FindHiddenVirtualMethods(CXXMethodDecl *MD,
- SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods);
- void NoteHiddenVirtualMethods(CXXMethodDecl *MD,
- SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods);
- // Returns true if the function declaration is a redeclaration
- bool CheckFunctionDeclaration(Scope *S,
- FunctionDecl *NewFD, LookupResult &Previous,
- bool IsExplicitSpecialization);
- void CheckMain(FunctionDecl *FD, const DeclSpec &D);
- void CheckMSVCRTEntryPoint(FunctionDecl *FD);
- Decl *ActOnParamDeclarator(Scope *S, Declarator &D);
- ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
- SourceLocation Loc,
- QualType T);
- ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation NameLoc, IdentifierInfo *Name,
- QualType T, TypeSourceInfo *TSInfo,
- StorageClass SC);
- void ActOnParamDefaultArgument(Decl *param,
- SourceLocation EqualLoc,
- Expr *defarg);
- void ActOnParamUnparsedDefaultArgument(Decl *param,
- SourceLocation EqualLoc,
- SourceLocation ArgLoc);
- void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc);
- bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
- SourceLocation EqualLoc);
-
- void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit,
- bool TypeMayContainAuto);
- void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto);
- void ActOnInitializerError(Decl *Dcl);
- void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc);
- void ActOnCXXForRangeDecl(Decl *D);
- StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
- IdentifierInfo *Ident,
- ParsedAttributes &Attrs,
- SourceLocation AttrEnd);
- void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc);
- void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc);
- void FinalizeDeclaration(Decl *D);
- DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
- ArrayRef<Decl *> Group);
- DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
- bool TypeMayContainAuto = true);
-
- /// Should be called on all declarations that might have attached
- /// documentation comments.
- void ActOnDocumentableDecl(Decl *D);
- void ActOnDocumentableDecls(ArrayRef<Decl *> Group);
-
- void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
- SourceLocation LocAfterDecls);
- void CheckForFunctionRedefinition(
- FunctionDecl *FD, const FunctionDecl *EffectiveDefinition = nullptr,
- SkipBodyInfo *SkipBody = nullptr);
- Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D,
- MultiTemplateParamsArg TemplateParamLists,
- SkipBodyInfo *SkipBody = nullptr);
- Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D,
- SkipBodyInfo *SkipBody = nullptr);
- void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
- bool isObjCMethodDecl(Decl *D) {
- return D && isa<ObjCMethodDecl>(D);
- }
-
- /// \brief 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.
- ///
- /// This will be \c false if we may need the body of the function in the
- /// middle of parsing an expression (where it's impractical to switch to
- /// parsing a different function), for instance, if it's constexpr in C++11
- /// 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
- /// definition, assuming we don't care about analyzing its body or emitting
- /// code for that function.
- ///
- /// This will be \c false only if we may need the body of the function in
- /// order to parse the rest of the program (for instance, if it is
- /// \c constexpr in C++11 or has an 'auto' return type in C++14).
- bool canSkipFunctionBody(Decl *D);
-
- void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope);
- Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
- Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation);
- Decl *ActOnSkippedFunctionBody(Decl *Decl);
- void ActOnFinishInlineMethodDef(CXXMethodDecl *D);
-
- /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an
- /// attribute for which parsing is delayed.
- void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs);
-
- /// \brief Diagnose any unused parameters in the given sequence of
- /// ParmVarDecl pointers.
- void DiagnoseUnusedParameters(ParmVarDecl * const *Begin,
- ParmVarDecl * const *End);
-
- /// \brief 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 DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Begin,
- ParmVarDecl * const *End,
- QualType ReturnTy,
- NamedDecl *D);
-
- void DiagnoseInvalidJumps(Stmt *Body);
- Decl *ActOnFileScopeAsmDecl(Expr *expr,
- SourceLocation AsmLoc,
- SourceLocation RParenLoc);
-
- /// \brief Handle a C++11 empty-declaration and attribute-declaration.
- Decl *ActOnEmptyDeclaration(Scope *S,
- AttributeList *AttrList,
- SourceLocation SemiLoc);
-
- /// \brief The parser has processed a module import declaration.
- ///
- /// \param AtLoc The location of the '@' symbol, if any.
- ///
- /// \param ImportLoc The location of the 'import' keyword.
- ///
- /// \param Path The module access path.
- DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc,
- ModuleIdPath Path);
-
- /// \brief The parser has processed a module import translated from a
- /// #include or similar preprocessing directive.
- void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
-
- /// \brief The parsed has entered a submodule.
- void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod);
- /// \brief The parser has left a submodule.
- void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod);
-
- /// \brief Check if module import may be found in the current context,
- /// emit error if not.
- void diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc);
-
- /// \brief 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
- /// is actually hidden within a module that we know about but the user
- /// has forgotten to import.
- void createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
- Module *Mod);
-
- /// Kinds of missing import. Note, the values of these enumerators correspond
- /// to %select values in diagnostics.
- enum class MissingImportKind {
- Declaration,
- Definition,
- DefaultArgument
- };
-
- /// \brief 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,
- bool NeedDefinition, bool Recover = true);
- void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
- SourceLocation DeclLoc, ArrayRef<Module *> Modules,
- MissingImportKind MIK, bool Recover);
-
- /// \brief Retrieve a suitable printing policy.
- PrintingPolicy getPrintingPolicy() const {
- return getPrintingPolicy(Context, PP);
- }
-
- /// \brief Retrieve a suitable printing policy.
- static PrintingPolicy getPrintingPolicy(const ASTContext &Ctx,
- const Preprocessor &PP);
-
- /// Scope actions.
- void ActOnPopScope(SourceLocation Loc, Scope *S);
- void ActOnTranslationUnitScope(Scope *S);
-
- Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
- DeclSpec &DS);
- Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
- DeclSpec &DS,
- MultiTemplateParamsArg TemplateParams,
- bool IsExplicitInstantiation = false);
-
- Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
- AccessSpecifier AS,
- RecordDecl *Record,
- const PrintingPolicy &Policy);
-
- Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
- RecordDecl *Record);
-
- bool isAcceptableTagRedeclaration(const TagDecl *Previous,
- TagTypeKind NewTag, bool isDefinition,
- SourceLocation NewTagLoc,
- const IdentifierInfo *Name);
-
- enum TagUseKind {
- TUK_Reference, // Reference to a tag: 'struct foo *X;'
- TUK_Declaration, // Fwd decl of a tag: 'struct foo;'
- TUK_Definition, // Definition of a tag: 'struct foo { int X; } Y;'
- TUK_Friend // Friend declaration: 'friend struct foo;'
- };
-
- Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr, AccessSpecifier AS,
- SourceLocation ModulePrivateLoc,
- MultiTemplateParamsArg TemplateParameterLists,
- bool &OwnedDecl, bool &IsDependent,
- SourceLocation ScopedEnumKWLoc,
- bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
- bool IsTypeSpecifier, SkipBodyInfo *SkipBody = nullptr);
-
- Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
- unsigned TagSpec, SourceLocation TagLoc,
- CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
- MultiTemplateParamsArg TempParamLists);
-
- TypeResult ActOnDependentTag(Scope *S,
- unsigned TagSpec,
- TagUseKind TUK,
- const CXXScopeSpec &SS,
- IdentifierInfo *Name,
- SourceLocation TagLoc,
- SourceLocation NameLoc);
-
- void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
- IdentifierInfo *ClassName,
- SmallVectorImpl<Decl *> &Decls);
- Decl *ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth);
-
- FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth,
- InClassInitStyle InitStyle,
- AccessSpecifier AS);
- MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD,
- SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth,
- InClassInitStyle InitStyle,
- AccessSpecifier AS,
- AttributeList *MSPropertyAttr);
-
- FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
- TypeSourceInfo *TInfo,
- RecordDecl *Record, SourceLocation Loc,
- bool Mutable, Expr *BitfieldWidth,
- InClassInitStyle InitStyle,
- SourceLocation TSSL,
- AccessSpecifier AS, NamedDecl *PrevDecl,
- Declarator *D = nullptr);
-
- bool CheckNontrivialField(FieldDecl *FD);
- void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM);
- bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
- bool Diagnose = false);
- CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
- void ActOnLastBitfield(SourceLocation DeclStart,
- SmallVectorImpl<Decl *> &AllIvarDecls);
- Decl *ActOnIvar(Scope *S, SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth,
- 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);
-
- /// ActOnTagStartDefinition - Invoked when we have entered the
- /// scope of a tag's definition (e.g., for an enumeration, class,
- /// struct, or union).
- void ActOnTagStartDefinition(Scope *S, Decl *TagDecl);
-
- typedef void *SkippedDefinitionContext;
-
- /// \brief Invoked when we enter a tag definition that we're skipping.
- SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD);
-
- Decl *ActOnObjCContainerStartDefinition(Decl *IDecl);
-
- /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
- /// C++ record definition's base-specifiers clause and are starting its
- /// member declarations.
- void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl,
- SourceLocation FinalLoc,
- bool IsFinalSpelledSealed,
- SourceLocation LBraceLoc);
-
- /// ActOnTagFinishDefinition - Invoked once we have finished parsing
- /// the definition of a tag (enumeration, class, struct, or union).
- void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl,
- SourceLocation RBraceLoc);
-
- void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context);
-
- void ActOnObjCContainerFinishDefinition();
-
- /// \brief 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
- void ActOnObjCTemporaryExitContainerContext(DeclContext *DC);
- void ActOnObjCReenterContainerContext(DeclContext *DC);
-
- /// ActOnTagDefinitionError - Invoked when there was an unrecoverable
- /// error parsing the definition of a tag.
- void ActOnTagDefinitionError(Scope *S, Decl *TagDecl);
-
- EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
- EnumConstantDecl *LastEnumConst,
- SourceLocation IdLoc,
- IdentifierInfo *Id,
- Expr *val);
- bool CheckEnumUnderlyingType(TypeSourceInfo *TI);
- bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped,
- QualType EnumUnderlyingTy,
- bool EnumUnderlyingIsImplicit,
- const EnumDecl *Prev);
-
- /// Determine whether the body of an anonymous enumeration should be skipped.
- /// \param II The name of the first enumerator.
- SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II,
- SourceLocation IILoc);
-
- Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant,
- SourceLocation IdLoc, IdentifierInfo *Id,
- AttributeList *Attrs,
- SourceLocation EqualLoc, Expr *Val);
- void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
- SourceLocation RBraceLoc, Decl *EnumDecl,
- ArrayRef<Decl *> Elements,
- Scope *S, AttributeList *Attr);
-
- DeclContext *getContainingDC(DeclContext *DC);
-
- /// Set the current declaration context until it gets popped.
- void PushDeclContext(Scope *S, DeclContext *DC);
- void PopDeclContext();
-
- /// EnterDeclaratorContext - Used when we must lookup names in the context
- /// of a declarator's nested name specifier.
- void EnterDeclaratorContext(Scope *S, DeclContext *DC);
- void ExitDeclaratorContext(Scope *S);
-
- /// Push the parameters of D, which must be a function, into scope.
- void ActOnReenterFunctionContext(Scope* S, Decl* D);
- void ActOnExitFunctionContext();
-
- DeclContext *getFunctionLevelDeclContext();
-
- /// getCurFunctionDecl - If inside of a function body, this returns a pointer
- /// to the function decl for the function being parsed. If we're currently
- /// in a 'block', this returns the containing context.
- FunctionDecl *getCurFunctionDecl();
-
- /// getCurMethodDecl - If inside of a method body, this returns a pointer to
- /// the method decl for the method being parsed. If we're currently
- /// in a 'block', this returns the containing context.
- ObjCMethodDecl *getCurMethodDecl();
-
- /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method
- /// or C function we're in, otherwise return null. If we're currently
- /// in a 'block', this returns the containing context.
- NamedDecl *getCurFunctionOrMethodDecl();
-
- /// 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
- /// top level scope.
- ///
- /// \param D The externally-produced declaration to push.
- ///
- /// \param Name The name of the externally-produced declaration.
- void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name);
-
- /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
- /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
- /// true if 'D' belongs to the given declaration context.
- ///
- /// \param AllowInlineNamespace If \c true, allow the declaration to be in the
- /// enclosing namespace set of the context, rather than contained
- /// directly within it.
- bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = nullptr,
- bool AllowInlineNamespace = false);
-
- /// Finds the scope corresponding to the given decl context, if it
- /// happens to be an enclosing scope. Otherwise return NULL.
- static Scope *getScopeForDeclContext(Scope *S, DeclContext *DC);
-
- /// Subroutines of ActOnDeclarator().
- TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
- TypeSourceInfo *TInfo);
- bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New);
-
- /// \brief 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.
- AMK_None,
- /// \brief Merge availability attributes for a redeclaration, which requires
- /// an exact match.
- AMK_Redeclaration,
- /// \brief 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
- /// a protocol requirement.
- AMK_ProtocolImplementation,
- };
-
- /// Attribute merging methods. Return true if a new attribute was added.
- AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
- IdentifierInfo *Platform,
- VersionTuple Introduced,
- VersionTuple Deprecated,
- VersionTuple Obsoleted,
- bool IsUnavailable,
- StringRef Message,
- AvailabilityMergeKind AMK,
- unsigned AttrSpellingListIndex);
- TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
- TypeVisibilityAttr::VisibilityType Vis,
- unsigned AttrSpellingListIndex);
- VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range,
- VisibilityAttr::VisibilityType Vis,
- unsigned AttrSpellingListIndex);
- DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex);
- DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex);
- MSInheritanceAttr *
- mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
- unsigned AttrSpellingListIndex,
- MSInheritanceAttr::Spelling SemanticSpelling);
- FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range,
- IdentifierInfo *Format, int FormatIdx,
- int FirstArg, unsigned AttrSpellingListIndex);
- SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name,
- unsigned AttrSpellingListIndex);
- AlwaysInlineAttr *mergeAlwaysInlineAttr(Decl *D, SourceRange Range,
- IdentifierInfo *Ident,
- unsigned AttrSpellingListIndex);
- MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex);
- OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex);
- InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, SourceRange Range,
- IdentifierInfo *Ident,
- unsigned AttrSpellingListIndex);
- CommonAttr *mergeCommonAttr(Decl *D, SourceRange Range, IdentifierInfo *Ident,
- unsigned AttrSpellingListIndex);
-
- void mergeDeclAttributes(NamedDecl *New, Decl *Old,
- AvailabilityMergeKind AMK = AMK_Redeclaration);
- void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
- LookupResult &OldDecls);
- bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S,
- bool MergeTypeWithOld);
- bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
- Scope *S, bool MergeTypeWithOld);
- void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old);
- void MergeVarDecl(VarDecl *New, LookupResult &Previous);
- void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
- void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
- bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
-
- // AssignmentAction - This is used by all the assignment diagnostic functions
- // to represent what is actually causing the operation
- enum AssignmentAction {
- AA_Assigning,
- AA_Passing,
- AA_Returning,
- AA_Converting,
- AA_Initializing,
- AA_Sending,
- AA_Casting,
- AA_Passing_CFAudited
- };
-
- /// C++ Overloading.
- enum OverloadKind {
- /// This is a legitimate overload: the existing declarations are
- /// functions or function templates with different signatures.
- Ovl_Overload,
-
- /// This is not an overload because the signature exactly matches
- /// an existing declaration.
- Ovl_Match,
-
- /// This is not an overload because the lookup results contain a
- /// non-function.
- Ovl_NonFunction
- };
- OverloadKind CheckOverload(Scope *S,
- FunctionDecl *New,
- const LookupResult &OldDecls,
- NamedDecl *&OldDecl,
- bool IsForUsingDecl);
- bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl);
-
- /// \brief 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
- /// an available function, false otherwise.
- bool isFunctionConsideredUnavailable(FunctionDecl *FD);
-
- ImplicitConversionSequence
- TryImplicitConversion(Expr *From, QualType ToType,
- bool SuppressUserConversions,
- bool AllowExplicit,
- bool InOverloadResolution,
- bool CStyle,
- bool AllowObjCWritebackConversion);
-
- bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
- bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
- bool IsComplexPromotion(QualType FromType, QualType ToType);
- bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
- bool InOverloadResolution,
- QualType& ConvertedType, bool &IncompatibleObjC);
- bool isObjCPointerConversion(QualType FromType, QualType ToType,
- QualType& ConvertedType, bool &IncompatibleObjC);
- bool isObjCWritebackConversion(QualType FromType, QualType ToType,
- QualType &ConvertedType);
- bool IsBlockPointerConversion(QualType FromType, QualType ToType,
- QualType& ConvertedType);
- bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
- const FunctionProtoType *NewType,
- unsigned *ArgPos = nullptr);
- void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
- QualType FromType, QualType ToType);
-
- void maybeExtendBlockObject(ExprResult &E);
- CastKind PrepareCastToObjCObjectPointer(ExprResult &E);
- bool CheckPointerConversion(Expr *From, QualType ToType,
- CastKind &Kind,
- CXXCastPath& BasePath,
- bool IgnoreBaseAccess);
- bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
- bool InOverloadResolution,
- QualType &ConvertedType);
- bool CheckMemberPointerConversion(Expr *From, QualType ToType,
- CastKind &Kind,
- CXXCastPath &BasePath,
- bool IgnoreBaseAccess);
- bool IsQualificationConversion(QualType FromType, QualType ToType,
- bool CStyle, bool &ObjCLifetimeConversion);
- bool IsNoReturnConversion(QualType FromType, QualType ToType,
- QualType &ResultTy);
- bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
- bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg);
-
- ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
- const VarDecl *NRVOCandidate,
- QualType ResultType,
- Expr *Value,
- bool AllowNRVO = true);
-
- bool CanPerformCopyInitialization(const InitializedEntity &Entity,
- ExprResult Init);
- ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
- SourceLocation EqualLoc,
- ExprResult Init,
- bool TopLevelOfInitList = false,
- bool AllowExplicit = false);
- ExprResult PerformObjectArgumentInitialization(Expr *From,
- NestedNameSpecifier *Qualifier,
- NamedDecl *FoundDecl,
- CXXMethodDecl *Method);
-
- ExprResult PerformContextuallyConvertToBool(Expr *From);
- ExprResult PerformContextuallyConvertToObjCPointer(Expr *From);
-
- /// Contexts in which a converted constant expression is required.
- enum CCEKind {
- CCEK_CaseValue, ///< Expression in a case label.
- CCEK_Enumerator, ///< Enumerator value with fixed underlying type.
- CCEK_TemplateArg, ///< Value of a non-type template parameter.
- CCEK_NewExpr ///< Constant expression in a noptr-new-declarator.
- };
- ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
- llvm::APSInt &Value, CCEKind CCE);
- ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
- APValue &Value, CCEKind CCE);
-
- /// \brief Abstract base class used to perform a contextual implicit
- /// conversion from an expression to any type passing a filter.
- class ContextualImplicitConverter {
- public:
- bool Suppress;
- bool SuppressConversion;
-
- ContextualImplicitConverter(bool Suppress = false,
- bool SuppressConversion = false)
- : Suppress(Suppress), SuppressConversion(SuppressConversion) {}
-
- /// \brief 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
- /// 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.
- virtual SemaDiagnosticBuilder
- diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) = 0;
-
- /// \brief 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.
- virtual SemaDiagnosticBuilder
- noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0;
-
- /// \brief 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.
- virtual SemaDiagnosticBuilder
- noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0;
-
- /// \brief 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;
-
- virtual ~ContextualImplicitConverter() {}
- };
-
- class ICEConvertDiagnoser : public ContextualImplicitConverter {
- bool AllowScopedEnumerations;
-
- public:
- ICEConvertDiagnoser(bool AllowScopedEnumerations,
- bool Suppress, bool SuppressConversion)
- : ContextualImplicitConverter(Suppress, SuppressConversion),
- AllowScopedEnumerations(AllowScopedEnumerations) {}
-
- /// Match an integral or (possibly scoped) enumeration type.
- bool match(QualType T) override;
-
- SemaDiagnosticBuilder
- diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override {
- return diagnoseNotInt(S, Loc, T);
- }
-
- /// \brief Emits a diagnostic complaining that the expression does not have
- /// integral or enumeration type.
- virtual SemaDiagnosticBuilder
- diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) = 0;
- };
-
- /// Perform a contextual implicit conversion.
- ExprResult PerformContextualImplicitConversion(
- SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter);
-
-
- enum ObjCSubscriptKind {
- OS_Array,
- OS_Dictionary,
- OS_Error
- };
- ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE);
-
- // Note that LK_String is intentionally after the other literals, as
- // this is used for diagnostics logic.
- enum ObjCLiteralKind {
- LK_Array,
- LK_Dictionary,
- LK_Numeric,
- LK_Boxed,
- LK_String,
- LK_Block,
- LK_None
- };
- ObjCLiteralKind CheckLiteralKind(Expr *FromE);
-
- ExprResult PerformObjectMemberConversion(Expr *From,
- NestedNameSpecifier *Qualifier,
- NamedDecl *FoundDecl,
- NamedDecl *Member);
-
- // Members have to be NamespaceDecl* or TranslationUnitDecl*.
- // TODO: make this is a typesafe union.
- typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet;
- typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
-
- void AddOverloadCandidate(FunctionDecl *Function,
- DeclAccessPair FoundDecl,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false,
- bool AllowExplicit = false);
- void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet &CandidateSet,
- TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false);
- void AddMethodCandidate(DeclAccessPair FoundDecl,
- QualType ObjectType,
- Expr::Classification ObjectClassification,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversion = false);
- void AddMethodCandidate(CXXMethodDecl *Method,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext, QualType ObjectType,
- Expr::Classification ObjectClassification,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false);
- void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- QualType ObjectType,
- Expr::Classification ObjectClassification,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false);
- void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
- DeclAccessPair FoundDecl,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false);
- void AddConversionCandidate(CXXConversionDecl *Conversion,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext,
- Expr *From, QualType ToType,
- OverloadCandidateSet& CandidateSet,
- bool AllowObjCConversionOnExplicit);
- void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext,
- Expr *From, QualType ToType,
- OverloadCandidateSet &CandidateSet,
- bool AllowObjCConversionOnExplicit);
- void AddSurrogateCandidate(CXXConversionDecl *Conversion,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext,
- const FunctionProtoType *Proto,
- Expr *Object, ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet);
- void AddMemberOperatorCandidates(OverloadedOperatorKind Op,
- SourceLocation OpLoc, ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- SourceRange OpRange = SourceRange());
- void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool IsAssignmentOperator = false,
- unsigned NumContextualBoolArguments = 0);
- void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
- SourceLocation OpLoc, ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet);
- void AddArgumentDependentLookupCandidates(DeclarationName Name,
- SourceLocation Loc,
- ArrayRef<Expr *> Args,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- OverloadCandidateSet& CandidateSet,
- bool PartialOverloading = false);
-
- // Emit as a 'note' the specific overload candidate
- void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType(),
- bool TakingAddress = false);
-
- // Emit as a series of 'note's all template and non-templates identified by
- // the expression Expr
- void NoteAllOverloadCandidates(Expr *E, QualType DestType = QualType(),
- bool TakingAddress = false);
-
- /// Check the enable_if expressions on the given function. Returns the first
- /// failing attribute, or NULL if they were all successful.
- EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
- bool MissingImplicitThis = false);
-
- /// Returns whether the given function's address can be taken or not,
- /// optionally emitting a diagnostic if the address can't be taken.
- ///
- /// Returns false if taking the address of the function is illegal.
- bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function,
- bool Complain = false,
- SourceLocation Loc = SourceLocation());
-
- // [PossiblyAFunctionType] --> [Return]
- // NonFunctionType --> NonFunctionType
- // R (A) --> R(A)
- // R (*)(A) --> R (A)
- // R (&)(A) --> R (A)
- // R (S::*)(A) --> R (A)
- QualType ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType);
-
- FunctionDecl *
- ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
- QualType TargetType,
- bool Complain,
- DeclAccessPair &Found,
- bool *pHadMultipleCandidates = nullptr);
-
- FunctionDecl *
- ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
- bool Complain = false,
- DeclAccessPair *Found = nullptr);
-
- bool ResolveAndFixSingleFunctionTemplateSpecialization(
- ExprResult &SrcExpr,
- bool DoFunctionPointerConverion = false,
- bool Complain = false,
- SourceRange OpRangeForComplaining = SourceRange(),
- QualType DestTypeForComplaining = QualType(),
- unsigned DiagIDForComplaining = 0);
-
-
- Expr *FixOverloadedFunctionReference(Expr *E,
- DeclAccessPair FoundDecl,
- FunctionDecl *Fn);
- ExprResult FixOverloadedFunctionReference(ExprResult,
- DeclAccessPair FoundDecl,
- FunctionDecl *Fn);
-
- void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet &CandidateSet,
- bool PartialOverloading = false);
-
- // An enum used to represent the different possible results of building a
- // range-based for loop.
- enum ForRangeStatus {
- FRS_Success,
- FRS_NoViableFunction,
- FRS_DiagnosticIssued
- };
-
- ForRangeStatus BuildForRangeBeginEndCall(SourceLocation Loc,
- SourceLocation RangeLoc,
- const DeclarationNameInfo &NameInfo,
- LookupResult &MemberLookup,
- OverloadCandidateSet *CandidateSet,
- Expr *Range, ExprResult *CallExpr);
-
- ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn,
- UnresolvedLookupExpr *ULE,
- SourceLocation LParenLoc,
- MultiExprArg Args,
- SourceLocation RParenLoc,
- Expr *ExecConfig,
- bool AllowTypoCorrection=true);
-
- bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
- MultiExprArg Args, SourceLocation RParenLoc,
- OverloadCandidateSet *CandidateSet,
- ExprResult *Result);
-
- ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
- UnaryOperatorKind Opc,
- const UnresolvedSetImpl &Fns,
- Expr *input);
-
- ExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
- BinaryOperatorKind Opc,
- const UnresolvedSetImpl &Fns,
- Expr *LHS, Expr *RHS);
-
- ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
- SourceLocation RLoc,
- Expr *Base,Expr *Idx);
-
- ExprResult
- BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
- SourceLocation LParenLoc,
- MultiExprArg Args,
- SourceLocation RParenLoc);
- ExprResult
- BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc,
- MultiExprArg Args,
- SourceLocation RParenLoc);
-
- ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base,
- SourceLocation OpLoc,
- bool *NoArrowOperatorFound = nullptr);
-
- /// CheckCallReturnType - Checks that a call expression's return type is
- /// complete. Returns true on failure. The location passed in is the location
- /// that best represents the call.
- bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
- CallExpr *CE, FunctionDecl *FD);
-
- /// Helpers for dealing with blocks and functions.
- bool CheckParmsForFunctionDef(ParmVarDecl *const *Param,
- ParmVarDecl *const *ParamEnd,
- bool CheckParameterNames);
- void CheckCXXDefaultArguments(FunctionDecl *FD);
- void CheckExtraCXXDefaultArguments(Declarator &D);
- Scope *getNonFieldDeclScope(Scope *S);
-
- /// \name Name lookup
- ///
- /// These routines provide name lookup that is used during semantic
- /// analysis to resolve the various kinds of names (identifiers,
- /// overloaded operator names, constructor names, etc.) into zero or
- /// more declarations within a particular scope. The major entry
- /// points are LookupName, which performs unqualified name lookup,
- /// and LookupQualifiedName, which performs qualified name lookup.
- ///
- /// All name lookup is performed based on some specific criteria,
- /// which specify what names will be visible to name lookup and how
- /// far name lookup should work. These criteria are important both
- /// for capturing language semantics (certain lookups will ignore
- /// certain names, for example) and for performance, since name
- /// lookup is often a bottleneck in the compilation of C++. Name
- /// lookup criteria is specified via the LookupCriteria enumeration.
- ///
- /// The results of name lookup can vary based on the kind of name
- /// lookup performed, the current language, and the translation
- /// unit. In C, for example, name lookup will either return nothing
- /// (no entity found) or a single declaration. In C++, name lookup
- /// can additionally refer to a set of overloaded functions or
- /// result in an ambiguity. All of the possible results of name
- /// lookup are captured by the LookupResult class, which provides
- /// the ability to distinguish among them.
- //@{
-
- /// @brief 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
- /// (functions, variables, members, types, etc.) in C++.
- LookupOrdinaryName = 0,
- /// Tag name lookup, which finds the names of enums, classes,
- /// structs, and unions.
- LookupTagName,
- /// Label name lookup.
- LookupLabel,
- /// Member name lookup, which finds the names of
- /// class/struct/union members.
- LookupMemberName,
- /// Look up of an operator name (e.g., operator+) for use with
- /// operator overloading. This lookup is similar to ordinary name
- /// lookup, but will ignore any declarations that are class members.
- LookupOperatorName,
- /// Look up of a name that precedes the '::' scope resolution
- /// operator in C++. This lookup completely ignores operator, object,
- /// function, and enumerator names (C++ [basic.lookup.qual]p1).
- LookupNestedNameSpecifierName,
- /// Look up a namespace name within a C++ using directive or
- /// namespace alias definition, ignoring non-namespace names (C++
- /// [basic.lookup.udir]p1).
- LookupNamespaceName,
- /// Look up all declarations in a scope with the given name,
- /// including resolved using declarations. This is appropriate
- /// for checking redeclarations for a using declaration.
- LookupUsingDeclName,
- /// Look up an ordinary name that is going to be redeclared as a
- /// name with linkage. This lookup ignores any declarations that
- /// are outside of the current scope unless they have linkage. See
- /// C99 6.2.2p4-5 and C++ [basic.link]p6.
- LookupRedeclarationWithLinkage,
- /// Look up a friend of a local class. This lookup does not look
- /// outside the innermost non-class scope. See C++11 [class.friend]p11.
- LookupLocalFriendName,
- /// Look up the name of an Objective-C protocol.
- LookupObjCProtocolName,
- /// Look up implicit 'self' parameter of an objective-c method.
- LookupObjCImplicitSelfParam,
- /// \brief Look up any declaration with any name.
- LookupAnyName
- };
-
- /// \brief 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
- /// purpose of redeclaring the name.
- NotForRedeclaration = 0,
- /// \brief The lookup results will be used for redeclaration of a name,
- /// if an entity by that name already exists.
- ForRedeclaration
- };
-
- /// \brief The possible outcomes of name lookup for a literal operator.
- enum LiteralOperatorLookupResult {
- /// \brief The lookup resulted in an error.
- LOLR_Error,
- /// \brief 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
- /// a string literal containing the spelling of the literal token.
- LOLR_Raw,
- /// \brief 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,
- /// which expect the character type and characters of the spelling of the
- /// string literal token to be passed as template arguments.
- LOLR_StringTemplate
- };
-
- SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D,
- CXXSpecialMember SM,
- bool ConstArg,
- bool VolatileArg,
- bool RValueThis,
- bool ConstThis,
- bool VolatileThis);
-
- typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator;
- typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)>
- TypoRecoveryCallback;
-
-private:
- bool CppLookupName(LookupResult &R, Scope *S);
-
- struct TypoExprState {
- std::unique_ptr<TypoCorrectionConsumer> Consumer;
- TypoDiagnosticGenerator DiagHandler;
- TypoRecoveryCallback RecoveryHandler;
- TypoExprState();
- TypoExprState(TypoExprState&& other) LLVM_NOEXCEPT;
- TypoExprState& operator=(TypoExprState&& other) LLVM_NOEXCEPT;
- };
-
- /// \brief The set of unhandled TypoExprs and their associated state.
- llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos;
-
- /// \brief 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 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
- /// source.
- bool LoadedExternalKnownNamespaces;
-
- /// \brief 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>
- makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo,
- Sema::LookupNameKind LookupKind, Scope *S,
- CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
- DeclContext *MemberContext, bool EnteringContext,
- const ObjCObjectPointerType *OPT,
- bool ErrorRecovery);
-
-public:
- const TypoExprState &getTypoExprState(TypoExpr *TE) const;
-
- /// \brief Clears the state of the given TypoExpr.
- void clearDelayedTypo(TypoExpr *TE);
-
- /// \brief 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
- /// ambiguity and overloaded.
- NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
- SourceLocation Loc,
- LookupNameKind NameKind,
- RedeclarationKind Redecl
- = NotForRedeclaration);
- bool LookupName(LookupResult &R, Scope *S,
- bool AllowBuiltinCreation = false);
- bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
- bool InUnqualifiedLookup = false);
- bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
- CXXScopeSpec &SS);
- bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
- bool AllowBuiltinCreation = false,
- bool EnteringContext = false);
- ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc,
- RedeclarationKind Redecl
- = NotForRedeclaration);
- bool LookupInSuper(LookupResult &R, CXXRecordDecl *Class);
-
- void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
- QualType T1, QualType T2,
- UnresolvedSetImpl &Functions);
- void addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions,
- DeclAccessPair Operator,
- QualType T1, QualType T2);
-
- LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc = SourceLocation());
-
- DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
- CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class);
- CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class,
- unsigned Quals);
- CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals,
- bool RValueThis, unsigned ThisQuals);
- CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class,
- unsigned Quals);
- CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals,
- bool RValueThis, unsigned ThisQuals);
- CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
-
- bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id);
- LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R,
- ArrayRef<QualType> ArgTys,
- bool AllowRaw,
- bool AllowTemplate,
- bool AllowStringTemplate);
- bool isKnownName(StringRef name);
-
- void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
- ArrayRef<Expr *> Args, ADLResult &Functions);
-
- void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
- VisibleDeclConsumer &Consumer,
- bool IncludeGlobalScope = true);
- void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
- VisibleDeclConsumer &Consumer,
- bool IncludeGlobalScope = true);
-
- enum CorrectTypoKind {
- CTK_NonError, // CorrectTypo used in a non error recovery situation.
- CTK_ErrorRecovery // CorrectTypo used in normal error recovery.
- };
-
- TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
- Sema::LookupNameKind LookupKind,
- Scope *S, CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
- CorrectTypoKind Mode,
- DeclContext *MemberContext = nullptr,
- bool EnteringContext = false,
- const ObjCObjectPointerType *OPT = nullptr,
- bool RecordFailure = true);
-
- TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo,
- Sema::LookupNameKind LookupKind, Scope *S,
- CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
- TypoDiagnosticGenerator TDG,
- TypoRecoveryCallback TRC, CorrectTypoKind Mode,
- DeclContext *MemberContext = nullptr,
- bool EnteringContext = false,
- const ObjCObjectPointerType *OPT = nullptr);
-
- /// \brief 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.
- ///
- /// \param E The Expr to check for TypoExprs.
- ///
- /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its
- /// initializer.
- ///
- /// \param Filter A function applied to a newly rebuilt Expr to determine if
- /// it is an acceptable/usable result from a single combination of typo
- /// corrections. As long as the filter returns ExprError, different
- /// combinations of corrections will be tried until all are exhausted.
- ExprResult
- CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl = nullptr,
- llvm::function_ref<ExprResult(Expr *)> Filter =
- [](Expr *E) -> ExprResult { return E; });
-
- ExprResult
- CorrectDelayedTyposInExpr(Expr *E,
- llvm::function_ref<ExprResult(Expr *)> Filter) {
- return CorrectDelayedTyposInExpr(E, nullptr, Filter);
- }
-
- ExprResult
- CorrectDelayedTyposInExpr(ExprResult ER, VarDecl *InitDecl = nullptr,
- llvm::function_ref<ExprResult(Expr *)> Filter =
- [](Expr *E) -> ExprResult { return E; }) {
- return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter);
- }
-
- ExprResult
- CorrectDelayedTyposInExpr(ExprResult ER,
- llvm::function_ref<ExprResult(Expr *)> Filter) {
- return CorrectDelayedTyposInExpr(ER, nullptr, Filter);
- }
-
- void diagnoseTypo(const TypoCorrection &Correction,
- const PartialDiagnostic &TypoDiag,
- bool ErrorRecovery = true);
-
- void diagnoseTypo(const TypoCorrection &Correction,
- const PartialDiagnostic &TypoDiag,
- const PartialDiagnostic &PrevNote,
- bool ErrorRecovery = true);
-
- void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc,
- ArrayRef<Expr *> Args,
- AssociatedNamespaceSet &AssociatedNamespaces,
- AssociatedClassSet &AssociatedClasses);
-
- void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
- bool ConsiderLinkage, bool AllowInlineNamespace);
-
- void DiagnoseAmbiguousLookup(LookupResult &Result);
- //@}
-
- ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
- SourceLocation IdLoc,
- bool TypoCorrection = false);
- NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
- Scope *S, bool ForRedeclaration,
- SourceLocation Loc);
- NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
- Scope *S);
- void AddKnownFunctionAttributes(FunctionDecl *FD);
-
- // More parsing and symbol table subroutines.
-
- void ProcessPragmaWeak(Scope *S, Decl *D);
- // Decl attributes - this routine is the top level dispatcher.
- void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
- void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
- bool IncludeCXX11Attributes = true);
- bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
- const AttributeList *AttrList);
-
- void checkUnusedDeclAttributes(Declarator &D);
-
- /// Determine if type T is a valid subject for a nonnull and similar
- /// attributes. By default, we look through references (the behavior used by
- /// nonnull), but if the second parameter is true, then we treat a reference
- /// type as valid.
- bool isValidPointerAttrType(QualType T, bool RefOkay = false);
-
- bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
- bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
- const FunctionDecl *FD = nullptr);
- bool CheckNoReturnAttr(const AttributeList &attr);
- bool checkStringLiteralArgumentAttr(const AttributeList &Attr,
- unsigned ArgNum, StringRef &Str,
- SourceLocation *ArgLocation = nullptr);
- bool checkSectionName(SourceLocation LiteralLoc, StringRef Str);
- void checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
- bool checkMSInheritanceAttrOnDefinition(
- CXXRecordDecl *RD, SourceRange Range, bool BestCase,
- MSInheritanceAttr::Spelling SemanticSpelling);
-
- void CheckAlignasUnderalignment(Decl *D);
-
- /// Adjust the calling convention of a method to be the ABI default if it
- /// wasn't specified explicitly. This handles method types formed from
- /// function type typedefs and typename template arguments.
- void adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor,
- SourceLocation Loc);
-
- // Check if there is an explicit attribute, but only look through parens.
- // The intent is to look for an attribute on the current declarator, but not
- // one that came from a typedef.
- bool hasExplicitCallingConv(QualType &T);
-
- /// Get the outermost AttributedType node that sets a calling convention.
- /// Valid types should not have multiple attributes with different CCs.
- const AttributedType *getCallingConvAttributedType(QualType T) const;
-
- /// Check whether a nullability type specifier can be added to the given
- /// type.
- ///
- /// \param type The type to which the nullability specifier will be
- /// added. On success, this type will be updated appropriately.
- ///
- /// \param nullability The nullability specifier to add.
- ///
- /// \param nullabilityLoc The location of the nullability specifier.
- ///
- /// \param isContextSensitive Whether this nullability specifier was
- /// written as a context-sensitive keyword (in an Objective-C
- /// method) or an Objective-C property attribute, rather than as an
- /// underscored type specifier.
- ///
- /// \returns true if nullability cannot be applied, false otherwise.
- bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability,
- SourceLocation nullabilityLoc,
- bool isContextSensitive);
-
- /// \brief Stmt attributes - this routine is the top level dispatcher.
- StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
- SourceRange Range);
-
- void WarnConflictingTypedMethods(ObjCMethodDecl *Method,
- ObjCMethodDecl *MethodDecl,
- bool IsProtocolMethodDecl);
-
- void CheckConflictingOverridingMethod(ObjCMethodDecl *Method,
- ObjCMethodDecl *Overridden,
- bool IsProtocolMethodDecl);
-
- /// WarnExactTypedMethods - This routine issues a warning if method
- /// implementation declaration matches exactly that of its declaration.
- void WarnExactTypedMethods(ObjCMethodDecl *Method,
- ObjCMethodDecl *MethodDecl,
- bool IsProtocolMethodDecl);
-
- typedef llvm::SmallPtrSet<Selector, 8> SelectorSet;
- typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap;
-
- /// CheckImplementationIvars - This routine checks if the instance variables
- /// listed in the implelementation match those listed in the interface.
- void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
- ObjCIvarDecl **Fields, unsigned nIvars,
- SourceLocation Loc);
-
- /// ImplMethodsVsClassMethods - This is main routine to warn if any method
- /// remains unimplemented in the class or category \@implementation.
- void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
- ObjCContainerDecl* IDecl,
- bool IncompleteImpl = false);
-
- /// DiagnoseUnimplementedProperties - This routine warns on those properties
- /// which must be implemented by this implementation.
- void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
- ObjCContainerDecl *CDecl,
- bool SynthesizeProperties);
-
- /// Diagnose any null-resettable synthesized setters.
- void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl);
-
- /// DefaultSynthesizeProperties - This routine default synthesizes all
- /// properties which must be synthesized in the class's \@implementation.
- void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
- ObjCInterfaceDecl *IDecl);
- void DefaultSynthesizeProperties(Scope *S, Decl *D);
-
- /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is
- /// an ivar synthesized for 'Method' and 'Method' is a property accessor
- /// declared in class 'IFace'.
- bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace,
- ObjCMethodDecl *Method, ObjCIvarDecl *IV);
-
- /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which
- /// backs the property is not used in the property's accessor.
- void DiagnoseUnusedBackingIvarInAccessor(Scope *S,
- const ObjCImplementationDecl *ImplD);
-
- /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and
- /// it property has a backing ivar, returns this ivar; otherwise, returns NULL.
- /// It also returns ivar's property on success.
- ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
- const ObjCPropertyDecl *&PDecl) const;
-
- /// Called by ActOnProperty to handle \@property declarations in
- /// class extensions.
- ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S,
- SourceLocation AtLoc,
- SourceLocation LParenLoc,
- FieldDeclarator &FD,
- Selector GetterSel,
- Selector SetterSel,
- const bool isReadWrite,
- unsigned &Attributes,
- const unsigned AttributesAsWritten,
- QualType T,
- TypeSourceInfo *TSI,
- tok::ObjCKeywordKind MethodImplKind);
-
- /// Called by ActOnProperty and HandlePropertyInClassExtension to
- /// handle creating the ObjcPropertyDecl for a category or \@interface.
- ObjCPropertyDecl *CreatePropertyDecl(Scope *S,
- ObjCContainerDecl *CDecl,
- SourceLocation AtLoc,
- SourceLocation LParenLoc,
- FieldDeclarator &FD,
- Selector GetterSel,
- Selector SetterSel,
- const bool isReadWrite,
- const unsigned Attributes,
- const unsigned AttributesAsWritten,
- QualType T,
- TypeSourceInfo *TSI,
- tok::ObjCKeywordKind MethodImplKind,
- DeclContext *lexicalDC = nullptr);
-
- /// AtomicPropertySetterGetterRules - This routine enforces the rule (via
- /// warning) when atomic property has one but not the other user-declared
- /// setter or getter.
- void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
- ObjCInterfaceDecl* IDecl);
-
- void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D);
-
- void DiagnoseMissingDesignatedInitOverrides(
- const ObjCImplementationDecl *ImplD,
- const ObjCInterfaceDecl *IFD);
-
- void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
-
- enum MethodMatchStrategy {
- MMS_loose,
- MMS_strict
- };
-
- /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
- /// true, or false, accordingly.
- bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
- const ObjCMethodDecl *PrevMethod,
- MethodMatchStrategy strategy = MMS_strict);
-
- /// MatchAllMethodDeclarations - Check methods declaraed in interface or
- /// or protocol against those declared in their implementations.
- void MatchAllMethodDeclarations(const SelectorSet &InsMap,
- const SelectorSet &ClsMap,
- SelectorSet &InsMapSeen,
- SelectorSet &ClsMapSeen,
- ObjCImplDecl* IMPDecl,
- ObjCContainerDecl* IDecl,
- bool &IncompleteImpl,
- bool ImmediateClass,
- bool WarnCategoryMethodImpl=false);
-
- /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in
- /// category matches with those implemented in its primary class and
- /// warns each time an exact match is found.
- void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP);
-
- /// \brief Add the given method to the list of globally-known methods.
- void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method);
-
-private:
- /// AddMethodToGlobalPool - Add an instance or factory method to the global
- /// pool. See descriptoin of AddInstanceMethodToGlobalPool.
- void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance);
-
- /// LookupMethodInGlobalPool - Returns the instance or factory method and
- /// optionally warns if there are multiple signatures.
- ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R,
- bool receiverIdOrClass,
- bool instance);
-
-public:
- /// \brief - Returns instance or factory methods in global method pool for
- /// given selector. If no such method or only one method found, function returns
- /// false; otherwise, it returns true
- bool CollectMultipleMethodsInGlobalPool(Selector Sel,
- SmallVectorImpl<ObjCMethodDecl*>& Methods,
- bool instance);
-
- bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod,
- SourceRange R,
- bool receiverIdOrClass);
-
- void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods,
- Selector Sel, SourceRange R,
- bool receiverIdOrClass);
-
-private:
- /// \brief - Returns a selector which best matches given argument list or
- /// nullptr if none could be found
- ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args,
- bool IsInstance);
-
-
- /// \brief Record the typo correction failure and return an empty correction.
- TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc,
- bool RecordFailure = true) {
- if (RecordFailure)
- TypoCorrectionFailures[Typo].insert(TypoLoc);
- return TypoCorrection();
- }
-
-public:
- /// AddInstanceMethodToGlobalPool - All instance methods in a translation
- /// unit are added to a global pool. This allows us to efficiently associate
- /// a selector with a method declaraation for purposes of typechecking
- /// messages sent to "id" (where the class of the object is unknown).
- void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
- AddMethodToGlobalPool(Method, impl, /*instance*/true);
- }
-
- /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
- void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
- AddMethodToGlobalPool(Method, impl, /*instance*/false);
- }
-
- /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global
- /// pool.
- void AddAnyMethodToGlobalPool(Decl *D);
-
- /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
- /// there are multiple signatures.
- ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R,
- bool receiverIdOrClass=false) {
- return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass,
- /*instance*/true);
- }
-
- /// LookupFactoryMethodInGlobalPool - Returns the method and warns if
- /// there are multiple signatures.
- ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R,
- bool receiverIdOrClass=false) {
- return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass,
- /*instance*/false);
- }
-
- const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel,
- QualType ObjectType=QualType());
- /// LookupImplementedMethodInGlobalPool - Returns the method which has an
- /// implementation.
- ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel);
-
- /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
- /// initialization.
- void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
- SmallVectorImpl<ObjCIvarDecl*> &Ivars);
-
- //===--------------------------------------------------------------------===//
- // Statement Parsing Callbacks: SemaStmt.cpp.
-public:
- class FullExprArg {
- public:
- FullExprArg(Sema &actions) : E(nullptr) { }
-
- ExprResult release() {
- return E;
- }
-
- Expr *get() const { return E; }
-
- Expr *operator->() {
- return E;
- }
-
- private:
- // FIXME: No need to make the entire Sema class a friend when it's just
- // Sema::MakeFullExpr that needs access to the constructor below.
- friend class Sema;
-
- explicit FullExprArg(Expr *expr) : E(expr) {}
-
- Expr *E;
- };
-
- FullExprArg MakeFullExpr(Expr *Arg) {
- return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation());
- }
- FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
- return FullExprArg(ActOnFinishFullExpr(Arg, CC).get());
- }
- FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) {
- ExprResult FE =
- ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
- /*DiscardedValue*/ true);
- return FullExprArg(FE.get());
- }
-
- StmtResult ActOnExprStmt(ExprResult Arg);
- StmtResult ActOnExprStmtError();
-
- StmtResult ActOnNullStmt(SourceLocation SemiLoc,
- bool HasLeadingEmptyMacro = false);
-
- void ActOnStartOfCompoundStmt();
- void ActOnFinishOfCompoundStmt();
- StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
- ArrayRef<Stmt *> Elts, bool isStmtExpr);
-
- /// \brief A RAII object to enter scope of a compound statement.
- class CompoundScopeRAII {
- public:
- CompoundScopeRAII(Sema &S): S(S) {
- S.ActOnStartOfCompoundStmt();
- }
-
- ~CompoundScopeRAII() {
- S.ActOnFinishOfCompoundStmt();
- }
-
- private:
- Sema &S;
- };
-
- /// An RAII helper that pops function a function scope on exit.
- struct FunctionScopeRAII {
- Sema &S;
- bool Active;
- FunctionScopeRAII(Sema &S) : S(S), Active(true) {}
- ~FunctionScopeRAII() {
- if (Active)
- S.PopFunctionScopeInfo();
- }
- void disable() { Active = false; }
- };
-
- StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
- SourceLocation StartLoc,
- SourceLocation EndLoc);
- void ActOnForEachDeclStmt(DeclGroupPtrTy Decl);
- StmtResult ActOnForEachLValueExpr(Expr *E);
- StmtResult ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
- SourceLocation DotDotDotLoc, Expr *RHSVal,
- SourceLocation ColonLoc);
- void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt);
-
- StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
- SourceLocation ColonLoc,
- Stmt *SubStmt, Scope *CurScope);
- StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
- SourceLocation ColonLoc, Stmt *SubStmt);
-
- StmtResult ActOnAttributedStmt(SourceLocation AttrLoc,
- ArrayRef<const Attr*> Attrs,
- Stmt *SubStmt);
-
- StmtResult ActOnIfStmt(SourceLocation IfLoc,
- FullExprArg CondVal, Decl *CondVar,
- Stmt *ThenVal,
- SourceLocation ElseLoc, Stmt *ElseVal);
- StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
- Expr *Cond,
- Decl *CondVar);
- StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
- Stmt *Switch, Stmt *Body);
- StmtResult ActOnWhileStmt(SourceLocation WhileLoc,
- FullExprArg Cond,
- Decl *CondVar, Stmt *Body);
- StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
- SourceLocation WhileLoc,
- SourceLocation CondLParen, Expr *Cond,
- SourceLocation CondRParen);
-
- StmtResult ActOnForStmt(SourceLocation ForLoc,
- SourceLocation LParenLoc,
- Stmt *First, FullExprArg Second,
- Decl *SecondVar,
- FullExprArg Third,
- SourceLocation RParenLoc,
- Stmt *Body);
- ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc,
- Expr *collection);
- StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
- Stmt *First, Expr *collection,
- SourceLocation RParenLoc);
- StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body);
-
- enum BuildForRangeKind {
- /// Initial building of a for-range statement.
- BFRK_Build,
- /// Instantiation or recovery rebuild of a for-range statement. Don't
- /// attempt any typo-correction.
- BFRK_Rebuild,
- /// Determining whether a for-range statement could be built. Avoid any
- /// unnecessary or irreversible actions.
- BFRK_Check
- };
-
- StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc,
- SourceLocation CoawaitLoc,
- Stmt *LoopVar,
- SourceLocation ColonLoc, Expr *Collection,
- SourceLocation RParenLoc,
- BuildForRangeKind Kind);
- StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc,
- SourceLocation CoawaitLoc,
- SourceLocation ColonLoc,
- Stmt *RangeDecl, Stmt *BeginEndDecl,
- Expr *Cond, Expr *Inc,
- Stmt *LoopVarDecl,
- SourceLocation RParenLoc,
- BuildForRangeKind Kind);
- StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body);
-
- StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
- SourceLocation LabelLoc,
- LabelDecl *TheDecl);
- StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
- SourceLocation StarLoc,
- Expr *DestExp);
- StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope);
- StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope);
-
- void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
- CapturedRegionKind Kind, unsigned NumParams);
- typedef std::pair<StringRef, QualType> CapturedParamNameType;
- void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
- CapturedRegionKind Kind,
- ArrayRef<CapturedParamNameType> Params);
- StmtResult ActOnCapturedRegionEnd(Stmt *S);
- void ActOnCapturedRegionError();
- RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD,
- SourceLocation Loc,
- unsigned NumParams);
- VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E,
- bool AllowFunctionParameters);
- bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
- bool AllowFunctionParameters);
-
- StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
- Scope *CurScope);
- StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
- StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
-
- StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
- bool IsVolatile, unsigned NumOutputs,
- unsigned NumInputs, IdentifierInfo **Names,
- MultiExprArg Constraints, MultiExprArg Exprs,
- Expr *AsmString, MultiExprArg Clobbers,
- SourceLocation RParenLoc);
-
- ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- UnqualifiedId &Id,
- llvm::InlineAsmIdentifierInfo &Info,
- bool IsUnevaluatedContext);
- bool LookupInlineAsmField(StringRef Base, StringRef Member,
- unsigned &Offset, SourceLocation AsmLoc);
- ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member,
- llvm::InlineAsmIdentifierInfo &Info,
- SourceLocation AsmLoc);
- StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
- ArrayRef<Token> AsmToks,
- StringRef AsmString,
- unsigned NumOutputs, unsigned NumInputs,
- ArrayRef<StringRef> Constraints,
- ArrayRef<StringRef> Clobbers,
- ArrayRef<Expr*> Exprs,
- SourceLocation EndLoc);
- LabelDecl *GetOrCreateMSAsmLabel(StringRef ExternalLabelName,
- SourceLocation Location,
- bool AlwaysCreate);
-
- VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
- SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- bool Invalid = false);
-
- Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D);
-
- StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen,
- Decl *Parm, Stmt *Body);
-
- StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body);
-
- StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try,
- MultiStmtArg Catch, Stmt *Finally);
-
- StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw);
- StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw,
- Scope *CurScope);
- ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc,
- Expr *operand);
- StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
- Expr *SynchExpr,
- Stmt *SynchBody);
-
- StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body);
-
- VarDecl *BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo,
- SourceLocation StartLoc,
- SourceLocation IdLoc,
- IdentifierInfo *Id);
-
- Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D);
-
- StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
- Decl *ExDecl, Stmt *HandlerBlock);
- StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
- ArrayRef<Stmt *> Handlers);
-
- StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ?
- SourceLocation TryLoc, Stmt *TryBlock,
- Stmt *Handler);
- StmtResult ActOnSEHExceptBlock(SourceLocation Loc,
- Expr *FilterExpr,
- Stmt *Block);
- void ActOnStartSEHFinallyBlock();
- void ActOnAbortSEHFinallyBlock();
- StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block);
- StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope);
-
- void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
-
- bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const;
-
- /// \brief If it's a file scoped decl that must warn if not used, keep track
- /// of it.
- void MarkUnusedFileScopedDecl(const DeclaratorDecl *D);
-
- /// DiagnoseUnusedExprResult - If the statement passed in is an expression
- /// whose result is unused, warn.
- void DiagnoseUnusedExprResult(const Stmt *S);
- void DiagnoseUnusedNestedTypedefs(const RecordDecl *D);
- void DiagnoseUnusedDecl(const NamedDecl *ND);
-
- /// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null
- /// statement as a \p Body, and it is located on the same line.
- ///
- /// This helps prevent bugs due to typos, such as:
- /// if (condition);
- /// do_stuff();
- void DiagnoseEmptyStmtBody(SourceLocation StmtLoc,
- const Stmt *Body,
- unsigned DiagID);
-
- /// Warn if a for/while loop statement \p S, which is followed by
- /// \p PossibleBody, has a suspicious null statement as a body.
- void DiagnoseEmptyLoopBody(const Stmt *S,
- const Stmt *PossibleBody);
-
- /// Warn if a value is moved to itself.
- void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr,
- SourceLocation OpLoc);
-
- /// \brief Warn if we're implicitly casting from a _Nullable pointer type to a
- /// _Nonnull one.
- void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType,
- SourceLocation Loc);
-
- ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) {
- return DelayedDiagnostics.push(pool);
- }
- void PopParsingDeclaration(ParsingDeclState state, Decl *decl);
-
- typedef ProcessingContextState ParsingClassState;
- ParsingClassState PushParsingClass() {
- return DelayedDiagnostics.pushUndelayed();
- }
- void PopParsingClass(ParsingClassState state) {
- DelayedDiagnostics.popUndelayed(state);
- }
-
- void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
-
- enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial };
-
- void EmitAvailabilityWarning(AvailabilityDiagnostic AD,
- NamedDecl *D, StringRef Message,
- SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
- bool ObjCPropertyAccess);
-
- bool makeUnavailableInSystemHeader(SourceLocation loc,
- UnavailableAttr::ImplicitReason reason);
-
- //===--------------------------------------------------------------------===//
- // Expression Parsing Callbacks: SemaExpr.cpp.
-
- bool CanUseDecl(NamedDecl *D);
- bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass=nullptr,
- bool ObjCPropertyAccess=false);
- void NoteDeletedFunction(FunctionDecl *FD);
- std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
- bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
- ObjCMethodDecl *Getter,
- SourceLocation Loc);
- void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
- ArrayRef<Expr *> Args);
-
- void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
- Decl *LambdaContextDecl = nullptr,
- bool IsDecltype = false);
- enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl };
- void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
- ReuseLambdaContextDecl_t,
- bool IsDecltype = false);
- void PopExpressionEvaluationContext();
-
- void DiscardCleanupsInEvaluationContext();
-
- ExprResult TransformToPotentiallyEvaluated(Expr *E);
- ExprResult HandleExprEvaluationContextForTypeof(Expr *E);
-
- ExprResult ActOnConstantExpression(ExprResult Res);
-
- // Functions for marking a declaration referenced. These functions also
- // contain the relevant logic for marking if a reference to a function or
- // variable is an odr-use (in the C++11 sense). There are separate variants
- // for expressions referring to a decl; these exist because odr-use marking
- // needs to be delayed for some constant variables when we build one of the
- // named expressions.
- void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse);
- void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
- bool OdrUse = true);
- void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
- void MarkDeclRefReferenced(DeclRefExpr *E);
- void MarkMemberReferenced(MemberExpr *E);
-
- void UpdateMarkingForLValueToRValue(Expr *E);
- void CleanupVarDeclMarking();
-
- enum TryCaptureKind {
- TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef
- };
-
- /// \brief Try to capture the given variable.
- ///
- /// \param Var The variable to capture.
- ///
- /// \param Loc The location at which the capture occurs.
- ///
- /// \param Kind The kind of capture, which may be implicit (for either a
- /// block or a lambda), or explicit by-value or by-reference (for a lambda).
- ///
- /// \param EllipsisLoc The location of the ellipsis, if one is provided in
- /// an explicit lambda capture.
- ///
- /// \param BuildAndDiagnose Whether we are actually supposed to add the
- /// captures or diagnose errors. If false, this routine merely check whether
- /// the capture can occur without performing the capture itself or complaining
- /// if the variable cannot be captured.
- ///
- /// \param CaptureType Will be set to the type of the field used to capture
- /// this variable in the innermost block or lambda. Only valid when the
- /// variable can be captured.
- ///
- /// \param DeclRefType Will be set to the type of a reference to the capture
- /// from within the current scope. Only valid when the variable can be
- /// captured.
- ///
- /// \param FunctionScopeIndexToStopAt If non-null, it points to the index
- /// of the FunctionScopeInfo stack beyond which we do not attempt to capture.
- /// This is useful when enclosing lambdas must speculatively capture
- /// variables that may or may not be used in certain specializations of
- /// a nested generic lambda.
- ///
- /// \returns true if an error occurred (i.e., the variable cannot be
- /// captured) and false if the capture succeeded.
- bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind,
- SourceLocation EllipsisLoc, bool BuildAndDiagnose,
- QualType &CaptureType,
- QualType &DeclRefType,
- const unsigned *const FunctionScopeIndexToStopAt);
-
- /// \brief 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.
- bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc);
-
- /// \brief Given a variable, determine the type that a reference to that
- /// variable will have in the given scope.
- QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
-
- void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
- void MarkDeclarationsReferencedInExpr(Expr *E,
- bool SkipLocalVariables = false);
-
- /// \brief 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.
- bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy,
- UnresolvedSetImpl &NonTemplateOverloads);
-
- /// \brief Conditionally issue a diagnostic based on the current
- /// evaluation context.
- ///
- /// \param Statement If Statement is non-null, delay reporting the
- /// diagnostic until the function body is parsed, and then do a basic
- /// reachability analysis to determine if the statement is reachable.
- /// If it is unreachable, the diagnostic will not be emitted.
- bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
- const PartialDiagnostic &PD);
-
- // Primary Expressions.
- SourceRange getExprRange(Expr *E) const;
-
- ExprResult ActOnIdExpression(
- Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
- UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr,
- bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr);
-
- void DecomposeUnqualifiedId(const UnqualifiedId &Id,
- TemplateArgumentListInfo &Buffer,
- DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *&TemplateArgs);
-
- bool
- DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
- TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
- ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr);
-
- ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S,
- IdentifierInfo *II,
- bool AllowBuiltinCreation=false);
-
- ExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool isAddressOfOperand,
- const TemplateArgumentListInfo *TemplateArgs);
-
- ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
- ExprValueKind VK,
- SourceLocation Loc,
- const CXXScopeSpec *SS = nullptr);
- ExprResult
- BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
- const DeclarationNameInfo &NameInfo,
- const CXXScopeSpec *SS = nullptr,
- NamedDecl *FoundD = nullptr,
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
- ExprResult
- BuildAnonymousStructUnionMemberReference(
- const CXXScopeSpec &SS,
- SourceLocation nameLoc,
- IndirectFieldDecl *indirectField,
- DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_none),
- Expr *baseObjectExpr = nullptr,
- SourceLocation opLoc = SourceLocation());
-
- ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- LookupResult &R,
- const TemplateArgumentListInfo *TemplateArgs,
- const Scope *S);
- ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- LookupResult &R,
- const TemplateArgumentListInfo *TemplateArgs,
- bool IsDefiniteInstance,
- const Scope *S);
- bool UseArgumentDependentLookup(const CXXScopeSpec &SS,
- const LookupResult &R,
- bool HasTrailingLParen);
-
- ExprResult
- BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
- const DeclarationNameInfo &NameInfo,
- bool IsAddressOfOperand, const Scope *S,
- TypeSourceInfo **RecoveryTSI = nullptr);
-
- ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
- LookupResult &R,
- bool NeedsADL,
- bool AcceptInvalidDecl = false);
- ExprResult BuildDeclarationNameExpr(
- const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
- NamedDecl *FoundD = nullptr,
- const TemplateArgumentListInfo *TemplateArgs = nullptr,
- bool AcceptInvalidDecl = false);
-
- ExprResult BuildLiteralOperatorCall(LookupResult &R,
- DeclarationNameInfo &SuffixInfo,
- ArrayRef<Expr *> Args,
- SourceLocation LitEndLoc,
- TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
-
- ExprResult BuildPredefinedExpr(SourceLocation Loc,
- PredefinedExpr::IdentType IT);
- ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
- ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
-
- bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);
-
- ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
- ExprResult ActOnCharacterConstant(const Token &Tok,
- Scope *UDLScope = nullptr);
- ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
- ExprResult ActOnParenListExpr(SourceLocation L,
- SourceLocation R,
- MultiExprArg Val);
-
- /// ActOnStringLiteral - The specified tokens were lexed as pasted string
- /// fragments (e.g. "foo" "bar" L"baz").
- ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks,
- Scope *UDLScope = nullptr);
-
- ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc,
- SourceLocation DefaultLoc,
- SourceLocation RParenLoc,
- Expr *ControllingExpr,
- ArrayRef<ParsedType> ArgTypes,
- ArrayRef<Expr *> ArgExprs);
- ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc,
- SourceLocation DefaultLoc,
- SourceLocation RParenLoc,
- Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo *> Types,
- ArrayRef<Expr *> Exprs);
-
- // Binary/Unary Operators. 'Tok' is the token for the operator.
- ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
- Expr *InputExpr);
- ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc,
- UnaryOperatorKind Opc, Expr *Input);
- ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Op, Expr *Input);
-
- QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc);
-
- ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
- SourceLocation OpLoc,
- UnaryExprOrTypeTrait ExprKind,
- SourceRange R);
- ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
- UnaryExprOrTypeTrait ExprKind);
- ExprResult
- ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc,
- UnaryExprOrTypeTrait ExprKind,
- bool IsType, void *TyOrEx,
- SourceRange ArgRange);
-
- ExprResult CheckPlaceholderExpr(Expr *E);
- bool CheckVecStepExpr(Expr *E);
-
- bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind);
- bool CheckUnaryExprOrTypeTraitOperand(QualType ExprType, SourceLocation OpLoc,
- SourceRange ExprRange,
- UnaryExprOrTypeTrait ExprKind);
- ExprResult ActOnSizeofParameterPackExpr(Scope *S,
- SourceLocation OpLoc,
- IdentifierInfo &Name,
- SourceLocation NameLoc,
- SourceLocation RParenLoc);
- ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Kind, Expr *Input);
-
- ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc,
- Expr *Idx, SourceLocation RLoc);
- ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
- Expr *Idx, SourceLocation RLoc);
- ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
- Expr *LowerBound, SourceLocation ColonLoc,
- Expr *Length, SourceLocation RBLoc);
-
- // This struct is for use by ActOnMemberAccess to allow
- // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after
- // changing the access operator from a '.' to a '->' (to see if that is the
- // change needed to fix an error about an unknown member, e.g. when the class
- // defines a custom operator->).
- struct ActOnMemberAccessExtraArgs {
- Scope *S;
- UnqualifiedId &Id;
- Decl *ObjCImpDecl;
- };
-
- ExprResult BuildMemberReferenceExpr(
- Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
- CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- const Scope *S,
- ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
-
- ExprResult
- BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc,
- bool IsArrow, const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierInScope, LookupResult &R,
- const TemplateArgumentListInfo *TemplateArgs,
- const Scope *S,
- bool SuppressQualifierCheck = false,
- ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
-
- ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
-
- bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
- const CXXScopeSpec &SS,
- const LookupResult &R);
-
- ExprResult ActOnDependentMemberExpr(Expr *Base, QualType BaseType,
- bool IsArrow, SourceLocation OpLoc,
- const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierInScope,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- UnqualifiedId &Member,
- Decl *ObjCImpDecl);
-
- void ActOnDefaultCtorInitializers(Decl *CDtorDecl);
- bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
- FunctionDecl *FDecl,
- const FunctionProtoType *Proto,
- ArrayRef<Expr *> Args,
- SourceLocation RParenLoc,
- bool ExecConfig = false);
- void CheckStaticArrayArgument(SourceLocation CallLoc,
- ParmVarDecl *Param,
- const Expr *ArgExpr);
-
- /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
- /// This provides the location of the left/right parens and a list of comma
- /// locations.
- ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
- MultiExprArg ArgExprs, SourceLocation RParenLoc,
- Expr *ExecConfig = nullptr,
- bool IsExecConfig = false);
- ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
- SourceLocation LParenLoc,
- ArrayRef<Expr *> Arg,
- SourceLocation RParenLoc,
- Expr *Config = nullptr,
- bool IsExecConfig = false);
-
- ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
- MultiExprArg ExecConfig,
- SourceLocation GGGLoc);
-
- ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
- Declarator &D, ParsedType &Ty,
- SourceLocation RParenLoc, Expr *CastExpr);
- ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc,
- TypeSourceInfo *Ty,
- SourceLocation RParenLoc,
- Expr *Op);
- CastKind PrepareScalarCast(ExprResult &src, QualType destType);
-
- /// \brief Build an altivec or OpenCL literal.
- ExprResult BuildVectorLiteral(SourceLocation LParenLoc,
- SourceLocation RParenLoc, Expr *E,
- TypeSourceInfo *TInfo);
-
- ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME);
-
- ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
- ParsedType Ty,
- SourceLocation RParenLoc,
- Expr *InitExpr);
-
- ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc,
- TypeSourceInfo *TInfo,
- SourceLocation RParenLoc,
- Expr *LiteralExpr);
-
- ExprResult ActOnInitList(SourceLocation LBraceLoc,
- MultiExprArg InitArgList,
- SourceLocation RBraceLoc);
-
- ExprResult ActOnDesignatedInitializer(Designation &Desig,
- SourceLocation Loc,
- bool GNUSyntax,
- ExprResult Init);
-
-private:
- static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind);
-
-public:
- ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
- tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr);
- ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc,
- BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr);
- ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc,
- Expr *LHSExpr, Expr *RHSExpr);
-
- /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
- /// in the case of a the GNU conditional expr extension.
- ExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
- SourceLocation ColonLoc,
- Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr);
-
- /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
- ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
- LabelDecl *TheDecl);
-
- void ActOnStartStmtExpr();
- ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
- SourceLocation RPLoc); // "({..})"
- void ActOnStmtExprError();
-
- // __builtin_offsetof(type, identifier(.identifier|[expr])*)
- struct OffsetOfComponent {
- SourceLocation LocStart, LocEnd;
- bool isBrackets; // true if [expr], false if .ident
- union {
- IdentifierInfo *IdentInfo;
- Expr *E;
- } U;
- };
-
- /// __builtin_offsetof(type, a.b[123][456].c)
- ExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
- TypeSourceInfo *TInfo,
- ArrayRef<OffsetOfComponent> Components,
- SourceLocation RParenLoc);
- ExprResult ActOnBuiltinOffsetOf(Scope *S,
- SourceLocation BuiltinLoc,
- SourceLocation TypeLoc,
- ParsedType ParsedArgTy,
- ArrayRef<OffsetOfComponent> Components,
- SourceLocation RParenLoc);
-
- // __builtin_choose_expr(constExpr, expr1, expr2)
- ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
- Expr *CondExpr, Expr *LHSExpr,
- Expr *RHSExpr, SourceLocation RPLoc);
-
- // __builtin_va_arg(expr, type)
- ExprResult ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty,
- SourceLocation RPLoc);
- ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
- TypeSourceInfo *TInfo, SourceLocation RPLoc);
-
- // __null
- ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
-
- bool CheckCaseExpression(Expr *E);
-
- /// \brief Describes the result of an "if-exists" condition check.
- enum IfExistsResult {
- /// \brief The symbol exists.
- IER_Exists,
-
- /// \brief The symbol does not exist.
- IER_DoesNotExist,
-
- /// \brief The name is a dependent name, so the results will differ
- /// from one instantiation to the next.
- IER_Dependent,
-
- /// \brief An error occurred.
- IER_Error
- };
-
- IfExistsResult
- CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS,
- const DeclarationNameInfo &TargetNameInfo);
-
- IfExistsResult
- CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
- bool IsIfExists, CXXScopeSpec &SS,
- UnqualifiedId &Name);
-
- StmtResult BuildMSDependentExistsStmt(SourceLocation KeywordLoc,
- bool IsIfExists,
- NestedNameSpecifierLoc QualifierLoc,
- DeclarationNameInfo NameInfo,
- Stmt *Nested);
- StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,
- bool IsIfExists,
- CXXScopeSpec &SS, UnqualifiedId &Name,
- Stmt *Nested);
-
- //===------------------------- "Block" Extension ------------------------===//
-
- /// ActOnBlockStart - This callback is invoked when a block literal is
- /// started.
- void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope);
-
- /// ActOnBlockArguments - This callback allows processing of block arguments.
- /// If there are no arguments, this is still invoked.
- void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
- Scope *CurScope);
-
- /// ActOnBlockError - If there is an error parsing a block, this callback
- /// is invoked to pop the information about the block from the action impl.
- void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);
-
- /// ActOnBlockStmtExpr - This is called when the body of a block statement
- /// literal was successfully completed. ^(int x){...}
- ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
- Scope *CurScope);
-
- //===---------------------------- Clang Extensions ----------------------===//
-
- /// __builtin_convertvector(...)
- ExprResult ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy,
- SourceLocation BuiltinLoc,
- SourceLocation RParenLoc);
-
- //===---------------------------- OpenCL Features -----------------------===//
-
- /// __builtin_astype(...)
- ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy,
- SourceLocation BuiltinLoc,
- SourceLocation RParenLoc);
-
- //===---------------------------- C++ Features --------------------------===//
-
- // Act on C++ namespaces
- Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc,
- SourceLocation NamespaceLoc,
- SourceLocation IdentLoc,
- IdentifierInfo *Ident,
- SourceLocation LBrace,
- AttributeList *AttrList,
- UsingDirectiveDecl * &UsingDecl);
- void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace);
-
- NamespaceDecl *getStdNamespace() const;
- NamespaceDecl *getOrCreateStdNamespace();
-
- CXXRecordDecl *getStdBadAlloc() const;
-
- /// \brief 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
- /// 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
- /// defined in [dcl.init.list]p2.
- bool isInitListConstructor(const CXXConstructorDecl *Ctor);
-
- Decl *ActOnUsingDirective(Scope *CurScope,
- SourceLocation UsingLoc,
- SourceLocation NamespcLoc,
- CXXScopeSpec &SS,
- SourceLocation IdentLoc,
- IdentifierInfo *NamespcName,
- AttributeList *AttrList);
-
- void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
-
- Decl *ActOnNamespaceAliasDef(Scope *CurScope,
- SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- CXXScopeSpec &SS,
- SourceLocation IdentLoc,
- IdentifierInfo *Ident);
-
- void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow);
- bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target,
- const LookupResult &PreviousDecls,
- UsingShadowDecl *&PrevShadow);
- UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD,
- NamedDecl *Target,
- UsingShadowDecl *PrevDecl);
-
- bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
- bool HasTypenameKeyword,
- const CXXScopeSpec &SS,
- SourceLocation NameLoc,
- const LookupResult &Previous);
- bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
- const CXXScopeSpec &SS,
- const DeclarationNameInfo &NameInfo,
- SourceLocation NameLoc);
-
- NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
- SourceLocation UsingLoc,
- CXXScopeSpec &SS,
- DeclarationNameInfo NameInfo,
- AttributeList *AttrList,
- bool IsInstantiation,
- bool HasTypenameKeyword,
- SourceLocation TypenameLoc);
-
- bool CheckInheritingConstructorUsingDecl(UsingDecl *UD);
-
- Decl *ActOnUsingDeclaration(Scope *CurScope,
- AccessSpecifier AS,
- bool HasUsingKeyword,
- SourceLocation UsingLoc,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- AttributeList *AttrList,
- bool HasTypenameKeyword,
- SourceLocation TypenameLoc);
- Decl *ActOnAliasDeclaration(Scope *CurScope,
- AccessSpecifier AS,
- MultiTemplateParamsArg TemplateParams,
- SourceLocation UsingLoc,
- UnqualifiedId &Name,
- AttributeList *AttrList,
- TypeResult Type,
- Decl *DeclFromDeclSpec);
-
- /// BuildCXXConstructExpr - Creates a complete call to a constructor,
- /// including handling of its default argument expressions.
- ///
- /// \param ConstructKind - a CXXConstructExpr::ConstructionKind
- ExprResult
- BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
- CXXConstructorDecl *Constructor, MultiExprArg Exprs,
- bool HadMultipleCandidates, bool IsListInitialization,
- bool IsStdInitListInitialization,
- bool RequiresZeroInit, unsigned ConstructKind,
- SourceRange ParenRange);
-
- // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if
- // the constructor can be elidable?
- ExprResult
- BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
- CXXConstructorDecl *Constructor, bool Elidable,
- MultiExprArg Exprs, bool HadMultipleCandidates,
- bool IsListInitialization,
- bool IsStdInitListInitialization, bool RequiresZeroInit,
- unsigned ConstructKind, SourceRange ParenRange);
-
- ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field);
-
- /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
- /// the default expr if needed.
- ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
- FunctionDecl *FD,
- ParmVarDecl *Param);
-
- /// FinalizeVarWithDestructor - Prepare for calling destructor on the
- /// constructed variable.
- void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
-
- /// \brief Helper class that collects exception specifications for
- /// implicitly-declared special member functions.
- class ImplicitExceptionSpecification {
- // Pointer to allow copying
- Sema *Self;
- // We order exception specifications thus:
- // noexcept is the most restrictive, but is only used in C++11.
- // throw() comes next.
- // Then a throw(collected exceptions)
- // Finally no specification, which is expressed as noexcept(false).
- // throw(...) is used instead if any called function uses it.
- ExceptionSpecificationType ComputedEST;
- llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen;
- SmallVector<QualType, 4> Exceptions;
-
- void ClearExceptions() {
- ExceptionsSeen.clear();
- Exceptions.clear();
- }
-
- public:
- explicit ImplicitExceptionSpecification(Sema &Self)
- : Self(&Self), ComputedEST(EST_BasicNoexcept) {
- if (!Self.getLangOpts().CPlusPlus11)
- ComputedEST = EST_DynamicNone;
- }
-
- /// \brief Get the computed exception specification type.
- ExceptionSpecificationType getExceptionSpecType() const {
- assert(ComputedEST != EST_ComputedNoexcept &&
- "noexcept(expr) should not be a possible result");
- return ComputedEST;
- }
-
- /// \brief The number of exceptions in the exception specification.
- unsigned size() const { return Exceptions.size(); }
-
- /// \brief The set of exceptions in the exception specification.
- const QualType *data() const { return Exceptions.data(); }
-
- /// \brief Integrate another called method into the collected data.
- void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method);
-
- /// \brief Integrate an invoked expression into the collected data.
- void CalledExpr(Expr *E);
-
- /// \brief Overwrite an EPI's exception specification with this
- /// computed exception specification.
- FunctionProtoType::ExceptionSpecInfo getExceptionSpec() const {
- FunctionProtoType::ExceptionSpecInfo ESI;
- ESI.Type = getExceptionSpecType();
- if (ESI.Type == EST_Dynamic) {
- ESI.Exceptions = Exceptions;
- } else if (ESI.Type == EST_None) {
- /// 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.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
- tok::kw_false).get();
- }
- return ESI;
- }
- };
-
- /// \brief 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
- /// 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
- /// 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
- /// constructor of a class will have.
- ImplicitExceptionSpecification
- ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD);
-
- /// \brief 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
- /// destructor of a class will have.
- ImplicitExceptionSpecification
- ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD);
-
- /// \brief Determine what sort of exception specification an inheriting
- /// constructor of a class will have.
- ImplicitExceptionSpecification
- ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD);
-
- /// \brief 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
- /// exception specification information with the results.
- void checkExceptionSpecification(bool IsTopLevel,
- ExceptionSpecificationType EST,
- ArrayRef<ParsedType> DynamicExceptions,
- ArrayRef<SourceRange> DynamicExceptionRanges,
- Expr *NoexceptExpr,
- SmallVectorImpl<QualType> &Exceptions,
- FunctionProtoType::ExceptionSpecInfo &ESI);
-
- /// \brief 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
- /// (or member function template). The exception-specification was parsed
- /// after the method itself was declared.
- void actOnDelayedExceptionSpecification(Decl *Method,
- ExceptionSpecificationType EST,
- SourceRange SpecificationRange,
- ArrayRef<ParsedType> DynamicExceptions,
- ArrayRef<SourceRange> DynamicExceptionRanges,
- Expr *NoexceptExpr);
-
- /// \brief Determine if a special member function should have a deleted
- /// definition when it is defaulted.
- bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
- bool Diagnose = false);
-
- /// \brief Declare the implicit default constructor for the given class.
- ///
- /// \param ClassDecl The class declaration into which the implicit
- /// default constructor will be added.
- ///
- /// \returns The implicitly-declared default constructor.
- CXXConstructorDecl *DeclareImplicitDefaultConstructor(
- CXXRecordDecl *ClassDecl);
-
- /// DefineImplicitDefaultConstructor - Checks for feasibility of
- /// defining this constructor as the default constructor.
- void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
- CXXConstructorDecl *Constructor);
-
- /// \brief Declare the implicit destructor for the given class.
- ///
- /// \param ClassDecl The class declaration into which the implicit
- /// destructor will be added.
- ///
- /// \returns The implicitly-declared destructor.
- CXXDestructorDecl *DeclareImplicitDestructor(CXXRecordDecl *ClassDecl);
-
- /// DefineImplicitDestructor - Checks for feasibility of
- /// defining this destructor as the default destructor.
- void DefineImplicitDestructor(SourceLocation CurrentLocation,
- CXXDestructorDecl *Destructor);
-
- /// \brief 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 Declare all inheriting constructors for the given class.
- ///
- /// \param ClassDecl The class declaration into which the inheriting
- /// constructors will be added.
- void DeclareInheritingConstructors(CXXRecordDecl *ClassDecl);
-
- /// \brief Define the specified inheriting constructor.
- void DefineInheritingConstructor(SourceLocation UseLoc,
- CXXConstructorDecl *Constructor);
-
- /// \brief Declare the implicit copy constructor for the given class.
- ///
- /// \param ClassDecl The class declaration into which the implicit
- /// copy constructor will be added.
- ///
- /// \returns The implicitly-declared copy constructor.
- CXXConstructorDecl *DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl);
-
- /// DefineImplicitCopyConstructor - Checks for feasibility of
- /// defining this constructor as the copy constructor.
- void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
- CXXConstructorDecl *Constructor);
-
- /// \brief Declare the implicit move constructor for the given class.
- ///
- /// \param ClassDecl The Class declaration into which the implicit
- /// move constructor will be added.
- ///
- /// \returns The implicitly-declared move constructor, or NULL if it wasn't
- /// declared.
- CXXConstructorDecl *DeclareImplicitMoveConstructor(CXXRecordDecl *ClassDecl);
-
- /// DefineImplicitMoveConstructor - Checks for feasibility of
- /// defining this constructor as the move constructor.
- void DefineImplicitMoveConstructor(SourceLocation CurrentLocation,
- CXXConstructorDecl *Constructor);
-
- /// \brief 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.
- ///
- /// \returns The implicitly-declared copy assignment operator.
- CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl);
-
- /// \brief Defines an implicitly-declared copy assignment operator.
- void DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
- CXXMethodDecl *MethodDecl);
-
- /// \brief 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.
- ///
- /// \returns The implicitly-declared move assignment operator, or NULL if it
- /// wasn't declared.
- CXXMethodDecl *DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl);
-
- /// \brief Defines an implicitly-declared move assignment operator.
- void DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
- CXXMethodDecl *MethodDecl);
-
- /// \brief Force the declaration of any implicitly-declared members of this
- /// class.
- void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class);
-
- /// \brief 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
- /// 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
- /// member function.
- bool checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method);
-
- /// \brief Check whether 'this' shows up in the attributes of the given
- /// static member function.
- ///
- /// \returns true if an error occurred.
- bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method);
-
- /// MaybeBindToTemporary - If the passed in expression has a record type with
- /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
- /// it simply returns the passed in expression.
- ExprResult MaybeBindToTemporary(Expr *E);
-
- bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
- MultiExprArg ArgsPtr,
- SourceLocation Loc,
- SmallVectorImpl<Expr*> &ConvertedArgs,
- bool AllowExplicit = false,
- bool IsListInitialization = false);
-
- ParsedType getInheritingConstructorName(CXXScopeSpec &SS,
- SourceLocation NameLoc,
- IdentifierInfo &Name);
-
- ParsedType getDestructorName(SourceLocation TildeLoc,
- IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, CXXScopeSpec &SS,
- ParsedType ObjectType,
- bool EnteringContext);
-
- ParsedType getDestructorType(const DeclSpec& DS, ParsedType ObjectType);
-
- // Checks that reinterpret casts don't have undefined behavior.
- void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
- bool IsDereference, SourceRange Range);
-
- /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
- ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
- tok::TokenKind Kind,
- SourceLocation LAngleBracketLoc,
- Declarator &D,
- SourceLocation RAngleBracketLoc,
- SourceLocation LParenLoc,
- Expr *E,
- SourceLocation RParenLoc);
-
- ExprResult BuildCXXNamedCast(SourceLocation OpLoc,
- tok::TokenKind Kind,
- TypeSourceInfo *Ty,
- Expr *E,
- SourceRange AngleBrackets,
- SourceRange Parens);
-
- ExprResult BuildCXXTypeId(QualType TypeInfoType,
- SourceLocation TypeidLoc,
- TypeSourceInfo *Operand,
- SourceLocation RParenLoc);
- ExprResult BuildCXXTypeId(QualType TypeInfoType,
- SourceLocation TypeidLoc,
- Expr *Operand,
- SourceLocation RParenLoc);
-
- /// ActOnCXXTypeid - Parse typeid( something ).
- ExprResult ActOnCXXTypeid(SourceLocation OpLoc,
- SourceLocation LParenLoc, bool isType,
- void *TyOrExpr,
- SourceLocation RParenLoc);
-
- ExprResult BuildCXXUuidof(QualType TypeInfoType,
- SourceLocation TypeidLoc,
- TypeSourceInfo *Operand,
- SourceLocation RParenLoc);
- ExprResult BuildCXXUuidof(QualType TypeInfoType,
- SourceLocation TypeidLoc,
- Expr *Operand,
- SourceLocation RParenLoc);
-
- /// ActOnCXXUuidof - Parse __uuidof( something ).
- ExprResult ActOnCXXUuidof(SourceLocation OpLoc,
- SourceLocation LParenLoc, bool isType,
- void *TyOrExpr,
- SourceLocation RParenLoc);
-
- /// \brief Handle a C++1z fold-expression: ( expr op ... op expr ).
- ExprResult ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
- tok::TokenKind Operator,
- SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc);
- ExprResult BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
- BinaryOperatorKind Operator,
- SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc);
- ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
- BinaryOperatorKind Operator);
-
- //// ActOnCXXThis - Parse 'this' pointer.
- ExprResult ActOnCXXThis(SourceLocation loc);
-
- /// \brief 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
- /// 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
- /// to be used, with the given qualifiers on the current class type.
- class CXXThisScopeRAII {
- Sema &S;
- QualType OldCXXThisTypeOverride;
- bool Enabled;
-
- public:
- /// \brief 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'.
- CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals,
- bool Enabled = true);
-
- ~CXXThisScopeRAII();
- };
-
- /// \brief 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.
- ///
- /// \param Explicit Whether 'this' is explicitly captured in a lambda
- /// capture list.
- ///
- /// \param FunctionScopeIndexToStopAt If non-null, it points to the index
- /// of the FunctionScopeInfo stack beyond which we do not attempt to capture.
- /// This is useful when enclosing lambdas must speculatively capture
- /// 'this' that may or may not be used in certain specializations of
- /// a nested generic lambda (depending on whether the name resolves to
- /// a non-static member function or a static function).
- /// \return returns 'true' if failed, 'false' if success.
- bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false,
- bool BuildAndDiagnose = true,
- const unsigned *const FunctionScopeIndexToStopAt = nullptr);
-
- /// \brief 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);
-
- /// ActOnCXXBoolLiteral - Parse {true,false} literals.
- ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
-
-
- /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
- ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
-
- /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
- ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc);
-
- //// ActOnCXXThrow - Parse throw expressions.
- ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr);
- ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
- bool IsThrownVarInScope);
- bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E);
-
- /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
- /// Can be interpreted either as function-style casting ("int(x)")
- /// or class type construction ("ClassType(x,y,z)")
- /// or creation of a value-initialized type ("int()").
- ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep,
- SourceLocation LParenLoc,
- MultiExprArg Exprs,
- SourceLocation RParenLoc);
-
- ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- MultiExprArg Exprs,
- SourceLocation RParenLoc);
-
- /// ActOnCXXNew - Parsed a C++ 'new' expression.
- ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
- SourceLocation PlacementLParen,
- MultiExprArg PlacementArgs,
- SourceLocation PlacementRParen,
- SourceRange TypeIdParens, Declarator &D,
- Expr *Initializer);
- ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal,
- SourceLocation PlacementLParen,
- MultiExprArg PlacementArgs,
- SourceLocation PlacementRParen,
- SourceRange TypeIdParens,
- QualType AllocType,
- TypeSourceInfo *AllocTypeInfo,
- Expr *ArraySize,
- SourceRange DirectInitRange,
- Expr *Initializer,
- bool TypeMayContainAuto = true);
-
- bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
- SourceRange R);
- bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
- bool UseGlobal, QualType AllocType, bool IsArray,
- MultiExprArg PlaceArgs,
- FunctionDecl *&OperatorNew,
- FunctionDecl *&OperatorDelete);
- bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
- DeclarationName Name, MultiExprArg Args,
- DeclContext *Ctx,
- bool AllowMissing, FunctionDecl *&Operator,
- bool Diagnose = true);
- void DeclareGlobalNewDelete();
- void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
- QualType Param1,
- QualType Param2 = QualType(),
- bool addRestrictAttr = false);
-
- bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
- DeclarationName Name, FunctionDecl* &Operator,
- bool Diagnose = true);
- FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc,
- bool CanProvideSize,
- DeclarationName Name);
-
- /// ActOnCXXDelete - Parsed a C++ 'delete' expression
- ExprResult ActOnCXXDelete(SourceLocation StartLoc,
- bool UseGlobal, bool ArrayForm,
- Expr *Operand);
-
- DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);
- ExprResult CheckConditionVariable(VarDecl *ConditionVar,
- SourceLocation StmtLoc,
- bool ConvertToBoolean);
-
- ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen,
- Expr *Operand, SourceLocation RParen);
- ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
- SourceLocation RParen);
-
- /// \brief Parsed one of the type trait support pseudo-functions.
- ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
- ArrayRef<ParsedType> Args,
- SourceLocation RParenLoc);
- ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc);
-
- /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support
- /// pseudo-functions.
- ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT,
- SourceLocation KWLoc,
- ParsedType LhsTy,
- Expr *DimExpr,
- SourceLocation RParen);
-
- ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT,
- SourceLocation KWLoc,
- TypeSourceInfo *TSInfo,
- Expr *DimExpr,
- SourceLocation RParen);
-
- /// ActOnExpressionTrait - Parsed one of the unary type trait support
- /// pseudo-functions.
- ExprResult ActOnExpressionTrait(ExpressionTrait OET,
- SourceLocation KWLoc,
- Expr *Queried,
- SourceLocation RParen);
-
- ExprResult BuildExpressionTrait(ExpressionTrait OET,
- SourceLocation KWLoc,
- Expr *Queried,
- SourceLocation RParen);
-
- ExprResult ActOnStartCXXMemberReference(Scope *S,
- Expr *Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- ParsedType &ObjectType,
- bool &MayBePseudoDestructor);
-
- ExprResult BuildPseudoDestructorExpr(Expr *Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- const CXXScopeSpec &SS,
- TypeSourceInfo *ScopeType,
- SourceLocation CCLoc,
- SourceLocation TildeLoc,
- PseudoDestructorTypeStorage DestroyedType);
-
- ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- CXXScopeSpec &SS,
- UnqualifiedId &FirstTypeName,
- SourceLocation CCLoc,
- SourceLocation TildeLoc,
- UnqualifiedId &SecondTypeName);
-
- ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation TildeLoc,
- const DeclSpec& DS);
-
- /// MaybeCreateExprWithCleanups - If the current full-expression
- /// requires any cleanups, surround it with a ExprWithCleanups node.
- /// Otherwise, just returns the passed-in expression.
- Expr *MaybeCreateExprWithCleanups(Expr *SubExpr);
- Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt);
- ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr);
-
- ExprResult ActOnFinishFullExpr(Expr *Expr) {
- return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
- : SourceLocation());
- }
- ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC,
- bool DiscardedValue = false,
- bool IsConstexpr = false,
- bool IsLambdaInitCaptureInitializer = false);
- StmtResult ActOnFinishFullStmt(Stmt *Stmt);
-
- // Marks SS invalid if it represents an incomplete type.
- bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC);
-
- DeclContext *computeDeclContext(QualType T);
- DeclContext *computeDeclContext(const CXXScopeSpec &SS,
- bool EnteringContext = false);
- bool isDependentScopeSpecifier(const CXXScopeSpec &SS);
- CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
-
- /// \brief The parser has parsed a global nested-name-specifier '::'.
- ///
- /// \param CCLoc The location of the '::'.
- ///
- /// \param SS The nested-name-specifier, which will be updated in-place
- /// to reflect the parsed nested-name-specifier.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS);
-
- /// \brief The parser has parsed a '__super' nested-name-specifier.
- ///
- /// \param SuperLoc The location of the '__super' keyword.
- ///
- /// \param ColonColonLoc The location of the '::'.
- ///
- /// \param SS The nested-name-specifier, which will be updated in-place
- /// to reflect the parsed nested-name-specifier.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc,
- SourceLocation ColonColonLoc, CXXScopeSpec &SS);
-
- bool isAcceptableNestedNameSpecifier(const NamedDecl *SD,
- bool *CanCorrect = nullptr);
- NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
-
- bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
- SourceLocation IdLoc,
- IdentifierInfo &II,
- ParsedType ObjectType);
-
- bool BuildCXXNestedNameSpecifier(Scope *S,
- IdentifierInfo &Identifier,
- SourceLocation IdentifierLoc,
- SourceLocation CCLoc,
- QualType ObjectType,
- bool EnteringContext,
- CXXScopeSpec &SS,
- NamedDecl *ScopeLookupResult,
- bool ErrorRecoveryLookup,
- bool *IsCorrectedToColon = nullptr);
-
- /// \brief The parser has parsed a nested-name-specifier 'identifier::'.
- ///
- /// \param S The scope in which this nested-name-specifier occurs.
- ///
- /// \param Identifier The identifier preceding the '::'.
- ///
- /// \param IdentifierLoc The location of the identifier.
- ///
- /// \param CCLoc The location of the '::'.
- ///
- /// \param ObjectType The type of the object, if we're parsing
- /// nested-name-specifier in a member access expression.
- ///
- /// \param EnteringContext Whether we're entering the context nominated by
- /// this nested-name-specifier.
- ///
- /// \param SS The nested-name-specifier, which is both an input
- /// parameter (the nested-name-specifier before this type) and an
- /// output parameter (containing the full nested-name-specifier,
- /// including this new type).
- ///
- /// \param ErrorRecoveryLookup If true, then this method is called to improve
- /// error recovery. In this case do not emit error message.
- ///
- /// \param IsCorrectedToColon If not null, suggestions to replace '::' -> ':'
- /// are allowed. The bool value pointed by this parameter is set to 'true'
- /// if the identifier is treated as if it was followed by ':', not '::'.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool ActOnCXXNestedNameSpecifier(Scope *S,
- IdentifierInfo &Identifier,
- SourceLocation IdentifierLoc,
- SourceLocation CCLoc,
- ParsedType ObjectType,
- bool EnteringContext,
- CXXScopeSpec &SS,
- bool ErrorRecoveryLookup = false,
- bool *IsCorrectedToColon = nullptr);
-
- ExprResult ActOnDecltypeExpression(Expr *E);
-
- bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS,
- const DeclSpec &DS,
- SourceLocation ColonColonLoc);
-
- bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
- IdentifierInfo &Identifier,
- SourceLocation IdentifierLoc,
- SourceLocation ColonLoc,
- ParsedType ObjectType,
- bool EnteringContext);
-
- /// \brief 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.
- ///
- /// \param SS The nested-name-specifier, which is both an input
- /// parameter (the nested-name-specifier before this type) and an
- /// output parameter (containing the full nested-name-specifier,
- /// including this new type).
- ///
- /// \param TemplateKWLoc the location of the 'template' keyword, if any.
- /// \param TemplateName the template name.
- /// \param TemplateNameLoc The location of the template name.
- /// \param LAngleLoc The location of the opening angle bracket ('<').
- /// \param TemplateArgs The template arguments.
- /// \param RAngleLoc The location of the closing angle bracket ('>').
- /// \param CCLoc The location of the '::'.
- ///
- /// \param EnteringContext Whether we're entering the context of the
- /// nested-name-specifier.
- ///
- ///
- /// \returns true if an error occurred, false otherwise.
- bool ActOnCXXNestedNameSpecifier(Scope *S,
- CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- TemplateTy TemplateName,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc,
- SourceLocation CCLoc,
- bool EnteringContext);
-
- /// \brief Given a C++ nested-name-specifier, produce an annotation value
- /// that the parser can use later to reconstruct the given
- /// nested-name-specifier.
- ///
- /// \param SS A nested-name-specifier.
- ///
- /// \returns A pointer containing all of the information in the
- /// nested-name-specifier \p SS.
- void *SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS);
-
- /// \brief Given an annotation pointer for a nested-name-specifier, restore
- /// the nested-name-specifier structure.
- ///
- /// \param Annotation The annotation pointer, produced by
- /// \c SaveNestedNameSpecifierAnnotation().
- ///
- /// \param AnnotationRange The source range corresponding to the annotation.
- ///
- /// \param SS The nested-name-specifier that will be updated with the contents
- /// of the annotation pointer.
- void RestoreNestedNameSpecifierAnnotation(void *Annotation,
- SourceRange AnnotationRange,
- CXXScopeSpec &SS);
-
- bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
-
- /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
- /// scope or nested-name-specifier) is parsed, part of a declarator-id.
- /// After this method is called, according to [C++ 3.4.3p3], names should be
- /// looked up in the declarator-id's scope, until the declarator is parsed and
- /// ActOnCXXExitDeclaratorScope is called.
- /// The 'SS' should be a non-empty valid CXXScopeSpec.
- bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS);
-
- /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
- /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
- /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
- /// Used to indicate that names should revert to being looked up in the
- /// defining scope.
- void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
-
- /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
- /// initializer for the declaration 'Dcl'.
- /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
- /// static data member of class X, names should be looked up in the scope of
- /// class X.
- void ActOnCXXEnterDeclInitializer(Scope *S, Decl *Dcl);
-
- /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
- /// initializer for the declaration 'Dcl'.
- void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl);
-
- /// \brief Create a new lambda closure type.
- CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
- TypeSourceInfo *Info,
- bool KnownDependent,
- LambdaCaptureDefault CaptureDefault);
-
- /// \brief Start the definition of a lambda expression.
- CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
- SourceRange IntroducerRange,
- TypeSourceInfo *MethodType,
- SourceLocation EndLoc,
- ArrayRef<ParmVarDecl *> Params);
-
- /// \brief Endow the lambda scope info with the relevant properties.
- void buildLambdaScope(sema::LambdaScopeInfo *LSI,
- CXXMethodDecl *CallOperator,
- SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc,
- bool ExplicitParams,
- bool ExplicitResultType,
- bool Mutable);
-
- /// \brief 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(
- SourceLocation Loc, bool ByRef, IdentifierInfo *Id,
- LambdaCaptureInitKind InitKind, Expr *&Init) {
- return ParsedType::make(buildLambdaInitCaptureInitialization(
- Loc, ByRef, Id, InitKind != LambdaCaptureInitKind::CopyInit, Init));
- }
- QualType buildLambdaInitCaptureInitialization(SourceLocation Loc, bool ByRef,
- IdentifierInfo *Id,
- bool DirectInit, Expr *&Init);
-
- /// \brief 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
- /// variables appropriately.
- VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc,
- QualType InitCaptureType,
- IdentifierInfo *Id,
- unsigned InitStyle, Expr *Init);
-
- /// \brief 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
- /// given lambda.
- void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
-
- /// \brief 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
- /// statements present in the body.
- void deduceClosureReturnType(sema::CapturingScopeInfo &CSI);
-
- /// ActOnStartOfLambdaDefinition - This is called just before we start
- /// parsing the body of a lambda; it analyzes the explicit captures and
- /// arguments, and sets up various data-structures for the body of the
- /// lambda.
- void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
- Declarator &ParamInfo, Scope *CurScope);
-
- /// ActOnLambdaError - If there is an error parsing a lambda, this callback
- /// is invoked to pop the information about the lambda.
- void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope,
- bool IsInstantiation = false);
-
- /// ActOnLambdaExpr - This is called when the body of a lambda expression
- /// was successfully completed.
- ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
- Scope *CurScope);
-
- /// \brief 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
- /// function pointer.
- ///
- /// This routine doesn't actually define a sensible body; rather, it fills
- /// in the initialization expression needed to copy the lambda object into
- /// the block, and IR generation actually generates the real body of the
- /// block pointer conversion.
- void DefineImplicitLambdaToFunctionPointerConversion(
- SourceLocation CurrentLoc, CXXConversionDecl *Conv);
-
- /// \brief 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
- /// in the initialization expression needed to copy the lambda object into
- /// the block, and IR generation actually generates the real body of the
- /// block pointer conversion.
- void DefineImplicitLambdaToBlockPointerConversion(SourceLocation CurrentLoc,
- CXXConversionDecl *Conv);
-
- ExprResult BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
- SourceLocation ConvLocation,
- CXXConversionDecl *Conv,
- Expr *Src);
-
- // ParseObjCStringLiteral - Parse Objective-C string literals.
- ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
- ArrayRef<Expr *> Strings);
-
- ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S);
-
- /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
- /// numeric literal expression. Type of the expression will be "NSNumber *"
- /// or "id" if NSNumber is unavailable.
- ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number);
- ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc,
- bool Value);
- ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements);
-
- /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the
- /// '@' prefixed parenthesized expression. The type of the expression will
- /// either be "NSNumber *", "NSString *" or "NSValue *" depending on the type
- /// of ValueType, which is allowed to be a built-in numeric type, "char *",
- /// "const char *" or C structure with attribute 'objc_boxable'.
- ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr);
-
- ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
- Expr *IndexExpr,
- ObjCMethodDecl *getterMethod,
- ObjCMethodDecl *setterMethod);
-
- ExprResult BuildObjCDictionaryLiteral(SourceRange SR,
- MutableArrayRef<ObjCDictionaryElement> Elements);
-
- ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc,
- TypeSourceInfo *EncodedTypeInfo,
- SourceLocation RParenLoc);
- ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl,
- CXXConversionDecl *Method,
- bool HadMultipleCandidates);
-
- ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
- SourceLocation EncodeLoc,
- SourceLocation LParenLoc,
- ParsedType Ty,
- SourceLocation RParenLoc);
-
- /// ParseObjCSelectorExpression - Build selector expression for \@selector
- ExprResult ParseObjCSelectorExpression(Selector Sel,
- SourceLocation AtLoc,
- SourceLocation SelLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc,
- bool WarnMultipleSelectors);
-
- /// ParseObjCProtocolExpression - Build protocol expression for \@protocol
- ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
- SourceLocation AtLoc,
- SourceLocation ProtoLoc,
- SourceLocation LParenLoc,
- SourceLocation ProtoIdLoc,
- SourceLocation RParenLoc);
-
- //===--------------------------------------------------------------------===//
- // C++ Declarations
- //
- Decl *ActOnStartLinkageSpecification(Scope *S,
- SourceLocation ExternLoc,
- Expr *LangStr,
- SourceLocation LBraceLoc);
- Decl *ActOnFinishLinkageSpecification(Scope *S,
- Decl *LinkageSpec,
- SourceLocation RBraceLoc);
-
-
- //===--------------------------------------------------------------------===//
- // C++ Classes
- //
- bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
- const CXXScopeSpec *SS = nullptr);
- bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS);
-
- bool ActOnAccessSpecifier(AccessSpecifier Access,
- SourceLocation ASLoc,
- SourceLocation ColonLoc,
- AttributeList *Attrs = nullptr);
-
- NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
- Declarator &D,
- MultiTemplateParamsArg TemplateParameterLists,
- Expr *BitfieldWidth, const VirtSpecifiers &VS,
- InClassInitStyle InitStyle);
-
- void ActOnStartCXXInClassMemberInitializer();
- void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl,
- SourceLocation EqualLoc,
- Expr *Init);
-
- MemInitResult ActOnMemInitializer(Decl *ConstructorD,
- Scope *S,
- CXXScopeSpec &SS,
- IdentifierInfo *MemberOrBase,
- ParsedType TemplateTypeTy,
- const DeclSpec &DS,
- SourceLocation IdLoc,
- SourceLocation LParenLoc,
- ArrayRef<Expr *> Args,
- SourceLocation RParenLoc,
- SourceLocation EllipsisLoc);
-
- MemInitResult ActOnMemInitializer(Decl *ConstructorD,
- Scope *S,
- CXXScopeSpec &SS,
- IdentifierInfo *MemberOrBase,
- ParsedType TemplateTypeTy,
- const DeclSpec &DS,
- SourceLocation IdLoc,
- Expr *InitList,
- SourceLocation EllipsisLoc);
-
- MemInitResult BuildMemInitializer(Decl *ConstructorD,
- Scope *S,
- CXXScopeSpec &SS,
- IdentifierInfo *MemberOrBase,
- ParsedType TemplateTypeTy,
- const DeclSpec &DS,
- SourceLocation IdLoc,
- Expr *Init,
- SourceLocation EllipsisLoc);
-
- MemInitResult BuildMemberInitializer(ValueDecl *Member,
- Expr *Init,
- SourceLocation IdLoc);
-
- MemInitResult BuildBaseInitializer(QualType BaseType,
- TypeSourceInfo *BaseTInfo,
- Expr *Init,
- CXXRecordDecl *ClassDecl,
- SourceLocation EllipsisLoc);
-
- MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo,
- Expr *Init,
- CXXRecordDecl *ClassDecl);
-
- bool SetDelegatingInitializer(CXXConstructorDecl *Constructor,
- CXXCtorInitializer *Initializer);
-
- bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
- ArrayRef<CXXCtorInitializer *> Initializers = None);
-
- void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation);
-
-
- /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,
- /// mark all the non-trivial destructors of its members and bases as
- /// referenced.
- void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
- CXXRecordDecl *Record);
-
- /// \brief 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
- /// materialized.
- SmallVector<VTableUse, 16> VTableUses;
-
- /// \brief 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.
- void LoadExternalVTableUses();
-
- /// \brief 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
- /// in the given class as needed.
- void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc,
- const CXXRecordDecl *RD);
-
- /// MarkVirtualMembersReferenced - Will mark all members of the given
- /// CXXRecordDecl referenced.
- void MarkVirtualMembersReferenced(SourceLocation Loc,
- const CXXRecordDecl *RD);
-
- /// \brief Define all of the vtables that have been used in this
- /// translation unit and reference any virtual members used by those
- /// vtables.
- ///
- /// \returns true if any work was done, false otherwise.
- bool DefineUsedVTables();
-
- void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
-
- void ActOnMemInitializers(Decl *ConstructorDecl,
- SourceLocation ColonLoc,
- ArrayRef<CXXCtorInitializer*> MemInits,
- bool AnyErrors);
-
- void checkClassLevelDLLAttribute(CXXRecordDecl *Class);
- void propagateDLLAttrToBaseClassTemplate(
- CXXRecordDecl *Class, Attr *ClassAttr,
- ClassTemplateSpecializationDecl *BaseTemplateSpec,
- SourceLocation BaseLoc);
- void CheckCompletedCXXClass(CXXRecordDecl *Record);
- void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- Decl *TagDecl,
- SourceLocation LBrac,
- SourceLocation RBrac,
- AttributeList *AttrList);
- void ActOnFinishCXXMemberDecls();
- void ActOnFinishCXXNonNestedClass(Decl *D);
-
- void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);
- unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template);
- void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
- void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
- void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
- void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record);
- void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
- void ActOnFinishDelayedMemberInitializers(Decl *Record);
- void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD,
- CachedTokens &Toks);
- void UnmarkAsLateParsedTemplate(FunctionDecl *FD);
- bool IsInsideALocalClassWithinATemplateFunction();
-
- Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc,
- Expr *AssertExpr,
- Expr *AssertMessageExpr,
- SourceLocation RParenLoc);
- Decl *BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
- Expr *AssertExpr,
- StringLiteral *AssertMessageExpr,
- SourceLocation RParenLoc,
- bool Failed);
-
- FriendDecl *CheckFriendTypeDecl(SourceLocation LocStart,
- SourceLocation FriendLoc,
- TypeSourceInfo *TSInfo);
- Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
- MultiTemplateParamsArg TemplateParams);
- NamedDecl *ActOnFriendFunctionDecl(Scope *S, Declarator &D,
- MultiTemplateParamsArg TemplateParams);
-
- QualType CheckConstructorDeclarator(Declarator &D, QualType R,
- StorageClass& SC);
- void CheckConstructor(CXXConstructorDecl *Constructor);
- QualType CheckDestructorDeclarator(Declarator &D, QualType R,
- StorageClass& SC);
- bool CheckDestructor(CXXDestructorDecl *Destructor);
- void CheckConversionDeclarator(Declarator &D, QualType &R,
- StorageClass& SC);
- Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
-
- void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD);
- void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD,
- const FunctionProtoType *T);
- void CheckDelayedMemberExceptionSpecs();
-
- //===--------------------------------------------------------------------===//
- // C++ Derived Classes
- //
-
- /// ActOnBaseSpecifier - Parsed a base specifier
- CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class,
- SourceRange SpecifierRange,
- bool Virtual, AccessSpecifier Access,
- TypeSourceInfo *TInfo,
- SourceLocation EllipsisLoc);
-
- BaseResult ActOnBaseSpecifier(Decl *classdecl,
- SourceRange SpecifierRange,
- ParsedAttributes &Attrs,
- bool Virtual, AccessSpecifier Access,
- ParsedType basetype,
- SourceLocation BaseLoc,
- SourceLocation EllipsisLoc);
-
- bool AttachBaseSpecifiers(CXXRecordDecl *Class,
- MutableArrayRef<CXXBaseSpecifier *> Bases);
- void ActOnBaseSpecifiers(Decl *ClassDecl,
- MutableArrayRef<CXXBaseSpecifier *> Bases);
-
- bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base);
- bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base,
- CXXBasePaths &Paths);
-
- // FIXME: I don't like this name.
- void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath);
-
- bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
- SourceLocation Loc, SourceRange Range,
- CXXCastPath *BasePath = nullptr,
- bool IgnoreAccess = false);
- bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
- unsigned InaccessibleBaseID,
- unsigned AmbigiousBaseConvID,
- SourceLocation Loc, SourceRange Range,
- DeclarationName Name,
- CXXCastPath *BasePath);
-
- std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
-
- bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
- const CXXMethodDecl *Old);
-
- /// CheckOverridingFunctionReturnType - Checks whether the return types are
- /// covariant, according to C++ [class.virtual]p5.
- bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
- const CXXMethodDecl *Old);
-
- /// CheckOverridingFunctionExceptionSpec - Checks whether the exception
- /// spec is a subset of base spec.
- bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
- const CXXMethodDecl *Old);
-
- bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange);
-
- /// CheckOverrideControl - Check C++11 override control semantics.
- void CheckOverrideControl(NamedDecl *D);
-
- /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
- /// not used in the declaration of an overriding method.
- void DiagnoseAbsenceOfOverrideControl(NamedDecl *D);
-
- /// CheckForFunctionMarkedFinal - Checks whether a virtual member function
- /// overrides a virtual member function marked 'final', according to
- /// C++11 [class.virtual]p4.
- bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New,
- const CXXMethodDecl *Old);
-
-
- //===--------------------------------------------------------------------===//
- // C++ Access Control
- //
-
- enum AccessResult {
- AR_accessible,
- AR_inaccessible,
- AR_dependent,
- AR_delayed
- };
-
- bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
- NamedDecl *PrevMemberDecl,
- AccessSpecifier LexicalAS);
-
- AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
- DeclAccessPair FoundDecl);
- AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
- DeclAccessPair FoundDecl);
- AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
- SourceRange PlacementRange,
- CXXRecordDecl *NamingClass,
- DeclAccessPair FoundDecl,
- bool Diagnose = true);
- AccessResult CheckConstructorAccess(SourceLocation Loc,
- CXXConstructorDecl *D,
- const InitializedEntity &Entity,
- AccessSpecifier Access,
- bool IsCopyBindingRefToTemp = false);
- AccessResult CheckConstructorAccess(SourceLocation Loc,
- CXXConstructorDecl *D,
- const InitializedEntity &Entity,
- AccessSpecifier Access,
- const PartialDiagnostic &PDiag);
- AccessResult CheckDestructorAccess(SourceLocation Loc,
- CXXDestructorDecl *Dtor,
- const PartialDiagnostic &PDiag,
- QualType objectType = QualType());
- AccessResult CheckFriendAccess(NamedDecl *D);
- AccessResult CheckMemberAccess(SourceLocation UseLoc,
- CXXRecordDecl *NamingClass,
- DeclAccessPair Found);
- AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
- Expr *ObjectExpr,
- Expr *ArgExpr,
- DeclAccessPair FoundDecl);
- AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr,
- DeclAccessPair FoundDecl);
- AccessResult CheckBaseClassAccess(SourceLocation AccessLoc,
- QualType Base, QualType Derived,
- const CXXBasePath &Path,
- unsigned DiagID,
- bool ForceCheck = false,
- bool ForceUnprivileged = false);
- void CheckLookupAccess(const LookupResult &R);
- bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx);
- bool isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl,
- AccessSpecifier access,
- QualType objectType);
-
- void HandleDependentAccessCheck(const DependentDiagnostic &DD,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- void PerformDependentDiagnostics(const DeclContext *Pattern,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
-
- /// \brief When true, access checking violations are treated as SFINAE
- /// failures rather than hard errors.
- bool AccessCheckingSFINAE;
-
- enum AbstractDiagSelID {
- AbstractNone = -1,
- AbstractReturnType,
- AbstractParamType,
- AbstractVariableType,
- AbstractFieldType,
- AbstractIvarType,
- AbstractSynthesizedIvarType,
- AbstractArrayType
- };
-
- bool isAbstractType(SourceLocation Loc, QualType T);
- bool RequireNonAbstractType(SourceLocation Loc, QualType T,
- TypeDiagnoser &Diagnoser);
- template <typename... Ts>
- bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,
- const Ts &...Args) {
- BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
- return RequireNonAbstractType(Loc, T, Diagnoser);
- }
-
- void DiagnoseAbstractType(const CXXRecordDecl *RD);
-
- //===--------------------------------------------------------------------===//
- // C++ Overloaded Operators [C++ 13.5]
- //
-
- bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl);
-
- bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl);
-
- //===--------------------------------------------------------------------===//
- // C++ Templates [C++ 14]
- //
- void FilterAcceptableTemplateNames(LookupResult &R,
- bool AllowFunctionTemplates = true);
- bool hasAnyAcceptableTemplateNames(LookupResult &R,
- bool AllowFunctionTemplates = true);
-
- void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
- QualType ObjectType, bool EnteringContext,
- bool &MemberOfUnknownSpecialization);
-
- TemplateNameKind isTemplateName(Scope *S,
- CXXScopeSpec &SS,
- bool hasTemplateKeyword,
- UnqualifiedId &Name,
- ParsedType ObjectType,
- bool EnteringContext,
- TemplateTy &Template,
- bool &MemberOfUnknownSpecialization);
-
- bool DiagnoseUnknownTemplateName(const IdentifierInfo &II,
- SourceLocation IILoc,
- Scope *S,
- const CXXScopeSpec *SS,
- TemplateTy &SuggestedTemplate,
- TemplateNameKind &SuggestedKind);
-
- void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
- TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl);
-
- Decl *ActOnTypeParameter(Scope *S, bool Typename,
- SourceLocation EllipsisLoc,
- SourceLocation KeyLoc,
- IdentifierInfo *ParamName,
- SourceLocation ParamNameLoc,
- unsigned Depth, unsigned Position,
- SourceLocation EqualLoc,
- ParsedType DefaultArg);
-
- QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
- Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
- unsigned Depth,
- unsigned Position,
- SourceLocation EqualLoc,
- Expr *DefaultArg);
- Decl *ActOnTemplateTemplateParameter(Scope *S,
- SourceLocation TmpLoc,
- TemplateParameterList *Params,
- SourceLocation EllipsisLoc,
- IdentifierInfo *ParamName,
- SourceLocation ParamNameLoc,
- unsigned Depth,
- unsigned Position,
- SourceLocation EqualLoc,
- ParsedTemplateArgument DefaultArg);
-
- TemplateParameterList *
- ActOnTemplateParameterList(unsigned Depth,
- SourceLocation ExportLoc,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ArrayRef<Decl *> Params,
- SourceLocation RAngleLoc);
-
- /// \brief The context in which we are checking a template parameter list.
- enum TemplateParamListContext {
- TPC_ClassTemplate,
- TPC_VarTemplate,
- TPC_FunctionTemplate,
- TPC_ClassTemplateMember,
- TPC_FriendClassTemplate,
- TPC_FriendFunctionTemplate,
- TPC_FriendFunctionTemplateDefinition,
- TPC_TypeAliasTemplate
- };
-
- bool CheckTemplateParameterList(TemplateParameterList *NewParams,
- TemplateParameterList *OldParams,
- TemplateParamListContext TPC);
- TemplateParameterList *MatchTemplateParametersToScopeSpecifier(
- SourceLocation DeclStartLoc, SourceLocation DeclLoc,
- const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
- ArrayRef<TemplateParameterList *> ParamLists,
- bool IsFriend, bool &IsExplicitSpecialization, 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);
-
- void translateTemplateArguments(const ASTTemplateArgsPtr &In,
- TemplateArgumentListInfo &Out);
-
- void NoteAllFoundTemplates(TemplateName Name);
-
- QualType CheckTemplateIdType(TemplateName Template,
- SourceLocation TemplateLoc,
- TemplateArgumentListInfo &TemplateArgs);
-
- TypeResult
- ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
- TemplateTy Template, SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc,
- bool IsCtorOrDtorName = false);
-
- /// \brief 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,
- SourceLocation TagLoc,
- CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- TemplateTy TemplateD,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation RAngleLoc);
-
- DeclResult ActOnVarTemplateSpecialization(
- Scope *S, Declarator &D, TypeSourceInfo *DI,
- SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
- StorageClass SC, bool IsPartialSpecialization);
-
- DeclResult CheckVarTemplateId(VarTemplateDecl *Template,
- SourceLocation TemplateLoc,
- SourceLocation TemplateNameLoc,
- const TemplateArgumentListInfo &TemplateArgs);
-
- ExprResult CheckVarTemplateId(const CXXScopeSpec &SS,
- const DeclarationNameInfo &NameInfo,
- VarTemplateDecl *Template,
- SourceLocation TemplateLoc,
- const TemplateArgumentListInfo *TemplateArgs);
-
- ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- LookupResult &R,
- bool RequiresADL,
- const TemplateArgumentListInfo *TemplateArgs);
-
- ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- TemplateNameKind ActOnDependentTemplateName(Scope *S,
- CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- UnqualifiedId &Name,
- ParsedType ObjectType,
- bool EnteringContext,
- TemplateTy &Template);
-
- DeclResult
- ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc,
- SourceLocation ModulePrivateLoc,
- TemplateIdAnnotation &TemplateId,
- AttributeList *Attr,
- MultiTemplateParamsArg TemplateParameterLists,
- SkipBodyInfo *SkipBody = nullptr);
-
- Decl *ActOnTemplateDeclarator(Scope *S,
- MultiTemplateParamsArg TemplateParameterLists,
- Declarator &D);
-
- bool
- CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
- TemplateSpecializationKind NewTSK,
- NamedDecl *PrevDecl,
- TemplateSpecializationKind PrevTSK,
- SourceLocation PrevPtOfInstantiation,
- bool &SuppressNew);
-
- bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
- const TemplateArgumentListInfo &ExplicitTemplateArgs,
- LookupResult &Previous);
-
- bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- LookupResult &Previous);
- bool CheckMemberSpecialization(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,
- CXXScopeSpec &SS,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- AttributeList *Attr);
-
- DeclResult ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- Declarator &D);
-
- TemplateArgumentLoc
- SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
- SourceLocation TemplateLoc,
- SourceLocation RAngleLoc,
- Decl *Param,
- SmallVectorImpl<TemplateArgument>
- &Converted,
- bool &HasDefaultArg);
-
- /// \brief 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
- /// instantiated with some deduced template arguments.
- CTAK_Specified,
-
- /// \brief The template argument was deduced via template argument
- /// deduction.
- CTAK_Deduced,
-
- /// \brief The template argument was deduced from an array bound
- /// via template argument deduction.
- CTAK_DeducedFromArrayBound
- };
-
- bool CheckTemplateArgument(NamedDecl *Param,
- TemplateArgumentLoc &Arg,
- NamedDecl *Template,
- SourceLocation TemplateLoc,
- SourceLocation RAngleLoc,
- unsigned ArgumentPackIndex,
- SmallVectorImpl<TemplateArgument> &Converted,
- CheckTemplateArgumentKind CTAK = CTAK_Specified);
-
- /// \brief 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
- /// provided.
- ///
- /// \param TemplateLoc The location of the template name in the source.
- ///
- /// \param TemplateArgs The list of template arguments. If the template is
- /// a template template parameter, this function may extend the set of
- /// template arguments to also include substituted, defaulted template
- /// arguments.
- ///
- /// \param PartialTemplateArgs True if the list of template arguments is
- /// intentionally partial, e.g., because we're checking just the initial
- /// set of template arguments.
- ///
- /// \param Converted Will receive the converted, canonicalized template
- /// arguments.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool CheckTemplateArgumentList(TemplateDecl *Template,
- SourceLocation TemplateLoc,
- TemplateArgumentListInfo &TemplateArgs,
- bool PartialTemplateArgs,
- SmallVectorImpl<TemplateArgument> &Converted);
-
- bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
- TemplateArgumentLoc &Arg,
- SmallVectorImpl<TemplateArgument> &Converted);
-
- bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
- TypeSourceInfo *Arg);
- ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
- QualType InstantiatedParamType, Expr *Arg,
- TemplateArgument &Converted,
- CheckTemplateArgumentKind CTAK = CTAK_Specified);
- bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
- TemplateArgumentLoc &Arg,
- unsigned ArgumentPackIndex);
-
- ExprResult
- BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
- QualType ParamType,
- SourceLocation Loc);
- ExprResult
- BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
- SourceLocation Loc);
-
- /// \brief Enumeration describing how template parameter lists are compared
- /// for equality.
- enum TemplateParameterListEqualKind {
- /// \brief We are matching the template parameter lists of two templates
- /// that might be redeclarations.
- ///
- /// \code
- /// template<typename T> struct X;
- /// template<typename T> struct X;
- /// \endcode
- TPL_TemplateMatch,
-
- /// \brief 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.
- ///
- /// \code
- /// template<template<int I> class TT> struct X;
- /// template<template<int Value> class Other> struct X;
- /// \endcode
- TPL_TemplateTemplateParmMatch,
-
- /// \brief We are matching the template parameter lists of a template
- /// template argument against the template parameter lists of a template
- /// template parameter.
- ///
- /// \code
- /// template<template<int Value> class Metafun> struct X;
- /// template<int Value> struct integer_c;
- /// X<integer_c> xic;
- /// \endcode
- TPL_TemplateTemplateArgumentMatch
- };
-
- bool TemplateParameterListsAreEqual(TemplateParameterList *New,
- TemplateParameterList *Old,
- bool Complain,
- TemplateParameterListEqualKind Kind,
- SourceLocation TemplateArgLoc
- = SourceLocation());
-
- bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
-
- /// \brief 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.
- /// \param TypenameLoc the location of the 'typename' keyword
- /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
- /// \param II the identifier we're retrieving (e.g., 'type' in the example).
- /// \param IdLoc the location of the identifier.
- TypeResult
- ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
- const CXXScopeSpec &SS, const IdentifierInfo &II,
- SourceLocation IdLoc);
-
- /// \brief Called when the parser has parsed a C++ typename
- /// specifier that ends in a template-id, e.g.,
- /// "typename MetaFun::template apply<T1, T2>".
- ///
- /// \param S The scope in which this typename type occurs.
- /// \param TypenameLoc the location of the 'typename' keyword
- /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
- /// \param TemplateLoc the location of the 'template' keyword, if any.
- /// \param TemplateName The template name.
- /// \param TemplateNameLoc The location of the template name.
- /// \param LAngleLoc The location of the opening angle bracket ('<').
- /// \param TemplateArgs The template arguments.
- /// \param RAngleLoc The location of the closing angle bracket ('>').
- TypeResult
- ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
- const CXXScopeSpec &SS,
- SourceLocation TemplateLoc,
- TemplateTy TemplateName,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc);
-
- QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
- SourceLocation KeywordLoc,
- NestedNameSpecifierLoc QualifierLoc,
- const IdentifierInfo &II,
- SourceLocation IILoc);
-
- TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
- SourceLocation Loc,
- DeclarationName Name);
- bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS);
-
- ExprResult RebuildExprInCurrentInstantiation(Expr *E);
- bool RebuildTemplateParamsInCurrentInstantiation(
- TemplateParameterList *Params);
-
- std::string
- getTemplateArgumentBindingsText(const TemplateParameterList *Params,
- const TemplateArgumentList &Args);
-
- std::string
- getTemplateArgumentBindingsText(const TemplateParameterList *Params,
- const TemplateArgument *Args,
- unsigned NumArgs);
-
- //===--------------------------------------------------------------------===//
- // C++ Variadic Templates (C++0x [temp.variadic])
- //===--------------------------------------------------------------------===//
-
- /// Determine whether an unexpanded parameter pack might be permitted in this
- /// location. Useful for error recovery.
- bool isUnexpandedParameterPackPermitted();
-
- /// \brief 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.
- UPPC_Expression = 0,
-
- /// \brief The base type of a class type.
- UPPC_BaseType,
-
- /// \brief The type of an arbitrary declaration.
- UPPC_DeclarationType,
-
- /// \brief The type of a data member.
- UPPC_DataMemberType,
-
- /// \brief The size of a bit-field.
- UPPC_BitFieldWidth,
-
- /// \brief The expression in a static assertion.
- UPPC_StaticAssertExpression,
-
- /// \brief The fixed underlying type of an enumeration.
- UPPC_FixedUnderlyingType,
-
- /// \brief The enumerator value.
- UPPC_EnumeratorValue,
-
- /// \brief A using declaration.
- UPPC_UsingDeclaration,
-
- /// \brief A friend declaration.
- UPPC_FriendDeclaration,
-
- /// \brief A declaration qualifier.
- UPPC_DeclarationQualifier,
-
- /// \brief An initializer.
- UPPC_Initializer,
-
- /// \brief A default argument.
- UPPC_DefaultArgument,
-
- /// \brief The type of a non-type template parameter.
- UPPC_NonTypeTemplateParameterType,
-
- /// \brief The type of an exception.
- UPPC_ExceptionType,
-
- /// \brief Partial specialization.
- UPPC_PartialSpecialization,
-
- /// \brief Microsoft __if_exists.
- UPPC_IfExists,
-
- /// \brief Microsoft __if_not_exists.
- UPPC_IfNotExists,
-
- /// \brief Lambda expression.
- UPPC_Lambda,
-
- /// \brief Block expression,
- UPPC_Block
- };
-
- /// \brief Diagnose unexpanded parameter packs.
- ///
- /// \param Loc The location at which we should emit the diagnostic.
- ///
- /// \param UPPC The context in which we are diagnosing unexpanded
- /// parameter packs.
- ///
- /// \param Unexpanded the set of unexpanded parameter packs.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
- UnexpandedParameterPackContext UPPC,
- ArrayRef<UnexpandedParameterPack> Unexpanded);
-
- /// \brief If the given type contains an unexpanded parameter pack,
- /// diagnose the error.
- ///
- /// \param Loc The source location where a diagnostc should be emitted.
- ///
- /// \param T The type that is being checked for unexpanded parameter
- /// packs.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T,
- UnexpandedParameterPackContext UPPC);
-
- /// \brief If the given expression contains an unexpanded parameter
- /// pack, diagnose the error.
- ///
- /// \param E The expression that is being checked for unexpanded
- /// parameter packs.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool DiagnoseUnexpandedParameterPack(Expr *E,
- UnexpandedParameterPackContext UPPC = UPPC_Expression);
-
- /// \brief 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
- /// unexpanded parameter packs.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
- UnexpandedParameterPackContext UPPC);
-
- /// \brief If the given name contains an unexpanded parameter pack,
- /// diagnose the error.
- ///
- /// \param NameInfo The name (with source location information) that
- /// is being checked for unexpanded parameter packs.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
- UnexpandedParameterPackContext UPPC);
-
- /// \brief If the given template name contains an unexpanded parameter pack,
- /// diagnose the error.
- ///
- /// \param Loc The location of the template name.
- ///
- /// \param Template The template name that is being checked for unexpanded
- /// parameter packs.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool DiagnoseUnexpandedParameterPack(SourceLocation Loc,
- TemplateName Template,
- UnexpandedParameterPackContext UPPC);
-
- /// \brief If the given template argument contains an unexpanded parameter
- /// pack, diagnose the error.
- ///
- /// \param Arg The template argument that is being checked for unexpanded
- /// parameter packs.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
- UnexpandedParameterPackContext UPPC);
-
- /// \brief Collect the set of unexpanded parameter packs within the given
- /// template argument.
- ///
- /// \param Arg The template argument that will be traversed to find
- /// unexpanded parameter packs.
- void collectUnexpandedParameterPacks(TemplateArgument Arg,
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
-
- /// \brief Collect the set of unexpanded parameter packs within the given
- /// template argument.
- ///
- /// \param Arg The template argument that will be traversed to find
- /// unexpanded parameter packs.
- void collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
-
- /// \brief Collect the set of unexpanded parameter packs within the given
- /// type.
- ///
- /// \param T The type that will be traversed to find
- /// unexpanded parameter packs.
- void collectUnexpandedParameterPacks(QualType T,
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
-
- /// \brief Collect the set of unexpanded parameter packs within the given
- /// type.
- ///
- /// \param TL The type that will be traversed to find
- /// unexpanded parameter packs.
- void collectUnexpandedParameterPacks(TypeLoc TL,
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
-
- /// \brief Collect the set of unexpanded parameter packs within the given
- /// nested-name-specifier.
- ///
- /// \param SS The nested-name-specifier that will be traversed to find
- /// unexpanded parameter packs.
- void collectUnexpandedParameterPacks(CXXScopeSpec &SS,
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
-
- /// \brief Collect the set of unexpanded parameter packs within the given
- /// name.
- ///
- /// \param NameInfo The name that will be traversed to find
- /// unexpanded parameter packs.
- void collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
-
- /// \brief Invoked when parsing a template argument followed by an
- /// ellipsis, which creates a pack expansion.
- ///
- /// \param Arg The template argument preceding the ellipsis, which
- /// may already be invalid.
- ///
- /// \param EllipsisLoc The location of the ellipsis.
- ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg,
- SourceLocation EllipsisLoc);
-
- /// \brief Invoked when parsing a type followed by an ellipsis, which
- /// creates a pack expansion.
- ///
- /// \param Type The type preceding the ellipsis, which will become
- /// the pattern of the pack expansion.
- ///
- /// \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
- /// expansion.
- TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern,
- SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions);
-
- /// \brief 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
- /// creates a pack expansion.
- ///
- /// \param Pattern The expression preceding the ellipsis, which will become
- /// the pattern of the pack expansion.
- ///
- /// \param EllipsisLoc The location of the ellipsis.
- ExprResult ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc);
-
- /// \brief Invoked when parsing an expression followed by an ellipsis, which
- /// creates a pack expansion.
- ///
- /// \param Pattern The expression preceding the ellipsis, which will become
- /// the pattern of the pack expansion.
- ///
- /// \param EllipsisLoc The location of the ellipsis.
- ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions);
-
- /// \brief Determine whether we could expand a pack expansion with the
- /// given set of parameter packs into separate arguments by repeatedly
- /// transforming the pattern.
- ///
- /// \param EllipsisLoc The location of the ellipsis that identifies the
- /// pack expansion.
- ///
- /// \param PatternRange The source range that covers the entire pattern of
- /// the pack expansion.
- ///
- /// \param Unexpanded The set of unexpanded parameter packs within the
- /// pattern.
- ///
- /// \param ShouldExpand Will be set to \c true if the transformer should
- /// expand the corresponding pack expansions into separate arguments. When
- /// set, \c NumExpansions must also be set.
- ///
- /// \param RetainExpansion Whether the caller should add an unexpanded
- /// pack expansion after all of the expanded arguments. This is used
- /// when extending explicitly-specified template argument packs per
- /// C++0x [temp.arg.explicit]p9.
- ///
- /// \param NumExpansions The number of separate arguments that will be in
- /// the expanded form of the corresponding pack expansion. This is both an
- /// input and an output parameter, which can be set by the caller if the
- /// number of expansions is known a priori (e.g., due to a prior substitution)
- /// and will be set by the callee when the number of expansions is known.
- /// The callee must set this value when \c ShouldExpand is \c true; it may
- /// set this value in other cases.
- ///
- /// \returns true if an error occurred (e.g., because the parameter packs
- /// are to be instantiated with arguments of different lengths), false
- /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
- /// must be set.
- bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
- SourceRange PatternRange,
- ArrayRef<UnexpandedParameterPack> Unexpanded,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- bool &ShouldExpand,
- bool &RetainExpansion,
- Optional<unsigned> &NumExpansions);
-
- /// \brief Determine the number of arguments in the given pack expansion
- /// type.
- ///
- /// This routine assumes that the number of arguments in the expansion is
- /// consistent across all of the unexpanded parameter packs in its pattern.
- ///
- /// Returns an empty Optional if the type can't be expanded.
- Optional<unsigned> getNumArgumentsInExpansion(QualType T,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- /// \brief Determine whether the given declarator contains any unexpanded
- /// parameter packs.
- ///
- /// This routine is used by the parser to disambiguate function declarators
- /// with an ellipsis prior to the ')', e.g.,
- ///
- /// \code
- /// void f(T...);
- /// \endcode
- ///
- /// To determine whether we have an (unnamed) function parameter pack or
- /// a variadic function.
- ///
- /// \returns true if the declarator contains any unexpanded parameter packs,
- /// false otherwise.
- bool containsUnexpandedParameterPacks(Declarator &D);
-
- /// \brief Returns the pattern of the pack expansion for a template argument.
- ///
- /// \param OrigLoc The template argument to expand.
- ///
- /// \param Ellipsis Will be set to the location of the ellipsis.
- ///
- /// \param NumExpansions Will be set to the number of expansions that will
- /// be generated from this pack expansion, if known a priori.
- TemplateArgumentLoc getTemplateArgumentPackExpansionPattern(
- TemplateArgumentLoc OrigLoc,
- SourceLocation &Ellipsis,
- Optional<unsigned> &NumExpansions) const;
-
- //===--------------------------------------------------------------------===//
- // C++ Template Argument Deduction (C++ [temp.deduct])
- //===--------------------------------------------------------------------===//
-
- QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType);
-
- /// \brief Describes the result of template argument deduction.
- ///
- /// The TemplateDeductionResult enumeration describes the result of
- /// template argument deduction, as returned from
- /// DeduceTemplateArguments(). The separate TemplateDeductionInfo
- /// structure provides additional information about the results of
- /// template argument deduction, e.g., the deduced template argument
- /// 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.
- TDK_Success = 0,
- /// \brief The declaration was invalid; do nothing.
- TDK_Invalid,
- /// \brief 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
- /// for every template parameter.
- TDK_Incomplete,
- /// \brief Template argument deduction produced inconsistent
- /// deduced values for the given template parameter.
- TDK_Inconsistent,
- /// \brief 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
- /// resulted in an error.
- TDK_SubstitutionFailure,
- /// \brief After substituting deduced template arguments, a dependent
- /// parameter type did not match the corresponding argument.
- TDK_DeducedMismatch,
- /// \brief 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
- /// template, there were too many call arguments.
- TDK_TooManyArguments,
- /// \brief 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
- /// template arguments for the given template.
- TDK_InvalidExplicitArguments,
- /// \brief The arguments included an overloaded function name that could
- /// not be resolved to a suitable function.
- TDK_FailedOverloadResolution,
- /// \brief Deduction failed; that's all we know.
- TDK_MiscellaneousDeductionFailure
- };
-
- TemplateDeductionResult
- DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
- const TemplateArgumentList &TemplateArgs,
- sema::TemplateDeductionInfo &Info);
-
- TemplateDeductionResult
- DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
- const TemplateArgumentList &TemplateArgs,
- sema::TemplateDeductionInfo &Info);
-
- TemplateDeductionResult SubstituteExplicitTemplateArguments(
- FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo &ExplicitTemplateArgs,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType,
- sema::TemplateDeductionInfo &Info);
-
- /// brief A function argument from which we performed template argument
- // deduction for a call.
- struct OriginalCallArg {
- OriginalCallArg(QualType OriginalParamType,
- unsigned ArgIdx,
- QualType OriginalArgType)
- : OriginalParamType(OriginalParamType), ArgIdx(ArgIdx),
- OriginalArgType(OriginalArgType) { }
-
- QualType OriginalParamType;
- unsigned ArgIdx;
- QualType OriginalArgType;
- };
-
- TemplateDeductionResult
- FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- unsigned NumExplicitlySpecified,
- FunctionDecl *&Specialization,
- sema::TemplateDeductionInfo &Info,
- SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr,
- bool PartialOverloading = false);
-
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- ArrayRef<Expr *> Args,
- FunctionDecl *&Specialization,
- sema::TemplateDeductionInfo &Info,
- bool PartialOverloading = false);
-
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- QualType ArgFunctionType,
- FunctionDecl *&Specialization,
- sema::TemplateDeductionInfo &Info,
- bool InOverloadResolution = false);
-
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- QualType ToType,
- CXXConversionDecl *&Specialization,
- sema::TemplateDeductionInfo &Info);
-
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- FunctionDecl *&Specialization,
- sema::TemplateDeductionInfo &Info,
- bool InOverloadResolution = false);
-
- /// \brief Substitute Replacement for \p auto in \p TypeWithAuto
- QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement);
- /// \brief Substitute Replacement for auto in TypeWithAuto
- TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
- QualType Replacement);
-
- /// \brief Result type of DeduceAutoType.
- enum DeduceAutoResult {
- DAR_Succeeded,
- DAR_Failed,
- DAR_FailedAlreadyDiagnosed
- };
-
- DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
- QualType &Result);
- DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer,
- QualType &Result);
- void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
- bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
- bool Diagnose = true);
-
- QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
- QualType Type, TypeSourceInfo *TSI,
- SourceRange Range, bool DirectInit,
- Expr *Init);
-
- TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
-
- bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
- SourceLocation ReturnLoc,
- Expr *&RetExpr, AutoType *AT);
-
- FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2);
- UnresolvedSetIterator
- getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
- TemplateSpecCandidateSet &FailedCandidates,
- SourceLocation Loc,
- const PartialDiagnostic &NoneDiag,
- const PartialDiagnostic &AmbigDiag,
- const PartialDiagnostic &CandidateDiag,
- bool Complain = true, QualType TargetType = QualType());
-
- ClassTemplatePartialSpecializationDecl *
- getMoreSpecializedPartialSpecialization(
- ClassTemplatePartialSpecializationDecl *PS1,
- ClassTemplatePartialSpecializationDecl *PS2,
- SourceLocation Loc);
-
- VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization(
- VarTemplatePartialSpecializationDecl *PS1,
- VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc);
-
- void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
- bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallBitVector &Used);
- void MarkDeducedTemplateParameters(
- const FunctionTemplateDecl *FunctionTemplate,
- llvm::SmallBitVector &Deduced) {
- return MarkDeducedTemplateParameters(Context, FunctionTemplate, Deduced);
- }
- static void MarkDeducedTemplateParameters(ASTContext &Ctx,
- const FunctionTemplateDecl *FunctionTemplate,
- llvm::SmallBitVector &Deduced);
-
- //===--------------------------------------------------------------------===//
- // C++ Template Instantiation
- //
-
- MultiLevelTemplateArgumentList
- getTemplateInstantiationArgs(NamedDecl *D,
- const TemplateArgumentList *Innermost = nullptr,
- bool RelativeToPrimary = false,
- const FunctionDecl *Pattern = nullptr);
-
- /// \brief A template instantiation that is currently in progress.
- struct ActiveTemplateInstantiation {
- /// \brief The kind of template instantiation we are performing
- enum InstantiationKind {
- /// We are instantiating a template declaration. The entity is
- /// the declaration we're instantiating (e.g., a CXXRecordDecl).
- TemplateInstantiation,
-
- /// We are instantiating a default argument for a template
- /// parameter. The Entity is the template, and
- /// TemplateArgs/NumTemplateArguments provides the template
- /// arguments as specified.
- /// FIXME: Use a TemplateArgumentList
- DefaultTemplateArgumentInstantiation,
-
- /// We are instantiating a default argument for a function.
- /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs
- /// provides the template arguments as specified.
- DefaultFunctionArgumentInstantiation,
-
- /// We are substituting explicit template arguments provided for
- /// a function template. The entity is a FunctionTemplateDecl.
- ExplicitTemplateArgumentSubstitution,
-
- /// We are substituting template argument determined as part of
- /// template argument deduction for either a class template
- /// partial specialization or a function template. The
- /// Entity is either a ClassTemplatePartialSpecializationDecl or
- /// a FunctionTemplateDecl.
- DeducedTemplateArgumentSubstitution,
-
- /// We are substituting prior template arguments into a new
- /// template parameter. The template parameter itself is either a
- /// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl.
- PriorTemplateArgumentSubstitution,
-
- /// We are checking the validity of a default template argument that
- /// has been used when naming a template-id.
- DefaultTemplateArgumentChecking,
-
- /// We are instantiating the exception specification for a function
- /// template which was deferred until it was needed.
- ExceptionSpecInstantiation
- } Kind;
-
- /// \brief The point of instantiation within the source code.
- SourceLocation PointOfInstantiation;
-
- /// \brief The template (or partial specialization) in which we are
- /// performing the instantiation, for substitutions of prior template
- /// arguments.
- NamedDecl *Template;
-
- /// \brief The entity that is being instantiated.
- Decl *Entity;
-
- /// \brief The list of template arguments we are substituting, if they
- /// are not part of the entity.
- const TemplateArgument *TemplateArgs;
-
- /// \brief The number of template arguments in TemplateArgs.
- unsigned NumTemplateArgs;
-
- /// \brief 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 instantiation, e.g., the template-id that causes a class
- /// template instantiation.
- SourceRange InstantiationRange;
-
- ActiveTemplateInstantiation()
- : Kind(TemplateInstantiation), Template(nullptr), Entity(nullptr),
- TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {}
-
- /// \brief Determines whether this template is an actual instantiation
- /// that should be counted toward the maximum instantiation depth.
- bool isInstantiationRecord() const;
-
- friend bool operator==(const ActiveTemplateInstantiation &X,
- const ActiveTemplateInstantiation &Y) {
- if (X.Kind != Y.Kind)
- return false;
-
- if (X.Entity != Y.Entity)
- return false;
-
- switch (X.Kind) {
- case TemplateInstantiation:
- case ExceptionSpecInstantiation:
- return true;
-
- case PriorTemplateArgumentSubstitution:
- case DefaultTemplateArgumentChecking:
- return X.Template == Y.Template && X.TemplateArgs == Y.TemplateArgs;
-
- case DefaultTemplateArgumentInstantiation:
- case ExplicitTemplateArgumentSubstitution:
- case DeducedTemplateArgumentSubstitution:
- case DefaultFunctionArgumentInstantiation:
- return X.TemplateArgs == Y.TemplateArgs;
-
- }
-
- llvm_unreachable("Invalid InstantiationKind!");
- }
-
- friend bool operator!=(const ActiveTemplateInstantiation &X,
- const ActiveTemplateInstantiation &Y) {
- return !(X == Y);
- }
- };
-
- /// \brief List of active template instantiations.
- ///
- /// This vector is treated as a stack. As one template instantiation
- /// requires another template instantiation, additional
- /// instantiations are pushed onto the stack up to a
- /// user-configurable limit LangOptions::InstantiationDepth.
- SmallVector<ActiveTemplateInstantiation, 16>
- ActiveTemplateInstantiations;
-
- /// \brief Extra modules inspected when performing a lookup during a template
- /// instantiation. Computed lazily.
- SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules;
-
- /// \brief 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
- /// name lookup. A module and its imports become visible when instanting a
- /// template defined within it.
- llvm::DenseSet<Module*> &getLookupModules();
-
- /// \brief 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 ActiveTemplateInstantiation entries in
- /// \c ActiveTemplateInstantiations that are not actual instantiations and,
- /// therefore, should not be counted as part of the instantiation depth.
- unsigned NonInstantiationEntries;
-
- /// \brief The last template from which a template instantiation
- /// error or warning was produced.
- ///
- /// This value is used to suppress printing of redundant template
- /// instantiation backtraces when there are multiple errors in the
- /// same instantiation. FIXME: Does this belong in Sema? It's tough
- /// to implement it anywhere else.
- ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
-
- /// \brief 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
- /// should be instantiated as themselves. Otherwise, the index specifies
- /// which argument within the parameter pack will be used for substitution.
- int ArgumentPackSubstitutionIndex;
-
- /// \brief RAII object used to change the argument pack substitution index
- /// within a \c Sema object.
- ///
- /// See \c ArgumentPackSubstitutionIndex for more information.
- class ArgumentPackSubstitutionIndexRAII {
- Sema &Self;
- int OldSubstitutionIndex;
-
- public:
- ArgumentPackSubstitutionIndexRAII(Sema &Self, int NewSubstitutionIndex)
- : Self(Self), OldSubstitutionIndex(Self.ArgumentPackSubstitutionIndex) {
- Self.ArgumentPackSubstitutionIndex = NewSubstitutionIndex;
- }
-
- ~ArgumentPackSubstitutionIndexRAII() {
- Self.ArgumentPackSubstitutionIndex = OldSubstitutionIndex;
- }
- };
-
- friend class ArgumentPackSubstitutionRAII;
-
- /// \brief For each declaration that involved template argument deduction, the
- /// set of diagnostics that were suppressed during that template argument
- /// deduction.
- ///
- /// FIXME: Serialize this structure to the AST file.
- typedef llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> >
- SuppressedDiagnosticsMap;
- SuppressedDiagnosticsMap SuppressedDiagnostics;
-
- /// \brief A stack object to be created when performing template
- /// instantiation.
- ///
- /// Construction of an object of type \c InstantiatingTemplate
- /// pushes the current instantiation onto the stack of active
- /// instantiations. If the size of this stack exceeds the maximum
- /// number of recursive template instantiations, construction
- /// produces an error and evaluates true.
- ///
- /// Destruction of this object will pop the named instantiation off
- /// the stack.
- struct InstantiatingTemplate {
- /// \brief Note that we are instantiating a class template,
- /// function template, variable template, alias template,
- /// or a member thereof.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- Decl *Entity,
- SourceRange InstantiationRange = SourceRange());
-
- struct ExceptionSpecification {};
- /// \brief 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
- /// template-id.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- TemplateDecl *Template,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange InstantiationRange = SourceRange());
-
- /// \brief Note that we are instantiating a default argument in a
- /// template-id.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- FunctionTemplateDecl *FunctionTemplate,
- ArrayRef<TemplateArgument> TemplateArgs,
- ActiveTemplateInstantiation::InstantiationKind Kind,
- sema::TemplateDeductionInfo &DeductionInfo,
- SourceRange InstantiationRange = SourceRange());
-
- /// \brief Note that we are instantiating as part of template
- /// argument deduction for a class template partial
- /// specialization.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- ClassTemplatePartialSpecializationDecl *PartialSpec,
- ArrayRef<TemplateArgument> TemplateArgs,
- sema::TemplateDeductionInfo &DeductionInfo,
- SourceRange InstantiationRange = SourceRange());
-
- /// \brief Note that we are instantiating as part of template
- /// argument deduction for a variable template partial
- /// specialization.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- VarTemplatePartialSpecializationDecl *PartialSpec,
- ArrayRef<TemplateArgument> TemplateArgs,
- sema::TemplateDeductionInfo &DeductionInfo,
- SourceRange InstantiationRange = SourceRange());
-
- /// \brief 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
- /// non-type parameter.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- NamedDecl *Template,
- NonTypeTemplateParmDecl *Param,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange InstantiationRange);
-
- /// \brief Note that we are substituting prior template arguments into a
- /// template template parameter.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- NamedDecl *Template,
- TemplateTemplateParmDecl *Param,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange InstantiationRange);
-
- /// \brief 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,
- NamedDecl *Param,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange InstantiationRange);
-
-
- /// \brief Note that we have finished instantiating this template.
- void Clear();
-
- ~InstantiatingTemplate() { Clear(); }
-
- /// \brief Determines whether we have exceeded the maximum
- /// recursive template instantiations.
- bool isInvalid() const { return Invalid; }
-
- private:
- Sema &SemaRef;
- bool Invalid;
- bool SavedInNonInstantiationSFINAEContext;
- bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
- SourceRange InstantiationRange);
-
- InstantiatingTemplate(
- Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind,
- SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
- Decl *Entity, NamedDecl *Template = nullptr,
- ArrayRef<TemplateArgument> TemplateArgs = None,
- sema::TemplateDeductionInfo *DeductionInfo = nullptr);
-
- InstantiatingTemplate(const InstantiatingTemplate&) = delete;
-
- InstantiatingTemplate&
- operator=(const InstantiatingTemplate&) = delete;
- };
-
- void PrintInstantiationStack();
-
- /// \brief Determines whether we are currently in a context where
- /// template argument substitution failures are not considered
- /// errors.
- ///
- /// \returns An empty \c Optional if we're not in a SFINAE context.
- /// Otherwise, contains a pointer that, if non-NULL, contains the nearest
- /// template-deduction context object, which can be used to capture
- /// diagnostics that will be suppressed.
- Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
-
- /// \brief Determines whether we are currently in a context that
- /// is not evaluated as per C++ [expr] p5.
- bool isUnevaluatedContext() const {
- assert(!ExprEvalContexts.empty() &&
- "Must be in an expression evaluation context");
- return ExprEvalContexts.back().isUnevaluated();
- }
-
- /// \brief RAII class used to determine whether SFINAE has
- /// trapped any errors that occur during template argument
- /// deduction.
- class SFINAETrap {
- Sema &SemaRef;
- unsigned PrevSFINAEErrors;
- bool PrevInNonInstantiationSFINAEContext;
- bool PrevAccessCheckingSFINAE;
-
- public:
- explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false)
- : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors),
- PrevInNonInstantiationSFINAEContext(
- SemaRef.InNonInstantiationSFINAEContext),
- PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE)
- {
- if (!SemaRef.isSFINAEContext())
- SemaRef.InNonInstantiationSFINAEContext = true;
- SemaRef.AccessCheckingSFINAE = AccessCheckingSFINAE;
- }
-
- ~SFINAETrap() {
- SemaRef.NumSFINAEErrors = PrevSFINAEErrors;
- SemaRef.InNonInstantiationSFINAEContext
- = PrevInNonInstantiationSFINAEContext;
- SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
- }
-
- /// \brief 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
- /// 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.
- class TentativeAnalysisScope {
- Sema &SemaRef;
- // FIXME: Using a SFINAETrap for this is a hack.
- SFINAETrap Trap;
- bool PrevDisableTypoCorrection;
- public:
- explicit TentativeAnalysisScope(Sema &SemaRef)
- : SemaRef(SemaRef), Trap(SemaRef, true),
- PrevDisableTypoCorrection(SemaRef.DisableTypoCorrection) {
- SemaRef.DisableTypoCorrection = true;
- }
- ~TentativeAnalysisScope() {
- SemaRef.DisableTypoCorrection = PrevDisableTypoCorrection;
- }
- };
-
- /// \brief The current instantiation scope used to store local
- /// variables.
- LocalInstantiationScope *CurrentInstantiationScope;
-
- /// \brief Tracks whether we are in a context where typo correction is
- /// disabled.
- bool DisableTypoCorrection;
-
- /// \brief 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
- /// 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.
- sema::AnalysisBasedWarnings AnalysisWarnings;
- threadSafety::BeforeSet *ThreadSafetyDeclCache;
-
- /// \brief 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
- /// the point of instantiation (which will be either before or after the
- /// namespace-scope declaration that triggered this implicit instantiation),
- /// However, it is the location that diagnostics should generally refer to,
- /// 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
- /// but have not yet been performed.
- std::deque<PendingImplicitInstantiation> PendingInstantiations;
-
- class SavePendingInstantiationsAndVTableUsesRAII {
- public:
- SavePendingInstantiationsAndVTableUsesRAII(Sema &S, bool Enabled)
- : S(S), Enabled(Enabled) {
- if (!Enabled) return;
-
- SavedPendingInstantiations.swap(S.PendingInstantiations);
- SavedVTableUses.swap(S.VTableUses);
- }
-
- ~SavePendingInstantiationsAndVTableUsesRAII() {
- if (!Enabled) return;
-
- // Restore the set of pending vtables.
- assert(S.VTableUses.empty() &&
- "VTableUses should be empty before it is discarded.");
- S.VTableUses.swap(SavedVTableUses);
-
- // Restore the set of pending implicit instantiations.
- assert(S.PendingInstantiations.empty() &&
- "PendingInstantiations should be empty before it is discarded.");
- S.PendingInstantiations.swap(SavedPendingInstantiations);
- }
-
- private:
- Sema &S;
- SmallVector<VTableUse, 16> SavedVTableUses;
- std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
- bool Enabled;
- };
-
- /// \brief 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
- /// templates, which must be instantiated in the same scope as their
- /// enclosing function, so that they can reference function-local
- /// types, static variables, enumerators, etc.
- std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
-
- class SavePendingLocalImplicitInstantiationsRAII {
- public:
- SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) {
- SavedPendingLocalImplicitInstantiations.swap(
- S.PendingLocalImplicitInstantiations);
- }
-
- ~SavePendingLocalImplicitInstantiationsRAII() {
- assert(S.PendingLocalImplicitInstantiations.empty() &&
- "there shouldn't be any pending local implicit instantiations");
- SavedPendingLocalImplicitInstantiations.swap(
- S.PendingLocalImplicitInstantiations);
- }
-
- private:
- Sema &S;
- std::deque<PendingImplicitInstantiation>
- SavedPendingLocalImplicitInstantiations;
- };
-
- void PerformPendingInstantiations(bool LocalOnly = false);
-
- TypeSourceInfo *SubstType(TypeSourceInfo *T,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc, DeclarationName Entity);
-
- QualType SubstType(QualType T,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc, DeclarationName Entity);
-
- TypeSourceInfo *SubstType(TypeLoc TL,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc, DeclarationName Entity);
-
- TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc,
- DeclarationName Entity,
- CXXRecordDecl *ThisContext,
- unsigned ThisTypeQuals);
- void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
- const MultiLevelTemplateArgumentList &Args);
- ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- int indexAdjustment,
- Optional<unsigned> NumExpansions,
- bool ExpectParameterPack);
- bool SubstParmTypes(SourceLocation Loc,
- ParmVarDecl **Params, unsigned NumParams,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SmallVectorImpl<QualType> &ParamTypes,
- SmallVectorImpl<ParmVarDecl *> *OutParams = nullptr);
- ExprResult SubstExpr(Expr *E,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- /// \brief Substitute the given template arguments into a list of
- /// expressions, expanding pack expansions if required.
- ///
- /// \param Exprs The list of expressions to substitute into.
- ///
- /// \param IsCall Whether this is some form of call, in which case
- /// default arguments will be dropped.
- ///
- /// \param TemplateArgs The set of template arguments to substitute.
- ///
- /// \param Outputs Will receive all of the substituted arguments.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SmallVectorImpl<Expr *> &Outputs);
-
- StmtResult SubstStmt(Stmt *S,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- Decl *SubstDecl(Decl *D, DeclContext *Owner,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- ExprResult SubstInitializer(Expr *E,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- bool CXXDirectInit);
-
- bool
- SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
- CXXRecordDecl *Pattern,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- bool
- InstantiateClass(SourceLocation PointOfInstantiation,
- CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- TemplateSpecializationKind TSK,
- bool Complain = true);
-
- bool InstantiateEnum(SourceLocation PointOfInstantiation,
- EnumDecl *Instantiation, EnumDecl *Pattern,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- TemplateSpecializationKind TSK);
-
- bool InstantiateInClassInitializer(
- SourceLocation PointOfInstantiation, FieldDecl *Instantiation,
- FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs);
-
- struct LateInstantiatedAttribute {
- const Attr *TmplAttr;
- LocalInstantiationScope *Scope;
- Decl *NewDecl;
-
- LateInstantiatedAttribute(const Attr *A, LocalInstantiationScope *S,
- Decl *D)
- : TmplAttr(A), Scope(S), NewDecl(D)
- { }
- };
- typedef SmallVector<LateInstantiatedAttribute, 16> LateInstantiatedAttrVec;
-
- void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
- const Decl *Pattern, Decl *Inst,
- LateInstantiatedAttrVec *LateAttrs = nullptr,
- LocalInstantiationScope *OuterMostScope = nullptr);
-
- bool
- InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
- ClassTemplateSpecializationDecl *ClassTemplateSpec,
- TemplateSpecializationKind TSK,
- bool Complain = true);
-
- void InstantiateClassMembers(SourceLocation PointOfInstantiation,
- CXXRecordDecl *Instantiation,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- TemplateSpecializationKind TSK);
-
- void InstantiateClassTemplateSpecializationMembers(
- SourceLocation PointOfInstantiation,
- ClassTemplateSpecializationDecl *ClassTemplateSpec,
- TemplateSpecializationKind TSK);
-
- NestedNameSpecifierLoc
- SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- DeclarationNameInfo
- SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- TemplateName
- SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name,
- SourceLocation Loc,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- bool Subst(const TemplateArgumentLoc *Args, unsigned NumArgs,
- TemplateArgumentListInfo &Result,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- void InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
- FunctionDecl *Function);
- void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
- FunctionDecl *Function,
- bool Recursive = false,
- bool DefinitionRequired = false);
- VarTemplateSpecializationDecl *BuildVarTemplateInstantiation(
- VarTemplateDecl *VarTemplate, VarDecl *FromVar,
- const TemplateArgumentList &TemplateArgList,
- const TemplateArgumentListInfo &TemplateArgsInfo,
- SmallVectorImpl<TemplateArgument> &Converted,
- SourceLocation PointOfInstantiation, void *InsertPos,
- LateInstantiatedAttrVec *LateAttrs = nullptr,
- LocalInstantiationScope *StartingScope = nullptr);
- VarTemplateSpecializationDecl *CompleteVarTemplateSpecializationDecl(
- VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- void
- BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- LateInstantiatedAttrVec *LateAttrs,
- DeclContext *Owner,
- LocalInstantiationScope *StartingScope,
- bool InstantiatingVarTemplate = false);
- void InstantiateVariableInitializer(
- VarDecl *Var, VarDecl *OldVar,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- void InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
- VarDecl *Var, bool Recursive = false,
- bool DefinitionRequired = false);
- void InstantiateStaticDataMemberDefinition(
- SourceLocation PointOfInstantiation,
- VarDecl *Var,
- bool Recursive = false,
- bool DefinitionRequired = false);
-
- void InstantiateMemInitializers(CXXConstructorDecl *New,
- const CXXConstructorDecl *Tmpl,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- // Objective-C declarations.
- enum ObjCContainerKind {
- OCK_None = -1,
- OCK_Interface = 0,
- OCK_Protocol,
- OCK_Category,
- OCK_ClassExtension,
- OCK_Implementation,
- OCK_CategoryImplementation
- };
- ObjCContainerKind getObjCContainerKind() const;
-
- DeclResult actOnObjCTypeParam(Scope *S,
- ObjCTypeParamVariance variance,
- SourceLocation varianceLoc,
- unsigned index,
- IdentifierInfo *paramName,
- SourceLocation paramLoc,
- SourceLocation colonLoc,
- ParsedType typeBound);
-
- ObjCTypeParamList *actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc,
- ArrayRef<Decl *> typeParams,
- 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);
-
- void ActOnSuperClassOfClassInterface(Scope *S,
- SourceLocation AtInterfaceLoc,
- ObjCInterfaceDecl *IDecl,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- ArrayRef<ParsedType> SuperTypeArgs,
- SourceRange SuperTypeArgsRange);
-
- void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc);
-
- Decl *ActOnCompatibilityAlias(
- SourceLocation AtCompatibilityAliasLoc,
- IdentifierInfo *AliasName, SourceLocation AliasLocation,
- IdentifierInfo *ClassName, SourceLocation ClassLocation);
-
- bool CheckForwardProtocolDeclarationForCircularDependency(
- IdentifierInfo *PName,
- SourceLocation &PLoc, SourceLocation PrevLoc,
- 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);
-
- Decl *ActOnStartClassImplementation(
- SourceLocation AtClassImplLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperClassname,
- SourceLocation SuperClassLoc);
-
- Decl *ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *CatName,
- SourceLocation CatLoc);
-
- DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl,
- ArrayRef<Decl *> Decls);
-
- DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc,
- IdentifierInfo **IdentList,
- SourceLocation *IdentLocs,
- ArrayRef<ObjCTypeParamList *> TypeParamLists,
- unsigned NumElts);
-
- DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
- ArrayRef<IdentifierLocPair> IdentList,
- AttributeList *attrList);
-
- void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
- ArrayRef<IdentifierLocPair> ProtocolId,
- SmallVectorImpl<Decl *> &Protocols);
-
- /// Given a list of identifiers (and their locations), resolve the
- /// names to either Objective-C protocol qualifiers or type
- /// arguments, as appropriate.
- void actOnObjCTypeArgsOrProtocolQualifiers(
- Scope *S,
- ParsedType baseType,
- SourceLocation lAngleLoc,
- ArrayRef<IdentifierInfo *> identifiers,
- ArrayRef<SourceLocation> identifierLocs,
- SourceLocation rAngleLoc,
- SourceLocation &typeArgsLAngleLoc,
- SmallVectorImpl<ParsedType> &typeArgs,
- SourceLocation &typeArgsRAngleLoc,
- SourceLocation &protocolLAngleLoc,
- SmallVectorImpl<Decl *> &protocols,
- SourceLocation &protocolRAngleLoc,
- bool warnOnIncompleteProtocols);
-
- /// Build a an Objective-C protocol-qualified 'id' type where no
- /// base type was specified.
- TypeResult actOnObjCProtocolQualifierType(
- SourceLocation lAngleLoc,
- ArrayRef<Decl *> protocols,
- ArrayRef<SourceLocation> protocolLocs,
- SourceLocation rAngleLoc);
-
- /// Build a specialized and/or protocol-qualified Objective-C type.
- TypeResult actOnObjCTypeArgsAndProtocolQualifiers(
- Scope *S,
- SourceLocation Loc,
- ParsedType BaseType,
- SourceLocation TypeArgsLAngleLoc,
- ArrayRef<ParsedType> TypeArgs,
- SourceLocation TypeArgsRAngleLoc,
- SourceLocation ProtocolLAngleLoc,
- ArrayRef<Decl *> Protocols,
- ArrayRef<SourceLocation> ProtocolLocs,
- SourceLocation ProtocolRAngleLoc);
-
- /// Build an Objective-C object pointer type.
- QualType BuildObjCObjectType(QualType BaseType,
- SourceLocation Loc,
- SourceLocation TypeArgsLAngleLoc,
- ArrayRef<TypeSourceInfo *> TypeArgs,
- SourceLocation TypeArgsRAngleLoc,
- SourceLocation ProtocolLAngleLoc,
- ArrayRef<ObjCProtocolDecl *> Protocols,
- ArrayRef<SourceLocation> ProtocolLocs,
- SourceLocation ProtocolRAngleLoc,
- bool FailOnError = false);
-
- /// Check the application of the Objective-C '__kindof' qualifier to
- /// the given type.
- bool checkObjCKindOfType(QualType &type, SourceLocation loc);
-
- /// Ensure attributes are consistent with type.
- /// \param [in, out] Attributes The attributes to check; they will
- /// be modified to be consistent with \p PropertyTy.
- void CheckObjCPropertyAttributes(Decl *PropertyPtrTy,
- SourceLocation Loc,
- unsigned &Attributes,
- bool propertyInPrimaryClass);
-
- /// Process the specified property declaration and create decls for the
- /// setters and getters as needed.
- /// \param property The property declaration being processed
- void ProcessPropertyDecl(ObjCPropertyDecl *property);
-
-
- void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
- ObjCPropertyDecl *SuperProperty,
- const IdentifierInfo *Name,
- bool OverridingProtocolProperty);
-
- void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
- ObjCInterfaceDecl *ID);
-
- Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd,
- ArrayRef<Decl *> allMethods = None,
- ArrayRef<DeclGroupPtrTy> allTUVars = None);
-
- Decl *ActOnProperty(Scope *S, SourceLocation AtLoc,
- SourceLocation LParenLoc,
- FieldDeclarator &FD, ObjCDeclSpec &ODS,
- Selector GetterSel, Selector SetterSel,
- tok::ObjCKeywordKind MethodImplKind,
- DeclContext *lexicalDC = nullptr);
-
- Decl *ActOnPropertyImplDecl(Scope *S,
- SourceLocation AtLoc,
- SourceLocation PropertyLoc,
- bool ImplKind,
- IdentifierInfo *PropertyId,
- IdentifierInfo *PropertyIvar,
- SourceLocation PropertyIvarLoc);
-
- enum ObjCSpecialMethodKind {
- OSMK_None,
- OSMK_Alloc,
- OSMK_New,
- OSMK_Copy,
- OSMK_RetainingInit,
- OSMK_NonRetainingInit
- };
-
- struct ObjCArgInfo {
- IdentifierInfo *Name;
- SourceLocation NameLoc;
- // The Type is null if no type was specified, and the DeclSpec is invalid
- // in this case.
- ParsedType Type;
- ObjCDeclSpec DeclSpec;
-
- /// ArgAttrs - Attribute list for this argument.
- AttributeList *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);
-
- ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel,
- const ObjCObjectPointerType *OPT,
- bool IsInstance);
- ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty,
- bool IsInstance);
-
- bool CheckARCMethodDecl(ObjCMethodDecl *method);
- bool inferObjCARCLifetime(ValueDecl *decl);
-
- ExprResult
- HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
- Expr *BaseExpr,
- SourceLocation OpLoc,
- DeclarationName MemberName,
- SourceLocation MemberLoc,
- SourceLocation SuperLoc, QualType SuperType,
- bool Super);
-
- ExprResult
- ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
- IdentifierInfo &propertyName,
- SourceLocation receiverNameLoc,
- SourceLocation propertyNameLoc);
-
- ObjCMethodDecl *tryCaptureObjCSelf(SourceLocation Loc);
-
- /// \brief 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'.
- ObjCSuperMessage,
- /// \brief The message is an instance message.
- ObjCInstanceMessage,
- /// \brief The message is a class message, and the identifier is a type
- /// name.
- ObjCClassMessage
- };
-
- ObjCMessageKind getObjCMessageKind(Scope *S,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- bool IsSuper,
- bool HasTrailingDot,
- ParsedType &ReceiverType);
-
- ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
- Selector Sel,
- SourceLocation LBracLoc,
- ArrayRef<SourceLocation> SelectorLocs,
- SourceLocation RBracLoc,
- MultiExprArg Args);
-
- ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
- QualType ReceiverType,
- SourceLocation SuperLoc,
- Selector Sel,
- ObjCMethodDecl *Method,
- SourceLocation LBracLoc,
- ArrayRef<SourceLocation> SelectorLocs,
- SourceLocation RBracLoc,
- MultiExprArg Args,
- bool isImplicit = false);
-
- ExprResult BuildClassMessageImplicit(QualType ReceiverType,
- bool isSuperReceiver,
- SourceLocation Loc,
- Selector Sel,
- ObjCMethodDecl *Method,
- MultiExprArg Args);
-
- ExprResult ActOnClassMessage(Scope *S,
- ParsedType Receiver,
- Selector Sel,
- SourceLocation LBracLoc,
- ArrayRef<SourceLocation> SelectorLocs,
- SourceLocation RBracLoc,
- MultiExprArg Args);
-
- ExprResult BuildInstanceMessage(Expr *Receiver,
- QualType ReceiverType,
- SourceLocation SuperLoc,
- Selector Sel,
- ObjCMethodDecl *Method,
- SourceLocation LBracLoc,
- ArrayRef<SourceLocation> SelectorLocs,
- SourceLocation RBracLoc,
- MultiExprArg Args,
- bool isImplicit = false);
-
- ExprResult BuildInstanceMessageImplicit(Expr *Receiver,
- QualType ReceiverType,
- SourceLocation Loc,
- Selector Sel,
- ObjCMethodDecl *Method,
- MultiExprArg Args);
-
- ExprResult ActOnInstanceMessage(Scope *S,
- Expr *Receiver,
- Selector Sel,
- SourceLocation LBracLoc,
- ArrayRef<SourceLocation> SelectorLocs,
- SourceLocation RBracLoc,
- MultiExprArg Args);
-
- ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc,
- ObjCBridgeCastKind Kind,
- SourceLocation BridgeKeywordLoc,
- TypeSourceInfo *TSInfo,
- Expr *SubExpr);
-
- ExprResult ActOnObjCBridgedCast(Scope *S,
- SourceLocation LParenLoc,
- ObjCBridgeCastKind Kind,
- SourceLocation BridgeKeywordLoc,
- ParsedType Type,
- SourceLocation RParenLoc,
- Expr *SubExpr);
-
- void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr);
-
- void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr);
-
- bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
- CastKind &Kind);
-
- bool checkObjCBridgeRelatedComponents(SourceLocation Loc,
- QualType DestType, QualType SrcType,
- ObjCInterfaceDecl *&RelatedClass,
- ObjCMethodDecl *&ClassMethod,
- ObjCMethodDecl *&InstanceMethod,
- TypedefNameDecl *&TDNDecl,
- bool CfToNs);
-
- bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
- QualType DestType, QualType SrcType,
- Expr *&SrcExpr);
-
- bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
-
- bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
-
- /// \brief 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.
- enum ResultTypeCompatibilityKind {
- RTC_Compatible,
- RTC_Incompatible,
- RTC_Unknown
- };
-
- void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
- ObjCInterfaceDecl *CurrentClass,
- ResultTypeCompatibilityKind RTC);
-
- enum PragmaOptionsAlignKind {
- POAK_Native, // #pragma options align=native
- POAK_Natural, // #pragma options align=natural
- POAK_Packed, // #pragma options align=packed
- POAK_Power, // #pragma options align=power
- POAK_Mac68k, // #pragma options align=mac68k
- POAK_Reset // #pragma options align=reset
- };
-
- /// ActOnPragmaOptionsAlign - Called on well formed \#pragma options align.
- void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
- SourceLocation PragmaLoc);
-
- enum PragmaPackKind {
- PPK_Default, // #pragma pack([n])
- PPK_Show, // #pragma pack(show), only supported by MSVC.
- PPK_Push, // #pragma pack(push, [identifier], [n])
- PPK_Pop // #pragma pack(pop, [identifier], [n])
- };
-
- enum PragmaMSStructKind {
- PMSST_OFF, // #pragms ms_struct off
- PMSST_ON // #pragms ms_struct on
- };
-
- enum PragmaMSCommentKind {
- PCK_Unknown,
- PCK_Linker, // #pragma comment(linker, ...)
- PCK_Lib, // #pragma comment(lib, ...)
- PCK_Compiler, // #pragma comment(compiler, ...)
- PCK_ExeStr, // #pragma comment(exestr, ...)
- PCK_User // #pragma comment(user, ...)
- };
-
- /// ActOnPragmaPack - Called on well formed \#pragma pack(...).
- void ActOnPragmaPack(PragmaPackKind Kind,
- IdentifierInfo *Name,
- Expr *Alignment,
- SourceLocation PragmaLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off].
- void ActOnPragmaMSStruct(PragmaMSStructKind Kind);
-
- /// ActOnPragmaMSComment - Called on well formed
- /// \#pragma comment(kind, "arg").
- void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg);
-
- /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma
- /// pointers_to_members(representation method[, general purpose
- /// representation]).
- void ActOnPragmaMSPointersToMembers(
- LangOptions::PragmaMSPointersToMembersKind Kind,
- SourceLocation PragmaLoc);
-
- /// \brief Called on well formed \#pragma vtordisp().
- void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc,
- MSVtorDispAttr::Mode Value);
-
- enum PragmaSectionKind {
- PSK_DataSeg,
- PSK_BSSSeg,
- PSK_ConstSeg,
- PSK_CodeSeg,
- };
-
- bool UnifySection(StringRef SectionName,
- int SectionFlags,
- DeclaratorDecl *TheDecl);
- bool UnifySection(StringRef SectionName,
- int SectionFlags,
- SourceLocation PragmaSectionLocation);
-
- /// \brief 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().
- void ActOnPragmaMSSection(SourceLocation PragmaLocation,
- int SectionFlags, StringLiteral *SegmentName);
-
- /// \brief Called on well-formed \#pragma init_seg().
- void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
- StringLiteral *SegmentName);
-
- /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
- void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
-
- /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'.
- void ActOnPragmaUnused(const Token &Identifier,
- Scope *curScope,
- SourceLocation PragmaLoc);
-
- /// ActOnPragmaVisibility - Called on well formed \#pragma GCC visibility... .
- void ActOnPragmaVisibility(const IdentifierInfo* VisType,
- SourceLocation PragmaLoc);
-
- NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
- SourceLocation Loc);
- void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
-
- /// ActOnPragmaWeakID - Called on well formed \#pragma weak ident.
- void ActOnPragmaWeakID(IdentifierInfo* WeakName,
- SourceLocation PragmaLoc,
- SourceLocation WeakNameLoc);
-
- /// ActOnPragmaRedefineExtname - Called on well formed
- /// \#pragma redefine_extname oldname newname.
- void ActOnPragmaRedefineExtname(IdentifierInfo* WeakName,
- IdentifierInfo* AliasName,
- SourceLocation PragmaLoc,
- SourceLocation WeakNameLoc,
- SourceLocation AliasNameLoc);
-
- /// ActOnPragmaWeakAlias - Called on well formed \#pragma weak ident = ident.
- void ActOnPragmaWeakAlias(IdentifierInfo* WeakName,
- IdentifierInfo* AliasName,
- SourceLocation PragmaLoc,
- SourceLocation WeakNameLoc,
- SourceLocation AliasNameLoc);
-
- /// ActOnPragmaFPContract - Called on well formed
- /// \#pragma {STDC,OPENCL} FP_CONTRACT
- void ActOnPragmaFPContract(tok::OnOffSwitch OOS);
-
- /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
- /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'.
- void AddAlignmentAttributesForRecord(RecordDecl *RD);
-
- /// AddMsStructLayoutForRecord - Adds ms_struct layout attribute to record.
- void AddMsStructLayoutForRecord(RecordDecl *RD);
-
- /// FreePackedContext - Deallocate and null out PackContext.
- void FreePackedContext();
-
- /// PushNamespaceVisibilityAttr - Note that we've entered a
- /// namespace with a visibility attribute.
- void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
- SourceLocation Loc);
-
- /// AddPushedVisibilityAttribute - If '\#pragma GCC visibility' was used,
- /// add an appropriate visibility attribute.
- void AddPushedVisibilityAttribute(Decl *RD);
-
- /// PopPragmaVisibility - Pop the top element of the visibility stack; used
- /// for '\#pragma GCC visibility' and visibility attributes on namespaces.
- void PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc);
-
- /// FreeVisContext - Deallocate and null out VisContext.
- void FreeVisContext();
-
- /// AddCFAuditedAttribute - Check whether we're currently within
- /// '\#pragma clang arc_cf_code_audited' and, if so, consider adding
- /// the appropriate attribute.
- void AddCFAuditedAttribute(Decl *D);
-
- /// \brief Called on well formed \#pragma clang optimize.
- void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);
-
- /// \brief 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
- /// 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
- /// 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);
-
- /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
- void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
- unsigned SpellingListIndex, bool IsPackExpansion);
- void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T,
- unsigned SpellingListIndex, bool IsPackExpansion);
-
- /// AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular
- /// declaration.
- void AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, Expr *OE,
- unsigned SpellingListIndex);
-
- /// AddAlignValueAttr - Adds an align_value attribute to a particular
- /// declaration.
- void AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E,
- unsigned SpellingListIndex);
-
- /// AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular
- /// declaration.
- void AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads,
- Expr *MinBlocks, unsigned SpellingListIndex);
-
- //===--------------------------------------------------------------------===//
- // C++ Coroutines TS
- //
- ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E);
- ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E);
- StmtResult ActOnCoreturnStmt(SourceLocation KwLoc, Expr *E);
-
- ExprResult BuildCoawaitExpr(SourceLocation KwLoc, Expr *E);
- ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E);
- StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E);
-
- void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
-
- //===--------------------------------------------------------------------===//
- // OpenMP directives and clauses.
- //
-private:
- void *VarDataSharingAttributesStack;
- /// \brief Initialization of data-sharing attributes stack.
- void InitDataSharingAttributesStack();
- void DestroyDataSharingAttributesStack();
- ExprResult
- VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind,
- bool StrictlyPositive = true);
-
-public:
- /// \brief Return true if the provided declaration \a VD should be captured by
- /// reference in the provided scope \a RSI. This will take into account the
- /// semantics of the directive and associated clauses.
- bool IsOpenMPCapturedByRef(VarDecl *VD,
- const sema::CapturedRegionScopeInfo *RSI);
-
- /// \brief Check if the specified variable is used in one of the private
- /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP
- /// constructs.
- bool IsOpenMPCapturedVar(VarDecl *VD);
-
- /// \brief 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 isOpenMPPrivateVar(VarDecl *VD, unsigned Level);
-
- /// \brief 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 isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level);
-
- ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
- Expr *Op);
- /// \brief 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.
- void StartOpenMPClause(OpenMPClauseKind K);
- /// \brief End analysis of clauses.
- void EndOpenMPClause();
- /// \brief 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,
- /// 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
- /// threadprivate'.
- ExprResult ActOnOpenMPIdExpression(Scope *CurScope,
- CXXScopeSpec &ScopeSpec,
- const DeclarationNameInfo &Id);
- /// \brief 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 Initialization of captured region for OpenMP region.
- void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);
- /// \brief End of OpenMP region.
- ///
- /// \param S Statement associated with the current OpenMP region.
- /// \param Clauses List of clauses for the current OpenMP region.
- ///
- /// \returns Statement for finished OpenMP region.
- StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses);
- StmtResult ActOnOpenMPExecutableDirective(
- 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
- /// 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
- /// of the associated statement.
- StmtResult ActOnOpenMPSimdDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief 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<VarDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief 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<VarDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief 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
- /// associated statement.
- StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief 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
- /// associated statement.
- StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief 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
- /// of the associated statement.
- StmtResult ActOnOpenMPParallelForDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief 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<VarDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief 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
- /// associated statement.
- StmtResult ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp taskyield'.
- StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp barrier'.
- StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp taskwait'.
- StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp taskgroup'.
- StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief 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
- /// 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
- /// 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
- /// 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
- /// the associated statement.
- StmtResult ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief 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'.
- StmtResult
- ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
- SourceLocation EndLoc,
- OpenMPDirectiveKind CancelRegion);
- /// \brief 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
- /// associated statement.
- StmtResult ActOnOpenMPTaskLoopDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief 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<VarDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief 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<VarDecl *, Expr *> &VarsWithImplicitDSA);
-
- OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
- Expr *Expr,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief 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.
- OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'num_threads' clause.
- OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'safelen' clause.
- OMPClause *ActOnOpenMPSafelenClause(Expr *Length,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'simdlen' clause.
- OMPClause *ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'collapse' clause.
- OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief 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.
- OMPClause *ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'num_tasks' clause.
- OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'hint' clause.
- OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
-
- OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
- unsigned Argument,
- SourceLocation ArgumentLoc,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief 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.
- OMPClause *ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
- SourceLocation KindLoc,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
-
- OMPClause *ActOnOpenMPSingleExprWithArgClause(
- OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- ArrayRef<SourceLocation> ArgumentsLoc, SourceLocation DelimLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'schedule' clause.
- OMPClause *ActOnOpenMPScheduleClause(
- OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
- OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
- SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc);
-
- OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'nowait' clause.
- OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'untied' clause.
- OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'mergeable' clause.
- OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'read' clause.
- OMPClause *ActOnOpenMPReadClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'write' clause.
- OMPClause *ActOnOpenMPWriteClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'update' clause.
- OMPClause *ActOnOpenMPUpdateClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'capture' clause.
- OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'seq_cst' clause.
- OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'threads' clause.
- OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'simd' clause.
- OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'nogroup' clause.
- OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc,
- SourceLocation EndLoc);
-
- OMPClause *ActOnOpenMPVarListClause(
- OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc,
- CXXScopeSpec &ReductionIdScopeSpec,
- const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
- OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
- OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc);
- /// \brief Called on well-formed 'private' clause.
- OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'firstprivate' clause.
- OMPClause *ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'lastprivate' clause.
- OMPClause *ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'shared' clause.
- OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'reduction' clause.
- OMPClause *
- ActOnOpenMPReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation ColonLoc,
- SourceLocation EndLoc,
- CXXScopeSpec &ReductionIdScopeSpec,
- const DeclarationNameInfo &ReductionId);
- /// \brief 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.
- OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
- Expr *Alignment,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation ColonLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'copyin' clause.
- OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief 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.
- OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief 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.
- OMPClause *ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'map' clause.
- OMPClause *ActOnOpenMPMapClause(
- OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType,
- SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
- SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
- /// \brief 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.
- OMPClause *ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
- /// \brief Called on well-formed 'priority' clause.
- OMPClause *ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
-
- /// \brief The kind of conversion being performed.
- enum CheckedConversionKind {
- /// \brief An implicit conversion.
- CCK_ImplicitConversion,
- /// \brief A C-style cast.
- CCK_CStyleCast,
- /// \brief A functional-style cast.
- CCK_FunctionalCast,
- /// \brief A cast other than a C-style cast.
- 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.
- ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK,
- ExprValueKind VK = VK_RValue,
- const CXXCastPath *BasePath = nullptr,
- CheckedConversionKind CCK
- = CCK_ImplicitConversion);
-
- /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
- /// to the conversion from scalar type ScalarTy to the Boolean type.
- static CastKind ScalarTypeToBooleanCastKind(QualType ScalarTy);
-
- /// IgnoredValueConversions - Given that an expression's result is
- /// syntactically ignored, perform any conversions that are
- /// required.
- ExprResult IgnoredValueConversions(Expr *E);
-
- // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
- // functions and arrays to their respective pointers (C99 6.3.2.1).
- ExprResult UsualUnaryConversions(Expr *E);
-
- /// CallExprUnaryConversions - a special case of an unary conversion
- /// performed on a function designator of a call expression.
- ExprResult CallExprUnaryConversions(Expr *E);
-
- // DefaultFunctionArrayConversion - converts functions and arrays
- // to their respective pointers (C99 6.3.2.1).
- ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose = true);
-
- // DefaultFunctionArrayLvalueConversion - converts functions and
- // arrays to their respective pointers and performs the
- // lvalue-to-rvalue conversion.
- ExprResult DefaultFunctionArrayLvalueConversion(Expr *E,
- bool Diagnose = true);
-
- // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on
- // the operand. This is DefaultFunctionArrayLvalueConversion,
- // except that it assumes the operand isn't of function or array
- // type.
- ExprResult DefaultLvalueConversion(Expr *E);
-
- // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
- // do not have a prototype. Integer promotions are performed on each
- // argument, and arguments that have type float are promoted to double.
- ExprResult DefaultArgumentPromotion(Expr *E);
-
- // Used for emitting the right warning by DefaultVariadicArgumentPromotion
- enum VariadicCallType {
- VariadicFunction,
- VariadicBlock,
- VariadicMethod,
- VariadicConstructor,
- VariadicDoesNotApply
- };
-
- VariadicCallType getVariadicCallType(FunctionDecl *FDecl,
- const FunctionProtoType *Proto,
- Expr *Fn);
-
- // Used for determining in which context a type is allowed to be passed to a
- // vararg function.
- enum VarArgKind {
- VAK_Valid,
- VAK_ValidInCXX11,
- VAK_Undefined,
- VAK_MSVCUndefined,
- VAK_Invalid
- };
-
- // Determines which VarArgKind fits an expression.
- VarArgKind isValidVarArgType(const QualType &Ty);
-
- /// Check to see if the given expression is a valid argument to a variadic
- /// function, issuing a diagnostic if not.
- void checkVariadicArgument(const Expr *E, VariadicCallType CT);
-
- /// Check to see if a given expression could have '.c_str()' called on it.
- bool hasCStrMethod(const Expr *E);
-
- /// GatherArgumentsForCall - Collector argument expressions for various
- /// form of call prototypes.
- bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
- const FunctionProtoType *Proto,
- unsigned FirstParam, ArrayRef<Expr *> Args,
- SmallVectorImpl<Expr *> &AllArgs,
- VariadicCallType CallType = VariadicDoesNotApply,
- bool AllowExplicit = false,
- bool IsListInitialization = false);
-
- // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
- // will create a runtime trap if the resulting type is not a POD type.
- ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
- FunctionDecl *FDecl);
-
- // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
- // operands and then handles various conversions that are common to binary
- // operators (C99 6.3.1.8). If both operands aren't arithmetic, this
- // routine returns the first non-arithmetic type found. The client is
- // responsible for emitting appropriate error diagnostics.
- QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
- bool IsCompAssign = false);
-
- /// AssignConvertType - All of the 'assignment' semantic checks return this
- /// enum to indicate whether the assignment was allowed. These checks are
- /// done for simple assignments, as well as initialization, return from
- /// function, argument passing, etc. The query is phrased in terms of a
- /// source and destination type.
- enum AssignConvertType {
- /// Compatible - the types are compatible according to the standard.
- Compatible,
-
- /// PointerToInt - The assignment converts a pointer to an int, which we
- /// accept as an extension.
- PointerToInt,
-
- /// IntToPointer - The assignment converts an int to a pointer, which we
- /// accept as an extension.
- IntToPointer,
-
- /// FunctionVoidPointer - The assignment is between a function pointer and
- /// void*, which the standard doesn't allow, but we accept as an extension.
- FunctionVoidPointer,
-
- /// IncompatiblePointer - The assignment is between two pointers types that
- /// are not compatible, but we accept them as an extension.
- IncompatiblePointer,
-
- /// IncompatiblePointer - The assignment is between two pointers types which
- /// point to integers which have a different sign, but are otherwise
- /// identical. This is a subset of the above, but broken out because it's by
- /// far the most common case of incompatible pointers.
- IncompatiblePointerSign,
-
- /// CompatiblePointerDiscardsQualifiers - The assignment discards
- /// c/v/r qualifiers, which we accept as an extension.
- CompatiblePointerDiscardsQualifiers,
-
- /// IncompatiblePointerDiscardsQualifiers - The assignment
- /// discards qualifiers that we don't permit to be discarded,
- /// like address spaces.
- IncompatiblePointerDiscardsQualifiers,
-
- /// IncompatibleNestedPointerQualifiers - The assignment is between two
- /// nested pointer types, and the qualifiers other than the first two
- /// levels differ e.g. char ** -> const char **, but we accept them as an
- /// extension.
- IncompatibleNestedPointerQualifiers,
-
- /// IncompatibleVectors - The assignment is between two vector types that
- /// have the same size, which we accept as an extension.
- IncompatibleVectors,
-
- /// IntToBlockPointer - The assignment converts an int to a block
- /// pointer. We disallow this.
- IntToBlockPointer,
-
- /// IncompatibleBlockPointer - The assignment is between two block
- /// pointers types that are not compatible.
- IncompatibleBlockPointer,
-
- /// IncompatibleObjCQualifiedId - The assignment is between a qualified
- /// id type and something else (that is incompatible with it). For example,
- /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol.
- IncompatibleObjCQualifiedId,
-
- /// IncompatibleObjCWeakRef - Assigning a weak-unavailable object to an
- /// object with __weak qualifier.
- IncompatibleObjCWeakRef,
-
- /// Incompatible - We reject this conversion outright, it is invalid to
- /// represent it in the AST.
- Incompatible
- };
-
- /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
- /// assignment conversion type specified by ConvTy. This returns true if the
- /// conversion was invalid or false if the conversion was accepted.
- bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
- SourceLocation Loc,
- QualType DstType, QualType SrcType,
- Expr *SrcExpr, AssignmentAction Action,
- bool *Complained = nullptr);
-
- /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag
- /// enum. If AllowMask is true, then we also allow the complement of a valid
- /// value, to be used as a mask.
- bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
- bool AllowMask) const;
-
- /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant
- /// integer not in the range of enum values.
- void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
- Expr *SrcExpr);
-
- /// CheckAssignmentConstraints - Perform type checking for assignment,
- /// argument passing, variable initialization, and function return values.
- /// C99 6.5.16.
- AssignConvertType CheckAssignmentConstraints(SourceLocation Loc,
- QualType LHSType,
- QualType RHSType);
-
- /// Check assignment constraints and optionally prepare for a conversion of
- /// the RHS to the LHS type. The conversion is prepared for if ConvertRHS
- /// is true.
- AssignConvertType CheckAssignmentConstraints(QualType LHSType,
- ExprResult &RHS,
- CastKind &Kind,
- bool ConvertRHS = true);
-
- // CheckSingleAssignmentConstraints - Currently used by
- // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
- // this routine performs the default function/array converions, if ConvertRHS
- // is true.
- AssignConvertType CheckSingleAssignmentConstraints(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
- // can initialize the transparent union with the given expression.
- AssignConvertType CheckTransparentUnionArgumentConstraints(QualType ArgType,
- ExprResult &RHS);
-
- bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
-
- bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType);
-
- ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
- AssignmentAction Action,
- bool AllowExplicit = false);
- ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
- AssignmentAction Action,
- bool AllowExplicit,
- ImplicitConversionSequence& ICS);
- ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
- const ImplicitConversionSequence& ICS,
- AssignmentAction Action,
- CheckedConversionKind CCK
- = CCK_ImplicitConversion);
- ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
- const StandardConversionSequence& SCS,
- AssignmentAction Action,
- CheckedConversionKind CCK);
-
- /// the following "Check" methods will return a valid/converted QualType
- /// or a null QualType (indicating an error diagnostic was issued).
-
- /// type checking binary operators (subroutines of CreateBuiltinBinOp).
- QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS,
- ExprResult &RHS);
- QualType CheckPointerToMemberOperands( // C++ 5.5
- ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK,
- SourceLocation OpLoc, bool isIndirect);
- QualType CheckMultiplyDivideOperands( // C99 6.5.5
- ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign,
- bool IsDivide);
- QualType CheckRemainderOperands( // C99 6.5.5
- ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
- bool IsCompAssign = false);
- QualType CheckAdditionOperands( // C99 6.5.6
- ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
- BinaryOperatorKind Opc, QualType* CompLHSTy = nullptr);
- QualType CheckSubtractionOperands( // C99 6.5.6
- ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
- QualType* CompLHSTy = nullptr);
- QualType CheckShiftOperands( // C99 6.5.7
- 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);
- QualType CheckBitwiseOperands( // C99 6.5.[10...12]
- ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
- bool IsCompAssign = false);
- QualType CheckLogicalOperands( // C99 6.5.[13,14]
- ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
- BinaryOperatorKind Opc);
- // CheckAssignmentOperands is used for both simple and compound assignment.
- // For simple assignment, pass both expressions and a null converted type.
- // For compound assignment, pass both expressions and the converted type.
- QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
- Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType);
-
- ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc,
- UnaryOperatorKind Opcode, Expr *Op);
- ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc,
- BinaryOperatorKind Opcode,
- Expr *LHS, Expr *RHS);
- ExprResult checkPseudoObjectRValue(Expr *E);
- Expr *recreateSyntacticForm(PseudoObjectExpr *E);
-
- QualType CheckConditionalOperands( // C99 6.5.15
- ExprResult &Cond, ExprResult &LHS, ExprResult &RHS,
- ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc);
- QualType CXXCheckConditionalOperands( // C++ 5.16
- ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
- ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
- QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
- bool *NonStandardCompositeType = nullptr);
- QualType FindCompositePointerType(SourceLocation Loc,
- ExprResult &E1, ExprResult &E2,
- bool *NonStandardCompositeType = nullptr) {
- Expr *E1Tmp = E1.get(), *E2Tmp = E2.get();
- QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp,
- NonStandardCompositeType);
- E1 = E1Tmp;
- E2 = E2Tmp;
- return Composite;
- }
-
- QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
- SourceLocation QuestionLoc);
-
- bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
- SourceLocation QuestionLoc);
-
- void DiagnoseAlwaysNonNullPointer(Expr *E,
- Expr::NullPointerConstantKind NullType,
- bool IsEqual, SourceRange Range);
-
- /// type checking for vector binary operators.
- QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
- SourceLocation Loc, bool IsCompAssign,
- bool AllowBothBool, bool AllowBoolConversion);
- QualType GetSignedVectorType(QualType V);
- QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
- SourceLocation Loc, bool isRelational);
- QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
- SourceLocation Loc);
-
- bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType);
- bool isLaxVectorConversion(QualType srcType, QualType destType);
-
- /// type checking declaration initializers (C99 6.7.8)
- bool CheckForConstantInitializer(Expr *e, QualType t);
-
- // type checking C++ declaration initializers (C++ [dcl.init]).
-
- /// ReferenceCompareResult - Expresses the result of comparing two
- /// types (cv1 T1 and cv2 T2) to determine their compatibility for the
- /// purposes of initialization by reference (C++ [dcl.init.ref]p4).
- enum ReferenceCompareResult {
- /// Ref_Incompatible - The two types are incompatible, so direct
- /// reference binding is not possible.
- Ref_Incompatible = 0,
- /// Ref_Related - The two types are reference-related, which means
- /// that their unqualified forms (T1 and T2) are either the same
- /// or T1 is a base class of T2.
- Ref_Related,
- /// Ref_Compatible_With_Added_Qualification - The two types are
- /// reference-compatible with added qualification, meaning that
- /// they are reference-compatible and the qualifiers on T1 (cv1)
- /// are greater than the qualifiers on T2 (cv2).
- Ref_Compatible_With_Added_Qualification,
- /// Ref_Compatible - The two types are reference-compatible and
- /// have equivalent qualifiers (cv1 == cv2).
- Ref_Compatible
- };
-
- ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc,
- QualType T1, QualType T2,
- bool &DerivedToBase,
- bool &ObjCConversion,
- bool &ObjCLifetimeConversion);
-
- ExprResult checkUnknownAnyCast(SourceRange TypeRange, QualType CastType,
- Expr *CastExpr, CastKind &CastKind,
- ExprValueKind &VK, CXXCastPath &Path);
-
- /// \brief 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
- /// __unknown_anytype parameter.
- ExprResult checkUnknownAnyArg(SourceLocation callLoc,
- Expr *result, QualType &paramType);
-
- // CheckVectorCast - check type constraints for vectors.
- // Since vectors are an extension, there are no C standard reference for this.
- // We allow casting between vectors and integer datatypes of the same size.
- // returns true if the cast is invalid
- bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
- CastKind &Kind);
-
- // CheckExtVectorCast - check type constraints for extended vectors.
- // Since vectors are an extension, there are no C standard reference for this.
- // We allow casting between vectors and integer datatypes of the same size,
- // or vectors and the element type of that vector.
- // returns the cast expr
- ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr,
- CastKind &Kind);
-
- ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
- SourceLocation LParenLoc,
- Expr *CastExpr,
- SourceLocation RParenLoc);
-
- enum ARCConversionResult { ACR_okay, ACR_unbridged };
-
- /// \brief Checks for invalid conversions and casts between
- /// retainable pointers and other pointer kinds.
- ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
- QualType castType, Expr *&op,
- CheckedConversionKind CCK,
- bool DiagnoseCFAudited = false,
- BinaryOperatorKind Opc = BO_PtrMemD
- );
-
- Expr *stripARCUnbridgedCast(Expr *e);
- void diagnoseARCUnbridgedCast(Expr *e);
-
- bool CheckObjCARCUnavailableWeakConversion(QualType castType,
- QualType ExprType);
-
- /// checkRetainCycles - Check whether an Objective-C message send
- /// might create an obvious retain cycle.
- void checkRetainCycles(ObjCMessageExpr *msg);
- void checkRetainCycles(Expr *receiver, Expr *argument);
- void checkRetainCycles(VarDecl *Var, Expr *Init);
-
- /// checkUnsafeAssigns - Check whether +1 expr is being assigned
- /// to weak/__unsafe_unretained type.
- bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS);
-
- /// checkUnsafeExprAssigns - Check whether +1 expr is being assigned
- /// to weak/__unsafe_unretained expression.
- void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS);
-
- /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
- /// \param Method - May be null.
- /// \param [out] ReturnType - The return type of the send.
- /// \return true iff there were any incompatible types.
- bool CheckMessageArgumentTypes(QualType ReceiverType,
- MultiExprArg Args, Selector Sel,
- ArrayRef<SourceLocation> SelectorLocs,
- ObjCMethodDecl *Method, bool isClassMessage,
- bool isSuperMessage,
- SourceLocation lbrac, SourceLocation rbrac,
- SourceRange RecRange,
- QualType &ReturnType, ExprValueKind &VK);
-
- /// \brief 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
- /// 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
- /// 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);
-
- /// CheckBooleanCondition - Diagnose problems involving the use of
- /// the given expression as a boolean condition (e.g. in an if
- /// statement). Also performs the standard function and array
- /// decays, possibly changing the input variable.
- ///
- /// \param Loc - A location associated with the condition, e.g. the
- /// 'if' keyword.
- /// \return true iff there were any errors
- ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc);
-
- ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
- Expr *SubExpr);
-
- /// DiagnoseAssignmentAsCondition - Given that an expression is
- /// 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
- /// that the user intended an assignment used as condition.
- void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE);
-
- /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
- ExprResult CheckCXXBooleanCondition(Expr *CondExpr);
-
- /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
- /// the specified width and sign. If an overflow occurs, detect it and emit
- /// the specified diagnostic.
- void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
- unsigned NewWidth, bool NewSign,
- SourceLocation Loc, unsigned DiagID);
-
- /// Checks that the Objective-C declaration is declared in the global scope.
- /// Emits an error and marks the declaration as invalid if it's not declared
- /// in the global scope.
- bool CheckObjCDeclScope(Decl *D);
-
- /// \brief Abstract base class used for diagnosing integer constant
- /// expression violations.
- class VerifyICEDiagnoser {
- public:
- bool Suppress;
-
- VerifyICEDiagnoser(bool Suppress = false) : Suppress(Suppress) { }
-
- virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) =0;
- virtual void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR);
- virtual ~VerifyICEDiagnoser() { }
- };
-
- /// VerifyIntegerConstantExpression - Verifies that an expression is an ICE,
- /// and reports the appropriate diagnostics. Returns false on success.
- /// Can optionally return the value of the expression.
- ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
- VerifyICEDiagnoser &Diagnoser,
- bool AllowFold = true);
- ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
- unsigned DiagID,
- bool AllowFold = true);
- ExprResult VerifyIntegerConstantExpression(Expr *E,
- llvm::APSInt *Result = nullptr);
-
- /// VerifyBitField - verifies that a bit field expression is an ICE and has
- /// the correct width, and that the field type is valid.
- /// Returns false on success.
- /// Can optionally return whether the bit-field is of width 0
- ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
- QualType FieldTy, bool IsMsStruct,
- Expr *BitWidth, bool *ZeroWidth = nullptr);
-
- enum CUDAFunctionTarget {
- CFT_Device,
- CFT_Global,
- CFT_Host,
- CFT_HostDevice,
- CFT_InvalidTarget
- };
-
- CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D);
-
- enum CUDAFunctionPreference {
- CFP_Never, // Invalid caller/callee combination.
- CFP_LastResort, // Lowest priority. Only in effect if
- // LangOpts.CUDADisableTargetCallChecks is true.
- CFP_Fallback, // Low priority caller/callee combination
- CFP_Best, // Preferred caller/callee combination
- };
-
- /// Identifies relative preference of a given Caller/Callee
- /// combination, based on their host/device attributes.
- /// \param Caller function which needs address of \p Callee.
- /// nullptr in case of global context.
- /// \param Callee target function
- ///
- /// \returns preference value for particular Caller/Callee combination.
- CUDAFunctionPreference IdentifyCUDAPreference(const FunctionDecl *Caller,
- const FunctionDecl *Callee);
-
- bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee);
-
- /// Finds a function in \p Matches with highest calling priority
- /// from \p Caller context and erases all functions with lower
- /// calling priority.
- void EraseUnwantedCUDAMatches(const FunctionDecl *Caller,
- SmallVectorImpl<FunctionDecl *> &Matches);
- void EraseUnwantedCUDAMatches(const FunctionDecl *Caller,
- SmallVectorImpl<DeclAccessPair> &Matches);
- void EraseUnwantedCUDAMatches(
- const FunctionDecl *Caller,
- SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches);
-
- /// Given a implicit special member, infer its CUDA target from the
- /// calls it needs to make to underlying base/field special members.
- /// \param ClassDecl the class for which the member is being created.
- /// \param CSM the kind of special member.
- /// \param MemberDecl the special member itself.
- /// \param ConstRHS true if this is a copy operation with a const object on
- /// its RHS.
- /// \param Diagnose true if this call should emit diagnostics.
- /// \return true if there was an error inferring.
- /// The result of this call is implicit CUDA target attribute(s) attached to
- /// the member declaration.
- bool inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
- CXXSpecialMember CSM,
- CXXMethodDecl *MemberDecl,
- bool ConstRHS,
- bool Diagnose);
-
- /// \name Code completion
- //@{
- /// \brief Describes the context in which code completion occurs.
- enum ParserCompletionContext {
- /// \brief Code completion occurs at top-level or namespace context.
- PCC_Namespace,
- /// \brief Code completion occurs within a class, struct, or union.
- PCC_Class,
- /// \brief Code completion occurs within an Objective-C interface, protocol,
- /// or category.
- PCC_ObjCInterface,
- /// \brief Code completion occurs within an Objective-C implementation or
- /// category implementation
- PCC_ObjCImplementation,
- /// \brief 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
- /// headers.
- PCC_Template,
- /// \brief Code completion occurs following one or more template
- /// headers within a class.
- PCC_MemberTemplate,
- /// \brief Code completion occurs within an expression.
- PCC_Expression,
- /// \brief 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
- /// initialization statement (or expression) in a for loop.
- PCC_ForInit,
- /// \brief 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
- /// 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.
- PCC_Type,
- /// \brief 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
- /// specifiers within a function, method, or block.
- PCC_LocalDeclarationSpecifiers
- };
-
- void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path);
- void CodeCompleteOrdinaryName(Scope *S,
- ParserCompletionContext CompletionContext);
- void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
- bool AllowNonIdentifiers,
- bool AllowNestedNameSpecifiers);
-
- struct CodeCompleteExpressionData;
- void CodeCompleteExpression(Scope *S,
- const CodeCompleteExpressionData &Data);
- void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
- SourceLocation OpLoc,
- bool IsArrow);
- void CodeCompletePostfixExpression(Scope *S, ExprResult LHS);
- void CodeCompleteTag(Scope *S, unsigned TagSpec);
- void CodeCompleteTypeQualifiers(DeclSpec &DS);
- void CodeCompleteCase(Scope *S);
- void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args);
- void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc,
- ArrayRef<Expr *> Args);
- void CodeCompleteInitializer(Scope *S, Decl *D);
- void CodeCompleteReturn(Scope *S);
- void CodeCompleteAfterIf(Scope *S);
- void CodeCompleteAssignmentRHS(Scope *S, Expr *LHS);
-
- void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
- bool EnteringContext);
- void CodeCompleteUsing(Scope *S);
- void CodeCompleteUsingDirective(Scope *S);
- void CodeCompleteNamespaceDecl(Scope *S);
- void CodeCompleteNamespaceAliasDecl(Scope *S);
- void CodeCompleteOperatorName(Scope *S);
- void CodeCompleteConstructorInitializer(
- Decl *Constructor,
- ArrayRef<CXXCtorInitializer *> Initializers);
-
- void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
- bool AfterAmpersand);
-
- void CodeCompleteObjCAtDirective(Scope *S);
- void CodeCompleteObjCAtVisibility(Scope *S);
- void CodeCompleteObjCAtStatement(Scope *S);
- void CodeCompleteObjCAtExpression(Scope *S);
- void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
- void CodeCompleteObjCPropertyGetter(Scope *S);
- void CodeCompleteObjCPropertySetter(Scope *S);
- void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
- bool IsParameter);
- void CodeCompleteObjCMessageReceiver(Scope *S);
- void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
- ArrayRef<IdentifierInfo *> SelIdents,
- bool AtArgumentExpression);
- void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
- ArrayRef<IdentifierInfo *> SelIdents,
- bool AtArgumentExpression,
- bool IsSuper = false);
- void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
- ArrayRef<IdentifierInfo *> SelIdents,
- bool AtArgumentExpression,
- ObjCInterfaceDecl *Super = nullptr);
- void CodeCompleteObjCForCollection(Scope *S,
- DeclGroupPtrTy IterationVar);
- void CodeCompleteObjCSelector(Scope *S,
- ArrayRef<IdentifierInfo *> SelIdents);
- void CodeCompleteObjCProtocolReferences(
- ArrayRef<IdentifierLocPair> Protocols);
- void CodeCompleteObjCProtocolDecl(Scope *S);
- void CodeCompleteObjCInterfaceDecl(Scope *S);
- void CodeCompleteObjCSuperclass(Scope *S,
- IdentifierInfo *ClassName,
- SourceLocation ClassNameLoc);
- void CodeCompleteObjCImplementationDecl(Scope *S);
- void CodeCompleteObjCInterfaceCategory(Scope *S,
- IdentifierInfo *ClassName,
- SourceLocation ClassNameLoc);
- void CodeCompleteObjCImplementationCategory(Scope *S,
- IdentifierInfo *ClassName,
- SourceLocation ClassNameLoc);
- void CodeCompleteObjCPropertyDefinition(Scope *S);
- void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
- IdentifierInfo *PropertyName);
- void CodeCompleteObjCMethodDecl(Scope *S,
- bool IsInstanceMethod,
- ParsedType ReturnType);
- void CodeCompleteObjCMethodDeclSelector(Scope *S,
- bool IsInstanceMethod,
- bool AtParameterName,
- ParsedType ReturnType,
- ArrayRef<IdentifierInfo *> SelIdents);
- void CodeCompletePreprocessorDirective(bool InConditional);
- void CodeCompleteInPreprocessorConditionalExclusion(Scope *S);
- void CodeCompletePreprocessorMacroName(bool IsDefinition);
- void CodeCompletePreprocessorExpression();
- void CodeCompletePreprocessorMacroArgument(Scope *S,
- IdentifierInfo *Macro,
- MacroInfo *MacroInfo,
- unsigned Argument);
- void CodeCompleteNaturalLanguage();
- void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo,
- SmallVectorImpl<CodeCompletionResult> &Results);
- //@}
-
- //===--------------------------------------------------------------------===//
- // Extra semantic analysis beyond the C type system
-
-public:
- SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL,
- unsigned ByteNo) const;
-
-private:
- void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
- const ArraySubscriptExpr *ASE=nullptr,
- bool AllowOnePastEnd=true, bool IndexNegated=false);
- void CheckArrayAccess(const Expr *E);
- // Used to grab the relevant information from a FormatAttr and a
- // FunctionDeclaration.
- struct FormatStringInfo {
- unsigned FormatIdx;
- unsigned FirstDataArg;
- bool HasVAListArg;
- };
-
- static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember,
- FormatStringInfo *FSI);
- bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
- const FunctionProtoType *Proto);
- bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc,
- ArrayRef<const Expr *> Args);
- bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
- const FunctionProtoType *Proto);
- bool CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto);
- void CheckConstructorCall(FunctionDecl *FDecl,
- ArrayRef<const Expr *> Args,
- const FunctionProtoType *Proto,
- SourceLocation Loc);
-
- void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
- ArrayRef<const Expr *> Args, bool IsMemberFunction,
- SourceLocation Loc, SourceRange Range,
- VariadicCallType CallType);
-
- bool CheckObjCString(Expr *Arg);
-
- ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl,
- unsigned BuiltinID, CallExpr *TheCall);
-
- bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
- unsigned MaxWidth);
- bool CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
-
- bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
-
- bool SemaBuiltinVAStartImpl(CallExpr *TheCall);
- bool SemaBuiltinVAStart(CallExpr *TheCall);
- bool SemaBuiltinMSVAStart(CallExpr *TheCall);
- bool SemaBuiltinVAStartARM(CallExpr *Call);
- bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
- bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
-
-public:
- // Used by C++ template instantiation.
- ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
- ExprResult SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
- SourceLocation BuiltinLoc,
- SourceLocation RParenLoc);
-
-private:
- bool SemaBuiltinPrefetch(CallExpr *TheCall);
- bool SemaBuiltinAssume(CallExpr *TheCall);
- bool SemaBuiltinAssumeAligned(CallExpr *TheCall);
- bool SemaBuiltinLongjmp(CallExpr *TheCall);
- bool SemaBuiltinSetjmp(CallExpr *TheCall);
- ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
- ExprResult SemaBuiltinNontemporalOverloaded(ExprResult TheCallResult);
- ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
- AtomicExpr::AtomicOp Op);
- bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
- llvm::APSInt &Result);
- bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,
- int Low, int High);
- bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall,
- int ArgNum, unsigned ExpectedFieldNum,
- bool AllowName);
-public:
- enum FormatStringType {
- FST_Scanf,
- FST_Printf,
- FST_NSString,
- FST_Strftime,
- FST_Strfmon,
- FST_Kprintf,
- FST_FreeBSDKPrintf,
- FST_OSTrace,
- FST_Unknown
- };
- static FormatStringType GetFormatStringType(const FormatAttr *Format);
-
- void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr,
- ArrayRef<const Expr *> Args, bool HasVAListArg,
- unsigned format_idx, unsigned firstDataArg,
- FormatStringType Type, bool inFunctionCall,
- VariadicCallType CallType,
- llvm::SmallBitVector &CheckedVarArgs);
-
- bool FormatStringHasSArg(const StringLiteral *FExpr);
-
- static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx);
-
-private:
- bool CheckFormatArguments(const FormatAttr *Format,
- ArrayRef<const Expr *> Args,
- bool IsCXXMember,
- VariadicCallType CallType,
- SourceLocation Loc, SourceRange Range,
- llvm::SmallBitVector &CheckedVarArgs);
- bool CheckFormatArguments(ArrayRef<const Expr *> Args,
- bool HasVAListArg, unsigned format_idx,
- unsigned firstDataArg, FormatStringType Type,
- VariadicCallType CallType,
- SourceLocation Loc, SourceRange range,
- llvm::SmallBitVector &CheckedVarArgs);
-
- void CheckAbsoluteValueFunction(const CallExpr *Call,
- const FunctionDecl *FDecl,
- IdentifierInfo *FnInfo);
-
- void CheckMemaccessArguments(const CallExpr *Call,
- unsigned BId,
- IdentifierInfo *FnName);
-
- void CheckStrlcpycatArguments(const CallExpr *Call,
- IdentifierInfo *FnName);
-
- void CheckStrncatArguments(const CallExpr *Call,
- IdentifierInfo *FnName);
-
- void CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
- SourceLocation ReturnLoc,
- bool isObjCMethod = false,
- const AttrVec *Attrs = nullptr,
- const FunctionDecl *FD = nullptr);
-
- void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
- 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
- /// be a full-expression or a default argument expression.
- void CheckCompletedExpr(Expr *E, SourceLocation CheckLoc = SourceLocation(),
- bool IsConstexpr = false);
-
- void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field,
- Expr *Init);
-
- /// \brief 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
- /// attempts to add itself into the container
- void CheckObjCCircularContainer(ObjCMessageExpr *Message);
-
- void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE);
- void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
- bool DeleteWasArrayForm);
-public:
- /// \brief 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);
-
- struct TypeTagData {
- TypeTagData() {}
-
- TypeTagData(QualType Type, bool LayoutCompatible, bool MustBeNull) :
- Type(Type), LayoutCompatible(LayoutCompatible),
- MustBeNull(MustBeNull)
- {}
-
- QualType Type;
-
- /// If true, \c Type should be compared with other expression's types for
- /// layout-compatibility.
- unsigned LayoutCompatible : 1;
- unsigned MustBeNull : 1;
- };
-
- /// A pair of ArgumentKind identifier and magic value. This uniquely
- /// identifies the magic value.
- typedef std::pair<const IdentifierInfo *, uint64_t> TypeTagMagicValue;
-
-private:
- /// \brief 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
- /// or pointer_with_type_tag attributes.
- void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,
- const Expr * const *ExprArgs);
-
- /// \brief The parser's current scope.
- ///
- /// The parser maintains this state here.
- Scope *CurScope;
-
- mutable IdentifierInfo *Ident_super;
- mutable IdentifierInfo *Ident___float128;
-
- /// Nullability type specifiers.
- IdentifierInfo *Ident__Nonnull = nullptr;
- IdentifierInfo *Ident__Nullable = nullptr;
- IdentifierInfo *Ident__Null_unspecified = nullptr;
-
- IdentifierInfo *Ident_NSError = nullptr;
-
-protected:
- friend class Parser;
- friend class InitializationSequence;
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTWriter;
-
-public:
- /// Retrieve the keyword associated
- IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability);
-
- /// The struct behind the CFErrorRef pointer.
- RecordDecl *CFError = nullptr;
-
- /// Retrieve the identifier "NSError".
- IdentifierInfo *getNSErrorIdent();
-
- /// \brief 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
- /// when, e.g., we are performing any kind of template instantiation.
- /// Therefore, the only safe places to use this scope are in the parser
- /// itself and in routines directly invoked from the parser and *never* from
- /// template substitution or instantiation.
- Scope *getCurScope() const { return CurScope; }
-
- void incrementMSManglingNumber() const {
- return CurScope->incrementMSManglingNumber();
- }
-
- IdentifierInfo *getSuperIdentifier() const;
- IdentifierInfo *getFloat128Identifier() const;
-
- Decl *getObjCDeclContext() const;
-
- DeclContext *getCurLexicalContext() const {
- return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
- }
-
- AvailabilityResult getCurContextAvailability() const;
-
- const DeclContext *getCurObjCLexicalContext() const {
- const DeclContext *DC = getCurLexicalContext();
- // A category implicitly has the attribute of the interface.
- if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC))
- DC = CatD->getClassInterface();
- return DC;
- }
-
- /// \brief 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) {
- // We check whether we're just after a comma in code-completion.
- if (NumArgs > 0 && PartialOverloading)
- return NumArgs + 1 > NumParams; // If so, we view as an extra argument.
- return NumArgs > NumParams;
- }
-
- // Emitting members of dllexported classes is delayed until the class
- // (including field initializers) is fully parsed.
- SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses;
-};
-
-/// \brief RAII object that enters a new expression evaluation context.
-class EnterExpressionEvaluationContext {
- Sema &Actions;
-
-public:
- EnterExpressionEvaluationContext(Sema &Actions,
- Sema::ExpressionEvaluationContext NewContext,
- Decl *LambdaContextDecl = nullptr,
- bool IsDecltype = false)
- : Actions(Actions) {
- Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
- IsDecltype);
- }
- EnterExpressionEvaluationContext(Sema &Actions,
- Sema::ExpressionEvaluationContext NewContext,
- Sema::ReuseLambdaContextDecl_t,
- bool IsDecltype = false)
- : Actions(Actions) {
- Actions.PushExpressionEvaluationContext(NewContext,
- Sema::ReuseLambdaContextDecl,
- IsDecltype);
- }
-
- ~EnterExpressionEvaluationContext() {
- Actions.PopExpressionEvaluationContext();
- }
-};
-
-DeductionFailureInfo
-MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK,
- sema::TemplateDeductionInfo &Info);
-
-/// \brief 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.
- Decl *D;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h
deleted file mode 100644
index 676646a..0000000
--- a/include/clang/Sema/SemaConsumer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===--- SemaConsumer.h - Abstract interface for AST semantics --*- 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 SemaConsumer class, a subclass of
-// ASTConsumer that is used by AST clients that also require
-// additional semantic analysis.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_SEMACONSUMER_H
-#define LLVM_CLANG_SEMA_SEMACONSUMER_H
-
-#include "clang/AST/ASTConsumer.h"
-
-namespace clang {
- class Sema;
-
- /// \brief 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 {
- virtual void anchor();
- public:
- SemaConsumer() {
- ASTConsumer::SemaConsumer = true;
- }
-
- /// \brief 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.
- virtual void ForgetSema() {}
-
- // isa/cast/dyn_cast support
- static bool classof(const ASTConsumer *Consumer) {
- return Consumer->SemaConsumer;
- }
- };
-}
-
-#endif
diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h
deleted file mode 100644
index 7740d5e..0000000
--- a/include/clang/Sema/SemaDiagnostic.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- DiagnosticSema.h - Diagnostics for libsema -------------*- 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_SEMA_SEMADIAGNOSTIC_H
-#define LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define SEMASTART
-#include "clang/Basic/DiagnosticSemaKinds.inc"
-#undef DIAG
- NUM_BUILTIN_SEMA_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/SemaFixItUtils.h b/include/clang/Sema/SemaFixItUtils.h
deleted file mode 100644
index 343ccfb..0000000
--- a/include/clang/Sema/SemaFixItUtils.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===--- SemaFixItUtils.h - Sema FixIts -----------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines helper classes for generation of Sema FixItHints.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_SEMAFIXITUTILS_H
-#define LLVM_CLANG_SEMA_SEMAFIXITUTILS_H
-
-#include "clang/AST/Expr.h"
-
-namespace clang {
-
-enum OverloadFixItKind {
- OFIK_Undefined = 0,
- OFIK_Dereference,
- OFIK_TakeAddress,
- OFIK_RemoveDereference,
- OFIK_RemoveTakeAddress
-};
-
-class Sema;
-
-/// The class facilities generation and storage of conversion FixIts. Hints for
-/// new conversions are added using TryToFixConversion method. The default type
-/// conversion checker can be reset.
-struct ConversionFixItGenerator {
- /// Performs a simple check to see if From type can be converted to To type.
- static bool compareTypesSimple(CanQualType From,
- CanQualType To,
- Sema &S,
- SourceLocation Loc,
- ExprValueKind FromVK);
-
- /// The list of Hints generated so far.
- std::vector<FixItHint> Hints;
-
- /// The number of Conversions fixed. This can be different from the size
- /// of the Hints vector since we allow multiple FixIts per conversion.
- unsigned NumConversionsFixed;
-
- /// The type of fix applied. If multiple conversions are fixed, corresponds
- /// to the kid of the very first conversion.
- OverloadFixItKind Kind;
-
- typedef bool (*TypeComparisonFuncTy) (const CanQualType FromTy,
- const CanQualType ToTy,
- Sema &S,
- SourceLocation Loc,
- ExprValueKind FromVK);
- /// The type comparison function used to decide if expression FromExpr of
- /// type FromTy can be converted to ToTy. For example, one could check if
- /// an implicit conversion exists. Returns true if comparison exists.
- TypeComparisonFuncTy CompareTypes;
-
- ConversionFixItGenerator(TypeComparisonFuncTy Foo): NumConversionsFixed(0),
- Kind(OFIK_Undefined),
- CompareTypes(Foo) {}
-
- ConversionFixItGenerator(): NumConversionsFixed(0),
- Kind(OFIK_Undefined),
- CompareTypes(compareTypesSimple) {}
-
- /// Resets the default conversion checker method.
- void setConversionChecker(TypeComparisonFuncTy Foo) {
- CompareTypes = Foo;
- }
-
- /// If possible, generates and stores a fix for the given conversion.
- bool tryToFixConversion(const Expr *FromExpr,
- const QualType FromQTy, const QualType ToQTy,
- Sema &S);
-
- void clear() {
- Hints.clear();
- NumConversionsFixed = 0;
- }
-
- bool isNull() {
- return (NumConversionsFixed == 0);
- }
-};
-
-} // endof namespace clang
-#endif
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
deleted file mode 100644
index 60c6598..0000000
--- a/include/clang/Sema/SemaInternal.h
+++ /dev/null
@@ -1,346 +0,0 @@
-//===--- SemaInternal.h - Internal Sema Interfaces --------------*- 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 common API and #includes for the internal
-// implementation of Sema.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_SEMAINTERNAL_H
-#define LLVM_CLANG_SEMA_SEMAINTERNAL_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/Sema/Lookup.h"
-#include "clang/Sema/Sema.h"
-#include "clang/Sema/SemaDiagnostic.h"
-
-namespace clang {
-
-inline PartialDiagnostic Sema::PDiag(unsigned DiagID) {
- return PartialDiagnostic(DiagID, Context.getDiagAllocator());
-}
-
-inline bool
-FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI) {
- return FTI.NumParams == 1 && !FTI.isVariadic &&
- FTI.Params[0].Ident == nullptr && FTI.Params[0].Param &&
- cast<ParmVarDecl>(FTI.Params[0].Param)->getType()->isVoidType();
-}
-
-inline bool
-FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI) {
- // Assume FTI is well-formed.
- return FTI.NumParams && !FTIHasSingleVoidParameter(FTI);
-}
-
-// This requires the variable to be non-dependent and the initializer
-// to not be value dependent.
-inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) {
- const VarDecl *DefVD = nullptr;
- return !isa<ParmVarDecl>(Var) &&
- Var->isUsableInConstantExpressions(Context) &&
- Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
-}
-
-// Helper function to check whether D's attributes match current CUDA mode.
-// Decls with mismatched attributes and related diagnostics may have to be
-// ignored during this CUDA compilation pass.
-inline bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D) {
- if (!LangOpts.CUDA || !D)
- return true;
- bool isDeviceSideDecl = D->hasAttr<CUDADeviceAttr>() ||
- D->hasAttr<CUDASharedAttr>() ||
- D->hasAttr<CUDAGlobalAttr>();
- return isDeviceSideDecl == LangOpts.CUDAIsDevice;
-}
-
-// Directly mark a variable odr-used. Given a choice, prefer to use
-// MarkVariableReferenced since it does additional checks and then
-// calls MarkVarDeclODRUsed.
-// If the variable must be captured:
-// - if FunctionScopeIndexToStopAt is null, capture it in the CurContext
-// - else capture it in the DeclContext that maps to the
-// *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.
-inline void MarkVarDeclODRUsed(VarDecl *Var,
- SourceLocation Loc, Sema &SemaRef,
- const unsigned *const FunctionScopeIndexToStopAt) {
- // Keep track of used but undefined variables.
- // FIXME: We shouldn't suppress this warning for static data members.
- if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
- !Var->isExternallyVisible() &&
- !(Var->isStaticDataMember() && Var->hasInit())) {
- SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
- if (old.isInvalid()) old = Loc;
- }
- QualType CaptureType, DeclRefType;
- SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit,
- /*EllipsisLoc*/ SourceLocation(),
- /*BuildAndDiagnose*/ true,
- CaptureType, DeclRefType,
- FunctionScopeIndexToStopAt);
-
- Var->markUsed(SemaRef.Context);
-}
-
-/// Return a DLL attribute from the declaration.
-inline InheritableAttr *getDLLAttr(Decl *D) {
- assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) &&
- "A declaration cannot be both dllimport and dllexport.");
- if (auto *Import = D->getAttr<DLLImportAttr>())
- return Import;
- if (auto *Export = D->getAttr<DLLExportAttr>())
- return Export;
- return nullptr;
-}
-
-class TypoCorrectionConsumer : public VisibleDeclConsumer {
- typedef SmallVector<TypoCorrection, 1> TypoResultList;
- typedef llvm::StringMap<TypoResultList> TypoResultsMap;
- typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
-
-public:
- TypoCorrectionConsumer(Sema &SemaRef,
- const DeclarationNameInfo &TypoName,
- Sema::LookupNameKind LookupKind,
- Scope *S, CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
- DeclContext *MemberContext,
- bool EnteringContext)
- : Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0),
- SavedTCIndex(0), SemaRef(SemaRef), S(S),
- SS(SS ? llvm::make_unique<CXXScopeSpec>(*SS) : nullptr),
- CorrectionValidator(std::move(CCC)), MemberContext(MemberContext),
- Result(SemaRef, TypoName, LookupKind),
- Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
- EnteringContext(EnteringContext), SearchNamespaces(false) {
- Result.suppressDiagnostics();
- // Arrange for ValidatedCorrections[0] to always be an empty correction.
- ValidatedCorrections.push_back(TypoCorrection());
- }
-
- bool includeHiddenDecls() const override { return true; }
-
- // Methods for adding potential corrections to the consumer.
- void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
- bool InBaseClass) override;
- void FoundName(StringRef Name);
- void addKeywordResult(StringRef Keyword);
- void addCorrection(TypoCorrection Correction);
-
- bool empty() const {
- return CorrectionResults.empty() && ValidatedCorrections.size() == 1;
- }
-
- /// \brief 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
- /// closest/best edit distance from the original typop.
- unsigned getBestEditDistance(bool Normalized) {
- if (CorrectionResults.empty())
- return (std::numeric_limits<unsigned>::max)();
-
- unsigned BestED = CorrectionResults.begin()->first;
- return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
- }
-
- /// \brief 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
- /// 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().
- const TypoCorrection &getCurrentCorrection() {
- return CurrentTCIndex < ValidatedCorrections.size()
- ? ValidatedCorrections[CurrentTCIndex]
- : ValidatedCorrections[0]; // The empty correction.
- }
-
- /// \brief 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).
- const TypoCorrection &peekNextCorrection() {
- auto Current = CurrentTCIndex;
- const TypoCorrection &TC = getNextCorrection();
- CurrentTCIndex = Current;
- return TC;
- }
-
- /// \brief 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
- /// reached.
- bool finished() {
- return CorrectionResults.empty() &&
- CurrentTCIndex >= ValidatedCorrections.size();
- }
-
- /// \brief 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.
- void restoreSavedPosition() {
- CurrentTCIndex = SavedTCIndex;
- }
-
- ASTContext &getContext() const { return SemaRef.Context; }
- const LookupResult &getLookupResult() const { return Result; }
-
- bool isAddressOfOperand() const { return CorrectionValidator->IsAddressOfOperand; }
- const CXXScopeSpec *getSS() const { return SS.get(); }
- Scope *getScope() const { return S; }
-
-private:
- class NamespaceSpecifierSet {
- struct SpecifierInfo {
- DeclContext* DeclCtx;
- NestedNameSpecifier* NameSpecifier;
- unsigned EditDistance;
- };
-
- typedef SmallVector<DeclContext*, 4> DeclContextList;
- typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
-
- ASTContext &Context;
- DeclContextList CurContextChain;
- std::string CurNameSpecifier;
- SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
- SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
-
- std::map<unsigned, SpecifierInfoList> DistanceMap;
-
- /// \brief Helper for building the list of DeclContexts between the current
- /// context and the top of the translation unit
- static DeclContextList buildContextChain(DeclContext *Start);
-
- unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
- NestedNameSpecifier *&NNS);
-
- public:
- NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
- CXXScopeSpec *CurScopeSpec);
-
- /// \brief 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.
- class iterator
- : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
- SpecifierInfo> {
- /// Always points to the last element in the distance map.
- const std::map<unsigned, SpecifierInfoList>::iterator OuterBack;
- /// Iterator on the distance map.
- std::map<unsigned, SpecifierInfoList>::iterator Outer;
- /// Iterator on an element in the distance map.
- SpecifierInfoList::iterator Inner;
-
- public:
- iterator(NamespaceSpecifierSet &Set, bool IsAtEnd)
- : OuterBack(std::prev(Set.DistanceMap.end())),
- Outer(Set.DistanceMap.begin()),
- Inner(!IsAtEnd ? Outer->second.begin() : OuterBack->second.end()) {
- assert(!Set.DistanceMap.empty());
- }
-
- iterator &operator++() {
- ++Inner;
- if (Inner == Outer->second.end() && Outer != OuterBack) {
- ++Outer;
- Inner = Outer->second.begin();
- }
- return *this;
- }
-
- SpecifierInfo &operator*() { return *Inner; }
- bool operator==(const iterator &RHS) const { return Inner == RHS.Inner; }
- };
-
- iterator begin() { return iterator(*this, /*IsAtEnd=*/false); }
- iterator end() { return iterator(*this, /*IsAtEnd=*/true); }
- };
-
- void addName(StringRef Name, NamedDecl *ND,
- NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
-
- /// \brief 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
- /// 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.
- IdentifierInfo *Typo;
-
- /// \brief 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
- /// whether there is a keyword with this name.
- TypoEditDistanceMap CorrectionResults;
-
- SmallVector<TypoCorrection, 4> ValidatedCorrections;
- size_t CurrentTCIndex;
- size_t SavedTCIndex;
-
- Sema &SemaRef;
- Scope *S;
- std::unique_ptr<CXXScopeSpec> SS;
- std::unique_ptr<CorrectionCandidateCallback> CorrectionValidator;
- DeclContext *MemberContext;
- LookupResult Result;
- NamespaceSpecifierSet Namespaces;
- SmallVector<TypoCorrection, 2> QualifiedResults;
- bool EnteringContext;
- bool SearchNamespaces;
-};
-
-inline Sema::TypoExprState::TypoExprState() {}
-
-inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) LLVM_NOEXCEPT {
- *this = std::move(other);
-}
-
-inline Sema::TypoExprState &Sema::TypoExprState::operator=(
- Sema::TypoExprState &&other) LLVM_NOEXCEPT {
- Consumer = std::move(other.Consumer);
- DiagHandler = std::move(other.DiagHandler);
- RecoveryHandler = std::move(other.RecoveryHandler);
- return *this;
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h
deleted file mode 100644
index d043e2c..0000000
--- a/include/clang/Sema/SemaLambda.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===--- SemaLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file 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 {
-
-
-/// \brief 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
-/// of the capture-capable lambda's LambdaScopeInfo.
-/// See Implementation for more detailed comments.
-
-Optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda(
- ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes,
- VarDecl *VarToCapture, Sema &S);
-
-} // clang
-
-#endif
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
deleted file mode 100644
index c092630..0000000
--- a/include/clang/Sema/Template.h
+++ /dev/null
@@ -1,519 +0,0 @@
-//===------- 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.
-//
-//===----------------------------------------------------------------------===/
-#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
-#define LLVM_CLANG_SEMA_TEMPLATE_H
-
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/Sema/Sema.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-#include <utility>
-
-namespace clang {
- /// \brief Data structure that captures multiple levels of template argument
- /// lists for use in template instantiation.
- ///
- /// Multiple levels of template arguments occur when instantiating the
- /// definitions of member templates. For example:
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<T Value>
- /// struct Y {
- /// void f();
- /// };
- /// };
- /// \endcode
- ///
- /// When instantiating X<int>::Y<17>::f, the multi-level template argument
- /// 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;
-
- /// \brief The template argument lists, stored from the innermost template
- /// argument list (first) to the outermost template argument list (last).
- SmallVector<ArgList, 4> TemplateArgumentLists;
-
- public:
- /// \brief Construct an empty set of template argument lists.
- MultiLevelTemplateArgumentList() { }
-
- /// \brief Construct a single-level template argument list.
- explicit
- MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
- addOuterTemplateArguments(&TemplateArgs);
- }
-
- /// \brief Determine the number of levels in this template argument
- /// list.
- unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
-
- /// \brief Retrieve the template argument at a given depth and index.
- const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
- assert(Depth < TemplateArgumentLists.size());
- 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
- /// given depth and index.
- ///
- /// There must exist a template argument list at the given depth.
- bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
- assert(Depth < TemplateArgumentLists.size());
-
- if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
- return false;
-
- return !(*this)(Depth, Index).isNull();
- }
-
- /// \brief Clear out a specific template argument.
- void setArgument(unsigned Depth, unsigned Index,
- TemplateArgument Arg) {
- assert(Depth < TemplateArgumentLists.size());
- assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
- const_cast<TemplateArgument&>(
- TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
- = Arg;
- }
-
- /// \brief 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
- /// list.
- void addOuterTemplateArguments(ArgList Args) {
- TemplateArgumentLists.push_back(Args);
- }
-
- /// \brief Retrieve the innermost template argument list.
- const ArgList &getInnermost() const {
- return TemplateArgumentLists.front();
- }
- };
-
- /// \brief The context in which partial ordering of function templates occurs.
- enum TPOC {
- /// \brief Partial ordering of function templates for a function call.
- TPOC_Call,
- /// \brief 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.,
- /// taking the address of a function template or matching a function
- /// template specialization to a function template.
- TPOC_Other
- };
-
- // This is lame but unavoidable in a world without forward
- // declarations of enums. The alternatives are to either pollute
- // Sema.h (by including this file) or sacrifice type safety (by
- // 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
- /// via c++ template argument deduction.
- class DeducedTemplateArgument : public TemplateArgument {
- /// \brief For a non-type template argument, whether the value was
- /// deduced from an array bound.
- bool DeducedFromArrayBound;
-
- public:
- DeducedTemplateArgument()
- : TemplateArgument(), DeducedFromArrayBound(false) { }
-
- DeducedTemplateArgument(const TemplateArgument &Arg,
- bool DeducedFromArrayBound = false)
- : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
-
- /// \brief 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) { }
-
- /// \brief 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
- /// was deduced from an array bound.
- void setDeducedFromArrayBound(bool Deduced) {
- DeducedFromArrayBound = Deduced;
- }
- };
-
- /// \brief 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
- /// instantiate a new function declaration, which will have its own
- /// set of parameter declarations.
- class LocalInstantiationScope {
- public:
- /// \brief A set of declarations.
- typedef SmallVector<ParmVarDecl *, 4> DeclArgumentPack;
-
- private:
- /// \brief Reference to the semantic analysis that is performing
- /// this template instantiation.
- Sema &SemaRef;
-
- typedef llvm::SmallDenseMap<
- const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>
- LocalDeclsMap;
-
- /// \brief A mapping from local declarations that occur
- /// within a template to their instantiations.
- ///
- /// This mapping is used during instantiation to keep track of,
- /// e.g., function parameter and variable declarations. For example,
- /// given:
- ///
- /// \code
- /// template<typename T> T add(T x, T y) { return x + y; }
- /// \endcode
- ///
- /// when we instantiate add<int>, we will introduce a mapping from
- /// the ParmVarDecl for 'x' that occurs in the template to the
- /// instantiated ParmVarDecl for 'x'.
- ///
- /// For a parameter pack, the local instantiation scope may contain a
- /// set of instantiated parameters. This is stored as a DeclArgumentPack
- /// pointer.
- LocalDeclsMap LocalDecls;
-
- /// \brief The set of argument packs we've allocated.
- SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
-
- /// \brief 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;
-
- /// \brief 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
- /// partially substituted per C++0x [temp.arg.explicit]p9.
- NamedDecl *PartiallySubstitutedPack;
-
- /// \brief 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
- /// 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.CurrentInstantiationScope = this;
- }
-
- ~LocalInstantiationScope() {
- Exit();
- }
-
- const Sema &getSema() const { return SemaRef; }
-
- /// \brief Exit this local instantiation scope early.
- void Exit() {
- if (Exited)
- return;
-
- for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
- delete ArgumentPacks[I];
-
- SemaRef.CurrentInstantiationScope = Outer;
- Exited = true;
- }
-
- /// \brief Clone this scope, and all outer scopes, down to the given
- /// outermost scope.
- LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
- if (this == Outermost) return this;
-
- // Save the current scope from SemaRef since the LocalInstantiationScope
- // will overwrite it on construction
- LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope;
-
- LocalInstantiationScope *newScope =
- new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
-
- newScope->Outer = nullptr;
- if (Outer)
- newScope->Outer = Outer->cloneScopes(Outermost);
-
- newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
- newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
- newScope->NumArgsInPartiallySubstitutedPack =
- NumArgsInPartiallySubstitutedPack;
-
- for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
- I != E; ++I) {
- const Decl *D = I->first;
- llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
- newScope->LocalDecls[D];
- if (I->second.is<Decl *>()) {
- Stored = I->second.get<Decl *>();
- } else {
- DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
- DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
- Stored = NewPack;
- newScope->ArgumentPacks.push_back(NewPack);
- }
- }
- // Restore the saved scope to SemaRef
- SemaRef.CurrentInstantiationScope = oldScope;
- return newScope;
- }
-
- /// \brief deletes the given scope, and all otuer scopes, down to the
- /// given outermost scope.
- static void deleteScopes(LocalInstantiationScope *Scope,
- LocalInstantiationScope *Outermost) {
- while (Scope && Scope != Outermost) {
- LocalInstantiationScope *Out = Scope->Outer;
- delete Scope;
- Scope = Out;
- }
- }
-
- /// \brief Find the instantiation of the declaration D within the current
- /// instantiation scope.
- ///
- /// \param D The declaration whose instantiation we are searching for.
- ///
- /// \returns A pointer to the declaration or argument pack of declarations
- /// to which the declaration \c D is instantiated, if found. Otherwise,
- /// returns NULL.
- llvm::PointerUnion<Decl *, DeclArgumentPack *> *
- findInstantiationOf(const Decl *D);
-
- void InstantiatedLocal(const Decl *D, Decl *Inst);
- void InstantiatedLocalPackArg(const Decl *D, ParmVarDecl *Inst);
- void MakeInstantiatedLocalArgPack(const Decl *D);
-
- /// \brief Note that the given parameter pack has been partially substituted
- /// via explicit specification of template arguments
- /// (C++0x [temp.arg.explicit]p9).
- ///
- /// \param Pack The parameter pack, which will always be a template
- /// parameter pack.
- ///
- /// \param ExplicitArgs The explicitly-specified template arguments provided
- /// for this parameter pack.
- ///
- /// \param NumExplicitArgs The number of explicitly-specified template
- /// arguments provided for this parameter pack.
- void SetPartiallySubstitutedPack(NamedDecl *Pack,
- const TemplateArgument *ExplicitArgs,
- unsigned NumExplicitArgs);
-
- /// \brief Reset the partially-substituted pack when it is no longer of
- /// interest.
- void ResetPartiallySubstitutedPack() {
- assert(PartiallySubstitutedPack && "No partially-substituted pack");
- PartiallySubstitutedPack = nullptr;
- ArgsInPartiallySubstitutedPack = nullptr;
- NumArgsInPartiallySubstitutedPack = 0;
- }
-
- /// \brief Retrieve the partially-substitued template parameter pack.
- ///
- /// If there is no partially-substituted parameter pack, returns NULL.
- NamedDecl *
- getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
- unsigned *NumExplicitArgs = nullptr) const;
- };
-
- class TemplateDeclInstantiator
- : public DeclVisitor<TemplateDeclInstantiator, Decl *>
- {
- Sema &SemaRef;
- Sema::ArgumentPackSubstitutionIndexRAII SubstIndex;
- DeclContext *Owner;
- const MultiLevelTemplateArgumentList &TemplateArgs;
- Sema::LateInstantiatedAttrVec* LateAttrs;
- LocalInstantiationScope *StartingScope;
-
- /// \brief 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
- /// specializations that will need to be instantiated after the
- /// enclosing variable's instantiation is complete.
- /// FIXME: Verify that this is needed.
- SmallVector<
- std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
- OutOfLineVarPartialSpecs;
-
- public:
- TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
- const MultiLevelTemplateArgumentList &TemplateArgs)
- : SemaRef(SemaRef),
- SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
- Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(nullptr),
- StartingScope(nullptr) {}
-
-// Define all the decl visitors using DeclNodes.inc
-#define DECL(DERIVED, BASE) \
- Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
-#define ABSTRACT_DECL(DECL)
-
-// Decls which never appear inside a class or function.
-#define OBJCCONTAINER(DERIVED, BASE)
-#define FILESCOPEASM(DERIVED, BASE)
-#define IMPORT(DERIVED, BASE)
-#define LINKAGESPEC(DERIVED, BASE)
-#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
-#define OBJCMETHOD(DERIVED, BASE)
-#define OBJCTYPEPARAM(DERIVED, BASE)
-#define OBJCIVAR(DERIVED, BASE)
-#define OBJCPROPERTY(DERIVED, BASE)
-#define OBJCPROPERTYIMPL(DERIVED, BASE)
-#define EMPTY(DERIVED, BASE)
-
-// Decls which use special-case instantiation code.
-#define BLOCK(DERIVED, BASE)
-#define CAPTURED(DERIVED, BASE)
-#define IMPLICITPARAM(DERIVED, BASE)
-
-#include "clang/AST/DeclNodes.inc"
-
- // A few supplemental visitor functions.
- Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
- TemplateParameterList *TemplateParams,
- bool IsClassScopeSpecialization = false);
- Decl *VisitFunctionDecl(FunctionDecl *D,
- TemplateParameterList *TemplateParams);
- Decl *VisitDecl(Decl *D);
- Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate);
-
- // Enable late instantiation of attributes. Late instantiated attributes
- // will be stored in LA.
- void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
- LateAttrs = LA;
- StartingScope = SemaRef.CurrentInstantiationScope;
- }
-
- // Disable late instantiation of attributes.
- void disableLateAttributeInstantiation() {
- LateAttrs = nullptr;
- StartingScope = nullptr;
- }
-
- LocalInstantiationScope *getStartingScope() const { return StartingScope; }
-
- typedef
- SmallVectorImpl<std::pair<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *> >
- ::iterator
- delayed_partial_spec_iterator;
-
- typedef SmallVectorImpl<std::pair<
- VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator
- delayed_var_partial_spec_iterator;
-
- /// \brief 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.
- delayed_partial_spec_iterator delayed_partial_spec_begin() {
- return OutOfLinePartialSpecs.begin();
- }
-
- delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
- return OutOfLineVarPartialSpecs.begin();
- }
-
- /// \brief 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.
- delayed_partial_spec_iterator delayed_partial_spec_end() {
- return OutOfLinePartialSpecs.end();
- }
-
- delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
- return OutOfLineVarPartialSpecs.end();
- }
-
- // Helper functions for instantiating methods.
- TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
- SmallVectorImpl<ParmVarDecl *> &Params);
- bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
- bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
-
- TemplateParameterList *
- SubstTemplateParams(TemplateParameterList *List);
-
- bool SubstQualifier(const DeclaratorDecl *OldDecl,
- DeclaratorDecl *NewDecl);
- bool SubstQualifier(const TagDecl *OldDecl,
- TagDecl *NewDecl);
-
- Decl *VisitVarTemplateSpecializationDecl(
- VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
- const TemplateArgumentListInfo &TemplateArgsInfo,
- ArrayRef<TemplateArgument> Converted);
-
- Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
- ClassTemplatePartialSpecializationDecl *
- InstantiateClassTemplatePartialSpecialization(
- ClassTemplateDecl *ClassTemplate,
- ClassTemplatePartialSpecializationDecl *PartialSpec);
- VarTemplatePartialSpecializationDecl *
- InstantiateVarTemplatePartialSpecialization(
- VarTemplateDecl *VarTemplate,
- VarTemplatePartialSpecializationDecl *PartialSpec);
- void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
- };
-}
-
-#endif // LLVM_CLANG_SEMA_TEMPLATE_H
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
deleted file mode 100644
index c22c703..0000000
--- a/include/clang/Sema/TemplateDeduction.h
+++ /dev/null
@@ -1,315 +0,0 @@
-//===- 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
-// routines.
-//
-//===----------------------------------------------------------------------===/
-#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
-#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
-
-#include "clang/AST/DeclTemplate.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-struct DeducedPack;
-class TemplateArgumentList;
-class Sema;
-
-namespace sema {
-
-/// \brief 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;
-
- /// \brief The source location at which template argument
- /// deduction is occurring.
- SourceLocation Loc;
-
- /// \brief Have we suppressed an error during deduction?
- bool HasSFINAEDiagnostic;
-
- /// \brief 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)
- : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
- Expression(nullptr) {}
-
- /// \brief Returns the location at which template argument is
- /// occurring.
- SourceLocation getLocation() const {
- return Loc;
- }
-
- /// \brief Take ownership of the deduced template argument list.
- TemplateArgumentList *take() {
- TemplateArgumentList *Result = Deduced;
- Deduced = nullptr;
- return Result;
- }
-
- /// \brief Take ownership of the SFINAE diagnostic.
- void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
- assert(HasSFINAEDiagnostic);
- PD.first = SuppressedDiagnostics.front().first;
- PD.second.swap(SuppressedDiagnostics.front().second);
- SuppressedDiagnostics.clear();
- HasSFINAEDiagnostic = false;
- }
-
- /// \brief 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?
- bool hasSFINAEDiagnostic() const {
- return HasSFINAEDiagnostic;
- }
-
- /// \brief Set the diagnostic which caused the SFINAE failure.
- void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
- // Only collect the first diagnostic.
- if (HasSFINAEDiagnostic)
- return;
- SuppressedDiagnostics.clear();
- SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
- HasSFINAEDiagnostic = true;
- }
-
- /// \brief Add a new diagnostic to the set of diagnostics
- void addSuppressedDiagnostic(SourceLocation Loc,
- PartialDiagnostic PD) {
- if (HasSFINAEDiagnostic)
- return;
- SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
- }
-
- /// \brief Iterator over the set of suppressed diagnostics.
- typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
- diag_iterator;
-
- /// \brief 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
- /// diagnostics.
- diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
-
- /// \brief The template parameter to which a template argument
- /// deduction failure refers.
- ///
- /// Depending on the result of template argument deduction, this
- /// template parameter may have different meanings:
- ///
- /// TDK_Incomplete: this is the first template parameter whose
- /// corresponding template argument was not deduced.
- ///
- /// 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
- /// argument deduction failure refers.
- ///
- /// Depending on the result of the template argument deduction,
- /// this template argument may have different meanings:
- ///
- /// TDK_Inconsistent: this argument is the first value deduced
- /// for the corresponding template parameter.
- ///
- /// TDK_SubstitutionFailure: this argument is the template
- /// argument we were instantiating when we encountered an error.
- ///
- /// TDK_DeducedMismatch: this is the parameter type, after substituting
- /// deduced arguments.
- ///
- /// TDK_NonDeducedMismatch: this is the component of the 'parameter'
- /// of the deduction, directly provided in the source code.
- TemplateArgument FirstArg;
-
- /// \brief The second template argument to which the template
- /// argument deduction failure refers.
- ///
- /// TDK_Inconsistent: this argument is the second value deduced
- /// for the corresponding template parameter.
- ///
- /// TDK_DeducedMismatch: this is the (adjusted) call argument type.
- ///
- /// TDK_NonDeducedMismatch: this is the mismatching component of the
- /// 'argument' of the deduction, from which we are deducing arguments.
- ///
- /// FIXME: Finish documenting this.
- TemplateArgument SecondArg;
-
- union {
- /// \brief The expression which caused a deduction failure.
- ///
- /// TDK_FailedOverloadResolution: this argument is the reference to
- /// an overloaded function which could not be resolved to a specific
- /// function.
- Expr *Expression;
-
- /// \brief 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;
- };
-
- /// \brief Information on packs that we're currently expanding.
- ///
- /// FIXME: This should be kept internal to SemaTemplateDeduction.
- SmallVector<DeducedPack *, 8> PendingDeducedPacks;
-};
-
-} // end namespace sema
-
-/// A structure used to record information about a failed
-/// template argument deduction, for diagnosis.
-struct DeductionFailureInfo {
- /// A Sema::TemplateDeductionResult.
- unsigned Result : 8;
-
- /// \brief Indicates whether a diagnostic is stored in Diagnostic.
- unsigned HasDiagnostic : 1;
-
- /// \brief Opaque pointer containing additional data about
- /// this deduction failure.
- void *Data;
-
- /// \brief A diagnostic indicating why deduction failed.
- union {
- void *Align;
- char Diagnostic[sizeof(PartialDiagnosticAt)];
- };
-
- /// \brief Retrieve the diagnostic which caused this deduction failure,
- /// if any.
- PartialDiagnosticAt *getSFINAEDiagnostic();
-
- /// \brief Retrieve the template parameter this deduction failure
- /// refers to, if any.
- TemplateParameter getTemplateParameter();
-
- /// \brief Retrieve the template argument list associated with this
- /// deduction failure, if any.
- TemplateArgumentList *getTemplateArgumentList();
-
- /// \brief Return the first template argument this deduction failure
- /// refers to, if any.
- const TemplateArgument *getFirstArg();
-
- /// \brief Return the second template argument this deduction failure
- /// refers to, if any.
- const TemplateArgument *getSecondArg();
-
- /// \brief Return the expression this deduction failure refers to,
- /// if any.
- Expr *getExpr();
-
- /// \brief 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.
- void Destroy();
-};
-
-/// TemplateSpecCandidate - This is a generalization of OverloadCandidate
-/// which keeps track of template argument deduction failure info, when
-/// handling explicit specializations (and instantiations) of templates
-/// beyond function overloading.
-/// For now, assume that the candidates are non-matching specializations.
-/// TODO: In the future, we may need to unify/generalize this with
-/// OverloadCandidate.
-struct TemplateSpecCandidate {
- /// Specialization - The actual specialization that this candidate
- /// represents. When NULL, this may be a built-in candidate.
- Decl *Specialization;
-
- /// Template argument deduction info
- DeductionFailureInfo DeductionFailure;
-
- void set(Decl *Spec, DeductionFailureInfo Info) {
- Specialization = Spec;
- DeductionFailure = Info;
- }
-
- /// Diagnose a template argument deduction failure.
- void NoteDeductionFailure(Sema &S, bool ForTakingAddress);
-};
-
-/// TemplateSpecCandidateSet - A set of generalized overload candidates,
-/// used in template specializations.
-/// TODO: In the future, we may need to unify/generalize this with
-/// OverloadCandidateSet.
-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() { destroyCandidates(); }
-
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Clear out all of the candidates.
- /// TODO: This may be unnecessary.
- void clear();
-
- typedef SmallVector<TemplateSpecCandidate, 16>::iterator 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
- /// to the overload set.
- TemplateSpecCandidate &addCandidate() {
- Candidates.emplace_back();
- return Candidates.back();
- }
-
- void NoteCandidates(Sema &S, SourceLocation Loc);
-
- void NoteCandidates(Sema &S, SourceLocation Loc) const {
- const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
deleted file mode 100644
index 3b0385e..0000000
--- a/include/clang/Sema/TypoCorrection.h
+++ /dev/null
@@ -1,366 +0,0 @@
-//===--- TypoCorrection.h - Class for typo correction results ---*- 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 TypoCorrection class, which stores the results of
-// Sema's typo correction (Sema::CorrectTypo).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H
-#define LLVM_CLANG_SEMA_TYPOCORRECTION_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/Ownership.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-/// @brief Simple class containing the result of Sema::CorrectTypo
-class TypoCorrection {
-public:
- // "Distance" for unusable corrections
- static const unsigned InvalidDistance = ~0U;
- // The largest distance still considered valid (larger edit distances are
- // mapped to InvalidDistance by getEditDistance).
- static const unsigned MaximumDistance = 10000U;
-
- // Relative weightings of the "edit distance" components. The higher the
- // weight, the more of a penalty to fitness the component will give (higher
- // weights mean greater contribution to the total edit distance, with the
- // best correction candidates having the lowest edit distance).
- static const unsigned CharDistanceWeight = 100U;
- static const unsigned QualifierDistanceWeight = 110U;
- static const unsigned CallbackDistanceWeight = 150U;
-
- TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl,
- NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0,
- unsigned QualifierDistance = 0)
- : CorrectionName(Name), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(QualifierDistance),
- CallbackDistance(0), ForceSpecifierReplacement(false),
- RequiresImport(false) {
- if (NameDecl)
- CorrectionDecls.push_back(NameDecl);
- }
-
- TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr,
- unsigned CharDistance = 0)
- : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
- ForceSpecifierReplacement(false), RequiresImport(false) {
- if (Name)
- CorrectionDecls.push_back(Name);
- }
-
- TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr,
- unsigned CharDistance = 0)
- : CorrectionName(Name), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
- ForceSpecifierReplacement(false), RequiresImport(false) {}
-
- TypoCorrection()
- : CorrectionNameSpec(nullptr), CharDistance(0), QualifierDistance(0),
- CallbackDistance(0), ForceSpecifierReplacement(false),
- RequiresImport(false) {}
-
- /// \brief 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
- NestedNameSpecifier *getCorrectionSpecifier() const {
- return CorrectionNameSpec;
- }
- void setCorrectionSpecifier(NestedNameSpecifier *NNS) {
- CorrectionNameSpec = NNS;
- ForceSpecifierReplacement = (NNS != nullptr);
- }
-
- void WillReplaceSpecifier(bool ForceReplacement) {
- ForceSpecifierReplacement = ForceReplacement;
- }
-
- bool WillReplaceSpecifier() const {
- return ForceSpecifierReplacement;
- }
-
- void setQualifierDistance(unsigned ED) {
- QualifierDistance = ED;
- }
-
- void setCallbackDistance(unsigned ED) {
- CallbackDistance = ED;
- }
-
- // Convert the given weighted edit distance to a roughly equivalent number of
- // single-character edits (typically for comparison to the length of the
- // string being edited).
- static unsigned NormalizeEditDistance(unsigned ED) {
- if (ED > MaximumDistance)
- return InvalidDistance;
- return (ED + CharDistanceWeight / 2) / CharDistanceWeight;
- }
-
- /// \brief 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 {
- if (CharDistance > MaximumDistance || QualifierDistance > MaximumDistance ||
- CallbackDistance > MaximumDistance)
- return InvalidDistance;
- unsigned ED =
- CharDistance * CharDistanceWeight +
- QualifierDistance * QualifierDistanceWeight +
- CallbackDistance * CallbackDistanceWeight;
- if (ED > MaximumDistance)
- return InvalidDistance;
- // Half the CharDistanceWeight is added to ED to simulate rounding since
- // integer division truncates the value (i.e. round-to-nearest-int instead
- // of round-to-zero).
- return Normalized ? NormalizeEditDistance(ED) : ED;
- }
-
- /// \brief 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
- NamedDecl *getCorrectionDecl() const {
- auto *D = getFoundDecl();
- return D ? D->getUnderlyingDecl() : nullptr;
- }
- template <class DeclClass>
- DeclClass *getCorrectionDeclAs() const {
- return dyn_cast_or_null<DeclClass>(getCorrectionDecl());
- }
-
- /// \brief Clears the list of NamedDecls.
- void ClearCorrectionDecls() {
- CorrectionDecls.clear();
- }
-
- /// \brief 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.
- 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
- /// 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
- explicit operator bool() const { return bool(CorrectionName); }
-
- /// \brief 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.
- void makeKeyword() {
- CorrectionDecls.clear();
- CorrectionDecls.push_back(nullptr);
- ForceSpecifierReplacement = true;
- }
-
- // Check if this TypoCorrection is a keyword by checking if the first
- // item in CorrectionDecls is NULL.
- bool isKeyword() const {
- return !CorrectionDecls.empty() && CorrectionDecls.front() == nullptr;
- }
-
- // Check if this TypoCorrection is the given keyword.
- template<std::size_t StrLen>
- bool isKeyword(const char (&Str)[StrLen]) const {
- return isKeyword() && getCorrectionAsIdentifierInfo()->isStr(Str);
- }
-
- // Returns true if the correction either is a keyword or has a known decl.
- bool isResolved() const { return !CorrectionDecls.empty(); }
-
- bool isOverloaded() const {
- return CorrectionDecls.size() > 1;
- }
-
- void setCorrectionRange(CXXScopeSpec *SS,
- const DeclarationNameInfo &TypoName) {
- CorrectionRange = TypoName.getSourceRange();
- if (ForceSpecifierReplacement && SS && !SS->isEmpty())
- CorrectionRange.setBegin(SS->getBeginLoc());
- }
-
- SourceRange getCorrectionRange() const {
- return CorrectionRange;
- }
-
- typedef SmallVectorImpl<NamedDecl *>::iterator decl_iterator;
- decl_iterator begin() {
- return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
- }
- decl_iterator end() { return CorrectionDecls.end(); }
- typedef SmallVectorImpl<NamedDecl *>::const_iterator const_decl_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
- /// declaration that was declared in a module that has not been imported.
- bool requiresImport() const { return RequiresImport; }
- void setRequiresImport(bool Req) { RequiresImport = Req; }
-
-private:
- bool hasCorrectionDecl() const {
- return (!isKeyword() && !CorrectionDecls.empty());
- }
-
- // Results.
- DeclarationName CorrectionName;
- NestedNameSpecifier *CorrectionNameSpec;
- SmallVector<NamedDecl *, 1> CorrectionDecls;
- unsigned CharDistance;
- unsigned QualifierDistance;
- unsigned CallbackDistance;
- SourceRange CorrectionRange;
- bool ForceSpecifierReplacement;
- bool RequiresImport;
-};
-
-/// @brief Base class for callback objects used by Sema::CorrectTypo to check
-/// the validity of a potential typo correction.
-class CorrectionCandidateCallback {
-public:
- static const unsigned InvalidDistance = TypoCorrection::InvalidDistance;
-
- 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) {}
-
- virtual ~CorrectionCandidateCallback() {}
-
- /// \brief 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
- /// candidate is viable, without ranking potentially viable candidates.
- /// Only ValidateCandidate or RankCandidate need to be overriden 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
- /// for keywords if WantTypeSpecifiers, WantExpressionKeywords,
- /// WantCXXNamedCasts, WantRemainingKeywords, or WantObjCSuper is true.
- virtual bool ValidateCandidate(const TypoCorrection &candidate);
-
- /// \brief 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,
- /// the default RankCandidate returns either 0 or InvalidDistance depending
- /// whether ValidateCandidate returns true or false.
- virtual unsigned RankCandidate(const TypoCorrection &candidate) {
- return (!MatchesTypo(candidate) && ValidateCandidate(candidate))
- ? 0
- : InvalidDistance;
- }
-
- void setTypoName(IdentifierInfo *II) { Typo = II; }
- void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; }
-
- // 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;
- // Temporary hack for the one case where a CorrectTypoContext enum is used
- // when looking up results.
- bool IsObjCIvarLookup;
- bool IsAddressOfOperand;
-
-protected:
- bool MatchesTypo(const TypoCorrection &candidate) {
- return Typo && candidate.isResolved() && !candidate.requiresImport() &&
- candidate.getCorrectionAsIdentifierInfo() == Typo &&
- // FIXME: This probably does not return true when both
- // NestedNameSpecifiers have the same textual representation.
- candidate.getCorrectionSpecifier() == TypoNNS;
- }
-
- IdentifierInfo *Typo;
- NestedNameSpecifier *TypoNNS;
-};
-
-/// @brief 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 {
-public:
- bool ValidateCandidate(const TypoCorrection &candidate) override {
- return candidate.getCorrectionDeclAs<C>();
- }
-};
-
-// @brief 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 {
-public:
- FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
- bool HasExplicitTemplateArgs,
- MemberExpr *ME = nullptr);
-
- bool ValidateCandidate(const TypoCorrection &candidate) override;
-
- private:
- unsigned NumArgs;
- bool HasExplicitTemplateArgs;
- DeclContext *CurContext;
- MemberExpr *MemberFn;
-};
-
-// @brief Callback class that effectively disabled typo correction
-class NoTypoCorrectionCCC : public CorrectionCandidateCallback {
-public:
- NoTypoCorrectionCCC() {
- WantTypeSpecifiers = false;
- WantExpressionKeywords = false;
- WantCXXNamedCasts = false;
- WantFunctionLikeCasts = false;
- WantRemainingKeywords = false;
- }
-
- bool ValidateCandidate(const TypoCorrection &candidate) override {
- return false;
- }
-};
-
-}
-
-#endif
diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h
deleted file mode 100644
index 9c7212e..0000000
--- a/include/clang/Sema/Weak.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- 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 WeakInfo class, which is used to store
-// information about the target of a #pragma weak directive.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_WEAK_H
-#define LLVM_CLANG_SEMA_WEAK_H
-
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-class IdentifierInfo;
-
-/// \brief Captures information about a \#pragma weak directive.
-class WeakInfo {
- IdentifierInfo *alias; // alias (optional)
- SourceLocation loc; // for diagnostics
- bool used; // identifier later declared?
-public:
- WeakInfo()
- : alias(nullptr), loc(SourceLocation()), used(false) {}
- WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
- : alias(Alias), loc(Loc), used(false) {}
- inline IdentifierInfo * getAlias() const { return alias; }
- inline SourceLocation getLocation() const { return loc; }
- void setUsed(bool Used=true) { used = Used; }
- inline bool getUsed() { return used; }
- bool operator==(WeakInfo RHS) const {
- return alias == RHS.getAlias() && loc == RHS.getLocation();
- }
- bool operator!=(WeakInfo RHS) const { return !(*this == RHS); }
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_WEAK_H
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
deleted file mode 100644
index 16bda6e..0000000
--- a/include/clang/Serialization/ASTBitCodes.h
+++ /dev/null
@@ -1,1605 +0,0 @@
-//===- ASTBitCodes.h - Enum values for the PCH bitcode format ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header defines Bitcode enum values for Clang serialized AST files.
-//
-// The enum values defined in this file should be considered permanent. If
-// new features are added, they should have values added at the end of the
-// respective lists.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
-#define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
-
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Type.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Bitcode/BitCodes.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace clang {
- namespace serialization {
- /// \brief AST file major version number supported by this version of
- /// Clang.
- ///
- /// Whenever the AST file format changes in a way that makes it
- /// incompatible with previous versions (such that a reader
- /// designed for the previous version could not support reading
- /// the new version), this number should be increased.
- ///
- /// 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;
-
- /// \brief AST file minor version number supported by this version of
- /// Clang.
- ///
- /// Whenever the AST format changes in a way that is still
- /// compatible with previous versions (such that a reader designed
- /// for the previous version could still support reading the new
- /// version by ignoring new kinds of subblocks), this number
- /// should be increased.
- const unsigned VERSION_MINOR = 0;
-
- /// \brief 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.
- typedef uint32_t IdentifierID;
-
- /// \brief 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.
- /// At the start of a chain of precompiled headers, declaration ID 1 is
- /// used for the translation unit declaration.
- typedef uint32_t DeclID;
-
- // FIXME: Turn these into classes so we can have some type safety when
- // we go from local ID to global and vice-versa.
- typedef DeclID LocalDeclID;
- typedef DeclID GlobalDeclID;
-
- /// \brief 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
- /// qualifiers (as with QualType) and the upper bits provide a
- /// type index. The type index values are partitioned into two
- /// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type
- /// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a
- /// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are
- /// other types that have serialized representations.
- typedef uint32_t TypeID;
-
- /// \brief A type index; the type ID with the qualifier bits removed.
- class TypeIdx {
- uint32_t Idx;
- public:
- TypeIdx() : Idx(0) { }
- explicit TypeIdx(uint32_t index) : Idx(index) { }
-
- uint32_t getIndex() const { return Idx; }
- TypeID asTypeID(unsigned FastQuals) const {
- if (Idx == uint32_t(-1))
- return TypeID(-1);
-
- return (Idx << Qualifiers::FastWidth) | FastQuals;
- }
- static TypeIdx fromTypeID(TypeID ID) {
- if (ID == TypeID(-1))
- return TypeIdx(-1);
-
- return TypeIdx(ID >> Qualifiers::FastWidth);
- }
- };
-
- /// A structure for putting "fast"-unqualified QualTypes into a
- /// DenseMap. This uses the standard pointer hash function.
- struct UnsafeQualTypeDenseMapInfo {
- static inline bool isEqual(QualType A, QualType B) { return A == B; }
- static inline QualType getEmptyKey() {
- return QualType::getFromOpaquePtr((void*) 1);
- }
- static inline QualType getTombstoneKey() {
- return QualType::getFromOpaquePtr((void*) 2);
- }
- static inline unsigned getHashValue(QualType T) {
- assert(!T.getLocalFastQualifiers() &&
- "hash invalid for types with fast quals");
- uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
- return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
- }
- };
-
- /// \brief An ID number that refers to an identifier in an AST file.
- typedef uint32_t IdentID;
-
- /// \brief 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.
- typedef uint32_t MacroID;
-
- /// \brief A global ID number that refers to a macro in an AST file.
- typedef uint32_t GlobalMacroID;
-
- /// \brief A local to a module ID number that refers to a macro in an
- /// AST file.
- typedef uint32_t LocalMacroID;
-
- /// \brief 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.
- typedef uint32_t SelectorID;
-
- /// \brief 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
- /// AST file.
- typedef uint32_t CXXBaseSpecifiersID;
-
- /// \brief An ID number that refers to a list of CXXCtorInitializers in an
- /// AST file.
- typedef uint32_t CXXCtorInitializersID;
-
- /// \brief An ID number that refers to an entity in the detailed
- /// preprocessing record.
- typedef uint32_t PreprocessedEntityID;
-
- /// \brief An ID number that refers to a submodule in a module file.
- typedef uint32_t SubmoduleID;
-
- /// \brief The number of predefined submodule IDs.
- const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1;
-
- /// \brief Source range/offset of a preprocessed entity.
- struct PPEntityOffset {
- /// \brief Raw source location of beginning of range.
- unsigned Begin;
- /// \brief Raw source location of end of range.
- unsigned End;
- /// \brief Offset in the AST file.
- uint32_t BitOffset;
-
- PPEntityOffset(SourceRange R, uint32_t BitOffset)
- : Begin(R.getBegin().getRawEncoding()),
- End(R.getEnd().getRawEncoding()),
- BitOffset(BitOffset) { }
- };
-
- /// \brief Source range/offset of a preprocessed entity.
- struct DeclOffset {
- /// \brief Raw source location.
- unsigned Loc;
- /// \brief Offset in the AST file.
- uint32_t BitOffset;
-
- DeclOffset() : Loc(0), BitOffset(0) { }
- DeclOffset(SourceLocation Loc, uint32_t BitOffset)
- : Loc(Loc.getRawEncoding()),
- BitOffset(BitOffset) { }
- void setLocation(SourceLocation L) {
- Loc = L.getRawEncoding();
- }
- };
-
- /// \brief 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
- /// an AST file.
- enum BlockIDs {
- /// \brief 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
- /// manager.
- SOURCE_MANAGER_BLOCK_ID,
-
- /// \brief The block containing information about the
- /// preprocessor.
- PREPROCESSOR_BLOCK_ID,
-
- /// \brief 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.
- PREPROCESSOR_DETAIL_BLOCK_ID,
-
- /// \brief The block containing the submodule structure.
- SUBMODULE_BLOCK_ID,
-
- /// \brief The block containing comments.
- COMMENTS_BLOCK_ID,
-
- /// \brief 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
- /// 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
- /// 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.
- EXTENSION_BLOCK_ID,
- };
-
- /// \brief Record types that occur within the control block.
- enum ControlRecordTypes {
- /// \brief 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
- /// this AST file.
- IMPORTS,
-
- /// \brief 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.
- ORIGINAL_PCH_DIR,
-
- /// \brief 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
- /// reside.
- INPUT_FILE_OFFSETS,
-
- /// \brief Record code for the module name.
- MODULE_NAME,
-
- /// \brief Record code for the module map file that was used to build this
- /// AST file.
- MODULE_MAP_FILE,
-
- /// \brief Record code for the signature that identifiers this AST file.
- SIGNATURE,
-
- /// \brief Record code for the module build directory.
- MODULE_DIRECTORY,
- };
-
- /// \brief Record types that occur within the options block inside
- /// the control block.
- enum OptionsRecordTypes {
- /// \brief 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
- /// the structure, and let the reader decide which options are
- /// actually important to check.
- LANGUAGE_OPTIONS = 1,
-
- /// \brief Record code for the target options table.
- TARGET_OPTIONS,
-
- /// \brief Record code for the diagnostic options table.
- DIAGNOSTIC_OPTIONS,
-
- /// \brief Record code for the filesystem options table.
- FILE_SYSTEM_OPTIONS,
-
- /// \brief Record code for the headers search options table.
- HEADER_SEARCH_OPTIONS,
-
- /// \brief Record code for the preprocessor options table.
- PREPROCESSOR_OPTIONS,
- };
-
- /// \brief Record code for extension blocks.
- enum ExtensionBlockRecordTypes {
- /// Metadata describing this particular extension.
- EXTENSION_METADATA = 1,
-
- /// The first record ID allocated to the extensions themselves.
- FIRST_EXTENSION_RECORD_ID = 4
- };
-
- /// \brief Record types that occur within the input-files block
- /// inside the control block.
- enum InputFileRecordTypes {
- /// \brief An input file.
- INPUT_FILE = 1
- };
-
- /// \brief Record types that occur within the AST block itself.
- enum ASTRecordTypes {
- /// \brief 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
- /// point into the declarations and types block (identified by
- /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
- /// of a type. For a given type ID @c T, the lower three bits of
- /// @c T are its qualifiers (const, volatile, restrict), as in
- /// the QualType class. The upper bits, after being shifted and
- /// subtracting NUM_PREDEF_TYPE_IDS, are used to index into the
- /// TYPE_OFFSET block to determine the offset of that type's
- /// corresponding record within the DECLTYPES_BLOCK_ID block.
- TYPE_OFFSET = 1,
-
- /// \brief 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
- /// the AST block. The record itself is an array of offsets that
- /// point into the declarations and types block (identified by
- /// DECLTYPES_BLOCK_ID). The declaration ID is an index into this
- /// record, after subtracting one to account for the use of
- /// declaration ID 0 for a NULL declaration pointer. Index 0 is
- /// reserved for the translation unit declaration.
- DECL_OFFSET = 2,
-
- /// \brief Record code for the table of offsets of each
- /// identifier ID.
- ///
- /// The offset table contains offsets into the blob stored in
- /// the IDENTIFIER_TABLE record. Each offset points to the
- /// NULL-terminated string that corresponds to that identifier.
- IDENTIFIER_OFFSET = 3,
-
- /// \brief 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.
- ///
- /// The identifier table is a simple blob that contains
- /// NULL-terminated strings for all of the identifiers
- /// referenced by the AST file. The IDENTIFIER_OFFSET table
- /// contains the mapping from identifier IDs to the characters
- /// in this blob. Note that the starting offsets of all of the
- /// identifiers are odd, so that, when the identifier offset
- /// table is loaded in, we can use the low bit to distinguish
- /// between offsets (for unresolved identifier IDs) and
- /// IdentifierInfo pointers (for already-resolved identifier
- /// IDs).
- IDENTIFIER_TABLE = 5,
-
- /// \brief 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
- /// array of declaration IDs. These declarations will be
- /// reported to the AST consumer after the AST file has been
- /// read, since their presence can affect the semantics of the
- /// program (e.g., for code generation).
- EAGERLY_DESERIALIZED_DECLS = 6,
-
- /// \brief Record code for the set of non-builtin, special
- /// types.
- ///
- /// This record contains the type IDs for the various type nodes
- /// that are constructed during semantic analysis (e.g.,
- /// __builtin_va_list). The SPECIAL_TYPE_* constants provide
- /// offsets into this record.
- SPECIAL_TYPES = 7,
-
- /// \brief Record code for the extra statistics we gather while
- /// generating an AST file.
- STATISTICS = 8,
-
- /// \brief 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
- /// Objective-C method pool.
- SELECTOR_OFFSETS = 11,
-
- /// \brief Record code for the Objective-C method pool,
- METHOD_POOL = 12,
-
- /// \brief 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
- /// of source-location information.
- SOURCE_LOCATION_OFFSETS = 14,
-
- /// \brief 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
- /// predefines buffer and for any file entries that need to be
- /// preloaded.
- SOURCE_LOCATION_PRELOADS = 15,
-
- /// \brief 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.
- UNUSED_FILESCOPED_DECLS = 17,
-
- /// \brief 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.
- VTABLE_USES = 19,
-
- // ID 20 used to be for a list of dynamic classes.
-
- /// \brief Record code for referenced selector pool.
- REFERENCED_SELECTOR_POOL = 21,
-
- /// \brief 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.
- SEMA_DECL_REFS = 24,
-
- /// \brief Record code for weak undeclared identifiers.
- WEAK_UNDECLARED_IDENTIFIERS = 25,
-
- /// \brief Record code for pending implicit instantiations.
- PENDING_IMPLICIT_INSTANTIATIONS = 26,
-
- /// \brief Record code for a decl replacement block.
- ///
- /// If a declaration is modified after having been deserialized, and then
- /// written to a dependent AST file, its ID and offset must be added to
- /// the replacement block.
- DECL_REPLACEMENTS = 27,
-
- /// \brief 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
- /// that were modified after being deserialized and need updates.
- DECL_UPDATE_OFFSETS = 29,
-
- /// \brief Record of updates for a declaration that was modified after
- /// being deserialized.
- DECL_UPDATES = 30,
-
- /// \brief Record code for the table of offsets to CXXBaseSpecifier
- /// sets.
- CXX_BASE_SPECIFIER_OFFSETS = 31,
-
- /// \brief Record code for \#pragma diagnostic mappings.
- DIAG_PRAGMA_MAPPINGS = 32,
-
- /// \brief Record code for special CUDA declarations.
- CUDA_SPECIAL_DECL_REFS = 33,
-
- /// \brief Record code for header search information.
- HEADER_SEARCH_TABLE = 34,
-
- /// \brief Record code for floating point \#pragma options.
- FP_PRAGMA_OPTIONS = 35,
-
- /// \brief Record code for enabled OpenCL extensions.
- OPENCL_EXTENSIONS = 36,
-
- /// \brief The list of delegating constructor declarations.
- DELEGATING_CTORS = 37,
-
- /// \brief 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
- /// 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,
- /// which stores information about \#line directives.
- SOURCE_MANAGER_LINE_TABLE = 40,
-
- /// \brief 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.
- FILE_SORTED_DECLS = 42,
-
- /// \brief 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
- /// 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.
- ///
- /// 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
- /// 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
- /// need a definition in this TU.
- UNDEFINED_BUT_USED = 49,
-
- /// \brief Record code for late parsed template functions.
- LATE_PARSED_TEMPLATE = 50,
-
- /// \brief Record code for \#pragma optimize options.
- OPTIMIZE_PRAGMA_OPTIONS = 51,
-
- /// \brief Record code for potentially unused local typedef names.
- UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES = 52,
-
- /// \brief Record code for the table of offsets to CXXCtorInitializers
- /// lists.
- CXX_CTOR_INITIALIZERS_OFFSETS = 53,
-
- /// \brief Delete expressions that will be analyzed later.
- DELETE_EXPRS_TO_ANALYZE = 54
- };
-
- /// \brief Record types used within a source manager block.
- enum SourceManagerRecordTypes {
- /// \brief Describes a source location entry (SLocEntry) for a
- /// file.
- SM_SLOC_FILE_ENTRY = 1,
- /// \brief 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
- /// 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 source location entry (SLocEntry) for a
- /// macro expansion.
- SM_SLOC_EXPANSION_ENTRY = 4
- };
-
- /// \brief 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.
- /// [PP_MACRO_OBJECT_LIKE, IdentInfoID, SLoc, IsUsed]
- PP_MACRO_OBJECT_LIKE = 1,
-
- /// \brief A function-like macro definition.
- /// [PP_MACRO_FUNCTION_LIKE, \<ObjectLikeStuff>, IsC99Varargs,
- /// IsGNUVarars, NumArgs, ArgIdentInfoID* ]
- PP_MACRO_FUNCTION_LIKE = 2,
-
- /// \brief Describes one token.
- /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
- PP_TOKEN = 3,
-
- /// \brief The macro directives history for a particular identifier.
- PP_MACRO_DIRECTIVE_HISTORY = 4,
-
- /// \brief 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.
- enum PreprocessorDetailRecordTypes {
- /// \brief Describes a macro expansion within the preprocessing record.
- PPD_MACRO_EXPANSION = 0,
-
- /// \brief Describes a macro definition within the preprocessing record.
- PPD_MACRO_DEFINITION = 1,
-
- /// \brief Describes an inclusion directive within the preprocessing
- /// record.
- PPD_INCLUSION_DIRECTIVE = 2
- };
-
- /// \brief Record types used within a submodule description block.
- enum SubmoduleRecordTypes {
- /// \brief Metadata for submodules as a whole.
- SUBMODULE_METADATA = 0,
- /// \brief 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,
- /// if any.
- SUBMODULE_UMBRELLA_HEADER = 2,
- /// \brief Specifies a header that falls into this (sub)module.
- SUBMODULE_HEADER = 3,
- /// \brief Specifies a top-level header that falls into this (sub)module.
- SUBMODULE_TOPHEADER = 4,
- /// \brief Specifies an umbrella directory.
- SUBMODULE_UMBRELLA_DIR = 5,
- /// \brief Specifies the submodules that are imported by this
- /// submodule.
- SUBMODULE_IMPORTS = 6,
- /// \brief Specifies the submodules that are re-exported from this
- /// submodule.
- SUBMODULE_EXPORTS = 7,
- /// \brief Specifies a required feature.
- SUBMODULE_REQUIRES = 8,
- /// \brief Specifies a header that has been explicitly excluded
- /// from this submodule.
- SUBMODULE_EXCLUDED_HEADER = 9,
- /// \brief Specifies a library or framework to link against.
- SUBMODULE_LINK_LIBRARY = 10,
- /// \brief Specifies a configuration macro for this module.
- SUBMODULE_CONFIG_MACRO = 11,
- /// \brief Specifies a conflict with another module.
- SUBMODULE_CONFLICT = 12,
- /// \brief 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
- /// textually included.
- SUBMODULE_TEXTUAL_HEADER = 14,
- /// \brief Specifies a header that is private to this submodule but
- /// must be textually included.
- SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15,
- };
-
- /// \brief Record types used within a comments block.
- enum CommentRecordTypes {
- COMMENTS_RAW_COMMENT = 0
- };
-
- /// \defgroup ASTAST AST file AST constants
- ///
- /// The constants in this group describe various components of the
- /// abstract syntax tree within an AST file.
- ///
- /// @{
-
- /// \brief Predefined type IDs.
- ///
- /// These type IDs correspond to predefined types in the AST
- /// context, such as built-in types (int) and special place-holder
- /// types (the \<overload> and \<dependent> type markers). Such
- /// types are never actually serialized, since they will be built
- /// by the AST context when it is created.
- enum PredefinedTypeIDs {
- /// \brief The NULL type.
- PREDEF_TYPE_NULL_ID = 0,
- /// \brief The void type.
- PREDEF_TYPE_VOID_ID = 1,
- /// \brief The 'bool' or '_Bool' type.
- PREDEF_TYPE_BOOL_ID = 2,
- /// \brief The 'char' type, when it is unsigned.
- PREDEF_TYPE_CHAR_U_ID = 3,
- /// \brief The 'unsigned char' type.
- PREDEF_TYPE_UCHAR_ID = 4,
- /// \brief The 'unsigned short' type.
- PREDEF_TYPE_USHORT_ID = 5,
- /// \brief The 'unsigned int' type.
- PREDEF_TYPE_UINT_ID = 6,
- /// \brief The 'unsigned long' type.
- PREDEF_TYPE_ULONG_ID = 7,
- /// \brief The 'unsigned long long' type.
- PREDEF_TYPE_ULONGLONG_ID = 8,
- /// \brief The 'char' type, when it is signed.
- PREDEF_TYPE_CHAR_S_ID = 9,
- /// \brief The 'signed char' type.
- PREDEF_TYPE_SCHAR_ID = 10,
- /// \brief The C++ 'wchar_t' type.
- PREDEF_TYPE_WCHAR_ID = 11,
- /// \brief The (signed) 'short' type.
- PREDEF_TYPE_SHORT_ID = 12,
- /// \brief The (signed) 'int' type.
- PREDEF_TYPE_INT_ID = 13,
- /// \brief The (signed) 'long' type.
- PREDEF_TYPE_LONG_ID = 14,
- /// \brief The (signed) 'long long' type.
- PREDEF_TYPE_LONGLONG_ID = 15,
- /// \brief The 'float' type.
- PREDEF_TYPE_FLOAT_ID = 16,
- /// \brief The 'double' type.
- PREDEF_TYPE_DOUBLE_ID = 17,
- /// \brief The 'long double' type.
- PREDEF_TYPE_LONGDOUBLE_ID = 18,
- /// \brief The placeholder type for overloaded function sets.
- PREDEF_TYPE_OVERLOAD_ID = 19,
- /// \brief The placeholder type for dependent types.
- PREDEF_TYPE_DEPENDENT_ID = 20,
- /// \brief The '__uint128_t' type.
- PREDEF_TYPE_UINT128_ID = 21,
- /// \brief The '__int128_t' type.
- PREDEF_TYPE_INT128_ID = 22,
- /// \brief The type of 'nullptr'.
- PREDEF_TYPE_NULLPTR_ID = 23,
- /// \brief The C++ 'char16_t' type.
- PREDEF_TYPE_CHAR16_ID = 24,
- /// \brief The C++ 'char32_t' type.
- PREDEF_TYPE_CHAR32_ID = 25,
- /// \brief The ObjC 'id' type.
- PREDEF_TYPE_OBJC_ID = 26,
- /// \brief The ObjC 'Class' type.
- PREDEF_TYPE_OBJC_CLASS = 27,
- /// \brief The ObjC 'SEL' type.
- PREDEF_TYPE_OBJC_SEL = 28,
- /// \brief The 'unknown any' placeholder type.
- PREDEF_TYPE_UNKNOWN_ANY = 29,
- /// \brief The placeholder type for bound member functions.
- PREDEF_TYPE_BOUND_MEMBER = 30,
- /// \brief The "auto" deduction type.
- PREDEF_TYPE_AUTO_DEDUCT = 31,
- /// \brief The "auto &&" deduction type.
- PREDEF_TYPE_AUTO_RREF_DEDUCT = 32,
- /// \brief The OpenCL 'half' / ARM NEON __fp16 type.
- PREDEF_TYPE_HALF_ID = 33,
- /// \brief ARC's unbridged-cast placeholder type.
- PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34,
- /// \brief The pseudo-object placeholder type.
- PREDEF_TYPE_PSEUDO_OBJECT = 35,
- /// \brief The placeholder type for builtin functions.
- PREDEF_TYPE_BUILTIN_FN = 36,
- /// \brief OpenCL 1d image type.
- PREDEF_TYPE_IMAGE1D_ID = 37,
- /// \brief OpenCL 1d image array type.
- PREDEF_TYPE_IMAGE1D_ARR_ID = 38,
- /// \brief OpenCL 1d image buffer type.
- PREDEF_TYPE_IMAGE1D_BUFF_ID = 39,
- /// \brief OpenCL 2d image type.
- PREDEF_TYPE_IMAGE2D_ID = 40,
- /// \brief OpenCL 2d image array type.
- PREDEF_TYPE_IMAGE2D_ARR_ID = 41,
- /// \brief OpenCL 2d image depth type.
- PREDEF_TYPE_IMAGE2D_DEP_ID = 42,
- /// \brief OpenCL 2d image array depth type.
- PREDEF_TYPE_IMAGE2D_ARR_DEP_ID = 43,
- /// \brief OpenCL 2d image MSAA type.
- PREDEF_TYPE_IMAGE2D_MSAA_ID = 44,
- /// \brief OpenCL 2d image array MSAA type.
- PREDEF_TYPE_IMAGE2D_ARR_MSAA_ID = 45,
- /// \brief OpenCL 2d image MSAA depth type.
- PREDEF_TYPE_IMAGE2D_MSAA_DEP_ID = 46,
- /// \brief OpenCL 2d image array MSAA depth type.
- PREDEF_TYPE_IMAGE2D_ARR_MSAA_DEPTH_ID = 47,
- /// \brief OpenCL 3d image type.
- PREDEF_TYPE_IMAGE3D_ID = 48,
- /// \brief OpenCL event type.
- PREDEF_TYPE_EVENT_ID = 49,
- /// \brief OpenCL clk event type.
- PREDEF_TYPE_CLK_EVENT_ID = 50,
- /// \brief OpenCL sampler type.
- PREDEF_TYPE_SAMPLER_ID = 51,
- /// \brief OpenCL queue type.
- PREDEF_TYPE_QUEUE_ID = 52,
- /// \brief OpenCL ndrange type.
- PREDEF_TYPE_NDRANGE_ID = 53,
- /// \brief OpenCL reserve_id type.
- PREDEF_TYPE_RESERVE_ID_ID = 54,
- /// \brief The placeholder type for OpenMP array section.
- PREDEF_TYPE_OMP_ARRAY_SECTION = 55
- };
-
- /// \brief 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;
-
- /// \brief 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.
- enum TypeCode {
- /// \brief An ExtQualType record.
- TYPE_EXT_QUAL = 1,
- /// \brief A ComplexType record.
- TYPE_COMPLEX = 3,
- /// \brief A PointerType record.
- TYPE_POINTER = 4,
- /// \brief A BlockPointerType record.
- TYPE_BLOCK_POINTER = 5,
- /// \brief An LValueReferenceType record.
- TYPE_LVALUE_REFERENCE = 6,
- /// \brief An RValueReferenceType record.
- TYPE_RVALUE_REFERENCE = 7,
- /// \brief A MemberPointerType record.
- TYPE_MEMBER_POINTER = 8,
- /// \brief A ConstantArrayType record.
- TYPE_CONSTANT_ARRAY = 9,
- /// \brief An IncompleteArrayType record.
- TYPE_INCOMPLETE_ARRAY = 10,
- /// \brief A VariableArrayType record.
- TYPE_VARIABLE_ARRAY = 11,
- /// \brief A VectorType record.
- TYPE_VECTOR = 12,
- /// \brief An ExtVectorType record.
- TYPE_EXT_VECTOR = 13,
- /// \brief A FunctionNoProtoType record.
- TYPE_FUNCTION_NO_PROTO = 14,
- /// \brief A FunctionProtoType record.
- TYPE_FUNCTION_PROTO = 15,
- /// \brief A TypedefType record.
- TYPE_TYPEDEF = 16,
- /// \brief A TypeOfExprType record.
- TYPE_TYPEOF_EXPR = 17,
- /// \brief A TypeOfType record.
- TYPE_TYPEOF = 18,
- /// \brief A RecordType record.
- TYPE_RECORD = 19,
- /// \brief An EnumType record.
- TYPE_ENUM = 20,
- /// \brief An ObjCInterfaceType record.
- TYPE_OBJC_INTERFACE = 21,
- /// \brief An ObjCObjectPointerType record.
- TYPE_OBJC_OBJECT_POINTER = 22,
- /// \brief a DecltypeType record.
- TYPE_DECLTYPE = 23,
- /// \brief An ElaboratedType record.
- TYPE_ELABORATED = 24,
- /// \brief A SubstTemplateTypeParmType record.
- TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
- /// \brief An UnresolvedUsingType record.
- TYPE_UNRESOLVED_USING = 26,
- /// \brief An InjectedClassNameType record.
- TYPE_INJECTED_CLASS_NAME = 27,
- /// \brief An ObjCObjectType record.
- TYPE_OBJC_OBJECT = 28,
- /// \brief An TemplateTypeParmType record.
- TYPE_TEMPLATE_TYPE_PARM = 29,
- /// \brief An TemplateSpecializationType record.
- TYPE_TEMPLATE_SPECIALIZATION = 30,
- /// \brief A DependentNameType record.
- TYPE_DEPENDENT_NAME = 31,
- /// \brief A DependentTemplateSpecializationType record.
- TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
- /// \brief A DependentSizedArrayType record.
- TYPE_DEPENDENT_SIZED_ARRAY = 33,
- /// \brief A ParenType record.
- TYPE_PAREN = 34,
- /// \brief A PackExpansionType record.
- TYPE_PACK_EXPANSION = 35,
- /// \brief An AttributedType record.
- TYPE_ATTRIBUTED = 36,
- /// \brief A SubstTemplateTypeParmPackType record.
- TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
- /// \brief A AutoType record.
- TYPE_AUTO = 38,
- /// \brief A UnaryTransformType record.
- TYPE_UNARY_TRANSFORM = 39,
- /// \brief An AtomicType record.
- TYPE_ATOMIC = 40,
- /// \brief A DecayedType record.
- TYPE_DECAYED = 41,
- /// \brief An AdjustedType record.
- TYPE_ADJUSTED = 42
- };
-
- /// \brief 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
- SPECIAL_TYPE_CF_CONSTANT_STRING = 0,
- /// \brief C FILE typedef type
- SPECIAL_TYPE_FILE = 1,
- /// \brief C jmp_buf typedef type
- SPECIAL_TYPE_JMP_BUF = 2,
- /// \brief C sigjmp_buf typedef type
- SPECIAL_TYPE_SIGJMP_BUF = 3,
- /// \brief Objective-C "id" redefinition type
- SPECIAL_TYPE_OBJC_ID_REDEFINITION = 4,
- /// \brief Objective-C "Class" redefinition type
- SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 5,
- /// \brief Objective-C "SEL" redefinition type
- SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 6,
- /// \brief C ucontext_t typedef type
- SPECIAL_TYPE_UCONTEXT_T = 7
- };
-
- /// \brief The number of special type IDs.
- const unsigned NumSpecialTypeIDs = 8;
-
- /// \brief 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.
- PREDEF_DECL_NULL_ID = 0,
-
- /// \brief The translation unit.
- PREDEF_DECL_TRANSLATION_UNIT_ID = 1,
-
- /// \brief The Objective-C 'id' type.
- PREDEF_DECL_OBJC_ID_ID = 2,
-
- /// \brief The Objective-C 'SEL' type.
- PREDEF_DECL_OBJC_SEL_ID = 3,
-
- /// \brief The Objective-C 'Class' type.
- PREDEF_DECL_OBJC_CLASS_ID = 4,
-
- /// \brief The Objective-C 'Protocol' type.
- PREDEF_DECL_OBJC_PROTOCOL_ID = 5,
-
- /// \brief The signed 128-bit integer type.
- PREDEF_DECL_INT_128_ID = 6,
-
- /// \brief The unsigned 128-bit integer type.
- PREDEF_DECL_UNSIGNED_INT_128_ID = 7,
-
- /// \brief The internal 'instancetype' typedef.
- PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,
-
- /// \brief The internal '__builtin_va_list' typedef.
- PREDEF_DECL_BUILTIN_VA_LIST_ID = 9,
-
- /// \brief The internal '__va_list_tag' struct, if any.
- PREDEF_DECL_VA_LIST_TAG = 10,
-
- /// \brief The internal '__builtin_ms_va_list' typedef.
- PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11,
-
- /// \brief The extern "C" context.
- PREDEF_DECL_EXTERN_C_CONTEXT_ID = 12,
-
- /// \brief The internal '__make_integer_seq' template.
- PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13,
- };
-
- /// \brief 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 = 14;
-
- /// \brief Record code for a list of local redeclarations of a declaration.
- const unsigned int LOCAL_REDECLARATIONS = 50;
-
- /// \brief Record codes for each kind of declaration.
- ///
- /// These constants describe the declaration records that can occur within
- /// a declarations block (identified by DECLS_BLOCK_ID). Each
- /// constant describes a record for a specific declaration class
- /// in the AST.
- enum DeclCode {
- /// \brief A TypedefDecl record.
- DECL_TYPEDEF = 51,
- /// \brief A TypeAliasDecl record.
- DECL_TYPEALIAS,
- /// \brief An EnumDecl record.
- DECL_ENUM,
- /// \brief A RecordDecl record.
- DECL_RECORD,
- /// \brief An EnumConstantDecl record.
- DECL_ENUM_CONSTANT,
- /// \brief A FunctionDecl record.
- DECL_FUNCTION,
- /// \brief A ObjCMethodDecl record.
- DECL_OBJC_METHOD,
- /// \brief A ObjCInterfaceDecl record.
- DECL_OBJC_INTERFACE,
- /// \brief A ObjCProtocolDecl record.
- DECL_OBJC_PROTOCOL,
- /// \brief A ObjCIvarDecl record.
- DECL_OBJC_IVAR,
- /// \brief A ObjCAtDefsFieldDecl record.
- DECL_OBJC_AT_DEFS_FIELD,
- /// \brief A ObjCCategoryDecl record.
- DECL_OBJC_CATEGORY,
- /// \brief A ObjCCategoryImplDecl record.
- DECL_OBJC_CATEGORY_IMPL,
- /// \brief A ObjCImplementationDecl record.
- DECL_OBJC_IMPLEMENTATION,
- /// \brief A ObjCCompatibleAliasDecl record.
- DECL_OBJC_COMPATIBLE_ALIAS,
- /// \brief A ObjCPropertyDecl record.
- DECL_OBJC_PROPERTY,
- /// \brief A ObjCPropertyImplDecl record.
- DECL_OBJC_PROPERTY_IMPL,
- /// \brief A FieldDecl record.
- DECL_FIELD,
- /// \brief A MSPropertyDecl record.
- DECL_MS_PROPERTY,
- /// \brief A VarDecl record.
- DECL_VAR,
- /// \brief An ImplicitParamDecl record.
- DECL_IMPLICIT_PARAM,
- /// \brief A ParmVarDecl record.
- DECL_PARM_VAR,
- /// \brief A FileScopeAsmDecl record.
- DECL_FILE_SCOPE_ASM,
- /// \brief A BlockDecl record.
- DECL_BLOCK,
- /// \brief A CapturedDecl record.
- DECL_CAPTURED,
- /// \brief 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,
- /// in the order in which those declarations were added to the
- /// declaration context. This data is used when iterating over
- /// the contents of a DeclContext, e.g., via
- /// DeclContext::decls_begin() and DeclContext::decls_end().
- DECL_CONTEXT_LEXICAL,
- /// \brief 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
- /// associates a declaration name with one or more declaration
- /// IDs. This data is used when performing qualified name lookup
- /// into a DeclContext via DeclContext::lookup.
- DECL_CONTEXT_VISIBLE,
- /// \brief A LabelDecl record.
- DECL_LABEL,
- /// \brief A NamespaceDecl record.
- DECL_NAMESPACE,
- /// \brief A NamespaceAliasDecl record.
- DECL_NAMESPACE_ALIAS,
- /// \brief A UsingDecl record.
- DECL_USING,
- /// \brief A UsingShadowDecl record.
- DECL_USING_SHADOW,
- /// \brief A UsingDirecitveDecl record.
- DECL_USING_DIRECTIVE,
- /// \brief An UnresolvedUsingValueDecl record.
- DECL_UNRESOLVED_USING_VALUE,
- /// \brief An UnresolvedUsingTypenameDecl record.
- DECL_UNRESOLVED_USING_TYPENAME,
- /// \brief A LinkageSpecDecl record.
- DECL_LINKAGE_SPEC,
- /// \brief A CXXRecordDecl record.
- DECL_CXX_RECORD,
- /// \brief A CXXMethodDecl record.
- DECL_CXX_METHOD,
- /// \brief A CXXConstructorDecl record.
- DECL_CXX_CONSTRUCTOR,
- /// \brief A CXXDestructorDecl record.
- DECL_CXX_DESTRUCTOR,
- /// \brief A CXXConversionDecl record.
- DECL_CXX_CONVERSION,
- /// \brief An AccessSpecDecl record.
- DECL_ACCESS_SPEC,
-
- /// \brief A FriendDecl record.
- DECL_FRIEND,
- /// \brief A FriendTemplateDecl record.
- DECL_FRIEND_TEMPLATE,
- /// \brief A ClassTemplateDecl record.
- DECL_CLASS_TEMPLATE,
- /// \brief A ClassTemplateSpecializationDecl record.
- DECL_CLASS_TEMPLATE_SPECIALIZATION,
- /// \brief A ClassTemplatePartialSpecializationDecl record.
- DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
- /// \brief A VarTemplateDecl record.
- DECL_VAR_TEMPLATE,
- /// \brief A VarTemplateSpecializationDecl record.
- DECL_VAR_TEMPLATE_SPECIALIZATION,
- /// \brief A VarTemplatePartialSpecializationDecl record.
- DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION,
- /// \brief A FunctionTemplateDecl record.
- DECL_FUNCTION_TEMPLATE,
- /// \brief A TemplateTypeParmDecl record.
- DECL_TEMPLATE_TYPE_PARM,
- /// \brief A NonTypeTemplateParmDecl record.
- DECL_NON_TYPE_TEMPLATE_PARM,
- /// \brief A TemplateTemplateParmDecl record.
- DECL_TEMPLATE_TEMPLATE_PARM,
- /// \brief A TypeAliasTemplateDecl record.
- DECL_TYPE_ALIAS_TEMPLATE,
- /// \brief A StaticAssertDecl record.
- DECL_STATIC_ASSERT,
- /// \brief A record containing CXXBaseSpecifiers.
- DECL_CXX_BASE_SPECIFIERS,
- /// \brief A record containing CXXCtorInitializers.
- DECL_CXX_CTOR_INITIALIZERS,
- /// \brief A IndirectFieldDecl record.
- DECL_INDIRECTFIELD,
- /// \brief 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
- /// template template parameter pack.
- DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK,
- /// \brief A ClassScopeFunctionSpecializationDecl record a class scope
- /// function specialization. (Microsoft extension).
- DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
- /// \brief An ImportDecl recording a module import.
- DECL_IMPORT,
- /// \brief An OMPThreadPrivateDecl record.
- DECL_OMP_THREADPRIVATE,
- /// \brief An EmptyDecl record.
- DECL_EMPTY,
- /// \brief An ObjCTypeParamDecl record.
- DECL_OBJC_TYPE_PARAM,
- };
-
- /// \brief 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
- /// block, so they begin with record values of 128. Each constant
- /// 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
- /// of an expression.
- STMT_STOP = 128,
- /// \brief A NULL expression.
- STMT_NULL_PTR,
- /// \brief A reference to a previously [de]serialized Stmt record.
- STMT_REF_PTR,
- /// \brief A NullStmt record.
- STMT_NULL,
- /// \brief A CompoundStmt record.
- STMT_COMPOUND,
- /// \brief A CaseStmt record.
- STMT_CASE,
- /// \brief A DefaultStmt record.
- STMT_DEFAULT,
- /// \brief A LabelStmt record.
- STMT_LABEL,
- /// \brief An AttributedStmt record.
- STMT_ATTRIBUTED,
- /// \brief An IfStmt record.
- STMT_IF,
- /// \brief A SwitchStmt record.
- STMT_SWITCH,
- /// \brief A WhileStmt record.
- STMT_WHILE,
- /// \brief A DoStmt record.
- STMT_DO,
- /// \brief A ForStmt record.
- STMT_FOR,
- /// \brief A GotoStmt record.
- STMT_GOTO,
- /// \brief An IndirectGotoStmt record.
- STMT_INDIRECT_GOTO,
- /// \brief A ContinueStmt record.
- STMT_CONTINUE,
- /// \brief A BreakStmt record.
- STMT_BREAK,
- /// \brief A ReturnStmt record.
- STMT_RETURN,
- /// \brief A DeclStmt record.
- STMT_DECL,
- /// \brief A CapturedStmt record.
- STMT_CAPTURED,
- /// \brief A GCC-style AsmStmt record.
- STMT_GCCASM,
- /// \brief A MS-style AsmStmt record.
- STMT_MSASM,
- /// \brief A PredefinedExpr record.
- EXPR_PREDEFINED,
- /// \brief A DeclRefExpr record.
- EXPR_DECL_REF,
- /// \brief An IntegerLiteral record.
- EXPR_INTEGER_LITERAL,
- /// \brief A FloatingLiteral record.
- EXPR_FLOATING_LITERAL,
- /// \brief An ImaginaryLiteral record.
- EXPR_IMAGINARY_LITERAL,
- /// \brief A StringLiteral record.
- EXPR_STRING_LITERAL,
- /// \brief A CharacterLiteral record.
- EXPR_CHARACTER_LITERAL,
- /// \brief A ParenExpr record.
- EXPR_PAREN,
- /// \brief A ParenListExpr record.
- EXPR_PAREN_LIST,
- /// \brief A UnaryOperator record.
- EXPR_UNARY_OPERATOR,
- /// \brief An OffsetOfExpr record.
- EXPR_OFFSETOF,
- /// \brief A SizefAlignOfExpr record.
- EXPR_SIZEOF_ALIGN_OF,
- /// \brief An ArraySubscriptExpr record.
- EXPR_ARRAY_SUBSCRIPT,
- /// \brief A CallExpr record.
- EXPR_CALL,
- /// \brief A MemberExpr record.
- EXPR_MEMBER,
- /// \brief A BinaryOperator record.
- EXPR_BINARY_OPERATOR,
- /// \brief A CompoundAssignOperator record.
- EXPR_COMPOUND_ASSIGN_OPERATOR,
- /// \brief A ConditionOperator record.
- EXPR_CONDITIONAL_OPERATOR,
- /// \brief An ImplicitCastExpr record.
- EXPR_IMPLICIT_CAST,
- /// \brief A CStyleCastExpr record.
- EXPR_CSTYLE_CAST,
- /// \brief A CompoundLiteralExpr record.
- EXPR_COMPOUND_LITERAL,
- /// \brief An ExtVectorElementExpr record.
- EXPR_EXT_VECTOR_ELEMENT,
- /// \brief An InitListExpr record.
- EXPR_INIT_LIST,
- /// \brief A DesignatedInitExpr record.
- EXPR_DESIGNATED_INIT,
- /// \brief A DesignatedInitUpdateExpr record.
- EXPR_DESIGNATED_INIT_UPDATE,
- /// \brief An ImplicitValueInitExpr record.
- EXPR_IMPLICIT_VALUE_INIT,
- /// \brief An NoInitExpr record.
- EXPR_NO_INIT,
- /// \brief A VAArgExpr record.
- EXPR_VA_ARG,
- /// \brief An AddrLabelExpr record.
- EXPR_ADDR_LABEL,
- /// \brief A StmtExpr record.
- EXPR_STMT,
- /// \brief A ChooseExpr record.
- EXPR_CHOOSE,
- /// \brief A GNUNullExpr record.
- EXPR_GNU_NULL,
- /// \brief A ShuffleVectorExpr record.
- EXPR_SHUFFLE_VECTOR,
- /// \brief A ConvertVectorExpr record.
- EXPR_CONVERT_VECTOR,
- /// \brief BlockExpr
- EXPR_BLOCK,
- /// \brief A GenericSelectionExpr record.
- EXPR_GENERIC_SELECTION,
- /// \brief A PseudoObjectExpr record.
- EXPR_PSEUDO_OBJECT,
- /// \brief An AtomicExpr record.
- EXPR_ATOMIC,
-
- // Objective-C
-
- /// \brief An ObjCStringLiteral record.
- EXPR_OBJC_STRING_LITERAL,
-
- EXPR_OBJC_BOXED_EXPRESSION,
- EXPR_OBJC_ARRAY_LITERAL,
- EXPR_OBJC_DICTIONARY_LITERAL,
-
-
- /// \brief An ObjCEncodeExpr record.
- EXPR_OBJC_ENCODE,
- /// \brief An ObjCSelectorExpr record.
- EXPR_OBJC_SELECTOR_EXPR,
- /// \brief An ObjCProtocolExpr record.
- EXPR_OBJC_PROTOCOL_EXPR,
- /// \brief An ObjCIvarRefExpr record.
- EXPR_OBJC_IVAR_REF_EXPR,
- /// \brief An ObjCPropertyRefExpr record.
- EXPR_OBJC_PROPERTY_REF_EXPR,
- /// \brief An ObjCSubscriptRefExpr record.
- EXPR_OBJC_SUBSCRIPT_REF_EXPR,
- /// \brief UNUSED
- EXPR_OBJC_KVC_REF_EXPR,
- /// \brief An ObjCMessageExpr record.
- EXPR_OBJC_MESSAGE_EXPR,
- /// \brief An ObjCIsa Expr record.
- EXPR_OBJC_ISA,
- /// \brief An ObjCIndirectCopyRestoreExpr record.
- EXPR_OBJC_INDIRECT_COPY_RESTORE,
-
- /// \brief An ObjCForCollectionStmt record.
- STMT_OBJC_FOR_COLLECTION,
- /// \brief An ObjCAtCatchStmt record.
- STMT_OBJC_CATCH,
- /// \brief An ObjCAtFinallyStmt record.
- STMT_OBJC_FINALLY,
- /// \brief An ObjCAtTryStmt record.
- STMT_OBJC_AT_TRY,
- /// \brief An ObjCAtSynchronizedStmt record.
- STMT_OBJC_AT_SYNCHRONIZED,
- /// \brief An ObjCAtThrowStmt record.
- STMT_OBJC_AT_THROW,
- /// \brief An ObjCAutoreleasePoolStmt record.
- STMT_OBJC_AUTORELEASE_POOL,
- /// \brief A ObjCBoolLiteralExpr record.
- EXPR_OBJC_BOOL_LITERAL,
-
- // C++
-
- /// \brief A CXXCatchStmt record.
- STMT_CXX_CATCH,
- /// \brief A CXXTryStmt record.
- STMT_CXX_TRY,
- /// \brief A CXXForRangeStmt record.
- STMT_CXX_FOR_RANGE,
-
- /// \brief A CXXOperatorCallExpr record.
- EXPR_CXX_OPERATOR_CALL,
- /// \brief A CXXMemberCallExpr record.
- EXPR_CXX_MEMBER_CALL,
- /// \brief A CXXConstructExpr record.
- EXPR_CXX_CONSTRUCT,
- /// \brief A CXXTemporaryObjectExpr record.
- EXPR_CXX_TEMPORARY_OBJECT,
- /// \brief A CXXStaticCastExpr record.
- EXPR_CXX_STATIC_CAST,
- /// \brief A CXXDynamicCastExpr record.
- EXPR_CXX_DYNAMIC_CAST,
- /// \brief A CXXReinterpretCastExpr record.
- EXPR_CXX_REINTERPRET_CAST,
- /// \brief A CXXConstCastExpr record.
- EXPR_CXX_CONST_CAST,
- /// \brief A CXXFunctionalCastExpr record.
- EXPR_CXX_FUNCTIONAL_CAST,
- /// \brief A UserDefinedLiteral record.
- EXPR_USER_DEFINED_LITERAL,
- /// \brief A CXXStdInitializerListExpr record.
- EXPR_CXX_STD_INITIALIZER_LIST,
- /// \brief A CXXBoolLiteralExpr record.
- EXPR_CXX_BOOL_LITERAL,
- EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
- EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr).
- EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type).
- EXPR_CXX_THIS, // CXXThisExpr
- EXPR_CXX_THROW, // CXXThrowExpr
- EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr
- EXPR_CXX_DEFAULT_INIT, // CXXDefaultInitExpr
- EXPR_CXX_BIND_TEMPORARY, // CXXBindTemporaryExpr
-
- EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr
- EXPR_CXX_NEW, // CXXNewExpr
- EXPR_CXX_DELETE, // CXXDeleteExpr
- EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr
-
- EXPR_EXPR_WITH_CLEANUPS, // ExprWithCleanups
-
- EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr
- EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr
- EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr
- EXPR_CXX_UNRESOLVED_MEMBER, // UnresolvedMemberExpr
- EXPR_CXX_UNRESOLVED_LOOKUP, // UnresolvedLookupExpr
-
- EXPR_CXX_EXPRESSION_TRAIT, // ExpressionTraitExpr
- EXPR_CXX_NOEXCEPT, // CXXNoexceptExpr
-
- EXPR_OPAQUE_VALUE, // OpaqueValueExpr
- EXPR_BINARY_CONDITIONAL_OPERATOR, // BinaryConditionalOperator
- EXPR_TYPE_TRAIT, // TypeTraitExpr
- EXPR_ARRAY_TYPE_TRAIT, // ArrayTypeTraitIntExpr
-
- EXPR_PACK_EXPANSION, // PackExpansionExpr
- EXPR_SIZEOF_PACK, // SizeOfPackExpr
- EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr
- EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr
- EXPR_FUNCTION_PARM_PACK, // FunctionParmPackExpr
- EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr
- EXPR_CXX_FOLD, // CXXFoldExpr
-
- // CUDA
- EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr
-
- // OpenCL
- EXPR_ASTYPE, // AsTypeExpr
-
- // Microsoft
- EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr
- EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR, // MSPropertySubscriptExpr
- EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr).
- EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type).
- STMT_SEH_LEAVE, // SEHLeaveStmt
- STMT_SEH_EXCEPT, // SEHExceptStmt
- STMT_SEH_FINALLY, // SEHFinallyStmt
- STMT_SEH_TRY, // SEHTryStmt
-
- // OpenMP directives
- STMT_OMP_PARALLEL_DIRECTIVE,
- STMT_OMP_SIMD_DIRECTIVE,
- STMT_OMP_FOR_DIRECTIVE,
- STMT_OMP_FOR_SIMD_DIRECTIVE,
- STMT_OMP_SECTIONS_DIRECTIVE,
- STMT_OMP_SECTION_DIRECTIVE,
- STMT_OMP_SINGLE_DIRECTIVE,
- STMT_OMP_MASTER_DIRECTIVE,
- STMT_OMP_CRITICAL_DIRECTIVE,
- STMT_OMP_PARALLEL_FOR_DIRECTIVE,
- STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE,
- STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE,
- STMT_OMP_TASK_DIRECTIVE,
- STMT_OMP_TASKYIELD_DIRECTIVE,
- STMT_OMP_BARRIER_DIRECTIVE,
- STMT_OMP_TASKWAIT_DIRECTIVE,
- STMT_OMP_FLUSH_DIRECTIVE,
- STMT_OMP_ORDERED_DIRECTIVE,
- STMT_OMP_ATOMIC_DIRECTIVE,
- STMT_OMP_TARGET_DIRECTIVE,
- STMT_OMP_TARGET_DATA_DIRECTIVE,
- STMT_OMP_TEAMS_DIRECTIVE,
- STMT_OMP_TASKGROUP_DIRECTIVE,
- STMT_OMP_CANCELLATION_POINT_DIRECTIVE,
- STMT_OMP_CANCEL_DIRECTIVE,
- STMT_OMP_TASKLOOP_DIRECTIVE,
- STMT_OMP_TASKLOOP_SIMD_DIRECTIVE,
- STMT_OMP_DISTRIBUTE_DIRECTIVE,
- EXPR_OMP_ARRAY_SECTION,
-
- // ARC
- EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
-
- STMT_MS_DEPENDENT_EXISTS, // MSDependentExistsStmt
- EXPR_LAMBDA // LambdaExpr
- };
-
- /// \brief The kinds of designators that can occur in a
- /// DesignatedInitExpr.
- enum DesignatorTypes {
- /// \brief Field designator where only the field name is known.
- DESIG_FIELD_NAME = 0,
- /// \brief Field designator where the field has been resolved to
- /// a declaration.
- DESIG_FIELD_DECL = 1,
- /// \brief Array designator.
- DESIG_ARRAY = 2,
- /// \brief GNU array range designator.
- DESIG_ARRAY_RANGE = 3
- };
-
- /// \brief The different kinds of data that can occur in a
- /// CtorInitializer.
- enum CtorInitializerType {
- CTOR_INITIALIZER_BASE,
- CTOR_INITIALIZER_DELEGATING,
- CTOR_INITIALIZER_MEMBER,
- CTOR_INITIALIZER_INDIRECT_MEMBER
- };
-
- /// \brief Describes the redeclarations of a declaration.
- struct LocalRedeclarationsInfo {
- DeclID FirstID; // The ID of the first declaration
- unsigned Offset; // Offset into the array of redeclaration chains.
-
- friend bool operator<(const LocalRedeclarationsInfo &X,
- const LocalRedeclarationsInfo &Y) {
- return X.FirstID < Y.FirstID;
- }
-
- friend bool operator>(const LocalRedeclarationsInfo &X,
- const LocalRedeclarationsInfo &Y) {
- return X.FirstID > Y.FirstID;
- }
-
- friend bool operator<=(const LocalRedeclarationsInfo &X,
- const LocalRedeclarationsInfo &Y) {
- return X.FirstID <= Y.FirstID;
- }
-
- friend bool operator>=(const LocalRedeclarationsInfo &X,
- const LocalRedeclarationsInfo &Y) {
- return X.FirstID >= Y.FirstID;
- }
- };
-
- /// \brief Describes the categories of an Objective-C class.
- struct ObjCCategoriesInfo {
- DeclID DefinitionID; // The ID of the definition
- unsigned Offset; // Offset into the array of category lists.
-
- friend bool operator<(const ObjCCategoriesInfo &X,
- const ObjCCategoriesInfo &Y) {
- return X.DefinitionID < Y.DefinitionID;
- }
-
- friend bool operator>(const ObjCCategoriesInfo &X,
- const ObjCCategoriesInfo &Y) {
- return X.DefinitionID > Y.DefinitionID;
- }
-
- friend bool operator<=(const ObjCCategoriesInfo &X,
- const ObjCCategoriesInfo &Y) {
- return X.DefinitionID <= Y.DefinitionID;
- }
-
- friend bool operator>=(const ObjCCategoriesInfo &X,
- const ObjCCategoriesInfo &Y) {
- return X.DefinitionID >= Y.DefinitionID;
- }
- };
-
- /// \brief 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
- /// contain types, in particular).
- class DeclarationNameKey {
- typedef unsigned NameKind;
-
- NameKind Kind;
- uint64_t Data;
-
- public:
- DeclarationNameKey() : Kind(), Data() {}
- DeclarationNameKey(DeclarationName Name);
-
- DeclarationNameKey(NameKind Kind, uint64_t Data)
- : Kind(Kind), Data(Data) {}
-
- NameKind getKind() const { return Kind; }
-
- IdentifierInfo *getIdentifier() const {
- assert(Kind == DeclarationName::Identifier ||
- Kind == DeclarationName::CXXLiteralOperatorName);
- return (IdentifierInfo *)Data;
- }
- Selector getSelector() const {
- assert(Kind == DeclarationName::ObjCZeroArgSelector ||
- Kind == DeclarationName::ObjCOneArgSelector ||
- Kind == DeclarationName::ObjCMultiArgSelector);
- return Selector(Data);
- }
- OverloadedOperatorKind getOperatorKind() const {
- assert(Kind == DeclarationName::CXXOperatorName);
- return (OverloadedOperatorKind)Data;
- }
-
- /// Compute a fingerprint of this key for use in on-disk hash table.
- unsigned getHash() const;
-
- friend bool operator==(const DeclarationNameKey &A,
- const DeclarationNameKey &B) {
- return A.Kind == B.Kind && A.Data == B.Data;
- }
- };
-
- /// @}
- }
-} // end namespace clang
-
-namespace llvm {
- template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> {
- static clang::serialization::DeclarationNameKey getEmptyKey() {
- return clang::serialization::DeclarationNameKey(-1, 1);
- }
- static clang::serialization::DeclarationNameKey getTombstoneKey() {
- return clang::serialization::DeclarationNameKey(-1, 2);
- }
- static unsigned
- getHashValue(const clang::serialization::DeclarationNameKey &Key) {
- return Key.getHash();
- }
- static bool isEqual(const clang::serialization::DeclarationNameKey &L,
- const clang::serialization::DeclarationNameKey &R) {
- return L == R;
- }
- };
-}
-
-#endif
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
deleted file mode 100644
index 4b10c39..0000000
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===- ASTDeserializationListener.h - Decl/Type PCH Read Events -*- 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 ASTDeserializationListener class, which is notified
-// by the ASTReader whenever a type or declaration is deserialized.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SERIALIZATION_ASTDESERIALIZATIONLISTENER_H
-#define LLVM_CLANG_SERIALIZATION_ASTDESERIALIZATIONLISTENER_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Serialization/ASTBitCodes.h"
-
-namespace clang {
-
-class Decl;
-class ASTReader;
-class QualType;
-class MacroDefinitionRecord;
-class MacroInfo;
-class Module;
-
-class ASTDeserializationListener {
-public:
- virtual ~ASTDeserializationListener();
-
- /// \brief The ASTReader was initialized.
- virtual void ReaderInitialized(ASTReader *Reader) { }
-
- /// \brief 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.
- virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { }
- /// \brief 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.
- virtual void DeclRead(serialization::DeclID ID, const Decl *D) { }
- /// \brief 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.
- virtual void MacroDefinitionRead(serialization::PreprocessedEntityID,
- MacroDefinitionRecord *MD) {}
- /// \brief A module definition was read from the AST file.
- virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {}
-};
-}
-
-#endif
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
deleted file mode 100644
index 588a6a9..0000000
--- a/include/clang/Serialization/ASTReader.h
+++ /dev/null
@@ -1,2141 +0,0 @@
-//===--- ASTReader.h - AST File Reader --------------------------*- 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 ASTReader class, which reads AST files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_H
-#define LLVM_CLANG_SERIALIZATION_ASTREADER_H
-
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Version.h"
-#include "clang/Lex/ExternalPreprocessorSource.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/PreprocessingRecord.h"
-#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Serialization/ContinuousRangeMap.h"
-#include "clang/Serialization/Module.h"
-#include "clang/Serialization/ModuleFileExtension.h"
-#include "clang/Serialization/ModuleManager.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/Timer.h"
-#include <deque>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace llvm {
- class MemoryBuffer;
-}
-
-namespace clang {
-
-class AddrLabelExpr;
-class ASTConsumer;
-class ASTContext;
-class ASTIdentifierIterator;
-class ASTUnit; // FIXME: Layering violation and egregious hack.
-class Attr;
-class Decl;
-class DeclContext;
-class DefMacroDirective;
-class DiagnosticOptions;
-class NestedNameSpecifier;
-class CXXBaseSpecifier;
-class CXXConstructorDecl;
-class CXXCtorInitializer;
-class GlobalModuleIndex;
-class GotoStmt;
-class MacroDefinition;
-class MacroDirective;
-class ModuleMacro;
-class NamedDecl;
-class OpaqueValueExpr;
-class Preprocessor;
-class PreprocessorOptions;
-class Sema;
-class SwitchCase;
-class ASTDeserializationListener;
-class ASTWriter;
-class ASTReader;
-class ASTDeclReader;
-class ASTStmtReader;
-class TypeLocReader;
-struct HeaderFileInfo;
-class VersionTuple;
-class TargetOptions;
-class LazyASTUnresolvedSet;
-
-/// \brief 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
-/// return true to indicate to the ASTReader that the information (and
-/// consequently the AST file) is invalid.
-class ASTReaderListener {
-public:
- virtual ~ASTReaderListener();
-
- /// \brief Receives the full Clang version information.
- ///
- /// \returns true to indicate that the version is invalid. Subclasses should
- /// generally defer to this implementation.
- virtual bool ReadFullVersionInformation(StringRef FullVersion) {
- return FullVersion != getClangFullRepositoryVersion();
- }
-
- virtual void ReadModuleName(StringRef ModuleName) {}
- virtual void ReadModuleMapFile(StringRef ModuleMapPath) {}
-
- /// \brief Receives the language options.
- ///
- /// \returns true to indicate the options are invalid or false otherwise.
- virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
- bool Complain,
- bool AllowCompatibleDifferences) {
- return false;
- }
-
- /// \brief Receives the target options.
- ///
- /// \returns true to indicate the target options are invalid, or false
- /// otherwise.
- virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
- bool AllowCompatibleDifferences) {
- return false;
- }
-
- /// \brief Receives the diagnostic options.
- ///
- /// \returns true to indicate the diagnostic options are invalid, or false
- /// otherwise.
- virtual bool
- ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
- bool Complain) {
- return false;
- }
-
- /// \brief Receives the file system options.
- ///
- /// \returns true to indicate the file system options are invalid, or false
- /// otherwise.
- virtual bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
- bool Complain) {
- return false;
- }
-
- /// \brief Receives the header search options.
- ///
- /// \returns true to indicate the header search options are invalid, or false
- /// otherwise.
- virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
- StringRef SpecificModuleCachePath,
- bool Complain) {
- return false;
- }
-
- /// \brief 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
- /// loading a precompiled header.
- ///
- /// \returns true to indicate the preprocessor options are invalid, or false
- /// otherwise.
- virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
- bool Complain,
- std::string &SuggestedPredefines) {
- return false;
- }
-
- /// \brief Receives __COUNTER__ value.
- virtual void ReadCounter(const serialization::ModuleFile &M,
- unsigned Value) {}
-
- /// This is called for each AST file loaded.
- virtual void visitModuleFile(StringRef Filename,
- serialization::ModuleKind Kind) {}
-
- /// \brief 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
- /// 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
- /// 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.
- ///
- /// \returns true to continue receiving the next input file, false to stop.
- virtual bool visitInputFile(StringRef Filename, bool isSystem,
- bool isOverridden, bool isExplicitModule) {
- return true;
- }
-
- /// \brief 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
- /// AST file imported by this AST file.
- virtual void visitImport(StringRef Filename) {}
-
- /// Indicates that a particular module file extension has been read.
- virtual void readModuleFileExtension(
- const ModuleFileExtensionMetadata &Metadata) {}
-};
-
-/// \brief Simple wrapper class for chaining listeners.
-class ChainedASTReaderListener : public ASTReaderListener {
- std::unique_ptr<ASTReaderListener> First;
- std::unique_ptr<ASTReaderListener> Second;
-
-public:
- /// Takes ownership of \p First and \p Second.
- ChainedASTReaderListener(std::unique_ptr<ASTReaderListener> First,
- std::unique_ptr<ASTReaderListener> Second)
- : First(std::move(First)), Second(std::move(Second)) {}
-
- std::unique_ptr<ASTReaderListener> takeFirst() { return std::move(First); }
- std::unique_ptr<ASTReaderListener> takeSecond() { return std::move(Second); }
-
- bool ReadFullVersionInformation(StringRef FullVersion) override;
- void ReadModuleName(StringRef ModuleName) override;
- void ReadModuleMapFile(StringRef ModuleMapPath) override;
- bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
- bool AllowCompatibleDifferences) override;
- bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
- bool AllowCompatibleDifferences) override;
- bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
- bool Complain) override;
- bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
- bool Complain) override;
-
- bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
- StringRef SpecificModuleCachePath,
- bool Complain) override;
- bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
- bool Complain,
- std::string &SuggestedPredefines) override;
-
- void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
- bool needsInputFileVisitation() override;
- bool needsSystemInputFileVisitation() override;
- void visitModuleFile(StringRef Filename,
- serialization::ModuleKind Kind) override;
- bool visitInputFile(StringRef Filename, bool isSystem,
- bool isOverridden, bool isExplicitModule) override;
- void readModuleFileExtension(
- const ModuleFileExtensionMetadata &Metadata) override;
-};
-
-/// \brief ASTReaderListener implementation to validate the information of
-/// the PCH file against an initialized Preprocessor.
-class PCHValidator : public ASTReaderListener {
- Preprocessor &PP;
- ASTReader &Reader;
-
-public:
- PCHValidator(Preprocessor &PP, ASTReader &Reader)
- : PP(PP), Reader(Reader) {}
-
- bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
- bool AllowCompatibleDifferences) override;
- bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
- bool AllowCompatibleDifferences) override;
- bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
- bool Complain) override;
- bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
- std::string &SuggestedPredefines) override;
- bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
- StringRef SpecificModuleCachePath,
- bool Complain) override;
- void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
-
-private:
- void Error(const char *Msg);
-};
-
-namespace serialization {
-
-class ReadMethodPoolVisitor;
-
-namespace reader {
- class ASTIdentifierLookupTrait;
- /// \brief The on-disk hash table(s) used for DeclContext name lookup.
- struct DeclContextLookupTable;
-}
-
-} // end namespace serialization
-
-/// \brief Reads an AST files chain containing the contents of a translation
-/// unit.
-///
-/// The ASTReader class reads bitstreams (produced by the ASTWriter
-/// class) containing the serialized representation of a given
-/// abstract syntax tree and its supporting data structures. An
-/// instance of the ASTReader can be attached to an ASTContext object,
-/// which will provide access to the contents of the AST files.
-///
-/// The AST reader provides lazy de-serialization of declarations, as
-/// required when traversing the AST. Only those AST nodes that are
-/// actually required will be de-serialized.
-class ASTReader
- : public ExternalPreprocessorSource,
- public ExternalPreprocessingRecordSource,
- public ExternalHeaderFileInfoSource,
- public ExternalSemaSource,
- public IdentifierInfoLookup,
- public ExternalSLocEntrySource
-{
-public:
- typedef SmallVector<uint64_t, 64> RecordData;
- typedef SmallVectorImpl<uint64_t> RecordDataImpl;
-
- /// \brief 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 AST file is safe to read into the current context.
- Success,
- /// \brief The AST file itself appears corrupted.
- Failure,
- /// \brief The AST file was missing.
- Missing,
- /// \brief 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.
- VersionMismatch,
- /// \brief The AST file was writtten with a different language/target
- /// configuration.
- ConfigurationMismatch,
- /// \brief The AST file has errors.
- HadErrors
- };
-
- /// \brief Types of AST files.
- friend class PCHValidator;
- friend class ASTDeclReader;
- friend class ASTStmtReader;
- friend class ASTIdentifierIterator;
- friend class serialization::reader::ASTIdentifierLookupTrait;
- friend class TypeLocReader;
- friend class ASTWriter;
- friend class ASTUnit; // ASTUnit needs to remap source locations.
- friend class serialization::ReadMethodPoolVisitor;
-
- typedef serialization::ModuleFile ModuleFile;
- typedef serialization::ModuleKind ModuleKind;
- typedef serialization::ModuleManager ModuleManager;
-
- typedef ModuleManager::ModuleIterator ModuleIterator;
- typedef ModuleManager::ModuleConstIterator ModuleConstIterator;
- typedef ModuleManager::ModuleReverseIterator ModuleReverseIterator;
-
-private:
- /// \brief The receiver of some callbacks invoked by ASTReader.
- std::unique_ptr<ASTReaderListener> Listener;
-
- /// \brief The receiver of deserialization events.
- ASTDeserializationListener *DeserializationListener;
- bool OwnsDeserializationListener;
-
- SourceManager &SourceMgr;
- FileManager &FileMgr;
- const PCHContainerReader &PCHContainerRdr;
- DiagnosticsEngine &Diags;
-
- /// \brief The semantic analysis object that will be processing the
- /// AST files and the translation unit that uses it.
- Sema *SemaObj;
-
- /// \brief The preprocessor that will be loading the source file.
- Preprocessor &PP;
-
- /// \brief The AST context into which we'll read the AST files.
- ASTContext &Context;
-
- /// \brief The AST consumer.
- ASTConsumer *Consumer;
-
- /// \brief The module manager which manages modules and their dependencies
- ModuleManager ModuleMgr;
-
- /// A mapping from extension block names to module file extensions.
- llvm::StringMap<IntrusiveRefCntPtr<ModuleFileExtension>> ModuleFileExtensions;
-
- /// \brief 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
- /// imported from. For non-module AST types it should be invalid.
- SourceLocation CurrentImportLoc;
-
- /// \brief The global module index, if loaded.
- std::unique_ptr<GlobalModuleIndex> GlobalIndex;
-
- /// \brief 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.
- ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocEntryMap;
-
- typedef ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocOffsetMapType;
-
- /// \brief 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.
- ///
- /// When the pointer at index I is non-NULL, the type with
- /// ID = (I + 1) << FastQual::Width has already been loaded
- std::vector<QualType> TypesLoaded;
-
- typedef ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>
- GlobalTypeMapType;
-
- /// \brief 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.
- ///
- /// When the pointer at index I is non-NULL, the declaration with ID
- /// = I + 1 has already been loaded.
- std::vector<Decl *> DeclsLoaded;
-
- typedef ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>
- GlobalDeclMapType;
-
- /// \brief Mapping from global declaration IDs to the module in which the
- /// declaration resides.
- GlobalDeclMapType GlobalDeclMap;
-
- typedef std::pair<ModuleFile *, uint64_t> FileOffset;
- typedef SmallVector<FileOffset, 2> FileOffsetsTy;
- typedef llvm::DenseMap<serialization::DeclID, FileOffsetsTy>
- DeclUpdateOffsetsMap;
-
- /// \brief Declarations that have modifications residing in a later file
- /// in the chain.
- DeclUpdateOffsetsMap DeclUpdateOffsets;
-
- /// \brief Declaration updates for already-loaded declarations that we need
- /// to apply once we finish processing an import.
- llvm::SmallVector<std::pair<serialization::GlobalDeclID, Decl*>, 16>
- PendingUpdateRecords;
-
- enum class PendingFakeDefinitionKind { NotFake, Fake, FakeLoaded };
-
- /// \brief 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
- /// 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;
-
- struct ReplacedDeclInfo {
- ModuleFile *Mod;
- uint64_t Offset;
- unsigned RawLoc;
-
- ReplacedDeclInfo() : Mod(nullptr), Offset(0), RawLoc(0) {}
- ReplacedDeclInfo(ModuleFile *Mod, uint64_t Offset, unsigned RawLoc)
- : Mod(Mod), Offset(Offset), RawLoc(RawLoc) {}
- };
-
- typedef llvm::DenseMap<serialization::DeclID, ReplacedDeclInfo>
- DeclReplacementMap;
- /// \brief Declarations that have been replaced in a later file in the chain.
- DeclReplacementMap ReplacedDecls;
-
- /// \brief 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
- /// within them, and those anonymous declarations.
- llvm::DenseMap<DeclContext*, llvm::SmallVector<NamedDecl*, 2>>
- AnonymousDeclarationsForMerging;
-
- struct FileDeclsInfo {
- ModuleFile *Mod;
- ArrayRef<serialization::LocalDeclID> Decls;
-
- FileDeclsInfo() : Mod(nullptr) {}
- FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls)
- : Mod(Mod), Decls(Decls) {}
- };
-
- /// \brief 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
- /// Decl::Kind, DeclID pairs.
- typedef ArrayRef<llvm::support::unaligned_uint32_t> LexicalContents;
-
- /// \brief 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.
- std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls;
-
- /// \brief Map from a DeclContext to its lookup tables.
- llvm::DenseMap<const DeclContext *,
- serialization::reader::DeclContextLookupTable> Lookups;
-
- // Updates for visible decls can occur for other contexts than just the
- // TU, and when we read those update records, the actual context may not
- // be available yet, so have this pending map using the ID as a key. It
- // will be realized when the context is actually loaded.
- struct PendingVisibleUpdate {
- ModuleFile *Mod;
- const unsigned char *Data;
- };
- typedef SmallVector<PendingVisibleUpdate, 1> DeclContextVisibleUpdates;
-
- /// \brief 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
- /// declarations that have not yet been linked to their definitions.
- llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
-
- typedef llvm::MapVector<Decl *, uint64_t,
- llvm::SmallDenseMap<Decl *, unsigned, 4>,
- SmallVector<std::pair<Decl *, uint64_t>, 4> >
- PendingBodiesMap;
-
- /// \brief Functions or methods that have bodies that will be attached.
- PendingBodiesMap PendingBodies;
-
- /// \brief 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.
- bool ReadLexicalDeclContextStorage(ModuleFile &M,
- llvm::BitstreamCursor &Cursor,
- uint64_t Offset, DeclContext *DC);
- /// \brief 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
- /// loaded.
- ///
- /// If the pointer at index I is non-NULL, then it refers to the
- /// IdentifierInfo for the identifier with ID=I+1 that has already
- /// been loaded.
- std::vector<IdentifierInfo *> IdentifiersLoaded;
-
- typedef ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4>
- GlobalIdentifierMapType;
-
- /// \brief 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
- /// loaded.
- ///
- /// If the pointer at index I is non-NULL, then it refers to the
- /// MacroInfo for the identifier with ID=I+1 that has already
- /// been loaded.
- std::vector<MacroInfo *> MacrosLoaded;
-
- typedef std::pair<IdentifierInfo *, serialization::SubmoduleID>
- LoadedMacroInfo;
-
- /// \brief 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;
-
- typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>
- GlobalMacroMapType;
-
- /// \brief 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.
- ///
- /// This vector is indexed by the Submodule ID (-1). NULL submodule entries
- /// indicate that the particular submodule ID has not yet been loaded.
- SmallVector<Module *, 2> SubmodulesLoaded;
-
- typedef ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4>
- GlobalSubmoduleMapType;
-
- /// \brief 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.
- typedef SmallVector<Decl*, 2> HiddenNames;
- typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
-
- /// \brief 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.
- struct UnresolvedModuleRef {
- /// \brief The file in which this module resides.
- ModuleFile *File;
-
- /// \brief The module that is importing or exporting.
- Module *Mod;
-
- /// \brief The kind of module reference.
- enum { Import, Export, Conflict } Kind;
-
- /// \brief The local ID of the module that is being exported.
- unsigned ID;
-
- /// \brief Whether this is a wildcard export.
- unsigned IsWildcard : 1;
-
- /// \brief String data.
- StringRef String;
- };
-
- /// \brief 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.
- ///
- /// This vector is indexed by the Selector ID (-1). NULL selector
- /// entries indicate that the particular selector ID has not yet
- /// been loaded.
- SmallVector<Selector, 16> SelectorsLoaded;
-
- typedef ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4>
- GlobalSelectorMapType;
-
- /// \brief 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
- /// global method pool for this selector.
- llvm::DenseMap<Selector, unsigned> SelectorGeneration;
-
- struct PendingMacroInfo {
- ModuleFile *M;
- uint64_t MacroDirectivesOffset;
-
- PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset)
- : M(M), MacroDirectivesOffset(MacroDirectivesOffset) {}
- };
-
- typedef llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2> >
- PendingMacroIDsMap;
-
- /// \brief 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;
-
- typedef ContinuousRangeMap<unsigned, ModuleFile *, 4>
- GlobalPreprocessedEntityMapType;
-
- /// \brief 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 entitiy ID to produce a local ID.
- GlobalPreprocessedEntityMapType GlobalPreprocessedEntityMap;
-
- /// \name CodeGen-relevant special data
- /// \brief Fields containing data that is relevant to CodeGen.
- //@{
-
- /// \brief The IDs of all declarations that fulfill the criteria of
- /// "interesting" decls.
- ///
- /// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks
- /// in the chain. The referenced declarations are deserialized and passed to
- /// the consumer eagerly.
- SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
-
- /// \brief 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
- /// 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.
- ///
- /// 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
- /// instantiation where the first value is the ID of the decl and the second
- /// is the instantiation location.
- SmallVector<uint64_t, 64> PendingInstantiations;
-
- //@}
-
- /// \name DiagnosticsEngine-relevant special data
- /// \brief Fields containing data that is used for generating diagnostics
- //@{
-
- /// \brief 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
- /// cycles.
- SmallVector<uint64_t, 4> DelegatingCtorDecls;
-
- /// \brief 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
- /// generating warnings.
- SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers;
-
- /// \brief 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;
-
- //@}
-
- /// \name Sema-relevant special data
- /// \brief Fields containing data that is used for semantic analysis
- //@{
-
- /// \brief The IDs of all potentially unused typedef names in the chain.
- ///
- /// Sema tracks these to emit warnings.
- SmallVector<uint64_t, 16> UnusedLocalTypedefNameCandidates;
-
- /// \brief 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 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 AST context tracks a few important decls, currently cudaConfigureCall,
- /// directly.
- SmallVector<uint64_t, 2> CUDASpecialDeclRefs;
-
- /// \brief The floating point pragma option settings.
- SmallVector<uint64_t, 1> FPPragmaOptions;
-
- /// \brief The pragma clang optimize location (if the pragma state is "off").
- SourceLocation OptimizeOffPragmaLocation;
-
- /// \brief The OpenCL extension settings.
- SmallVector<uint64_t, 1> OpenCLExtensions;
-
- /// \brief 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
- /// SourceLocation of a matching ODR-use.
- SmallVector<uint64_t, 8> UndefinedButUsed;
-
- /// \brief Delete expressions to analyze at the end of translation unit.
- SmallVector<uint64_t, 8> DelayedDeleteExprs;
-
- // \brief A list of late parsed template function data.
- SmallVector<uint64_t, 1> LateParsedTemplates;
-
- struct ImportedSubmodule {
- serialization::SubmoduleID ID;
- SourceLocation ImportLoc;
-
- ImportedSubmodule(serialization::SubmoduleID ID, SourceLocation ImportLoc)
- : ID(ID), ImportLoc(ImportLoc) {}
- };
-
- /// \brief A list of modules that were imported by precompiled headers or
- /// any other non-module AST file.
- SmallVector<ImportedSubmodule, 2> ImportedModules;
- //@}
-
- /// \brief The directory that the PCH we are reading is stored in.
- std::string CurrentDir;
-
- /// \brief 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
- /// headers when they are loaded.
- bool DisableValidation;
-
- /// \brief Whether to accept an AST file with compiler errors.
- bool AllowASTWithCompilerErrors;
-
- /// \brief Whether to accept an AST file that has a different configuration
- /// from the current compiler instance.
- bool AllowConfigurationMismatch;
-
- /// \brief Whether validate system input files.
- bool ValidateSystemInputs;
-
- /// \brief Whether we are allowed to use the global module index.
- bool UseGlobalIndex;
-
- /// \brief Whether we have tried loading the global module index yet.
- bool TriedLoadingGlobalIndex;
-
- typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy;
- /// \brief 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.
- SwitchCaseMapTy SwitchCaseStmts;
-
- SwitchCaseMapTy *CurrSwitchCaseStmts;
-
- /// \brief The number of source location entries de-serialized from
- /// the PCH file.
- unsigned NumSLocEntriesRead;
-
- /// \brief The number of source location entries in the chain.
- unsigned TotalNumSLocEntries;
-
- /// \brief The number of statements (and expressions) de-serialized
- /// from the chain.
- unsigned NumStatementsRead;
-
- /// \brief The total number of statements (and expressions) stored
- /// in the chain.
- unsigned TotalNumStatements;
-
- /// \brief The number of macros de-serialized from the chain.
- unsigned NumMacrosRead;
-
- /// \brief The total number of macros stored in the chain.
- unsigned TotalNumMacros;
-
- /// \brief The number of lookups into identifier tables.
- unsigned NumIdentifierLookups;
-
- /// \brief The number of lookups into identifier tables that succeed.
- unsigned NumIdentifierLookupHits;
-
- /// \brief The number of selectors that have been read.
- unsigned NumSelectorsRead;
-
- /// \brief The number of method pool entries that have been read.
- unsigned NumMethodPoolEntriesRead;
-
- /// \brief The number of times we have looked up a selector in the method
- /// pool.
- unsigned NumMethodPoolLookups;
-
- /// \brief The number of times we have looked up a selector in the method
- /// pool and found something.
- unsigned NumMethodPoolHits;
-
- /// \brief The number of times we have looked up a selector in the method
- /// pool within a specific module.
- unsigned NumMethodPoolTableLookups;
-
- /// \brief The number of times we have looked up a selector in the method
- /// pool within a specific module and found something.
- unsigned NumMethodPoolTableHits;
-
- /// \brief The total number of method pool entries in the selector table.
- unsigned TotalNumMethodPoolEntries;
-
- /// Number of lexical decl contexts read/total.
- unsigned NumLexicalDeclContextsRead, TotalLexicalDeclContexts;
-
- /// Number of visible decl contexts read/total.
- unsigned NumVisibleDeclContextsRead, TotalVisibleDeclContexts;
-
- /// Total size of modules, in bits, currently loaded
- uint64_t TotalModulesSizeInBits;
-
- /// \brief Number of Decl/types that are currently deserializing.
- unsigned NumCurrentElementsDeserializing;
-
- /// \brief 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;
-
- /// \brief 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
- /// loaded once the recursive loading has completed.
- llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4> >
- PendingIdentifierInfos;
-
- /// \brief 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 last time we loaded information about this identifier.
- llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration;
-
- /// \brief Contains declarations and definitions that will be
- /// "interesting" to the ASTConsumer, when we get that AST consumer.
- ///
- /// "Interesting" declarations are those that have data that may
- /// need to be emitted, such as inline function definitions or
- /// Objective-C protocols.
- std::deque<Decl *> InterestingDecls;
-
- /// \brief 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
- /// 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
- /// been loaded but its DeclContext was not set yet.
- struct PendingDeclContextInfo {
- Decl *D;
- serialization::GlobalDeclID SemaDC;
- serialization::GlobalDeclID LexicalDC;
- };
-
- /// \brief 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
- /// context that has been merged into another context where the corresponding
- /// declaration is either missing or has not yet been loaded.
- ///
- /// We will check whether the corresponding declaration is in fact missing
- /// once recursing loading has been completed.
- llvm::SmallVector<NamedDecl *, 16> PendingOdrMergeChecks;
-
- /// \brief Record definitions in which we found an ODR violation.
- llvm::SmallDenseMap<CXXRecordDecl *, llvm::TinyPtrVector<CXXRecordDecl *>, 2>
- PendingOdrMergeFailures;
-
- /// \brief 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
- /// 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
- /// loaded, for which we will need to check for categories whenever a new
- /// module is loaded.
- SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
-
- typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> >
- KeyDeclsMap;
-
- /// \brief 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
- /// 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
- /// 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.
- SmallVector<Stmt *, 16> StmtStack;
-
- /// \brief 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.
- ReadingKind ReadingKind;
-
- /// \brief RAII object to change the reading kind.
- class ReadingKindTracker {
- ASTReader &Reader;
- enum ReadingKind PrevKind;
-
- ReadingKindTracker(const ReadingKindTracker &) = delete;
- void operator=(const ReadingKindTracker &) = delete;
-
- public:
- ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader)
- : Reader(reader), PrevKind(Reader.ReadingKind) {
- Reader.ReadingKind = newKind;
- }
-
- ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; }
- };
-
- /// \brief Suggested contents of the predefines buffer, after this
- /// PCH file has been processed.
- ///
- /// In most cases, this string will be empty, because the predefines
- /// buffer computed to build the PCH file will be identical to the
- /// predefines buffer computed from the command line. However, when
- /// there are differences that the PCH reader can work around, this
- /// predefines buffer may contain additional definitions.
- std::string SuggestedPredefines;
-
- /// \brief Reads a statement from the specified cursor.
- Stmt *ReadStmtFromStream(ModuleFile &F);
-
- struct InputFileInfo {
- std::string Filename;
- off_t StoredSize;
- time_t StoredTime;
- bool Overridden;
- bool Transient;
- };
-
- /// \brief 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
- /// file in the given module file.
- serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
- bool Complain = true);
-
-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
- /// 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) {
- D = D->getCanonicalDecl();
- if (D->isFromASTFile())
- return D;
-
- auto I = KeyDecls.find(D);
- if (I == KeyDecls.end() || I->second.empty())
- return D;
- return GetExistingDecl(I->second[0]);
- }
- const Decl *getKeyDeclaration(const Decl *D) {
- return getKeyDeclaration(const_cast<Decl*>(D));
- }
-
- /// \brief Run a callback on each imported key declaration of \p D.
- template <typename Fn>
- void forEachImportedKeyDecl(const Decl *D, Fn Visit) {
- D = D->getCanonicalDecl();
- if (D->isFromASTFile())
- Visit(D);
-
- auto It = KeyDecls.find(const_cast<Decl*>(D));
- if (It != KeyDecls.end())
- for (auto ID : It->second)
- Visit(GetExistingDecl(ID));
- }
-
- /// \brief Get the loaded lookup tables for \p Primary, if any.
- const serialization::reader::DeclContextLookupTable *
- getLoadedLookupTables(DeclContext *Primary) const;
-
-private:
- struct ImportedModule {
- ModuleFile *Mod;
- ModuleFile *ImportedBy;
- SourceLocation ImportLoc;
-
- ImportedModule(ModuleFile *Mod,
- ModuleFile *ImportedBy,
- SourceLocation ImportLoc)
- : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) { }
- };
-
- ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type,
- SourceLocation ImportLoc, ModuleFile *ImportedBy,
- SmallVectorImpl<ImportedModule> &Loaded,
- off_t ExpectedSize, time_t ExpectedModTime,
- serialization::ASTFileSignature ExpectedSignature,
- unsigned ClientLoadCapabilities);
- ASTReadResult ReadControlBlock(ModuleFile &F,
- SmallVectorImpl<ImportedModule> &Loaded,
- const ModuleFile *ImportedBy,
- unsigned ClientLoadCapabilities);
- static ASTReadResult ReadOptionsBlock(
- llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
- bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
- std::string &SuggestedPredefines);
- ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
- ASTReadResult ReadExtensionBlock(ModuleFile &F);
- bool ParseLineTable(ModuleFile &F, const RecordData &Record);
- bool ReadSourceManagerBlock(ModuleFile &F);
- llvm::BitstreamCursor &SLocCursorForID(int ID);
- SourceLocation getImportLocation(ModuleFile *F);
- ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
- const ModuleFile *ImportedBy,
- unsigned ClientLoadCapabilities);
- ASTReadResult ReadSubmoduleBlock(ModuleFile &F,
- unsigned ClientLoadCapabilities);
- static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener,
- bool AllowCompatibleDifferences);
- static bool ParseTargetOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener,
- bool AllowCompatibleDifferences);
- static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener);
- static bool ParseFileSystemOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener);
- static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener);
- static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener,
- std::string &SuggestedPredefines);
-
- struct RecordLocation {
- RecordLocation(ModuleFile *M, uint64_t O)
- : F(M), Offset(O) {}
- ModuleFile *F;
- uint64_t Offset;
- };
-
- QualType readTypeRecord(unsigned Index);
- void readExceptionSpec(ModuleFile &ModuleFile,
- SmallVectorImpl<QualType> &ExceptionStorage,
- FunctionProtoType::ExceptionSpecInfo &ESI,
- const RecordData &Record, unsigned &Index);
- RecordLocation TypeCursorForIndex(unsigned Index);
- void LoadedDecl(unsigned Index, Decl *D);
- Decl *ReadDeclRecord(serialization::DeclID ID);
- void markIncompleteDeclChain(Decl *Canon);
-
- /// \brief 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);
-
- RecordLocation DeclCursorForID(serialization::DeclID ID,
- unsigned &RawLocation);
- void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D);
- void loadPendingDeclChain(Decl *D, uint64_t LocalOffset);
- void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D,
- unsigned PreviousGeneration = 0);
-
- 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
- /// \arg Loc.
- serialization::PreprocessedEntityID
- findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const;
-
- /// \brief 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
- /// preprocessed entities or the entities it contains are not the
- /// ones we are looking for.
- serialization::PreprocessedEntityID
- findNextPreprocessedEntity(
- GlobalSLocOffsetMapType::const_iterator SLocMapI) const;
-
- /// \brief 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
- /// particular module.
- llvm::iterator_range<PreprocessingRecord::iterator>
- getModulePreprocessedEntities(ModuleFile &Mod) const;
-
- class ModuleDeclIterator
- : public llvm::iterator_adaptor_base<
- ModuleDeclIterator, const serialization::LocalDeclID *,
- std::random_access_iterator_tag, const Decl *, ptrdiff_t,
- const Decl *, const Decl *> {
- ASTReader *Reader;
- ModuleFile *Mod;
-
- public:
- ModuleDeclIterator()
- : iterator_adaptor_base(nullptr), Reader(nullptr), Mod(nullptr) {}
-
- ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod,
- const serialization::LocalDeclID *Pos)
- : iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {}
-
- value_type operator*() const {
- return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I));
- }
- value_type operator->() const { return **this; }
-
- bool operator==(const ModuleDeclIterator &RHS) const {
- assert(Reader == RHS.Reader && Mod == RHS.Mod);
- return I == RHS.I;
- }
- };
-
- llvm::iterator_range<ModuleDeclIterator>
- getModuleFileLevelDecls(ModuleFile &Mod);
-
- void PassInterestingDeclsToConsumer();
- void PassInterestingDeclToConsumer(Decl *D);
-
- void finishPendingActions();
- void diagnoseOdrViolations();
-
- void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name);
-
- void addPendingDeclContextInfo(Decl *D,
- serialization::GlobalDeclID SemaDC,
- serialization::GlobalDeclID LexicalDC) {
- assert(D);
- PendingDeclContextInfo Info = { D, SemaDC, LexicalDC };
- PendingDeclContextInfos.push_back(Info);
- }
-
- /// \brief 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).
- void Error(StringRef Msg);
- void Error(unsigned DiagID, StringRef Arg1 = StringRef(),
- StringRef Arg2 = StringRef());
-
- ASTReader(const ASTReader &) = delete;
- void operator=(const ASTReader &) = delete;
-public:
- /// \brief Load the AST file and validate its contents against the given
- /// Preprocessor.
- ///
- /// \param PP the preprocessor associated with the context in which this
- /// precompiled header will be loaded.
- ///
- /// \param Context the AST context that this precompiled header will be
- /// loaded into.
- ///
- /// \param PCHContainerRdr the PCHContainerOperations to use for loading and
- /// creating modules.
- ///
- /// \param Extensions the list of module file extensions that can be loaded
- /// from the AST files.
- ///
- /// \param isysroot If non-NULL, the system include path specified by the
- /// user. This is only used with relocatable PCH files. If non-NULL,
- /// a relocatable PCH file will use the default path "/".
- ///
- /// \param DisableValidation If true, the AST reader will suppress most
- /// of its regular consistency checking, allowing the use of precompiled
- /// headers that cannot be determined to be compatible.
- ///
- /// \param AllowASTWithCompilerErrors If true, the AST reader will accept an
- /// AST file the was created out of an AST with compiler errors,
- /// otherwise it will reject it.
- ///
- /// \param AllowConfigurationMismatch If true, the AST reader will not check
- /// for configuration differences between the AST file and the invocation.
- ///
- /// \param ValidateSystemInputs If true, the AST reader will validate
- /// system input files in addition to user input files. This is only
- /// meaningful if \p DisableValidation is false.
- ///
- /// \param UseGlobalIndex If true, the AST reader will try to load and use
- /// the global module index.
- ///
- /// \param ReadTimer If non-null, a timer used to track the time spent
- /// deserializing.
- ASTReader(Preprocessor &PP, ASTContext &Context,
- const PCHContainerReader &PCHContainerRdr,
- ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
- StringRef isysroot = "", bool DisableValidation = false,
- bool AllowASTWithCompilerErrors = false,
- bool AllowConfigurationMismatch = false,
- bool ValidateSystemInputs = false, bool UseGlobalIndex = true,
- std::unique_ptr<llvm::Timer> ReadTimer = {});
-
- ~ASTReader() override;
-
- SourceManager &getSourceManager() const { return SourceMgr; }
- FileManager &getFileManager() const { return FileMgr; }
- DiagnosticsEngine &getDiags() const { return Diags; }
-
- /// \brief 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.
- ARR_None = 0,
- /// \brief 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
- /// 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
- /// 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
- /// 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.
- ///
- /// \param FileName The name of the AST file to load.
- ///
- /// \param Type The kind of AST being loaded, e.g., PCH, module, main file,
- /// or preamble.
- ///
- /// \param ImportLoc the location where the module file will be considered as
- /// imported from. For non-module AST types it should be invalid.
- ///
- /// \param ClientLoadCapabilities The set of client load-failure
- /// capabilities, represented as a bitset of the enumerators of
- /// LoadFailureCapabilities.
- ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type,
- SourceLocation ImportLoc,
- unsigned ClientLoadCapabilities);
-
- /// \brief 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.
- ///
- /// \param NameVisibility The level of visibility to give the names in the
- /// module. Visibility can only be increased over time.
- ///
- /// \param ImportLoc The location at which the import occurs.
- void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind NameVisibility,
- SourceLocation ImportLoc);
-
- /// \brief Make the names within this set of hidden names visible.
- void makeNamesVisible(const HiddenNames &Names, Module *Owner);
-
- /// \brief Take the AST callbacks listener.
- std::unique_ptr<ASTReaderListener> takeListener() {
- return std::move(Listener);
- }
-
- /// \brief Set the AST callbacks listener.
- void setListener(std::unique_ptr<ASTReaderListener> Listener) {
- this->Listener = std::move(Listener);
- }
-
- /// \brief Add an AST callback listener.
- ///
- /// Takes ownership of \p L.
- void addListener(std::unique_ptr<ASTReaderListener> L) {
- if (Listener)
- L = llvm::make_unique<ChainedASTReaderListener>(std::move(L),
- std::move(Listener));
- Listener = std::move(L);
- }
-
- /// RAII object to temporarily add an AST callback listener.
- class ListenerScope {
- ASTReader &Reader;
- bool Chained;
-
- public:
- ListenerScope(ASTReader &Reader, std::unique_ptr<ASTReaderListener> L)
- : Reader(Reader), Chained(false) {
- auto Old = Reader.takeListener();
- if (Old) {
- Chained = true;
- L = llvm::make_unique<ChainedASTReaderListener>(std::move(L),
- std::move(Old));
- }
- Reader.setListener(std::move(L));
- }
- ~ListenerScope() {
- auto New = Reader.takeListener();
- if (Chained)
- Reader.setListener(static_cast<ChainedASTReaderListener *>(New.get())
- ->takeSecond());
- }
- };
-
- /// \brief Set the AST deserialization listener.
- void setDeserializationListener(ASTDeserializationListener *Listener,
- bool TakeOwnership = false);
-
- /// \brief Determine whether this AST reader has a global index.
- bool hasGlobalIndex() const { return (bool)GlobalIndex; }
-
- /// \brief Return global module index.
- GlobalModuleIndex *getGlobalIndex() { return GlobalIndex.get(); }
-
- /// \brief Reset reader for a reload try.
- void resetForReload() { TriedLoadingGlobalIndex = false; }
-
- /// \brief 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,
- /// e.g., because it is out-of-date or does not exist.
- bool isGlobalIndexUnavailable() const;
-
- /// \brief Initializes the ASTContext
- void InitializeContext();
-
- /// \brief Update the state of Sema after loading some additional modules.
- void UpdateSema();
-
- /// \brief 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
- /// disk.
- ///
- /// This operation may undo temporary state in the AST that should not be
- /// emitted.
- void finalizeForWriting();
-
- /// \brief Retrieve the module manager.
- ModuleManager &getModuleManager() { return ModuleMgr; }
-
- /// \brief Retrieve the preprocessor.
- Preprocessor &getPreprocessor() const { return PP; }
-
- /// \brief 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
- /// 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.
- ///
- /// \returns true if an error occurred, false otherwise.
- static bool
- readASTFileControlBlock(StringRef Filename, FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr,
- bool FindModuleFileExtensions,
- ASTReaderListener &Listener);
-
- /// \brief 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,
- const LangOptions &LangOpts,
- const TargetOptions &TargetOpts,
- const PreprocessorOptions &PPOpts,
- std::string ExistingModuleCachePath);
-
- /// \brief 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.
- ///
- /// \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
- /// preprocessed entities that \p Range encompasses.
- std::pair<unsigned, unsigned>
- findPreprocessedEntitiesInRange(SourceRange Range) override;
-
- /// \brief 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.
- HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) override;
-
- void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag);
-
- /// \brief 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.
- unsigned getTotalNumIdentifiers() const {
- return static_cast<unsigned>(IdentifiersLoaded.size());
- }
-
- /// \brief 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.
- unsigned getTotalNumTypes() const {
- return static_cast<unsigned>(TypesLoaded.size());
- }
-
- /// \brief 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.
- unsigned getTotalNumSubmodules() const {
- return static_cast<unsigned>(SubmodulesLoaded.size());
- }
-
- /// \brief 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
- /// reader.
- unsigned getTotalNumPreprocessedEntities() const {
- unsigned Result = 0;
- for (ModuleConstIterator I = ModuleMgr.begin(),
- E = ModuleMgr.end(); I != E; ++I) {
- Result += (*I)->NumPreprocessedEntities;
- }
-
- return Result;
- }
-
- /// \brief 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.
- TemplateArgumentLoc
- ReadTemplateArgumentLoc(ModuleFile &F,
- const RecordData &Record, unsigned &Idx);
-
- const ASTTemplateArgumentListInfo*
- ReadASTTemplateArgumentListInfo(ModuleFile &F,
- const RecordData &Record, unsigned &Index);
-
- /// \brief 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
- /// type.
- QualType GetType(serialization::TypeID ID);
-
- /// \brief 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.
- serialization::TypeID getGlobalTypeID(ModuleFile &F, unsigned LocalID) const;
-
- /// \brief 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 getLocalType(F, Record[Idx++]);
- }
-
- /// \brief 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.
- bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const;
-
- /// \brief 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
- /// 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.
- SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
-
- /// \brief 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
- /// been loaded yet.
- Decl *GetExistingDecl(serialization::DeclID ID);
-
- /// \brief 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.
- ///
- /// \returns The requested declaration, casted to the given return type.
- template<typename T>
- T *GetLocalDeclAs(ModuleFile &F, uint32_t LocalID) {
- return cast_or_null<T>(GetLocalDecl(F, LocalID));
- }
-
- /// \brief 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
- /// module file.
- serialization::DeclID
- mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
- serialization::DeclID GlobalID);
-
- /// \brief 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
- /// 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
- /// given module.
- ///
- /// \returns The declaration read from this location, casted to the given
- /// result type.
- template<typename T>
- T *ReadDeclAs(ModuleFile &F, const RecordData &R, unsigned &I) {
- return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I)));
- }
-
- /// \brief 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;
-
- /// \brief Read a CXXBaseSpecifiers ID form the given record and
- /// return its global bit offset.
- uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record,
- unsigned &Idx);
-
- CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
-
- /// \brief 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
- /// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
- Stmt *GetExternalDeclStmt(uint64_t Offset) override;
-
- /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
- /// specified cursor. Read the abbreviations that are at the top of the block
- /// 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.
- /// 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
- /// declaration context.
- ///
- /// \param DC The declaration context whose declarations will be
- /// read.
- ///
- /// \param IsKindWeWant A predicate indicating which declaration kinds
- /// we are interested in.
- ///
- /// \param Decls Vector that will contain the declarations loaded
- /// from the external source. The caller is responsible for merging
- /// these declarations with any declarations already stored in the
- /// declaration context.
- void
- FindExternalLexicalDecls(const DeclContext *DC,
- 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
- /// 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
- /// 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
- /// a decl or type. Must be paired with StartedDeserializing.
- void FinishedDeserializing() override;
-
- /// \brief 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.
- void PrintStats() override;
-
- /// \brief 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
- /// 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.
- void ForgetSema() override { SemaObj = nullptr; }
-
- /// \brief 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
- /// declarations will be deserialized and introduced into the declaration
- /// chain of the identifier.
- IdentifierInfo *get(StringRef Name) override;
-
- /// \brief 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
- /// selector.
- void ReadMethodPool(Selector Sel) override;
-
- /// \brief 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;
-
- void ReadUndefinedButUsed(
- llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) override;
-
- void ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
- Exprs) override;
-
- void ReadTentativeDefinitions(
- SmallVectorImpl<VarDecl *> &TentativeDefs) override;
-
- void ReadUnusedFileScopedDecls(
- SmallVectorImpl<const DeclaratorDecl *> &Decls) override;
-
- void ReadDelegatingConstructors(
- SmallVectorImpl<CXXConstructorDecl *> &Decls) override;
-
- void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) override;
-
- void ReadUnusedLocalTypedefNameCandidates(
- llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
-
- void ReadReferencedSelectors(
- SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) override;
-
- void ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) override;
-
- void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
-
- void ReadPendingInstantiations(
- SmallVectorImpl<std::pair<ValueDecl *,
- SourceLocation> > &Pending) override;
-
- void ReadLateParsedTemplates(
- llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap)
- override;
-
- /// \brief Load a selector from disk, registering its ID if it exists.
- void LoadSelector(Selector Sel);
-
- void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
- void SetGloballyVisibleDecls(IdentifierInfo *II,
- const SmallVectorImpl<uint32_t> &DeclIDs,
- SmallVectorImpl<Decl *> *Decls = nullptr);
-
- /// \brief Report a diagnostic.
- DiagnosticBuilder Diag(unsigned DiagID);
-
- /// \brief Report a diagnostic.
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
-
- IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID);
-
- IdentifierInfo *GetIdentifierInfo(ModuleFile &M, const RecordData &Record,
- unsigned &Idx) {
- return DecodeIdentifierInfo(getGlobalIdentifierID(M, Record[Idx++]));
- }
-
- IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) override {
- // Note that we are loading an identifier.
- Deserializing AnIdentifier(this);
-
- return DecodeIdentifierInfo(ID);
- }
-
- IdentifierInfo *getLocalIdentifier(ModuleFile &M, unsigned LocalID);
-
- serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
- unsigned LocalID);
-
- void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
-
- /// \brief Retrieve the macro with the given ID.
- MacroInfo *getMacro(serialization::MacroID ID);
-
- /// \brief 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.
- bool ReadSLocEntry(int ID) override;
-
- /// \brief 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
- /// number.
- serialization::SubmoduleID
- getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID);
-
- /// \brief 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.
- ///
- /// Note: overrides method in ExternalASTSource
- Module *getModule(unsigned ID) override;
-
- /// \brief 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.
- unsigned getModuleFileID(ModuleFile *M);
-
- /// \brief Return a descriptor for the corresponding module.
- llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override;
-
- /// \brief Retrieve a selector from the given module with its local ID
- /// number.
- Selector getLocalSelector(ModuleFile &M, unsigned LocalID);
-
- Selector DecodeSelector(serialization::SelectorID Idx);
-
- Selector GetExternalSelector(serialization::SelectorID ID) override;
- uint32_t GetNumExternalSelectors() override;
-
- Selector ReadSelector(ModuleFile &M, const RecordData &Record, unsigned &Idx) {
- return getLocalSelector(M, Record[Idx++]);
- }
-
- /// \brief 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.
- DeclarationName ReadDeclarationName(ModuleFile &F,
- const RecordData &Record, unsigned &Idx);
- void ReadDeclarationNameLoc(ModuleFile &F,
- DeclarationNameLoc &DNLoc, DeclarationName Name,
- const RecordData &Record, unsigned &Idx);
- void ReadDeclarationNameInfo(ModuleFile &F, DeclarationNameInfo &NameInfo,
- const RecordData &Record, unsigned &Idx);
-
- void ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info,
- const RecordData &Record, unsigned &Idx);
-
- NestedNameSpecifier *ReadNestedNameSpecifier(ModuleFile &F,
- const RecordData &Record,
- unsigned &Idx);
-
- NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(ModuleFile &F,
- const RecordData &Record,
- unsigned &Idx);
-
- /// \brief Read a template name.
- TemplateName ReadTemplateName(ModuleFile &F, const RecordData &Record,
- unsigned &Idx);
-
- /// \brief Read a template argument.
- TemplateArgument ReadTemplateArgument(ModuleFile &F, const RecordData &Record,
- unsigned &Idx,
- bool Canonicalize = false);
-
- /// \brief Read a template parameter list.
- TemplateParameterList *ReadTemplateParameterList(ModuleFile &F,
- const RecordData &Record,
- unsigned &Idx);
-
- /// \brief 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.
- void ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set,
- const RecordData &Record, unsigned &Idx);
-
- /// \brief Read a C++ base specifier.
- CXXBaseSpecifier ReadCXXBaseSpecifier(ModuleFile &F,
- const RecordData &Record,unsigned &Idx);
-
- /// \brief Read a CXXCtorInitializer array.
- CXXCtorInitializer **
- ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,
- unsigned &Idx);
-
- /// \brief Read a CXXCtorInitializers ID from the given record and
- /// return its global bit offset.
- uint64_t ReadCXXCtorInitializersRef(ModuleFile &M, const RecordData &Record,
- unsigned &Idx);
-
- /// \brief Read the contents of a CXXCtorInitializer array.
- CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override;
-
- /// \brief Read a source location from raw form.
- SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, unsigned Raw) const {
- SourceLocation Loc = SourceLocation::getFromRawEncoding(Raw);
- assert(ModuleFile.SLocRemap.find(Loc.getOffset()) != ModuleFile.SLocRemap.end() &&
- "Cannot find offset to remap.");
- int Remap = ModuleFile.SLocRemap.find(Loc.getOffset())->second;
- return Loc.getLocWithOffset(Remap);
- }
-
- /// \brief Read a source location.
- SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
- const RecordDataImpl &Record,
- unsigned &Idx) {
- return ReadSourceLocation(ModuleFile, Record[Idx++]);
- }
-
- /// \brief Read a source range.
- SourceRange ReadSourceRange(ModuleFile &F,
- const RecordData &Record, unsigned &Idx);
-
- /// \brief Read an integral value
- llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
-
- /// \brief Read a signed integral value
- llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
-
- /// \brief Read a floating-point value
- llvm::APFloat ReadAPFloat(const RecordData &Record,
- const llvm::fltSemantics &Sem, unsigned &Idx);
-
- // \brief Read a string
- static std::string ReadString(const RecordData &Record, unsigned &Idx);
-
- // \brief Read a path
- std::string ReadPath(ModuleFile &F, const RecordData &Record, unsigned &Idx);
-
- /// \brief 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.
- void ReadAttributes(ModuleFile &F, AttrVec &Attrs,
- const RecordData &Record, unsigned &Idx);
-
- /// \brief Reads a statement.
- Stmt *ReadStmt(ModuleFile &F);
-
- /// \brief Reads an expression.
- Expr *ReadExpr(ModuleFile &F);
-
- /// \brief Reads a sub-statement operand during statement reading.
- Stmt *ReadSubStmt() {
- assert(ReadingKind == Read_Stmt &&
- "Should be called only during statement reading!");
- // Subexpressions are stored from last to first, so the next Stmt we need
- // is at the back of the stack.
- assert(!StmtStack.empty() && "Read too many sub-statements!");
- return StmtStack.pop_back_val();
- }
-
- /// \brief Reads a sub-expression operand during statement reading.
- Expr *ReadSubExpr();
-
- /// \brief 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.
- MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset);
-
- /// \brief 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.
- ///
- /// \param II The name of the macro.
- /// \param M The module file.
- /// \param MacroDirectivesOffset Offset of the serialized macro directive
- /// history.
- void addPendingMacro(IdentifierInfo *II, ModuleFile *M,
- uint64_t MacroDirectivesOffset);
-
- /// \brief Read the set of macros defined by this external macro source.
- void ReadDefinedMacros() override;
-
- /// \brief Update an out-of-date identifier.
- void updateOutOfDateIdentifier(IdentifierInfo &II) override;
-
- /// \brief Note that this identifier is up-to-date.
- void markIdentifierUpToDate(IdentifierInfo *II);
-
- /// \brief 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.
- ASTContext &getContext() { return Context; }
-
- // \brief 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
- /// translation unit in which the precompiled header is being
- /// imported.
- Sema *getSema() { return SemaObj; }
-
- /// \brief Retrieve the identifier table associated with the
- /// preprocessor.
- IdentifierTable &getIdentifierTable();
-
- /// \brief 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.
- SwitchCase *getSwitchCaseWithID(unsigned ID);
-
- void ClearSwitchCaseIDs();
-
- /// \brief Cursors for comments blocks.
- SmallVector<std::pair<llvm::BitstreamCursor,
- serialization::ModuleFile *>, 8> CommentsCursors;
-
- /// \brief Loads comments ranges.
- void ReadComments() override;
-};
-
-/// \brief 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()) { }
-
- ~SavedStreamPosition() {
- Cursor.JumpToBit(Offset);
- }
-
-private:
- llvm::BitstreamCursor &Cursor;
- uint64_t Offset;
-};
-
-inline void PCHValidator::Error(const char *Msg) {
- Reader.Error(Msg);
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
deleted file mode 100644
index ed34547..0000000
--- a/include/clang/Serialization/ASTWriter.h
+++ /dev/null
@@ -1,920 +0,0 @@
-//===--- ASTWriter.h - AST File Writer --------------------------*- 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 ASTWriter class, which writes an AST file
-// containing a serialized representation of a translation unit.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATION_ASTWRITER_H
-#define LLVM_CLANG_SERIALIZATION_ASTWRITER_H
-
-#include "clang/AST/ASTMutationListener.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/Frontend/PCHContainerOperations.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/Sema/SemaConsumer.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Serialization/ASTDeserializationListener.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
-#include <map>
-#include <queue>
-#include <vector>
-
-namespace llvm {
- class APFloat;
- class APInt;
- class BitstreamWriter;
-}
-
-namespace clang {
-
-class ASTContext;
-class Attr;
-class NestedNameSpecifier;
-class CXXBaseSpecifier;
-class CXXCtorInitializer;
-class FileEntry;
-class FPOptions;
-class HeaderSearch;
-class HeaderSearchOptions;
-class IdentifierResolver;
-class MacroDefinitionRecord;
-class MacroDirective;
-class MacroInfo;
-class OpaqueValueExpr;
-class OpenCLOptions;
-class ASTReader;
-class Module;
-class ModuleFileExtension;
-class ModuleFileExtensionWriter;
-class PreprocessedEntity;
-class PreprocessingRecord;
-class Preprocessor;
-class RecordDecl;
-class Sema;
-class SourceManager;
-struct StoredDeclsList;
-class SwitchCase;
-class TargetInfo;
-class Token;
-class VersionTuple;
-class ASTUnresolvedSet;
-
-namespace SrcMgr { class SLocEntry; }
-
-/// \brief 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
-/// data structures. This bitstream can be de-serialized via an
-/// instance of the ASTReader class.
-class ASTWriter : public ASTDeserializationListener,
- public ASTMutationListener {
-public:
- typedef SmallVector<uint64_t, 64> RecordData;
- typedef SmallVectorImpl<uint64_t> RecordDataImpl;
- typedef ArrayRef<uint64_t> RecordDataRef;
-
- friend class ASTDeclWriter;
- friend class ASTStmtWriter;
-private:
- /// \brief 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)
- /// and start at 1. 0 is reserved for NULL. When types are actually
- /// stored in the stream, the ID number is shifted by 2 bits to
- /// allow for the const/volatile qualifiers.
- ///
- /// Keys in the map never have const/volatile qualifiers.
- typedef llvm::DenseMap<QualType, serialization::TypeIdx,
- serialization::UnsafeQualTypeDenseMapInfo>
- TypeIdxMap;
-
- /// \brief The bitstream writer used to emit this precompiled header.
- llvm::BitstreamWriter &Stream;
-
- /// \brief The ASTContext we're writing.
- ASTContext *Context;
-
- /// \brief The preprocessor we're writing.
- Preprocessor *PP;
-
- /// \brief The reader of existing AST files, if we're chaining.
- ASTReader *Chain;
-
- /// \brief The module we're currently writing, if any.
- Module *WritingModule;
-
- /// \brief The base directory for any relative paths we emit.
- std::string BaseDirectory;
-
- /// \brief 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
- /// serialization, rather than just queueing updates.
- bool WritingAST;
-
- /// \brief Indicates that we are done serializing the collection of decls
- /// and types to emit.
- bool DoneWritingDeclsAndTypes;
-
- /// \brief Indicates that the AST contained compiler errors.
- bool ASTHasCompilerErrors;
-
- /// \brief 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.
- class DeclOrType {
- public:
- DeclOrType(Decl *D) : Stored(D), IsType(false) { }
- DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) { }
-
- bool isType() const { return IsType; }
- bool isDecl() const { return !IsType; }
-
- QualType getType() const {
- assert(isType() && "Not a type!");
- return QualType::getFromOpaquePtr(Stored);
- }
-
- Decl *getDecl() const {
- assert(isDecl() && "Not a decl!");
- return static_cast<Decl *>(Stored);
- }
-
- private:
- void *Stored;
- bool IsType;
- };
-
- /// \brief The declarations and types to emit.
- std::queue<DeclOrType> DeclTypesToEmit;
-
- /// \brief The first ID number we can use for our own declarations.
- serialization::DeclID FirstDeclID;
-
- /// \brief The decl ID that will be assigned to the next new decl.
- serialization::DeclID NextDeclID;
-
- /// \brief 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
- /// discovery) and start at 2. 1 is reserved for the translation
- /// unit, while 0 is reserved for NULL.
- llvm::DenseMap<const Decl *, serialization::DeclID> DeclIDs;
-
- /// \brief 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.
- typedef SmallVector<std::pair<unsigned, serialization::DeclID>, 64>
- LocDeclIDsTy;
- struct DeclIDInFileInfo {
- LocDeclIDsTy DeclIDs;
- /// \brief 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;
- };
- typedef llvm::DenseMap<FileID, DeclIDInFileInfo *> FileDeclIDsTy;
-
- /// \brief 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.
- serialization::TypeID FirstTypeID;
-
- /// \brief The type ID that will be assigned to the next new type.
- serialization::TypeID NextTypeID;
-
- /// \brief 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)
- /// and start at 1. 0 is reserved for NULL. When types are actually
- /// stored in the stream, the ID number is shifted by 2 bits to
- /// allow for the const/volatile qualifiers.
- ///
- /// Keys in the map never have const/volatile qualifiers.
- TypeIdxMap TypeIdxs;
-
- /// \brief 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.
- serialization::IdentID FirstIdentID;
-
- /// \brief The identifier ID that will be assigned to the next new identifier.
- serialization::IdentID NextIdentID;
-
- /// \brief Map that provides the ID numbers of each identifier in
- /// the output stream.
- ///
- /// The ID numbers for identifiers are consecutive (in order of
- /// discovery), starting at 1. An ID of zero refers to a NULL
- /// IdentifierInfo.
- llvm::MapVector<const IdentifierInfo *, serialization::IdentID> IdentifierIDs;
-
- /// \brief The first ID number we can use for our own macros.
- serialization::MacroID FirstMacroID;
-
- /// \brief The identifier ID that will be assigned to the next new identifier.
- serialization::MacroID NextMacroID;
-
- /// \brief Map that provides the ID numbers of each macro.
- llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
-
- struct MacroInfoToEmitData {
- const IdentifierInfo *Name;
- MacroInfo *MI;
- serialization::MacroID ID;
- };
- /// \brief The macro infos to emit.
- std::vector<MacroInfoToEmitData> MacroInfosToEmit;
-
- llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap;
-
- /// @name FlushStmt Caches
- /// @{
-
- /// \brief Set of parent Stmts for the currently serializing sub-stmt.
- llvm::DenseSet<Stmt *> ParentStmts;
-
- /// \brief 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
- /// table.
- std::vector<uint32_t> IdentifierOffsets;
-
- /// \brief The first ID number we can use for our own submodules.
- serialization::SubmoduleID FirstSubmoduleID;
-
- /// \brief The submodule ID that will be assigned to the next new submodule.
- serialization::SubmoduleID NextSubmoduleID;
-
- /// \brief The first ID number we can use for our own selectors.
- serialization::SelectorID FirstSelectorID;
-
- /// \brief The selector ID that will be assigned to the next new selector.
- serialization::SelectorID NextSelectorID;
-
- /// \brief 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
- /// table, indexed by the Selector ID (-1).
- std::vector<uint32_t> SelectorOffsets;
-
- /// \brief 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
- /// contexts.
- llvm::DenseMap<const Decl *, unsigned> AnonymousDeclarationNumbers;
-
- /// An update to a Decl.
- class DeclUpdate {
- /// A DeclUpdateKind.
- unsigned Kind;
- union {
- const Decl *Dcl;
- void *Type;
- unsigned Loc;
- unsigned Val;
- Module *Mod;
- const Attr *Attribute;
- };
-
- public:
- DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(nullptr) {}
- DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {}
- DeclUpdate(unsigned Kind, QualType Type)
- : Kind(Kind), Type(Type.getAsOpaquePtr()) {}
- DeclUpdate(unsigned Kind, SourceLocation Loc)
- : Kind(Kind), Loc(Loc.getRawEncoding()) {}
- DeclUpdate(unsigned Kind, unsigned Val)
- : Kind(Kind), Val(Val) {}
- DeclUpdate(unsigned Kind, Module *M)
- : Kind(Kind), Mod(M) {}
- DeclUpdate(unsigned Kind, const Attr *Attribute)
- : Kind(Kind), Attribute(Attribute) {}
-
- unsigned getKind() const { return Kind; }
- const Decl *getDecl() const { return Dcl; }
- QualType getType() const { return QualType::getFromOpaquePtr(Type); }
- SourceLocation getLoc() const {
- return SourceLocation::getFromRawEncoding(Loc);
- }
- unsigned getNumber() const { return Val; }
- Module *getModule() const { return Mod; }
- const Attr *getAttr() const { return Attribute; }
- };
-
- typedef SmallVector<DeclUpdate, 1> UpdateRecord;
- typedef llvm::MapVector<const Decl *, UpdateRecord> DeclUpdateMap;
- /// \brief Mapping from declarations that came from a chained PCH to the
- /// record containing modifications to them.
- DeclUpdateMap DeclUpdates;
-
- typedef llvm::DenseMap<Decl *, Decl *> FirstLatestDeclMap;
- /// \brief 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
- /// definitions.
- ///
- /// We keep track of external definitions and other 'interesting' declarations
- /// as we are emitting declarations to the AST file. The AST file contains a
- /// separate record for these declarations, which are provided to the AST
- /// consumer by the AST reader. This is behavior is required to properly cope with,
- /// e.g., tentative variable definitions that occur within
- /// headers. The declarations themselves are stored as declaration
- /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
- /// record.
- SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
-
- /// \brief DeclContexts that have received extensions since their serialized
- /// form.
- ///
- /// For namespaces, when we're chaining and encountering a namespace, we check
- /// if its primary namespace comes from the chain. If it does, we add the
- /// primary to this set, so that we can write out lexical content updates for
- /// it.
- llvm::SmallSetVector<const DeclContext *, 16> UpdatedDeclContexts;
-
- /// \brief Keeps track of visible decls that were added in DeclContexts
- /// coming from another AST file.
- SmallVector<const Decl *, 16> UpdatingVisibleDecls;
-
- /// \brief The set of Objective-C class that have categories we
- /// should serialize.
- llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories;
-
- struct ReplacedDeclInfo {
- serialization::DeclID ID;
- uint64_t Offset;
- unsigned Loc;
-
- ReplacedDeclInfo() : ID(0), Offset(0), Loc(0) {}
- ReplacedDeclInfo(serialization::DeclID ID, uint64_t Offset,
- SourceLocation Loc)
- : ID(ID), Offset(Offset), Loc(Loc.getRawEncoding()) {}
- };
-
- /// \brief Decls that have been replaced in the current dependent AST file.
- ///
- /// When a decl changes fundamentally after being deserialized (this shouldn't
- /// happen, but the ObjC AST nodes are designed this way), it will be
- /// serialized again. In this case, it is registered here, so that the reader
- /// knows to read the updated version.
- SmallVector<ReplacedDeclInfo, 16> ReplacedDecls;
-
- /// \brief 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"
- /// redeclaration chains.
- llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache;
-
- /// \brief Statements that we've encountered while serializing a
- /// declaration or type.
- SmallVector<Stmt *, 16> StmtsToEmit;
-
- /// \brief Statements collection to use for ASTWriter::AddStmt().
- /// It will point to StmtsToEmit unless it is overriden.
- SmallVector<Stmt *, 16> *CollectedStmts;
-
- /// \brief Mapping from SwitchCase statements to IDs.
- llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs;
-
- /// \brief The number of statements written to the AST file.
- unsigned NumStatements;
-
- /// \brief The number of macros written to the AST file.
- unsigned NumMacros;
-
- /// \brief The number of lexical declcontexts written to the AST
- /// file.
- unsigned NumLexicalDeclContexts;
-
- /// \brief The number of visible declcontexts written to the AST
- /// file.
- unsigned NumVisibleDeclContexts;
-
- /// \brief The offset of each CXXBaseSpecifier set within the AST.
- SmallVector<uint32_t, 16> CXXBaseSpecifiersOffsets;
-
- /// \brief The first ID number we can use for our own base specifiers.
- serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID;
-
- /// \brief The base specifiers ID that will be assigned to the next new
- /// set of C++ base specifiers.
- serialization::CXXBaseSpecifiersID NextCXXBaseSpecifiersID;
-
- /// \brief A set of C++ base specifiers that is queued to be written into the
- /// AST file.
- struct QueuedCXXBaseSpecifiers {
- QueuedCXXBaseSpecifiers() : ID(), Bases(), BasesEnd() { }
-
- QueuedCXXBaseSpecifiers(serialization::CXXBaseSpecifiersID ID,
- CXXBaseSpecifier const *Bases,
- CXXBaseSpecifier const *BasesEnd)
- : ID(ID), Bases(Bases), BasesEnd(BasesEnd) { }
-
- serialization::CXXBaseSpecifiersID ID;
- CXXBaseSpecifier const * Bases;
- CXXBaseSpecifier const * BasesEnd;
- };
-
- /// \brief Queue of C++ base specifiers to be written to the AST file,
- /// in the order they should be written.
- SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite;
-
- /// \brief The offset of each CXXCtorInitializer list within the AST.
- SmallVector<uint32_t, 16> CXXCtorInitializersOffsets;
-
- /// \brief The first ID number we can use for our own ctor initializers.
- serialization::CXXCtorInitializersID FirstCXXCtorInitializersID;
-
- /// \brief The ctor initializers ID that will be assigned to the next new
- /// list of C++ ctor initializers.
- serialization::CXXCtorInitializersID NextCXXCtorInitializersID;
-
- /// \brief A set of C++ ctor initializers that is queued to be written
- /// into the AST file.
- struct QueuedCXXCtorInitializers {
- QueuedCXXCtorInitializers() : ID() {}
-
- QueuedCXXCtorInitializers(serialization::CXXCtorInitializersID ID,
- ArrayRef<CXXCtorInitializer*> Inits)
- : ID(ID), Inits(Inits) {}
-
- serialization::CXXCtorInitializersID ID;
- ArrayRef<CXXCtorInitializer*> Inits;
- };
-
- /// \brief Queue of C++ ctor initializers to be written to the AST file,
- /// in the order they should be written.
- SmallVector<QueuedCXXCtorInitializers, 2> CXXCtorInitializersToWrite;
-
- /// \brief 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.
- std::vector<std::unique_ptr<ModuleFileExtensionWriter>>
- ModuleFileExtensionWriters;
-
- /// \brief Retrieve or create a submodule ID for this module.
- unsigned getSubmoduleID(Module *Mod);
-
- /// \brief Write the given subexpression to the bitstream.
- void WriteSubStmt(Stmt *S,
- llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
- llvm::DenseSet<Stmt *> &ParentStmts);
-
- void WriteBlockInfoBlock();
- uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context,
- StringRef isysroot, const std::string &OutputFile);
- void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts,
- bool Modules);
- void WriteSourceManagerBlock(SourceManager &SourceMgr,
- const Preprocessor &PP);
- void WritePreprocessor(const Preprocessor &PP, bool IsModule);
- void WriteHeaderSearch(const HeaderSearch &HS);
- void WritePreprocessorDetail(PreprocessingRecord &PPRec);
- void WriteSubmodules(Module *WritingModule);
-
- void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
- bool isModule);
- void WriteCXXBaseSpecifiersOffsets();
- void WriteCXXCtorInitializersOffsets();
-
- unsigned TypeExtQualAbbrev;
- unsigned TypeFunctionProtoAbbrev;
- void WriteTypeAbbrevs();
- void WriteType(QualType T);
-
- bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
- bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC);
-
- void GenerateNameLookupTable(const DeclContext *DC,
- llvm::SmallVectorImpl<char> &LookupTable);
- uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
- uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
- void WriteTypeDeclOffsets();
- void WriteFileDeclIDsMap();
- void WriteComments();
- void WriteSelectors(Sema &SemaRef);
- void WriteReferencedSelectorsPool(Sema &SemaRef);
- void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
- bool IsModule);
- void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
- void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
- void WriteDeclReplacementsBlock();
- void WriteDeclContextVisibleUpdate(const DeclContext *DC);
- void WriteFPPragmaOptions(const FPOptions &Opts);
- void WriteOpenCLExtensions(Sema &SemaRef);
- void WriteObjCCategories();
- void WriteLateParsedTemplates(Sema &SemaRef);
- void WriteOptimizePragmaOptions(Sema &SemaRef);
- void WriteModuleFileExtension(Sema &SemaRef,
- ModuleFileExtensionWriter &Writer);
-
- unsigned DeclParmVarAbbrev;
- unsigned DeclContextLexicalAbbrev;
- unsigned DeclContextVisibleLookupAbbrev;
- unsigned UpdateVisibleAbbrev;
- unsigned DeclRecordAbbrev;
- unsigned DeclTypedefAbbrev;
- unsigned DeclVarAbbrev;
- unsigned DeclFieldAbbrev;
- unsigned DeclEnumAbbrev;
- unsigned DeclObjCIvarAbbrev;
- unsigned DeclCXXMethodAbbrev;
-
- unsigned DeclRefExprAbbrev;
- unsigned CharacterLiteralAbbrev;
- unsigned IntegerLiteralAbbrev;
- unsigned ExprImplicitCastAbbrev;
-
- void WriteDeclAbbrevs();
- void WriteDecl(ASTContext &Context, Decl *D);
- void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
-
- uint64_t WriteASTCore(Sema &SemaRef,
- StringRef isysroot, const std::string &OutputFile,
- Module *WritingModule);
-
-public:
- /// \brief Create a new precompiled header writer that outputs to
- /// the given bitstream.
- ASTWriter(llvm::BitstreamWriter &Stream,
- ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
- bool IncludeTimestamps = true);
- ~ASTWriter() override;
-
- const LangOptions &getLangOpts() const;
-
- /// \brief 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.
- ///
- /// \param SemaRef a reference to the semantic analysis object that processed
- /// the AST to be written into the precompiled header.
- ///
- /// \param WritingModule The module that we are writing. If null, we are
- /// writing a precompiled header.
- ///
- /// \param isysroot if non-empty, write a relocatable file whose headers
- /// are relative to the given system root. If we're writing a module, its
- /// build directory will be used in preference to this if both are available.
- ///
- /// \return the module signature, which eventually will be a hash of
- /// the module but currently is merely a random 32-bit number.
- uint64_t WriteAST(Sema &SemaRef, const std::string &OutputFile,
- Module *WritingModule, StringRef isysroot,
- bool hasErrors = false);
-
- /// \brief Emit a token.
- void AddToken(const Token &Tok, RecordDataImpl &Record);
-
- /// \brief Emit a source location.
- void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record);
-
- /// \brief Emit a source range.
- void AddSourceRange(SourceRange Range, RecordDataImpl &Record);
-
- /// \brief Emit an integral value.
- void AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record);
-
- /// \brief Emit a signed integral value.
- void AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record);
-
- /// \brief Emit a floating-point value.
- void AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record);
-
- /// \brief Emit a reference to an identifier.
- void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
-
- /// \brief Emit a Selector (which is a smart pointer reference).
- void AddSelectorRef(Selector, RecordDataImpl &Record);
-
- /// \brief Emit a CXXTemporary.
- void AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record);
-
- /// \brief Emit a set of C++ base specifiers to the record.
- void AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases,
- CXXBaseSpecifier const *BasesEnd,
- RecordDataImpl &Record);
-
- /// \brief 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.
- serialization::IdentID getIdentifierRef(const IdentifierInfo *II);
-
- /// \brief 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.
- serialization::MacroID getMacroID(MacroInfo *MI);
-
- uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name);
-
- /// \brief Emit a reference to a type.
- void AddTypeRef(QualType T, RecordDataImpl &Record);
-
- /// \brief 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.
- serialization::TypeID getTypeID(QualType T) const;
-
- /// \brief Emits a reference to a declarator info.
- void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record);
-
- /// \brief Emits a type with source-location information.
- void AddTypeLoc(TypeLoc TL, RecordDataImpl &Record);
-
- /// \brief Emits a template argument location info.
- void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
- const TemplateArgumentLocInfo &Arg,
- RecordDataImpl &Record);
-
- /// \brief Emits a template argument location.
- void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
- RecordDataImpl &Record);
-
- /// \brief Emits an AST template argument list info.
- void AddASTTemplateArgumentListInfo(
- const ASTTemplateArgumentListInfo *ASTTemplArgList,
- RecordDataImpl &Record);
-
- /// \brief Find the first local declaration of a given local redeclarable
- /// decl.
- const Decl *getFirstLocalDecl(const Decl *D);
-
- /// \brief Emit a reference to a declaration.
- void AddDeclRef(const Decl *D, RecordDataImpl &Record);
-
-
- /// \brief 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
- /// declaration.
- serialization::DeclID getDeclID(const Decl *D);
-
- /// \brief Emit a declaration name.
- void AddDeclarationName(DeclarationName Name, RecordDataImpl &Record);
- void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
- DeclarationName Name, RecordDataImpl &Record);
- void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
- RecordDataImpl &Record);
- unsigned getAnonymousDeclarationNumber(const NamedDecl *D);
-
- void AddQualifierInfo(const QualifierInfo &Info, RecordDataImpl &Record);
-
- /// \brief Emit a nested name specifier.
- void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record);
-
- /// \brief Emit a nested name specifier with source-location information.
- void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
- RecordDataImpl &Record);
-
- /// \brief Emit a template name.
- void AddTemplateName(TemplateName Name, RecordDataImpl &Record);
-
- /// \brief Emit a template argument.
- void AddTemplateArgument(const TemplateArgument &Arg, RecordDataImpl &Record);
-
- /// \brief Emit a template parameter list.
- void AddTemplateParameterList(const TemplateParameterList *TemplateParams,
- RecordDataImpl &Record);
-
- /// \brief Emit a template argument list.
- void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
- RecordDataImpl &Record);
-
- /// \brief Emit a UnresolvedSet structure.
- void AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record);
-
- /// \brief Emit a C++ base specifier.
- void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
- RecordDataImpl &Record);
-
- /// \brief Emit the ID for a CXXCtorInitializer array and register the array
- /// for later serialization.
- void AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits,
- RecordDataImpl &Record);
-
- /// \brief Emit a CXXCtorInitializer array.
- void AddCXXCtorInitializers(
- const CXXCtorInitializer * const *CtorInitializers,
- unsigned NumCtorInitializers,
- RecordDataImpl &Record);
-
- void AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record);
-
- /// \brief 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
- /// for emission in the module file.
- bool PreparePathForOutput(SmallVectorImpl<char> &Path);
-
- /// \brief 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.
- void EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record,
- StringRef Path);
-
- /// \brief Add a version tuple to the given record
- void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
-
- /// \brief Infer the submodule ID that contains an entity at the given
- /// source location.
- serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
-
- /// \brief 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
- /// within the identifier table.
- void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
-
- /// \brief Note that the selector Sel occurs at the given offset
- /// within the method pool/selector table.
- void SetSelectorOffset(Selector Sel, uint32_t Offset);
-
- /// \brief Add the given statement or expression to the queue of
- /// statements to emit.
- ///
- /// This routine should be used when emitting types and declarations
- /// that have expressions as part of their formulation. Once the
- /// type or declaration has been written, call FlushStmts() to write
- /// the corresponding statements just after the type or
- /// declaration.
- void AddStmt(Stmt *S) {
- CollectedStmts->push_back(S);
- }
-
- /// \brief Flush all of the statements and expressions that have
- /// been added to the queue via AddStmt().
- void FlushStmts();
-
- /// \brief Flush all of the C++ base specifier sets that have been added
- /// via \c AddCXXBaseSpecifiersRef().
- void FlushCXXBaseSpecifiers();
-
- /// \brief Flush all of the C++ constructor initializer lists that have been
- /// added via \c AddCXXCtorInitializersRef().
- void FlushCXXCtorInitializers();
-
- /// \brief Flush all pending records that are tacked onto the end of
- /// decl and decl update records.
- void FlushPendingAfterDecl() {
- FlushStmts();
- FlushCXXBaseSpecifiers();
- FlushCXXCtorInitializers();
- }
-
- /// \brief Record an ID for the given switch-case statement.
- unsigned RecordSwitchCaseID(SwitchCase *S);
-
- /// \brief Retrieve the ID for the given switch-case statement.
- unsigned getSwitchCaseID(SwitchCase *S);
-
- void ClearSwitchCaseIDs();
-
- unsigned getTypeExtQualAbbrev() const {
- return TypeExtQualAbbrev;
- }
- unsigned getTypeFunctionProtoAbbrev() const {
- return TypeFunctionProtoAbbrev;
- }
-
- unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; }
- unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; }
- unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; }
- unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; }
- unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; }
- unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; }
- unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; }
- unsigned getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; }
-
- unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
- unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
- unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
- unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; }
-
- bool hasChain() const { return Chain; }
- ASTReader *getChain() const { return Chain; }
-
- // ASTDeserializationListener implementation
- 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 SelectorRead(serialization::SelectorID ID, Selector Sel) override;
- void MacroDefinitionRead(serialization::PreprocessedEntityID ID,
- MacroDefinitionRecord *MD) override;
- void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
-
- // ASTMutationListener implementation.
- void CompletedTagDefinition(const TagDecl *D) override;
- void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
- void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
- void ResolvedExceptionSpec(const FunctionDecl *FD) override;
- void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
- void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
- const FunctionDecl *Delete) override;
- void CompletedImplicitDefinition(const FunctionDecl *D) override;
- void StaticDataMemberInstantiated(const VarDecl *D) override;
- void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
- void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
- const ObjCInterfaceDecl *IFD) override;
- void DeclarationMarkedUsed(const Decl *D) override;
- void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
- void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
- void AddedAttributeToRecord(const Attr *Attr,
- const RecordDecl *Record) override;
-};
-
-/// \brief AST and semantic-analysis consumer that generates a
-/// precompiled header from the parsed source code.
-class PCHGenerator : public SemaConsumer {
- const Preprocessor &PP;
- std::string OutputFile;
- clang::Module *Module;
- std::string isysroot;
- Sema *SemaPtr;
- std::shared_ptr<PCHBuffer> Buffer;
- llvm::BitstreamWriter Stream;
- ASTWriter Writer;
- bool AllowASTWithErrors;
-
-protected:
- ASTWriter &getWriter() { return Writer; }
- const ASTWriter &getWriter() const { return Writer; }
- SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
-
-public:
- PCHGenerator(
- const Preprocessor &PP, StringRef OutputFile,
- clang::Module *Module, StringRef isysroot,
- std::shared_ptr<PCHBuffer> Buffer,
- ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
- bool AllowASTWithErrors = false,
- bool IncludeTimestamps = true);
- ~PCHGenerator() override;
- void InitializeSema(Sema &S) override { SemaPtr = &S; }
- void HandleTranslationUnit(ASTContext &Ctx) override;
- ASTMutationListener *GetASTMutationListener() override;
- ASTDeserializationListener *GetASTDeserializationListener() override;
- bool hasEmittedPCH() const { return Buffer->IsComplete; }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Serialization/CMakeLists.txt b/include/clang/Serialization/CMakeLists.txt
deleted file mode 100644
index d91513d..0000000
--- a/include/clang/Serialization/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-clang_tablegen(AttrPCHRead.inc -gen-clang-attr-pch-read
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrPCHRead)
-
-clang_tablegen(AttrPCHWrite.inc -gen-clang-attr-pch-write
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrPCHWrite)
diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h
deleted file mode 100644
index 244b01b..0000000
--- a/include/clang/Serialization/ContinuousRangeMap.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===--- ContinuousRangeMap.h - Map with int range as key -------*- 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 ContinuousRangeMap class, which is a highly
-// specialized container used by serialization.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
-#define LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/SmallVector.h"
-#include <algorithm>
-#include <utility>
-
-namespace clang {
-
-/// \brief 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.
-/// where one ends, the next one begins. So if the map contains the stops I0-3,
-/// the first range is from I0 to I1, the second from I1 to I2, the third from
-/// I2 to I3 and the last from I3 to infinity.
-///
-/// Ranges must be inserted in order. Inserting a new stop I4 into the map will
-/// shrink the fourth range to I3 to I4 and add the new range I4 to inf.
-template <typename Int, typename V, unsigned InitialCapacity>
-class ContinuousRangeMap {
-public:
- typedef std::pair<Int, V> value_type;
- typedef value_type &reference;
- typedef const value_type &const_reference;
- typedef value_type *pointer;
- typedef const value_type *const_pointer;
-
-private:
- typedef SmallVector<value_type, InitialCapacity> Representation;
- Representation Rep;
-
- struct Compare {
- bool operator ()(const_reference L, Int R) const {
- return L.first < R;
- }
- bool operator ()(Int L, const_reference R) const {
- return L < R.first;
- }
- bool operator ()(Int L, Int R) const {
- return L < R;
- }
- bool operator ()(const_reference L, const_reference R) const {
- return L.first < R.first;
- }
- };
-
-public:
- void insert(const value_type &Val) {
- if (!Rep.empty() && Rep.back() == Val)
- return;
-
- assert((Rep.empty() || Rep.back().first < Val.first) &&
- "Must insert keys in order.");
- Rep.push_back(Val);
- }
-
- void insertOrReplace(const value_type &Val) {
- iterator I = std::lower_bound(Rep.begin(), Rep.end(), Val, Compare());
- if (I != Rep.end() && I->first == Val.first) {
- I->second = Val.second;
- return;
- }
-
- Rep.insert(I, Val);
- }
-
- typedef typename Representation::iterator iterator;
- typedef typename Representation::const_iterator const_iterator;
-
- iterator begin() { return Rep.begin(); }
- iterator end() { return Rep.end(); }
- const_iterator begin() const { return Rep.begin(); }
- const_iterator end() const { return Rep.end(); }
-
- iterator find(Int K) {
- iterator I = std::upper_bound(Rep.begin(), Rep.end(), K, Compare());
- // I points to the first entry with a key > K, which is the range that
- // follows the one containing K.
- if (I == Rep.begin())
- return Rep.end();
- --I;
- return I;
- }
- const_iterator find(Int K) const {
- return const_cast<ContinuousRangeMap*>(this)->find(K);
- }
-
- reference back() { return Rep.back(); }
- const_reference back() const { return Rep.back(); }
-
- /// \brief An object that helps properly build a continuous range map
- /// from a set of values.
- class Builder {
- ContinuousRangeMap &Self;
-
- Builder(const Builder&) = delete;
- Builder &operator=(const Builder&) = delete;
-
- public:
- explicit Builder(ContinuousRangeMap &Self) : Self(Self) { }
-
- ~Builder() {
- std::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
- // duplicate 0 -> 0 mappings to remove first.
- assert((A == B || A.first != B.first) &&
- "ContinuousRangeMap::Builder given non-unique keys");
- return A == B;
- });
- }
-
- void insert(const value_type &Val) {
- Self.Rep.push_back(Val);
- }
- };
- friend class Builder;
-};
-
-}
-
-#endif
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
deleted file mode 100644
index 0f14eca..0000000
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ /dev/null
@@ -1,207 +0,0 @@
-//===--- GlobalModuleIndex.h - Global Module Index --------------*- 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 GlobalModuleIndex class, which manages a global index
-// containing all of the identifiers known to the various modules within a given
-// subdirectory of the module cache. It is used to improve the performance of
-// queries such as "do any modules know about this identifier?"
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
-#define LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <memory>
-#include <utility>
-
-namespace llvm {
-class BitstreamCursor;
-class MemoryBuffer;
-}
-
-namespace clang {
-
-class DirectoryEntry;
-class FileEntry;
-class FileManager;
-class IdentifierIterator;
-class PCHContainerOperations;
-class PCHContainerReader;
-
-namespace serialization {
- class ModuleFile;
-}
-
-using llvm::SmallVector;
-using llvm::SmallVectorImpl;
-using llvm::StringRef;
-using serialization::ModuleFile;
-
-/// \brief 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
-/// place where one can look for identifiers determine which
-/// module files contain any information about that identifier. This
-/// allows the client to restrict the search to only those module files known
-/// to have a information about that identifier, improving performance. Moreover,
-/// the global module index may know about module files that have not been
-/// 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
- /// as the global module index is live.
- std::unique_ptr<llvm::MemoryBuffer> Buffer;
-
- /// \brief 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.
- struct ModuleInfo {
- ModuleInfo() : File(), Size(), ModTime() { }
-
- /// \brief The module file, once it has been resolved.
- ModuleFile *File;
-
- /// \brief The module file name.
- std::string FileName;
-
- /// \brief 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
- /// index was built.
- time_t ModTime;
-
- /// \brief 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.
- ///
- /// 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
- /// corresponding index into the \c Modules vector.
- llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile;
-
- /// \brief 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.
- unsigned NumIdentifierLookups;
-
- /// \brief The number of identifier lookup hits, where we recognize the
- /// identifier.
- unsigned NumIdentifierLookupHits;
-
- /// \brief Internal constructor. Use \c readIndex() to read an index.
- explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,
- llvm::BitstreamCursor Cursor);
-
- GlobalModuleIndex(const GlobalModuleIndex &) = delete;
- GlobalModuleIndex &operator=(const GlobalModuleIndex &) = delete;
-
-public:
- ~GlobalModuleIndex();
-
- /// \brief An error code returned when trying to read an index.
- enum ErrorCode {
- /// \brief No error occurred.
- EC_None,
- /// \brief No index was found.
- EC_NotFound,
- /// \brief 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.
- EC_IOError
- };
-
- /// \brief 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.
- ///
- /// \returns A pair containing the global module index (if it exists) and
- /// the error code.
- static std::pair<GlobalModuleIndex *, ErrorCode>
- readIndex(StringRef Path);
-
- /// \brief 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.
- ///
- /// \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
- /// directly depends.
- void getModuleDependencies(ModuleFile *File,
- SmallVectorImpl<ModuleFile *> &Dependencies);
-
- /// \brief 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
- /// identifier, e.g., a global function, variable, or type with that name.
- ///
- /// \param Name The identifier to look for.
- ///
- /// \param Hits Will be populated with the set of module files that have
- /// information about this name.
- ///
- /// \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.
- ///
- /// \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.
- void printStats();
-
- /// \brief Print debugging view to standard error.
- void dump();
-
- /// \brief 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
- /// creating modules.
- /// \param Path The path to the directory containing module files, into
- /// which the global index will be written.
- static ErrorCode writeIndex(FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr,
- StringRef Path);
-};
-}
-
-#endif
diff --git a/include/clang/Serialization/Makefile b/include/clang/Serialization/Makefile
deleted file mode 100644
index 386f453..0000000
--- a/include/clang/Serialization/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-CLANG_LEVEL := ../../..
-TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrPCHRead.inc AttrPCHWrite.inc
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/AttrPCHRead.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang PCH reader with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-pch-read -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrPCHWrite.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang PCH writer with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-pch-write -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
deleted file mode 100644
index d6d16a0..0000000
--- a/include/clang/Serialization/Module.h
+++ /dev/null
@@ -1,475 +0,0 @@
-//===--- Module.h - Module description --------------------------*- 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 Module class, which describes a module that has
-// been loaded from an AST file.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H
-#define LLVM_CLANG_SERIALIZATION_MODULE_H
-
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Serialization/ContinuousRangeMap.h"
-#include "clang/Serialization/ModuleFileExtension.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/Endian.h"
-#include <memory>
-#include <string>
-
-namespace llvm {
-template <typename Info> class OnDiskChainedHashTable;
-template <typename Info> class OnDiskIterableChainedHashTable;
-}
-
-namespace clang {
-
-class DeclContext;
-class Module;
-
-namespace serialization {
-
-namespace reader {
- class ASTDeclContextNameLookupTrait;
-}
-
-/// \brief 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.
-};
-
-/// \brief 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 {
- enum {
- Overridden = 1,
- OutOfDate = 2,
- NotFound = 3
- };
- llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val;
-
-public:
- InputFile() {}
- InputFile(const FileEntry *File,
- bool isOverridden = false, bool isOutOfDate = false) {
- assert(!(isOverridden && isOutOfDate) &&
- "an overridden cannot be out-of-date");
- unsigned intVal = 0;
- if (isOverridden)
- intVal = Overridden;
- else if (isOutOfDate)
- intVal = OutOfDate;
- Val.setPointerAndInt(File, intVal);
- }
-
- static InputFile getNotFound() {
- InputFile File;
- File.Val.setInt(NotFound);
- return File;
- }
-
- const FileEntry *getFile() const { return Val.getPointer(); }
- bool isOverridden() const { return Val.getInt() == Overridden; }
- bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
- bool isNotFound() const { return Val.getInt() == NotFound; }
-};
-
-typedef unsigned ASTFileSignature;
-
-/// \brief 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
-/// of some sort loaded as the main file, all of which are specific formulations
-/// of the general notion of a "module". A module may depend on any number of
-/// other modules.
-class ModuleFile {
-public:
- ModuleFile(ModuleKind Kind, unsigned Generation);
- ~ModuleFile();
-
- // === General information ===
-
- /// \brief The index of this module in the list of modules.
- unsigned Index;
-
- /// \brief The type of this module.
- ModuleKind Kind;
-
- /// \brief The file name of the module file.
- std::string FileName;
-
- /// \brief The name of the module.
- std::string ModuleName;
-
- /// \brief 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
- /// 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
- /// build this AST file.
- std::string ActualOriginalSourceFileName;
-
- /// \brief 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
- /// 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.
- bool RelocatablePCH;
-
- /// \brief Whether timestamps are included in this module file.
- bool HasTimestamps;
-
- /// \brief The file entry for the module file.
- const FileEntry *File;
-
- /// \brief The signature of the module file, which may be used along with size
- /// and modification time to identify this particular file.
- ASTFileSignature Signature;
-
- /// \brief Whether this module has been directly imported by the
- /// user.
- bool DirectlyImported;
-
- /// \brief The generation of which this module file is a part.
- unsigned Generation;
-
- /// \brief The memory buffer that stores the data associated with
- /// this AST file.
- std::unique_ptr<llvm::MemoryBuffer> Buffer;
-
- /// \brief The size of this file, in bits.
- uint64_t SizeInBits;
-
- /// \brief The global bit offset (or base) of this module
- uint64_t GlobalBitOffset;
-
- /// \brief The bitstream reader from which we'll read the AST file.
- llvm::BitstreamReader StreamFile;
-
- /// \brief The main bitstream cursor for the main block.
- llvm::BitstreamCursor Stream;
-
- /// \brief 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
- /// same DirectImportLoc, but different ImportLoc (B's ImportLoc will be a
- /// source location inside module A).
- ///
- /// WARNING: This is largely useless. It doesn't tell you when a module was
- /// made visible, just when the first submodule of that module was imported.
- SourceLocation DirectImportLoc;
-
- /// \brief The source location where this module was first imported.
- SourceLocation ImportLoc;
-
- /// \brief The first source location in this module.
- SourceLocation FirstLoc;
-
- /// The list of extension readers that are attached to this module
- /// file.
- std::vector<std::unique_ptr<ModuleFileExtensionReader>> ExtensionReaders;
-
- // === Input Files ===
- /// \brief 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.
- const llvm::support::unaligned_uint64_t *InputFileOffsets;
-
- /// \brief The input files that have been loaded from this AST file.
- std::vector<InputFile> InputFilesLoaded;
-
- /// \brief 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.
- uint64_t InputFilesValidationTimestamp;
-
- // === Source Locations ===
-
- /// \brief Cursor used to read source location entries.
- llvm::BitstreamCursor SLocEntryCursor;
-
- /// \brief The number of source location entries in this AST file.
- unsigned LocalNumSLocEntries;
-
- /// \brief The base ID in the source manager's view of this module.
- int SLocEntryBaseID;
-
- /// \brief The base offset in the source manager's view of this module.
- unsigned SLocEntryBaseOffset;
-
- /// \brief Offsets for all of the source location entries in the
- /// AST file.
- const uint32_t *SLocEntryOffsets;
-
- /// \brief SLocEntries that we're going to preload.
- SmallVector<uint64_t, 4> PreloadSLocEntries;
-
- /// \brief Remapping table for source locations in this module.
- ContinuousRangeMap<uint32_t, int, 2> SLocRemap;
-
- // === Identifiers ===
-
- /// \brief The number of identifiers in this AST file.
- unsigned LocalNumIdentifiers;
-
- /// \brief 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;
-
- /// \brief Base identifier ID for identifiers local to this module.
- serialization::IdentID BaseIdentifierID;
-
- /// \brief 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.
- ///
- /// This pointer points into a memory buffer, where the on-disk hash
- /// table for identifiers actually lives.
- const char *IdentifierTableData;
-
- /// \brief A pointer to an on-disk hash table of opaque type
- /// IdentifierHashTable.
- void *IdentifierLookupTable;
-
- /// \brief 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
- /// all of the macro definitions.
- llvm::BitstreamCursor MacroCursor;
-
- /// \brief The number of macros in this AST file.
- unsigned LocalNumMacros;
-
- /// \brief 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;
-
- /// \brief Base macro ID for macros local to this module.
- serialization::MacroID BaseMacroID;
-
- /// \brief 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.
- uint64_t MacroStartOffset;
-
- // === Detailed PreprocessingRecord ===
-
- /// \brief 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.
- uint64_t PreprocessorDetailStartOffset;
-
- /// \brief Base preprocessed entity ID for preprocessed entities local to
- /// this module.
- serialization::PreprocessedEntityID BasePreprocessedEntityID;
-
- /// \brief Remapping table for preprocessed entity IDs in this module.
- ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
-
- const PPEntityOffset *PreprocessedEntityOffsets;
- unsigned NumPreprocessedEntities;
-
- // === Header search information ===
-
- /// \brief The number of local HeaderFileInfo structures.
- unsigned LocalNumHeaderFileInfos;
-
- /// \brief 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;
-
- /// \brief The on-disk hash table that contains information about each of
- /// the header files.
- void *HeaderFileInfoTable;
-
- // === Submodule information ===
- /// \brief The number of submodules in this module.
- unsigned LocalNumSubmodules;
-
- /// \brief Base submodule ID for submodules local to this module.
- serialization::SubmoduleID BaseSubmoduleID;
-
- /// \brief Remapping table for submodule IDs in this module.
- ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap;
-
- // === Selectors ===
-
- /// \brief The number of selectors new to this file.
- ///
- /// This is the number of entries in SelectorOffsets.
- unsigned LocalNumSelectors;
-
- /// \brief Offsets into the selector lookup table's data array
- /// where each selector resides.
- const uint32_t *SelectorOffsets;
-
- /// \brief Base selector ID for selectors local to this module.
- serialization::SelectorID BaseSelectorID;
-
- /// \brief 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
- ///
- /// The SelectorOffsets table refers into this memory.
- const unsigned char *SelectorLookupTableData;
-
- /// \brief A pointer to an on-disk hash table of opaque type
- /// ASTSelectorLookupTable.
- ///
- /// This hash table provides the IDs of all selectors, and the associated
- /// instance and factory methods.
- void *SelectorLookupTable;
-
- // === Declarations ===
-
- /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It
- /// has read all the abbreviations at the start of the block and is ready to
- /// jump around with these in context.
- llvm::BitstreamCursor DeclsCursor;
-
- /// \brief The number of declarations in this AST file.
- unsigned LocalNumDecls;
-
- /// \brief Offset of each declaration within the bitstream, indexed
- /// by the declaration ID (-1).
- const DeclOffset *DeclOffsets;
-
- /// \brief Base declaration ID for declarations local to this module.
- serialization::DeclID BaseDeclID;
-
- /// \brief 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
- /// to the base declaration ID for that module as it is understood within this
- /// module.
- ///
- /// This is effectively a reverse global-to-local mapping for declaration
- /// IDs, so that we can interpret a true global ID (for this translation unit)
- /// as a local ID (for this module file).
- llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
-
- /// \brief The number of C++ base specifier sets in this AST file.
- unsigned LocalNumCXXBaseSpecifiers;
-
- /// \brief Offset of each C++ base specifier set within the bitstream,
- /// indexed by the C++ base specifier set ID (-1).
- const uint32_t *CXXBaseSpecifiersOffsets;
-
- /// \brief The number of C++ ctor initializer lists in this AST file.
- unsigned LocalNumCXXCtorInitializers;
-
- /// \brief Offset of each C++ ctor initializer list within the bitstream,
- /// indexed by the C++ ctor initializer list ID minus 1.
- const uint32_t *CXXCtorInitializersOffsets;
-
- /// \brief Array of file-level DeclIDs sorted by file.
- const serialization::DeclID *FileSortedDecls;
- unsigned NumFileSortedDecls;
-
- /// \brief Array of category list location information within this
- /// module file, sorted by the definition ID.
- const serialization::ObjCCategoriesInfo *ObjCCategoriesMap;
-
- /// \brief The number of redeclaration info entries in ObjCCategoriesMap.
- unsigned LocalNumObjCCategoriesInMap;
-
- /// \brief 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.
- unsigned LocalNumTypes;
-
- /// \brief Offset of each type within the bitstream, indexed by the
- /// type ID, or the representation of a Type*.
- const uint32_t *TypeOffsets;
-
- /// \brief Base type ID for types local to this module as represented in
- /// the global type ID space.
- serialization::TypeID BaseTypeIndex;
-
- /// \brief 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.
- SmallVector<uint64_t, 8> PragmaDiagMappings;
-
- /// \brief List of modules which depend on this module
- llvm::SetVector<ModuleFile *> ImportedBy;
-
- /// \brief List of modules which this module depends on
- llvm::SetVector<ModuleFile *> Imports;
-
- /// \brief 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).
- bool isModule() const {
- return Kind == MK_ImplicitModule || Kind == MK_ExplicitModule;
- }
-
- /// \brief Dump debugging output for this module.
- void dump();
-};
-
-} // end namespace serialization
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Serialization/ModuleFileExtension.h b/include/clang/Serialization/ModuleFileExtension.h
deleted file mode 100644
index ba2e2fd..0000000
--- a/include/clang/Serialization/ModuleFileExtension.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- ModuleFileExtension.h - Module File Extensions ----------*- 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_SERIALIZATION_MODULEFILEEXTENSION_H
-#define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
-
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include <memory>
-#include <string>
-
-namespace llvm {
-class BitstreamCursor;
-class BitstreamWriter;
-class hash_code;
-class raw_ostream;
-}
-
-namespace clang {
-
-class ASTReader;
-class ASTWriter;
-class Sema;
-
-namespace serialization {
- class ModuleFile;
-} // end namespace serialization
-
-/// Metadata for a module file extension.
-struct ModuleFileExtensionMetadata {
- /// The name used to identify this particular extension block within
- /// the resulting module file. It should be unique to the particular
- /// extension, because this name will be used to match the name of
- /// an extension block to the appropriate reader.
- std::string BlockName;
-
- /// The major version of the extension data.
- unsigned MajorVersion;
-
- /// The minor version of the extension data.
- unsigned MinorVersion;
-
- /// A string containing additional user information that will be
- /// stored with the metadata.
- std::string UserInfo;
-};
-
-class ModuleFileExtensionReader;
-class ModuleFileExtensionWriter;
-
-/// An abstract superclass that describes a custom extension to the
-/// module/precompiled header file format.
-///
-/// A module file extension can introduce additional information into
-/// compiled module files (.pcm) and precompiled headers (.pch) via a
-/// custom writer that can then be accessed via a custom reader when
-/// the module file or precompiled header is loaded.
-class ModuleFileExtension : public llvm::RefCountedBase<ModuleFileExtension> {
-public:
- virtual ~ModuleFileExtension();
-
- /// Retrieves the metadata for this module file extension.
- virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0;
-
- /// Hash information about the presence of this extension into the
- /// module hash code.
- ///
- /// The module hash code is used to distinguish different variants
- /// of a module that are incompatible. If the presence, absence, or
- /// version of the module file extension should force the creation
- /// of a separate set of module files, override this method to
- /// combine that distinguishing information into the module hash
- /// code.
- ///
- /// The default implementation of this function simply returns the
- /// hash code as given, so the presence/absence of this extension
- /// does not distinguish module files.
- virtual llvm::hash_code hashExtension(llvm::hash_code c) const;
-
- /// Create a new module file extension writer, which will be
- /// responsible for writing the extension contents into a particular
- /// module file.
- virtual std::unique_ptr<ModuleFileExtensionWriter>
- createExtensionWriter(ASTWriter &Writer) = 0;
-
- /// Create a new module file extension reader, given the
- /// metadata read from the block and the cursor into the extension
- /// block.
- ///
- /// May return null to indicate that an extension block with the
- /// given metadata cannot be read.
- virtual std::unique_ptr<ModuleFileExtensionReader>
- createExtensionReader(const ModuleFileExtensionMetadata &Metadata,
- ASTReader &Reader, serialization::ModuleFile &Mod,
- const llvm::BitstreamCursor &Stream) = 0;
-};
-
-/// Abstract base class that writes a module file extension block into
-/// a module file.
-class ModuleFileExtensionWriter {
- ModuleFileExtension *Extension;
-
-protected:
- ModuleFileExtensionWriter(ModuleFileExtension *Extension)
- : Extension(Extension) { }
-
-public:
- virtual ~ModuleFileExtensionWriter();
-
- /// Retrieve the module file extension with which this writer is
- /// associated.
- ModuleFileExtension *getExtension() const { return Extension; }
-
- /// Write the contents of the extension block into the given bitstream.
- ///
- /// Responsible for writing the contents of the extension into the
- /// given stream. All of the contents should be written into custom
- /// records with IDs >= FIRST_EXTENSION_RECORD_ID.
- virtual void writeExtensionContents(Sema &SemaRef,
- llvm::BitstreamWriter &Stream) = 0;
-};
-
-/// Abstract base class that reads a module file extension block from
-/// a module file.
-///
-/// Subclasses
-class ModuleFileExtensionReader {
- ModuleFileExtension *Extension;
-
-protected:
- ModuleFileExtensionReader(ModuleFileExtension *Extension)
- : Extension(Extension) { }
-
-public:
- /// Retrieve the module file extension with which this reader is
- /// associated.
- ModuleFileExtension *getExtension() const { return Extension; }
-
- virtual ~ModuleFileExtensionReader();
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
deleted file mode 100644
index 08e7d40..0000000
--- a/include/clang/Serialization/ModuleManager.h
+++ /dev/null
@@ -1,289 +0,0 @@
-//===--- ModuleManager.cpp - Module Manager ---------------------*- 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 ModuleManager class, which manages a set of loaded
-// modules for the ASTReader.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
-#define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
-
-#include "clang/Basic/FileManager.h"
-#include "clang/Serialization/Module.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-
-namespace clang {
-
-class GlobalModuleIndex;
-class ModuleMap;
-class PCHContainerReader;
-
-namespace serialization {
-
-/// \brief 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
- /// them (this order isn't really useful for anything).
- SmallVector<ModuleFile *, 2> Chain;
-
- /// \brief 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
- // to implement short-circuiting logic when running DFS over the dependencies.
- SmallVector<ModuleFile *, 2> Roots;
-
- /// \brief All loaded modules, indexed by name.
- llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
-
- /// \brief FileManager that handles translating between filenames and
- /// FileEntry *.
- FileManager &FileMgr;
-
- /// \brief Knows how to unwrap module containers.
- const PCHContainerReader &PCHContainerRdr;
-
- /// \brief A lookup of in-memory (virtual file) buffers
- llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
- InMemoryBuffers;
-
- /// \brief The visitation order.
- SmallVector<ModuleFile *, 4> VisitOrder;
-
- /// \brief 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
- /// other does not know about, because the global index can be out-of-date
- /// (in which case the module manager could have modules it does not) and
- /// this particular translation unit might not have loaded all of the modules
- /// known to the global index.
- SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
-
- /// \brief 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;
-
- /// \brief State used by the "visit" operation to avoid malloc traffic in
- /// calls to visit().
- struct VisitState {
- explicit VisitState(unsigned N)
- : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
- {
- Stack.reserve(N);
- }
-
- ~VisitState() {
- delete NextState;
- }
-
- /// \brief 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
- /// this module file was last visited.
- SmallVector<unsigned, 4> VisitNumber;
-
- /// \brief The next visit number to use to mark visited module files.
- unsigned NextVisitNumber;
-
- /// \brief The next visit state.
- VisitState *NextState;
- };
-
- /// \brief The first visit() state in the chain.
- VisitState *FirstVisitState;
-
- VisitState *allocateVisitState();
- void returnVisitState(VisitState *State);
-
-public:
- typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator;
- typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator;
- typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
- typedef std::pair<uint32_t, StringRef> ModuleOffset;
-
- explicit ModuleManager(FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr);
- ~ModuleManager();
-
- /// \brief Forward iterator to traverse all loaded modules.
- ModuleIterator begin() { return Chain.begin(); }
- /// \brief Forward iterator end-point to traverse all loaded modules
- ModuleIterator end() { return Chain.end(); }
-
- /// \brief 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
- ModuleConstIterator end() const { return Chain.end(); }
-
- /// \brief Reverse iterator to traverse all loaded modules.
- ModuleReverseIterator rbegin() { return Chain.rbegin(); }
- /// \brief 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.
- llvm::iterator_range<ModuleConstIterator> pch_modules() const {
- return llvm::make_range(PCHChain.begin(), PCHChain.end());
- }
-
- /// \brief 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,
- /// the first module loaded.
- ModuleFile &getPrimaryModule() const { return *Chain[0]; }
-
- /// \brief Returns the module associated with the given index
- ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
-
- /// \brief Returns the module associated with the given name
- ModuleFile *lookup(StringRef Name);
-
- /// \brief Returns the module associated with the given module file.
- ModuleFile *lookup(const FileEntry *File);
-
- /// \brief Returns the in-memory (virtual file) buffer with the given name
- std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name);
-
- /// \brief Number of modules loaded
- unsigned size() const { return Chain.size(); }
-
- /// \brief The result of attempting to add a new module.
- enum AddModuleResult {
- /// \brief The module file had already been loaded.
- AlreadyLoaded,
- /// \brief The module file was just loaded in response to this call.
- NewlyLoaded,
- /// \brief The module file is missing.
- Missing,
- /// \brief The module file is out-of-date.
- OutOfDate
- };
-
- typedef ASTFileSignature(*ASTFileSignatureReader)(llvm::BitstreamReader &);
-
- /// \brief 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.
- ///
- /// \param Type The kind of module being loaded.
- ///
- /// \param ImportLoc The location at which the module is imported.
- ///
- /// \param ImportedBy The module that is importing this module, or NULL if
- /// this module is imported directly by the user.
- ///
- /// \param Generation The generation in which this module was loaded.
- ///
- /// \param ExpectedSize The expected size of the module file, used for
- /// validation. This will be zero if unknown.
- ///
- /// \param ExpectedModTime The expected modification time of the module
- /// file, used for validation. This will be zero if unknown.
- ///
- /// \param ExpectedSignature The expected signature of the module file, used
- /// for validation. This will be zero if unknown.
- ///
- /// \param ReadSignature Reads the signature from an AST file without actually
- /// loading it.
- ///
- /// \param Module A pointer to the module file if the module was successfully
- /// loaded.
- ///
- /// \param ErrorStr Will be set to a non-empty string if any errors occurred
- /// while trying to load the module.
- ///
- /// \return A pointer to the module that corresponds to this file name,
- /// and a value indicating whether the module was loaded.
- AddModuleResult addModule(StringRef FileName, ModuleKind Type,
- SourceLocation ImportLoc,
- ModuleFile *ImportedBy, unsigned Generation,
- off_t ExpectedSize, time_t ExpectedModTime,
- ASTFileSignature ExpectedSignature,
- ASTFileSignatureReader ReadSignature,
- ModuleFile *&Module,
- std::string &ErrorStr);
-
- /// \brief Remove the given set of modules.
- void removeModules(ModuleIterator first, ModuleIterator last,
- llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
- ModuleMap *modMap);
-
- /// \brief 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.
- void setGlobalIndex(GlobalModuleIndex *Index);
-
- /// \brief 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.
- ///
- /// This routine visits each of the modules, starting with the
- /// "root" modules that no other loaded modules depend on, and
- /// proceeding to the leaf modules, visiting each module only once
- /// during the traversal.
- ///
- /// This traversal is intended to support various "lookup"
- /// operations that can find data in any of the loaded modules.
- ///
- /// \param Visitor A visitor function that will be invoked with each
- /// module. The return value must be convertible to bool; when false, the
- /// visitation continues to modules that the current module depends on. When
- /// true, the visitation skips any modules that the current module depends on.
- ///
- /// \param ModuleFilesHit If non-NULL, contains the set of module files
- /// that we know we need to visit because the global module index told us to.
- /// Any module that is known to both the global module index and the module
- /// manager that is *not* in this set can be skipped.
- 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.
- ///
- /// \param FileName The name of the module file.
- ///
- /// \param ExpectedSize The size that the module file is expected to have.
- /// If the actual size differs, the resolver should return \c true.
- ///
- /// \param ExpectedModTime The modification time that the module file is
- /// expected to have. If the actual modification time differs, the resolver
- /// should return \c true.
- ///
- /// \param File Will be set to the file if there is one, or null
- /// otherwise.
- ///
- /// \returns True if a file exists but does not meet the size/
- /// modification time criteria, false if the file is either available and
- /// suitable, or is missing.
- bool lookupModuleFile(StringRef FileName,
- off_t ExpectedSize,
- time_t ExpectedModTime,
- const FileEntry *&File);
-
- /// \brief View the graphviz representation of the module graph.
- void viewGraph();
-};
-
-} } // end namespace clang::serialization
-
-#endif
diff --git a/include/clang/Serialization/SerializationDiagnostic.h b/include/clang/Serialization/SerializationDiagnostic.h
deleted file mode 100644
index d50422a..0000000
--- a/include/clang/Serialization/SerializationDiagnostic.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- SerializationDiagnostic.h - Serialization Diagnostics -*- 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_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H
-#define LLVM_CLANG_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define SERIALIZATIONSTART
-#include "clang/Basic/DiagnosticSerializationKinds.inc"
-#undef DIAG
- NUM_BUILTIN_SERIALIZATION_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
deleted file mode 100644
index 11f1e5d..0000000
--- a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
+++ /dev/null
@@ -1,39 +0,0 @@
-//===--- CheckerBase.td - Checker TableGen classes ------------------------===//
-//
-// 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 core definitions for checkers
-//
-//===----------------------------------------------------------------------===//
-
-class CheckerGroup<string name> {
- string GroupName = name;
-}
-class InGroup<CheckerGroup G> { CheckerGroup Group = G; }
-
-class Package<string name> {
- string PackageName = name;
- bit Hidden = 0;
- Package ParentPackage;
- CheckerGroup Group;
-}
-class InPackage<Package P> { Package ParentPackage = P; }
-
-// All checkers are an indirect subclass of this.
-class Checker<string name = ""> {
- string CheckerName = name;
- string DescFile;
- string HelpText;
- bit Hidden = 0;
- Package ParentPackage;
- CheckerGroup Group;
-}
-
-class DescFile<string filename> { string DescFile = filename; }
-class HelpText<string text> { string HelpText = text; }
-class Hidden { bit Hidden = 1; }
diff --git a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h b/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h
deleted file mode 100644
index cf0a30a..0000000
--- a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===--- ClangCheckers.h - Provides builtin checkers ------------*- 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_STATICANALYZER_CHECKERS_CLANGCHECKERS_H
-#define LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H
-
-namespace clang {
-namespace ento {
-class CheckerRegistry;
-
-void registerBuiltinCheckers(CheckerRegistry &registry);
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
deleted file mode 100644
index 463f04a..0000000
--- a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//==- LocalCheckers.h - Intra-Procedural+Flow-Sensitive Checkers -*- 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 interface to call a set of intra-procedural (local)
-// checkers that use flow/path-sensitive analyses to find bugs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_LOCALCHECKERS_H
-#define LLVM_CLANG_STATICANALYZER_CHECKERS_LOCALCHECKERS_H
-
-namespace clang {
-namespace ento {
-
-class ExprEngine;
-
-void RegisterCallInliner(ExprEngine &Eng);
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
deleted file mode 100644
index 5850656..0000000
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ /dev/null
@@ -1,234 +0,0 @@
-//==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- 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 core data structures for retain count "summaries"
-// for Objective-C and Core Foundation APIs. These summaries are used
-// by the static analyzer to summarize the retain/release effects of
-// function and method calls. This drives a path-sensitive typestate
-// analysis in the static analyzer, but can also potentially be used by
-// other clients.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
-#define LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-class FunctionDecl;
-class ObjCMethodDecl;
-
-namespace ento { namespace objc_retain {
-
-/// An ArgEffect summarizes the retain count behavior on an argument or receiver
-/// to a function or method.
-enum ArgEffect {
- /// There is no effect.
- DoNothing,
-
- /// The argument is treated as if an -autorelease message had been sent to
- /// the referenced object.
- Autorelease,
-
- /// The argument is treated as if an -dealloc message had been sent to
- /// the referenced object.
- Dealloc,
-
- /// The argument has its reference count decreased by 1. This is as
- /// if CFRelease has been called on the argument.
- DecRef,
-
- /// The argument has its reference count decreased by 1. This is as
- /// if a -release message has been sent to the argument. This differs
- /// in behavior from DecRef when GC is enabled.
- DecRefMsg,
-
- /// The argument has its reference count decreased by 1 to model
- /// a transferred bridge cast under ARC.
- DecRefBridgedTransferred,
-
- /// The argument has its reference count increased by 1. This is as
- /// if a -retain message has been sent to the argument. This differs
- /// in behavior from IncRef when GC is enabled.
- IncRefMsg,
-
- /// The argument has its reference count increased by 1. This is as
- /// if CFRetain has been called on the argument.
- IncRef,
-
- /// The argument acts as if has been passed to CFMakeCollectable, which
- /// transfers the object to the Garbage Collector under GC.
- MakeCollectable,
-
- /// The argument is a pointer to a retain-counted object; on exit, the new
- /// value of the pointer is a +0 value or NULL.
- UnretainedOutParameter,
-
- /// The argument is a pointer to a retain-counted object; on exit, the new
- /// value of the pointer is a +1 value or NULL.
- RetainedOutParameter,
-
- /// The argument is treated as potentially escaping, meaning that
- /// even when its reference count hits 0 it should be treated as still
- /// possibly being alive as someone else *may* be holding onto the object.
- MayEscape,
-
- /// All typestate tracking of the object ceases. This is usually employed
- /// when the effect of the call is completely unknown.
- StopTracking,
-
- /// All typestate tracking of the object ceases. Unlike StopTracking,
- /// this is also enforced when the method body is inlined.
- ///
- /// In some cases, we obtain a better summary for this checker
- /// by looking at the call site than by inlining the function.
- /// Signifies that we should stop tracking the symbol even if
- /// the function is inlined.
- StopTrackingHard,
-
- /// Performs the combined functionality of DecRef and StopTrackingHard.
- ///
- /// The models the effect that the called function decrements the reference
- /// count of the argument and all typestate tracking on that argument
- /// should cease.
- DecRefAndStopTrackingHard,
-
- /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
- ///
- /// The models the effect that the called function decrements the reference
- /// count of the argument and all typestate tracking on that argument
- /// should cease.
- DecRefMsgAndStopTrackingHard
-};
-
-/// RetEffect summarizes a call's retain/release behavior with respect
-/// to its return value.
-class RetEffect {
-public:
- enum Kind {
- /// Indicates that no retain count information is tracked for
- /// the return value.
- NoRet,
- /// Indicates that the returned value is an owned (+1) symbol.
- OwnedSymbol,
- /// Indicates that the returned value is an owned (+1) symbol and
- /// that it should be treated as freshly allocated.
- OwnedAllocatedSymbol,
- /// Indicates that the returned value is an object with retain count
- /// semantics but that it is not owned (+0). This is the default
- /// for getters, etc.
- NotOwnedSymbol,
- /// Indicates that the object is not owned and controlled by the
- /// Garbage collector.
- GCNotOwnedSymbol,
- /// Indicates that the return value is an owned object when the
- /// receiver is also a tracked object.
- OwnedWhenTrackedReceiver,
- // Treat this function as returning a non-tracked symbol even if
- // the function has been inlined. This is used where the call
- // site summary is more presise than the summary indirectly produced
- // by inlining the function
- NoRetHard
- };
-
- /// Determines the object kind of a tracked object.
- enum ObjKind {
- /// Indicates that the tracked object is a CF object. This is
- /// important between GC and non-GC code.
- CF,
- /// Indicates that the tracked object is an Objective-C object.
- ObjC,
- /// Indicates that the tracked object could be a CF or Objective-C object.
- AnyObj
- };
-
-private:
- Kind K;
- ObjKind O;
-
- RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
-
-public:
- Kind getKind() const { return K; }
-
- ObjKind getObjKind() const { return O; }
-
- bool isOwned() const {
- return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
- K == OwnedWhenTrackedReceiver;
- }
-
- bool notOwned() const {
- return K == NotOwnedSymbol;
- }
-
- bool operator==(const RetEffect &Other) const {
- return K == Other.K && O == Other.O;
- }
-
- static RetEffect MakeOwnedWhenTrackedReceiver() {
- return RetEffect(OwnedWhenTrackedReceiver, ObjC);
- }
-
- static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
- return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
- }
- static RetEffect MakeNotOwned(ObjKind o) {
- return RetEffect(NotOwnedSymbol, o);
- }
- static RetEffect MakeGCNotOwned() {
- return RetEffect(GCNotOwnedSymbol, ObjC);
- }
- static RetEffect MakeNoRet() {
- return RetEffect(NoRet);
- }
- static RetEffect MakeNoRetHard() {
- return RetEffect(NoRetHard);
- }
-};
-
-/// Encapsulates the retain count semantics on the arguments, return value,
-/// and receiver (if any) of a function/method call.
-///
-/// Note that construction of these objects is not highly efficient. That
-/// is okay for clients where creating these objects isn't really a bottleneck.
-/// The purpose of the API is to provide something simple. The actual
-/// static analyzer checker that implements retain/release typestate
-/// tracking uses something more efficient.
-class CallEffects {
- llvm::SmallVector<ArgEffect, 10> Args;
- RetEffect Ret;
- ArgEffect Receiver;
-
- CallEffects(const RetEffect &R) : Ret(R) {}
-
-public:
- /// Returns the argument effects for a call.
- ArrayRef<ArgEffect> getArgs() const { return Args; }
-
- /// Returns the effects on the receiver.
- ArgEffect getReceiver() const { return Receiver; }
-
- /// Returns the effect on the return value.
- RetEffect getReturnValue() const { return Ret; }
-
- /// Return the CallEfect for a given Objective-C method.
- static CallEffects getEffect(const ObjCMethodDecl *MD);
-
- /// Return the CallEfect for a given C/C++ function.
- static CallEffects getEffect(const FunctionDecl *FD);
-};
-
-}}}
-
-#endif
-
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
deleted file mode 100644
index 3355f4b..0000000
--- a/include/clang/StaticAnalyzer/Core/Analyses.def
+++ /dev/null
@@ -1,57 +0,0 @@
-//===-- Analyses.def - Metadata about Static Analyses -----------*- 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 set of static analyses used by AnalysisConsumer.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ANALYSIS_STORE
-#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
-#endif
-
-ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateRegionStoreManager)
-
-#ifndef ANALYSIS_CONSTRAINTS
-#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)
-#endif
-
-ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager)
-
-#ifndef ANALYSIS_DIAGNOSTICS
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
-#endif
-
-ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer)
-
-#ifndef ANALYSIS_PURGE
-#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC)
-#endif
-
-ANALYSIS_PURGE(PurgeStmt, "statement", "Purge symbols, bindings, and constraints before every statement")
-ANALYSIS_PURGE(PurgeBlock, "block", "Purge symbols, bindings, and constraints before every basic block")
-ANALYSIS_PURGE(PurgeNone, "none", "Do not purge symbols, bindings, or constraints")
-
-#ifndef ANALYSIS_INLINING_MODE
-#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC)
-#endif
-
-ANALYSIS_INLINING_MODE(All, "all", "Analyze all functions as top level")
-ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function which has been previously inlined")
-
-#undef ANALYSIS_STORE
-#undef ANALYSIS_CONSTRAINTS
-#undef ANALYSIS_DIAGNOSTICS
-#undef ANALYSIS_PURGE
-#undef ANALYSIS_INLINING_MODE
-#undef ANALYSIS_IPA
-
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
deleted file mode 100644
index 3959de2..0000000
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ /dev/null
@@ -1,567 +0,0 @@
-//===--- AnalyzerOptions.h - Analysis Engine Options ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header defines various options for the static analyzer that are set
-// by the frontend and are consulted throughout the analyzer.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
-#define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringMap.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-class ASTConsumer;
-class DiagnosticsEngine;
-class Preprocessor;
-class LangOptions;
-
-namespace ento {
-class CheckerBase;
-}
-
-/// Analysis - Set of available source code analyses.
-enum Analyses {
-#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-NumAnalyses
-};
-
-/// AnalysisStores - Set of available analysis store models.
-enum AnalysisStores {
-#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-NumStores
-};
-
-/// AnalysisConstraints - Set of available constraint models.
-enum AnalysisConstraints {
-#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-NumConstraints
-};
-
-/// AnalysisDiagClients - Set of available diagnostic clients for rendering
-/// analysis results.
-enum AnalysisDiagClients {
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-PD_NONE,
-NUM_ANALYSIS_DIAG_CLIENTS
-};
-
-/// AnalysisPurgeModes - Set of available strategies for dead symbol removal.
-enum AnalysisPurgeMode {
-#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-NumPurgeModes
-};
-
-/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
-enum AnalysisInliningMode {
-#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-NumInliningModes
-};
-
-/// \brief 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
-/// enable all kinds with lower enum values.
-enum CXXInlineableMemberKind {
- // Uninitialized = 0,
-
- /// A dummy mode in which no C++ inlining is enabled.
- CIMK_None = 1,
-
- /// Refers to regular member function and operator calls.
- CIMK_MemberFunctions,
-
- /// Refers to constructors (implicit or explicit).
- ///
- /// Note that a constructor will not be inlined if the corresponding
- /// destructor is non-trivial.
- CIMK_Constructors,
-
- /// Refers to destructors (implicit or explicit).
- CIMK_Destructors
-};
-
-/// \brief Describes the different modes of inter-procedural analysis.
-enum IPAKind {
- IPAK_NotSet = 0,
-
- /// Perform only intra-procedural analysis.
- IPAK_None = 1,
-
- /// Inline C functions and blocks when their definitions are available.
- IPAK_BasicInlining = 2,
-
- /// Inline callees(C, C++, ObjC) when their definitions are available.
- IPAK_Inlining = 3,
-
- /// Enable inlining of dynamically dispatched methods.
- IPAK_DynamicDispatch = 4,
-
- /// Enable inlining of dynamically dispatched methods, bifurcate paths when
- /// exact type info is unavailable.
- IPAK_DynamicDispatchBifurcate = 5
-};
-
-class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
-public:
- typedef llvm::StringMap<std::string> ConfigTable;
-
- /// \brief 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.
- ConfigTable Config;
- AnalysisStores AnalysisStoreOpt;
- AnalysisConstraints AnalysisConstraintsOpt;
- AnalysisDiagClients AnalysisDiagOpt;
- AnalysisPurgeMode AnalysisPurgeOpt;
-
- std::string AnalyzeSpecificFunction;
-
- /// \brief The maximum number of times the analyzer visits a block.
- unsigned maxBlockVisitOnPath;
-
-
- /// \brief 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
- /// command-line options will get checked.
- unsigned DisableAllChecks : 1;
-
- unsigned ShowCheckerHelp : 1;
- unsigned AnalyzeAll : 1;
- unsigned AnalyzerDisplayProgress : 1;
- unsigned AnalyzeNestedBlocks : 1;
-
- /// \brief 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 =
- /// (y != 0)'. When this flag is true then the subexpression 'y != 0' will be
- /// eagerly assumed to be true or false, thus evaluating it to the integers 0
- /// or 1 respectively. The upside is that this can increase analysis
- /// precision until we have a better way to lazily evaluate such logic. The
- /// downside is that it eagerly bifurcates paths.
- unsigned eagerlyAssumeBinOpBifurcation : 1;
-
- unsigned TrimGraph : 1;
- unsigned visualizeExplodedGraphWithGraphViz : 1;
- unsigned visualizeExplodedGraphWithUbiGraph : 1;
- unsigned UnoptimizedCFG : 1;
- unsigned PrintStats : 1;
-
- /// \brief 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;
-
- /// \brief The mode of function selection used during inlining.
- AnalysisInliningMode InliningMode;
-
-private:
- /// \brief 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
- };
-
- /// 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;
-
- /// Controls the mode of inter-procedural analysis.
- IPAKind IPAMode;
-
- /// Controls which C++ member functions will be considered for inlining.
- CXXInlineableMemberKind CXXMemberInliningMode;
-
- /// \sa includeTemporaryDtorsInCFG
- Optional<bool> IncludeTemporaryDtorsInCFG;
-
- /// \sa mayInlineCXXStandardLibrary
- Optional<bool> InlineCXXStandardLibrary;
-
- /// \sa mayInlineTemplateFunctions
- Optional<bool> InlineTemplateFunctions;
-
- /// \sa mayInlineCXXAllocator
- Optional<bool> InlineCXXAllocator;
-
- /// \sa mayInlineCXXContainerMethods
- Optional<bool> InlineCXXContainerMethods;
-
- /// \sa mayInlineCXXSharedPtrDtor
- Optional<bool> InlineCXXSharedPtrDtor;
-
- /// \sa mayInlineObjCMethod
- Optional<bool> ObjCInliningMode;
-
- // Cache of the "ipa-always-inline-size" setting.
- // \sa getAlwaysInlineSize
- Optional<unsigned> AlwaysInlineSize;
-
- /// \sa shouldSuppressNullReturnPaths
- Optional<bool> SuppressNullReturnPaths;
-
- // \sa getMaxInlinableSize
- Optional<unsigned> MaxInlinableSize;
-
- /// \sa shouldAvoidSuppressingNullArgumentPaths
- Optional<bool> AvoidSuppressingNullArgumentPaths;
-
- /// \sa shouldSuppressInlinedDefensiveChecks
- Optional<bool> SuppressInlinedDefensiveChecks;
-
- /// \sa shouldSuppressFromCXXStandardLibrary
- Optional<bool> SuppressFromCXXStandardLibrary;
-
- /// \sa reportIssuesInMainSourceFile
- Optional<bool> ReportIssuesInMainSourceFile;
-
- /// \sa StableReportFilename
- Optional<bool> StableReportFilename;
-
- /// \sa getGraphTrimInterval
- Optional<unsigned> GraphTrimInterval;
-
- /// \sa getMaxTimesInlineLarge
- Optional<unsigned> MaxTimesInlineLarge;
-
- /// \sa getMinCFGSizeTreatFunctionsAsLarge
- Optional<unsigned> MinCFGSizeTreatFunctionsAsLarge;
-
- /// \sa getMaxNodesPerTopLevelFunction
- Optional<unsigned> MaxNodesPerTopLevelFunction;
-
- /// \sa shouldInlineLambdas
- Optional<bool> InlineLambdas;
-
- /// \sa shouldWidenLoops
- Optional<bool> WidenLoops;
-
- /// A helper function that retrieves option for a given full-qualified
- /// checker name.
- /// Options for checkers can be specified via 'analyzer-config' command-line
- /// option.
- /// Example:
- /// @code-analyzer-config unix.Malloc:OptionName=CheckerOptionValue @endcode
- /// or @code-analyzer-config unix:OptionName=GroupOptionValue @endcode
- /// for groups of checkers.
- /// @param [in] CheckerName Full-qualified checker name, like
- /// alpha.unix.StreamChecker.
- /// @param [in] OptionName Name of the option to get.
- /// @param [in] Default Default value if no option is specified.
- /// @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
- /// ones.
- /// @retval CheckerOptionValue An option for a checker if it was specified.
- /// @retval GroupOptionValue An option for group if it was specified and no
- /// checker-specific options were found. The closer group to checker,
- /// the more priority it has. For example, @c coregroup.subgroup has more
- /// priority than @c coregroup for @c coregroup.subgroup.CheckerName checker.
- /// @retval Default If nor checker option, nor group option was found.
- StringRef getCheckerOption(StringRef CheckerName, StringRef OptionName,
- StringRef Default,
- bool SearchInParents = false);
-
-public:
- /// Interprets an option's string value as a boolean. The "true" string is
- /// interpreted as true and the "false" string is interpreted as false.
- ///
- /// If an option value is not provided, returns the given \p DefaultVal.
- /// @param [in] Name Name for option to retrieve.
- /// @param [in] DefaultVal Default value returned if no such option was
- /// 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).
- /// @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
- /// ones.
- bool getBooleanOption(StringRef Name, bool DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
-
- /// Variant that accepts a Optional value to cache the result.
- ///
- /// @param [in,out] V Return value storage, returned if parameter contains
- /// an existing valid option, else it is used to store a return value
- /// @param [in] Name Name for option to retrieve.
- /// @param [in] DefaultVal Default value returned if no such option was
- /// 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).
- /// @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
- /// ones.
- bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
-
- /// Interprets an option's string value as an integer value.
- ///
- /// If an option value is not provided, returns the given \p DefaultVal.
- /// @param [in] Name Name for option to retrieve.
- /// @param [in] DefaultVal Default value returned if no such option was
- /// 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).
- /// @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
- /// ones.
- int getOptionAsInteger(StringRef Name, int DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
-
- /// Query an option's string value.
- ///
- /// If an option value is not provided, returns the given \p DefaultVal.
- /// @param [in] Name Name for option to retrieve.
- /// @param [in] DefaultVal Default value returned if no such option was
- /// 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).
- /// @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
- /// ones.
- StringRef getOptionAsString(StringRef Name, StringRef DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
-
- /// \brief 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.
- IPAKind getIPAMode();
-
- /// Returns the option controlling which C++ member functions will be
- /// considered for inlining.
- ///
- /// This is controlled by the 'c++-inlining' config option.
- ///
- /// \sa CXXMemberInliningMode
- bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K);
-
- /// Returns true if ObjectiveC inlining is enabled, false otherwise.
- bool mayInlineObjCMethod();
-
- /// Returns whether or not the destructors for C++ temporary objects should
- /// be included in the CFG.
- ///
- /// This is controlled by the 'cfg-temporary-dtors' config option, which
- /// accepts the values "true" and "false".
- bool includeTemporaryDtorsInCFG();
-
- /// Returns whether or not C++ standard library functions may be considered
- /// for inlining.
- ///
- /// This is controlled by the 'c++-stdlib-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXStandardLibrary();
-
- /// Returns whether or not templated functions may be considered for inlining.
- ///
- /// This is controlled by the 'c++-template-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineTemplateFunctions();
-
- /// Returns whether or not allocator call may be considered for inlining.
- ///
- /// This is controlled by the 'c++-allocator-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXAllocator();
-
- /// Returns whether or not methods of C++ container objects may be considered
- /// for inlining.
- ///
- /// This is controlled by the 'c++-container-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXContainerMethods();
-
- /// Returns whether or not the destructor of C++ 'shared_ptr' may be
- /// considered for inlining.
- ///
- /// This covers std::shared_ptr, std::tr1::shared_ptr, and boost::shared_ptr,
- /// and indeed any destructor named "~shared_ptr".
- ///
- /// This is controlled by the 'c++-shared_ptr-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXSharedPtrDtor();
-
- /// Returns whether or not paths that go through null returns should be
- /// suppressed.
- ///
- /// This is a heuristic for avoiding bug reports with paths that go through
- /// inlined functions that are more defensive than their callers.
- ///
- /// This is controlled by the 'suppress-null-return-paths' config option,
- /// which accepts the values "true" and "false".
- bool shouldSuppressNullReturnPaths();
-
- /// Returns whether a bug report should \em not be suppressed if its path
- /// includes a call with a null argument, even if that call has a null return.
- ///
- /// This option has no effect when #shouldSuppressNullReturnPaths() is false.
- ///
- /// This is a counter-heuristic to avoid false negatives.
- ///
- /// This is controlled by the 'avoid-suppressing-null-argument-paths' config
- /// option, which accepts the values "true" and "false".
- bool shouldAvoidSuppressingNullArgumentPaths();
-
- /// Returns whether or not diagnostics containing inlined defensive NULL
- /// checks should be suppressed.
- ///
- /// This is controlled by the 'suppress-inlined-defensive-checks' config
- /// option, which accepts the values "true" and "false".
- bool shouldSuppressInlinedDefensiveChecks();
-
- /// Returns whether or not diagnostics reported within the C++ standard
- /// library should be suppressed.
- ///
- /// This is controlled by the 'suppress-c++-stdlib' config option,
- /// which accepts the values "true" and "false".
- bool shouldSuppressFromCXXStandardLibrary();
-
- /// Returns whether or not the diagnostic report should be always reported
- /// in the main source file and not the headers.
- ///
- /// This is controlled by the 'report-in-main-source-file' config option,
- /// which accepts the values "true" and "false".
- bool shouldReportIssuesInMainSourceFile();
-
- /// Returns whether or not the report filename should be random or not.
- ///
- /// This is controlled by the 'stable-report-filename' config option,
- /// which accepts the values "true" and "false". Default = false
- bool shouldWriteStableReportFilename();
-
- /// Returns whether irrelevant parts of a bug report path should be pruned
- /// out of the final output.
- ///
- /// This is controlled by the 'prune-paths' config option, which accepts the
- /// values "true" and "false".
- bool shouldPrunePaths();
-
- /// Returns true if 'static' initializers should be in conditional logic
- /// in the CFG.
- bool shouldConditionalizeStaticInitializers();
-
- // Returns the size of the functions (in basic blocks), which should be
- // considered to be small enough to always inline.
- //
- // This is controlled by "ipa-always-inline-size" analyzer-config option.
- unsigned getAlwaysInlineSize();
-
- // Returns the bound on the number of basic blocks in an inlined function
- // (50 by default).
- //
- // This is controlled by "-analyzer-config max-inlinable-size" option.
- unsigned getMaxInlinableSize();
-
- /// Returns true if the analyzer engine should synthesize fake bodies
- /// for well-known functions.
- bool shouldSynthesizeBodies();
-
- /// Returns how often nodes in the ExplodedGraph should be recycled to save
- /// memory.
- ///
- /// This is controlled by the 'graph-trim-interval' config option. To disable
- /// node reclamation, set the option to "0".
- unsigned getGraphTrimInterval();
-
- /// Returns the maximum times a large function could be inlined.
- ///
- /// This is controlled by the 'max-times-inline-large' config option.
- unsigned getMaxTimesInlineLarge();
-
- /// Returns the number of basic blocks a function needs to have to be
- /// considered large for the 'max-times-inline-large' config option.
- ///
- /// This is controlled by the 'min-cfg-size-treat-functions-as-large' config
- /// option.
- unsigned getMinCFGSizeTreatFunctionsAsLarge();
-
- /// Returns the maximum number of nodes the analyzer can generate while
- /// exploring a top level function (for each exploded graph).
- /// 150000 is default; 0 means no limit.
- ///
- /// This is controlled by the 'max-nodes' config option.
- unsigned getMaxNodesPerTopLevelFunction();
-
- /// Returns true if lambdas should be inlined. Otherwise a sink node will be
- /// generated each time a LambdaExpr is visited.
- bool shouldInlineLambdas();
-
- /// Returns true if the analysis should try to widen loops.
- /// This is controlled by the 'widen-loops' config option.
- bool shouldWidenLoops();
-
-public:
- AnalyzerOptions() :
- AnalysisStoreOpt(RegionStoreModel),
- AnalysisConstraintsOpt(RangeConstraintsModel),
- AnalysisDiagOpt(PD_HTML),
- AnalysisPurgeOpt(PurgeStmt),
- DisableAllChecks(0),
- ShowCheckerHelp(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() {}
-
-};
-
-typedef IntrusiveRefCntPtr<AnalyzerOptions> AnalyzerOptionsRef;
-
-}
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
deleted file mode 100644
index 57c73fd..0000000
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ /dev/null
@@ -1,561 +0,0 @@
-//===--- BugReporter.h - Generate PathDiagnostics --------------*- 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 BugReporter, a utility class for generating
-// PathDiagnostics for analyses based on ProgramState.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ImmutableSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
-
-namespace clang {
-
-class ASTContext;
-class DiagnosticsEngine;
-class Stmt;
-class ParentMap;
-
-namespace ento {
-
-class PathDiagnostic;
-class ExplodedNode;
-class ExplodedGraph;
-class BugReport;
-class BugReporter;
-class BugReporterContext;
-class ExprEngine;
-class BugType;
-
-//===----------------------------------------------------------------------===//
-// Interface for individual bug reports.
-//===----------------------------------------------------------------------===//
-
-/// 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 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;
-
-protected:
- friend class BugReporter;
- friend class BugReportEquivClass;
-
- BugType& BT;
- const Decl *DeclWithIssue;
- std::string ShortDescription;
- std::string Description;
- PathDiagnosticLocation Location;
- PathDiagnosticLocation UniqueingLocation;
- const Decl *UniqueingDecl;
-
- const ExplodedNode *ErrorNode;
- SmallVector<SourceRange, 4> Ranges;
- ExtraTextList ExtraText;
-
- typedef llvm::DenseSet<SymbolRef> Symbols;
- typedef llvm::DenseSet<const MemRegion *> Regions;
-
- /// A (stack of) a set of symbols that are registered with this
- /// report as being "interesting", and thus used to help decide which
- /// diagnostics to include when constructing the final path diagnostic.
- /// The stack is largely used by BugReporter when generating PathDiagnostics
- /// for multiple PathDiagnosticConsumers.
- SmallVector<Symbols *, 2> interestingSymbols;
-
- /// A (stack of) set of regions that are registered with this report as being
- /// "interesting", and thus used to help decide which diagnostics
- /// to include when constructing the final path diagnostic.
- /// The stack is largely used by BugReporter when generating PathDiagnostics
- /// for multiple PathDiagnosticConsumers.
- SmallVector<Regions *, 2> interestingRegions;
-
- /// A set of location contexts that correspoind to call sites which should be
- /// considered "interesting".
- llvm::SmallSet<const LocationContext *, 2> InterestingLocationContexts;
-
- /// A set of custom visitors which generate "event" diagnostics at
- /// interesting points in the path.
- VisitorList Callbacks;
-
- /// 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;
-
- /// Used to track unique reasons why a bug report might be invalid.
- ///
- /// \sa markInvalid
- /// \sa removeInvalidation
- typedef std::pair<const void *, const void *> InvalidationRecord;
-
- /// If non-empty, this bug report is likely a false positive and should not be
- /// shown to the user.
- ///
- /// \sa markInvalid
- /// \sa removeInvalidation
- llvm::SmallSet<InvalidationRecord, 4> Invalidations;
-
-private:
- // Used internally by BugReporter.
- Symbols &getInterestingSymbols();
- Regions &getInterestingRegions();
-
- void lazyInitializeInterestingSets();
- void pushInterestingSymbolsAndRegions();
- void popInterestingSymbolsAndRegions();
-
-public:
- BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
- : BT(bt), DeclWithIssue(nullptr), Description(desc), ErrorNode(errornode),
- ConfigurationChangeToken(0), DoNotPrunePath(false) {}
-
- BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
- const ExplodedNode *errornode)
- : BT(bt), DeclWithIssue(nullptr), ShortDescription(shortDesc),
- Description(desc), ErrorNode(errornode), ConfigurationChangeToken(0),
- DoNotPrunePath(false) {}
-
- BugReport(BugType &bt, StringRef desc, PathDiagnosticLocation l)
- : BT(bt), DeclWithIssue(nullptr), Description(desc), Location(l),
- ErrorNode(nullptr), ConfigurationChangeToken(0), DoNotPrunePath(false) {}
-
- /// \brief 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
- /// to the user. This method allows to rest the location which should be used
- /// for uniquing reports. For example, memory leaks checker, could set this to
- /// 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) {}
-
- virtual ~BugReport();
-
- const BugType& getBugType() const { return BT; }
- BugType& getBugType() { return BT; }
-
- const ExplodedNode *getErrorNode() const { return ErrorNode; }
-
- StringRef getDescription() const { return Description; }
-
- StringRef getShortDescription(bool UseFallback = true) const {
- if (ShortDescription.empty() && UseFallback)
- return Description;
- return ShortDescription;
- }
-
- /// Indicates whether or not any path pruning should take place
- /// when generating a PathDiagnostic from this BugReport.
- bool shouldPrunePath() const { return !DoNotPrunePath; }
-
- /// Disable all path pruning when generating a PathDiagnostic.
- void disablePathPruning() { DoNotPrunePath = true; }
-
- void markInteresting(SymbolRef sym);
- void markInteresting(const MemRegion *R);
- void markInteresting(SVal V);
- void markInteresting(const LocationContext *LC);
-
- bool isInteresting(SymbolRef sym);
- bool isInteresting(const MemRegion *R);
- 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
- /// positives after the fact.
- bool isValid() const {
- return Invalidations.empty();
- }
-
- /// Marks the current report as invalid, meaning that it is probably a false
- /// positive and should not be reported to the user.
- ///
- /// The \p Tag and \p Data arguments are intended to be opaque identifiers for
- /// this particular invalidation, where \p Tag represents the visitor
- /// responsible for invalidation, and \p Data represents the reason this
- /// visitor decided to invalidate the bug report.
- ///
- /// \sa removeInvalidation
- 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.
- const Decl *getDeclWithIssue() const;
-
- /// Specifically set the Decl where an issue occurred. This isn't necessary
- /// for BugReports that cover a path as it will be automatically inferred.
- void setDeclWithIssue(const Decl *declWithIssue) {
- DeclWithIssue = declWithIssue;
- }
-
- /// \brief This allows for addition of meta data to the diagnostic.
- ///
- /// Currently, only the HTMLDiagnosticClient knows how to display it.
- void addExtraText(StringRef S) {
- ExtraText.push_back(S);
- }
-
- virtual const ExtraTextList &getExtraText() {
- return ExtraText;
- }
-
- /// \brief 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.
- PathDiagnosticLocation getUniqueingLocation() const {
- return UniqueingLocation;
- }
-
- /// \brief 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.
- ///
- /// 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.
- /// By default, the source range of the statement corresponding to the error
- /// node will be used; add a single invalid range to specify absence of
- /// ranges.
- void addRange(SourceRange R) {
- assert((R.isValid() || Ranges.empty()) && "Invalid range can only be used "
- "to specify that the report does not have a range.");
- Ranges.push_back(R);
- }
-
- /// \brief 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.
- ///
- /// The visitors should be used when the default trace is not sufficient.
- /// For example, they allow constructing a more elaborate trace.
- /// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(),
- /// registerFindLastStore(), registerNilReceiverVisitor(), and
- /// registerVarDeclsLastStore().
- void addVisitor(std::unique_ptr<BugReporterVisitor> visitor);
-
- /// Iterators through the custom diagnostic visitors.
- visitor_iterator visitor_begin() { return Callbacks.begin(); }
- visitor_iterator visitor_end() { return Callbacks.end(); }
-
- /// Profile to identify equivalent bug reports for error report coalescing.
- /// Reports are uniqued to ensure that we do not emit multiple diagnostics
- /// for each bug.
- virtual void Profile(llvm::FoldingSetNodeID& hash) const;
-};
-
-} // end ento namespace
-} // end clang namespace
-
-namespace llvm {
- template<> struct ilist_traits<clang::ento::BugReport>
- : public ilist_default_traits<clang::ento::BugReport> {
- clang::ento::BugReport *createSentinel() const {
- return static_cast<clang::ento::BugReport *>(&Sentinel);
- }
- void destroySentinel(clang::ento::BugReport *) const {}
-
- clang::ento::BugReport *provideInitialHead() const {
- return createSentinel();
- }
- clang::ento::BugReport *ensureHead(clang::ento::BugReport *) const {
- return createSentinel();
- }
- private:
- mutable ilist_half_node<clang::ento::BugReport> Sentinel;
- };
-}
-
-namespace clang {
-namespace ento {
-
-//===----------------------------------------------------------------------===//
-// BugTypes (collections of related reports).
-//===----------------------------------------------------------------------===//
-
-class BugReportEquivClass : public llvm::FoldingSetNode {
- /// List of *owned* BugReport objects.
- llvm::ilist<BugReport> Reports;
-
- friend class BugReporter;
- void AddReport(std::unique_ptr<BugReport> R) {
- Reports.push_back(R.release());
- }
-
-public:
- BugReportEquivClass(std::unique_ptr<BugReport> R) { AddReport(std::move(R)); }
- ~BugReportEquivClass();
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- assert(!Reports.empty());
- Reports.front().Profile(ID);
- }
-
- typedef llvm::ilist<BugReport>::iterator iterator;
- typedef llvm::ilist<BugReport>::const_iterator const_iterator;
-
- iterator begin() { return Reports.begin(); }
- iterator end() { return Reports.end(); }
-
- const_iterator begin() const { return Reports.begin(); }
- const_iterator end() const { return Reports.end(); }
-};
-
-//===----------------------------------------------------------------------===//
-// BugReporter and friends.
-//===----------------------------------------------------------------------===//
-
-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;
-};
-
-/// 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.
-class BugReporter {
-public:
- enum Kind { BaseBRKind, GRBugReporterKind };
-
-private:
- typedef llvm::ImmutableSet<BugType*> BugTypesTy;
- BugTypesTy::Factory F;
- BugTypesTy BugTypes;
-
- const Kind kind;
- BugReporterData& D;
-
- /// 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);
-
- /// 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) {}
-
-public:
- BugReporter(BugReporterData& d) : BugTypes(F.getEmptySet()), kind(BaseBRKind),
- D(d) {}
- virtual ~BugReporter();
-
- /// \brief Generate and flush diagnostics for all bug reports.
- void FlushReports();
-
- Kind getKind() const { return kind; }
-
- DiagnosticsEngine& getDiagnostic() {
- return D.getDiagnostic();
- }
-
- ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() {
- return D.getPathDiagnosticConsumers();
- }
-
- /// \brief Iterator over the set of BugTypes tracked by the BugReporter.
- typedef BugTypesTy::iterator 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;
- EQClasses_iterator EQClasses_begin() { return EQClasses.begin(); }
- EQClasses_iterator EQClasses_end() { return EQClasses.end(); }
-
- ASTContext &getContext() { return D.getASTContext(); }
-
- SourceManager& getSourceManager() { return D.getSourceManager(); }
-
- AnalyzerOptions& getAnalyzerOptions() { return D.getAnalyzerOptions(); }
-
- virtual bool generatePathDiagnostic(PathDiagnostic& pathDiagnostic,
- PathDiagnosticConsumer &PC,
- ArrayRef<BugReport *> &bugReports) {
- return true;
- }
-
- bool RemoveUnneededCalls(PathPieces &pieces, BugReport *R);
-
- void Register(BugType *BT);
-
- /// \brief 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
- /// reports.
- void emitReport(std::unique_ptr<BugReport> R);
-
- void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker,
- StringRef BugName, StringRef BugCategory,
- StringRef BugStr, PathDiagnosticLocation Loc,
- ArrayRef<SourceRange> Ranges = None);
-
- void EmitBasicReport(const Decl *DeclWithIssue, CheckName CheckName,
- StringRef BugName, StringRef BugCategory,
- StringRef BugStr, PathDiagnosticLocation Loc,
- ArrayRef<SourceRange> Ranges = None);
-
-private:
- llvm::StringMap<BugType *> StrBugTypes;
-
- /// \brief 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.
-class GRBugReporter : public BugReporter {
- ExprEngine& Eng;
-public:
- GRBugReporter(BugReporterData& d, ExprEngine& 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();
-
- /// getStateManager - Return the state manager used by the analysis
- /// 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.
- ///
- /// \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;
-
- /// classof - Used by isa<>, cast<>, and dyn_cast<>.
- static bool classof(const BugReporter* R) {
- return R->getKind() == GRBugReporterKind;
- }
-};
-
-class BugReporterContext {
- virtual void anchor();
- GRBugReporter &BR;
-public:
- BugReporterContext(GRBugReporter& br) : BR(br) {}
-
- virtual ~BugReporterContext() {}
-
- GRBugReporter& getBugReporter() { return BR; }
-
- ExplodedGraph &getGraph() { return BR.getGraph(); }
-
- ProgramStateManager& getStateManager() {
- return BR.getStateManager();
- }
-
- SValBuilder& getSValBuilder() {
- return getStateManager().getSValBuilder();
- }
-
- ASTContext &getASTContext() {
- return BR.getContext();
- }
-
- SourceManager& getSourceManager() {
- return BR.getSourceManager();
- }
-
- virtual BugReport::NodeResolver& getNodeResolver() = 0;
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
deleted file mode 100644
index 197d27a..0000000
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ /dev/null
@@ -1,366 +0,0 @@
-//===--- BugReporterVisitor.h - Generate PathDiagnostics -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares BugReporterVisitors, which are used to generate enhanced
-// diagnostic traces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITOR_H
-#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITOR_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/ADT/FoldingSet.h"
-
-namespace clang {
-
-namespace ento {
-
-class BugReport;
-class BugReporterContext;
-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.)
-class BugReporterVisitor : public llvm::FoldingSetNode {
-public:
- BugReporterVisitor() = default;
- BugReporterVisitor(const BugReporterVisitor &) = default;
- 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
- /// given node.
- ///
- /// The last parameter can be used to register a new visitor with the given
- /// BugReport while processing a node.
- virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) = 0;
-
- /// \brief 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>
- 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>
- 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> {
- const MemRegion *R;
- SVal V;
- bool Satisfied;
-
- /// If the visitor is tracking the value directly responsible for the
- /// bug, we are going to employ false positive suppression.
- bool EnableNullFPSuppression;
-
-public:
- /// Creates a visitor for every VarDecl inside a Stmt and registers it with
- /// the BugReport.
- static void registerStatementVarDecls(BugReport &BR, const Stmt *S,
- bool EnableNullFPSuppression);
-
- FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R,
- bool InEnableNullFPSuppression)
- : R(R),
- V(V),
- Satisfied(false),
- EnableNullFPSuppression(InEnableNullFPSuppression) {}
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
-};
-
-class TrackConstraintBRVisitor final
- : public BugReporterVisitorImpl<TrackConstraintBRVisitor> {
- DefinedSVal Constraint;
- bool Assumption;
- bool IsSatisfied;
- bool IsZeroCheck;
-
- /// We should start tracking from the last node along the path in which the
- /// value is constrained.
- bool IsTrackingTurnedOn;
-
-public:
- TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
- : Constraint(constraint), Assumption(assumption), IsSatisfied(false),
- IsZeroCheck(!Assumption && Constraint.getAs<Loc>()),
- IsTrackingTurnedOn(false) {}
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- /// Return the tag associated with this visitor. This tag will be used
- /// to make all PathDiagnosticPieces created by this visitor.
- static const char *getTag();
-
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
-
-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> {
-public:
-
- void Profile(llvm::FoldingSetNodeID &ID) const override {
- static int x = 0;
- ID.AddPointer(&x);
- }
-
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
-
- /// If the statement is a message send expression with nil receiver, returns
- /// the receiver expression. Returns NULL otherwise.
- static const Expr *getNilReceiver(const Stmt *S, const ExplodedNode *N);
-};
-
-/// Visitor that tries to report interesting diagnostics from conditions.
-class ConditionBRVisitor final
- : public BugReporterVisitorImpl<ConditionBRVisitor> {
-public:
- void Profile(llvm::FoldingSetNodeID &ID) const override {
- static int x = 0;
- ID.AddPointer(&x);
- }
-
- /// Return the tag associated with this visitor. This tag will be used
- /// to make all PathDiagnosticPieces created by this visitor.
- static const char *getTag();
-
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR) override;
-
- PathDiagnosticPiece *VisitNodeImpl(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR);
-
- PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
- const ExplodedNode *N,
- const CFGBlock *srcBlk,
- const CFGBlock *dstBlk,
- BugReport &R,
- BugReporterContext &BRC);
-
- PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
- bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N);
-
- PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
- const DeclRefExpr *DR,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N);
-
- PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
- const BinaryOperator *BExpr,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N);
-
- PathDiagnosticPiece *VisitConditionVariable(StringRef LhsString,
- const Expr *CondVarExpr,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N);
-
- bool patternMatch(const Expr *Ex,
- raw_ostream &Out,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N,
- Optional<bool> &prunable);
-};
-
-/// \brief 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:
- static void *getTag() {
- static int Tag = 0;
- return static_cast<void *>(&Tag);
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const override {
- ID.AddPointer(getTag());
- }
-
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR) override {
- return nullptr;
- }
-
- std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
- const ExplodedNode *N,
- BugReport &BR) override;
-};
-
-/// \brief 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> {
-
- /// The interesting memory region this visitor is tracking.
- const MemRegion *R;
-
-public:
- UndefOrNullArgVisitor(const MemRegion *InR) : R(InR) {}
-
- void Profile(llvm::FoldingSetNodeID &ID) const override {
- static int Tag = 0;
- ID.AddPointer(&Tag);
- ID.AddPointer(R);
- }
-
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
-};
-
-class SuppressInlineDefensiveChecksVisitor final
- : public BugReporterVisitorImpl<SuppressInlineDefensiveChecksVisitor> {
- /// 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;
-
- /// 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;
-
-public:
- SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N);
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- /// Return the tag associated with this visitor. This tag will be used
- /// to make all PathDiagnosticPieces created by this visitor.
- static const char *getTag();
-
- PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) override;
-};
-
-namespace bugreporter {
-
-/// Attempts to add visitors to trace a null or undefined value back to its
-/// point of origin, whether it is a symbol constrained to null or an explicit
-/// assignment.
-///
-/// \param N A node "downstream" from the evaluation of the statement.
-/// \param S The statement whose value is null or undefined.
-/// \param R The bug report to which visitors should be attached.
-/// \param IsArg Whether the statement is an argument to an inlined function.
-/// If this is the case, \p N \em must be the CallEnter node for
-/// the function.
-/// \param EnableNullFPSuppression Whether we should employ false positive
-/// suppression (inlined defensive checks, returned null).
-///
-/// \return Whether or not the function was able to add visitors for this
-/// statement. Note that returning \c true does not actually imply
-/// that any visitors were added.
-bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R,
- bool IsArg = false,
- bool EnableNullFPSuppression = true);
-
-const Expr *getDerefExpr(const Stmt *S);
-const Stmt *GetDenomExpr(const ExplodedNode *N);
-const Stmt *GetRetValExpr(const ExplodedNode *N);
-bool isDeclRefExprToReference(const Expr *E);
-
-
-} // end namespace clang
-} // end namespace ento
-} // end namespace bugreporter
-
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
deleted file mode 100644
index 16226e9..0000000
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ /dev/null
@@ -1,81 +0,0 @@
-//===--- BugType.h - Bug Information Desciption ----------------*- 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 BugType, a class representing a bug type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGTYPE_H
-#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGTYPE_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
-#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "llvm/ADT/FoldingSet.h"
-#include <string>
-
-namespace clang {
-
-namespace ento {
-
-class BugReporter;
-class ExplodedNode;
-class ExprEngine;
-
-class BugType {
-private:
- const CheckName Check;
- const std::string Name;
- const std::string Category;
- 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?
- StringRef getName() const { return Name; }
- StringRef getCategory() const { return Category; }
- StringRef getCheckName() const { return Check.getName(); }
-
- /// 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; }
-
- virtual void FlushReports(BugReporter& BR);
-};
-
-class BuiltinBug : public BugType {
- const std::string desc;
- void anchor() override;
-public:
- BuiltinBug(class CheckName check, const char *name, const char *description)
- : BugType(check, name, categories::LogicError), desc(description) {}
-
- BuiltinBug(const CheckerBase *checker, const char *name,
- const char *description)
- : BugType(checker, name, categories::LogicError), desc(description) {}
-
- BuiltinBug(const CheckerBase *checker, const char *name)
- : BugType(checker, name, categories::LogicError), desc(name) {}
-
- StringRef getDescription() const { return desc; }
-};
-
-} // end GR namespace
-
-} // end clang namespace
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
deleted file mode 100644
index 8df2bc3..0000000
--- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//=--- CommonBugCategories.h - Provides common issue categories -*- 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_STATICANALYZER_CORE_BUGREPORTER_COMMONBUGCATEGORIES_H
-#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_COMMONBUGCATEGORIES_H
-
-// Common strings used for the "category" of many static analyzer issues.
-namespace clang {
- namespace ento {
- namespace categories {
- extern const char * const CoreFoundationObjectiveC;
- extern const char * const LogicError;
- extern const char * const MemoryCoreFoundationObjectiveC;
- extern const char * const UnixAPI;
- }
- }
-}
-#endif
-
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
deleted file mode 100644
index 35421f9..0000000
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ /dev/null
@@ -1,848 +0,0 @@
-//===--- PathDiagnostic.h - Path-Specific Diagnostic Handling ---*- 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 PathDiagnostic-related interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
-#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
-
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerUnion.h"
-#include <deque>
-#include <iterator>
-#include <list>
-#include <string>
-#include <vector>
-
-namespace clang {
-class ConditionalOperator;
-class AnalysisDeclContext;
-class BinaryOperator;
-class CompoundStmt;
-class Decl;
-class LocationContext;
-class MemberExpr;
-class ParentMap;
-class ProgramPoint;
-class SourceManager;
-class Stmt;
-class CallExpr;
-
-namespace ento {
-
-class ExplodedNode;
-class SymExpr;
-typedef const SymExpr* SymbolRef;
-
-//===----------------------------------------------------------------------===//
-// High-level interface for handlers of path-sensitive diagnostics.
-//===----------------------------------------------------------------------===//
-
-class PathDiagnostic;
-
-class PathDiagnosticConsumer {
-public:
- class PDFileEntry : public llvm::FoldingSetNode {
- public:
- PDFileEntry(llvm::FoldingSetNodeID &NodeID) : NodeID(NodeID) {}
-
- typedef std::vector<std::pair<StringRef, StringRef> > ConsumerFiles;
-
- /// \brief A vector of <consumer,file> pairs.
- ConsumerFiles files;
-
- /// \brief A precomputed hash tag used for uniquing PDFileEntry objects.
- const llvm::FoldingSetNodeID NodeID;
-
- /// \brief Used for profiling in the FoldingSet.
- void Profile(llvm::FoldingSetNodeID &ID) { ID = NodeID; }
- };
-
- class FilesMade {
- llvm::BumpPtrAllocator Alloc;
- llvm::FoldingSet<PDFileEntry> Set;
-
- public:
- ~FilesMade();
-
- bool empty() const { return Set.empty(); }
-
- void addDiagnostic(const PathDiagnostic &PD,
- StringRef ConsumerName,
- StringRef fileName);
-
- PDFileEntry::ConsumerFiles *getFiles(const PathDiagnostic &PD);
- };
-
-private:
- virtual void anchor();
-public:
- PathDiagnosticConsumer() : flushed(false) {}
- virtual ~PathDiagnosticConsumer();
-
- void FlushDiagnostics(FilesMade *FilesMade);
-
- virtual void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
- FilesMade *filesMade) = 0;
-
- virtual StringRef getName() const = 0;
-
- void HandlePathDiagnostic(std::unique_ptr<PathDiagnostic> D);
-
- enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive };
- virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
- virtual bool supportsLogicalOpControlFlow() const { return false; }
-
- /// Return true if the PathDiagnosticConsumer supports individual
- /// PathDiagnostics that span multiple files.
- virtual bool supportsCrossFileDiagnostics() const { return false; }
-
-protected:
- bool flushed;
- llvm::FoldingSet<PathDiagnostic> Diags;
-};
-
-//===----------------------------------------------------------------------===//
-// Path-sensitive diagnostics.
-//===----------------------------------------------------------------------===//
-
-class PathDiagnosticRange : public SourceRange {
-public:
- bool isPoint;
-
- PathDiagnosticRange(SourceRange R, bool isP = false)
- : SourceRange(R), isPoint(isP) {}
-
- PathDiagnosticRange() : isPoint(false) {}
-};
-
-typedef llvm::PointerUnion<const LocationContext*, AnalysisDeclContext*>
- LocationOrAnalysisDeclContext;
-
-class PathDiagnosticLocation {
-private:
- enum Kind { RangeK, SingleLocK, StmtK, DeclK } K;
- const Stmt *S;
- const Decl *D;
- const SourceManager *SM;
- 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()) {
- }
-
- FullSourceLoc genLocation(
- SourceLocation L = SourceLocation(),
- LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext *)nullptr) const;
-
- PathDiagnosticRange genRange(
- LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext *)nullptr) const;
-
-public:
- /// Create an invalid location.
- PathDiagnosticLocation()
- : K(SingleLocK), S(nullptr), D(nullptr), SM(nullptr) {}
-
- /// 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)) {
- assert(K == SingleLocK || S);
- assert(K == SingleLocK || Loc.isValid());
- assert(K == SingleLocK || Range.isValid());
- }
-
- /// 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()) {
- assert(D);
- assert(Loc.isValid());
- assert(Range.isValid());
- }
-
- /// Create a location at an explicit offset in the source.
- ///
- /// 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()) {
- assert(Loc.isValid());
- assert(Range.isValid());
- }
-
- /// Create a location corresponding to the given declaration.
- static PathDiagnosticLocation create(const Decl *D,
- const SourceManager &SM) {
- return PathDiagnosticLocation(D, SM);
- }
-
- /// Create a location for the beginning of the declaration.
- static PathDiagnosticLocation createBegin(const Decl *D,
- const SourceManager &SM);
-
- /// Create a location for the beginning of the statement.
- static PathDiagnosticLocation createBegin(const Stmt *S,
- const SourceManager &SM,
- const LocationOrAnalysisDeclContext LAC);
-
- /// Create a location for the end of the statement.
- ///
- /// If the statement is a CompoundStatement, the location will point to the
- /// closing brace instead of following it.
- static PathDiagnosticLocation createEnd(const Stmt *S,
- const SourceManager &SM,
- const LocationOrAnalysisDeclContext LAC);
-
- /// Create the location for the operator of the binary expression.
- /// Assumes the statement has a valid location.
- static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO,
- const SourceManager &SM);
- static PathDiagnosticLocation createConditionalColonLoc(
- const ConditionalOperator *CO,
- const SourceManager &SM);
-
- /// For member expressions, return the location of the '.' or '->'.
- /// Assumes the statement has a valid location.
- static PathDiagnosticLocation createMemberLoc(const MemberExpr *ME,
- const SourceManager &SM);
-
- /// Create a location for the beginning of the compound statement.
- /// Assumes the statement has a valid location.
- static PathDiagnosticLocation createBeginBrace(const CompoundStmt *CS,
- const SourceManager &SM);
-
- /// Create a location for the end of the compound statement.
- /// Assumes the statement has a valid location.
- static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS,
- const SourceManager &SM);
-
- /// Create a location for the beginning of the enclosing declaration body.
- /// Defaults to the beginning of the first statement in the declaration body.
- static PathDiagnosticLocation createDeclBegin(const LocationContext *LC,
- const SourceManager &SM);
-
- /// Constructs a location for the end of the enclosing declaration body.
- /// Defaults to the end of brace.
- static PathDiagnosticLocation createDeclEnd(const LocationContext *LC,
- const SourceManager &SM);
-
- /// Create a location corresponding to the given valid ExplodedNode.
- static PathDiagnosticLocation create(const ProgramPoint& P,
- const SourceManager &SMng);
-
- /// Create a location corresponding to the next valid ExplodedNode as end
- /// of path location.
- static PathDiagnosticLocation createEndOfPath(const ExplodedNode* N,
- const SourceManager &SM);
-
- /// Convert the given location into a single kind location.
- static PathDiagnosticLocation createSingleLocation(
- const PathDiagnosticLocation &PDL);
-
- bool operator==(const PathDiagnosticLocation &X) const {
- return K == X.K && Loc == X.Loc && Range == X.Range;
- }
-
- bool operator!=(const PathDiagnosticLocation &X) const {
- return !(*this == X);
- }
-
- bool isValid() const {
- return SM != nullptr;
- }
-
- FullSourceLoc asLocation() const {
- return Loc;
- }
-
- PathDiagnosticRange asRange() const {
- return Range;
- }
-
- const Stmt *asStmt() const { assert(isValid()); return S; }
- const Decl *asDecl() const { assert(isValid()); return D; }
-
- bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
-
- void invalidate() {
- *this = PathDiagnosticLocation();
- }
-
- void flatten();
-
- const SourceManager& getManager() const { assert(isValid()); return *SM; }
-
- void Profile(llvm::FoldingSetNodeID &ID) const;
-
- void dump() const;
-
- /// \brief 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.
- 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) {}
-
- const PathDiagnosticLocation &getStart() const { return Start; }
- const PathDiagnosticLocation &getEnd() const { return End; }
-
- void setStart(const PathDiagnosticLocation &L) { Start = L; }
- void setEnd(const PathDiagnosticLocation &L) { End = L; }
-
- void flatten() {
- Start.flatten();
- End.flatten();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Start.Profile(ID);
- End.Profile(ID);
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Path "pieces" for path-sensitive diagnostics.
-//===----------------------------------------------------------------------===//
-
-class PathDiagnosticPiece : public RefCountedBaseVPTR {
-public:
- enum Kind { ControlFlow, Event, Macro, Call };
- enum DisplayHint { Above, Below };
-
-private:
- const std::string str;
- const Kind kind;
- const DisplayHint Hint;
-
- /// \brief In the containing bug report, this piece is the last piece from
- /// the main source file.
- bool LastInMainSourceFile;
-
- /// A constant string that can be used to tag the PathDiagnosticPiece,
- /// typically with the identification of the creator. The actual pointer
- /// value is meant to be an identifier; the string itself is useful for
- /// debugging.
- StringRef Tag;
-
- 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() override;
-
- StringRef getString() const { return str; }
-
- /// Tag this PathDiagnosticPiece with the given C-string.
- void setTag(const char *tag) { Tag = tag; }
-
- /// Return the opaque tag (if any) on the PathDiagnosticPiece.
- const void *getTag() const { return Tag.data(); }
-
- /// Return the string representation of the tag. This is useful
- /// for debugging.
- StringRef getTagStr() const { return Tag; }
-
- /// getDisplayHint - Return a hint indicating where the diagnostic should
- /// be displayed by the PathDiagnosticConsumer.
- DisplayHint getDisplayHint() const { return Hint; }
-
- virtual PathDiagnosticLocation getLocation() const = 0;
- virtual void flattenLocations() = 0;
-
- Kind getKind() const { return kind; }
-
- void addRange(SourceRange R) {
- if (!R.isValid())
- return;
- ranges.push_back(R);
- }
-
- void addRange(SourceLocation B, SourceLocation E) {
- if (!B.isValid() || !E.isValid())
- return;
- ranges.push_back(SourceRange(B,E));
- }
-
- /// Return the SourceRanges associated with this PathDiagnosticPiece.
- ArrayRef<SourceRange> getRanges() const { return ranges; }
-
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
-
- void setAsLastInMainSourceFile() {
- LastInMainSourceFile = true;
- }
-
- bool isLastInMainSourceFile() const {
- return LastInMainSourceFile;
- }
-
- virtual void dump() const = 0;
-};
-
-
-class PathPieces : public std::list<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
- void flattenTo(PathPieces &Primary, PathPieces &Current,
- bool ShouldFlattenMacros) const;
-public:
-
- PathPieces flatten(bool ShouldFlattenMacros) const {
- PathPieces Result;
- flattenTo(Result, Result, ShouldFlattenMacros);
- return Result;
- }
-
- void dump() const;
-};
-
-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) {
- assert(Pos.isValid() && Pos.asLocation().isValid() &&
- "PathDiagnosticSpotPiece's must have a valid location.");
- if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
- }
-
- PathDiagnosticLocation getLocation() const override { return Pos; }
- void flattenLocations() override { Pos.flatten(); }
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- static bool classof(const PathDiagnosticPiece *P) {
- return P->getKind() == Event || P->getKind() == Macro;
- }
-};
-
-/// \brief 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.
-class StackHintGenerator {
-public:
- virtual ~StackHintGenerator() = 0;
-
- /// \brief 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.
-///
-/// The class knows how to construct the stack hint message based on
-/// traversing the CallExpr associated with the call and checking if the given
-/// symbol is returned or is one of the arguments.
-/// The hint can be customized by redefining 'getMessageForX()' methods.
-class StackHintGeneratorForSymbol : public StackHintGenerator {
-private:
- SymbolRef Sym;
- std::string Msg;
-
-public:
- StackHintGeneratorForSymbol(SymbolRef S, StringRef M) : Sym(S), Msg(M) {}
- ~StackHintGeneratorForSymbol() override {}
-
- /// \brief 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;
- }
-};
-
-class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
- Optional<bool> IsPrunable;
-
- /// If the event occurs in a different frame than the final diagnostic,
- /// supply a message that will be used to construct an extra hint on the
- /// returns from all the calls on the stack from this event to the final
- /// diagnostic.
- std::unique_ptr<StackHintGenerator> CallStackHint;
-
-public:
- PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
- StringRef s, bool addPosRange = true,
- StackHintGenerator *stackHint = nullptr)
- : PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
- CallStackHint(stackHint) {}
-
- ~PathDiagnosticEventPiece() override;
-
- /// Mark the diagnostic piece as being potentially prunable. This
- /// flag may have been previously set, at which point it will not
- /// be reset unless one specifies to do so.
- void setPrunable(bool isPrunable, bool override = false) {
- if (IsPrunable.hasValue() && !override)
- return;
- IsPrunable = isPrunable;
- }
-
- /// Return true if the diagnostic piece is prunable.
- bool isPrunable() const {
- return IsPrunable.hasValue() ? IsPrunable.getValue() : false;
- }
-
- bool hasCallStackHint() { return (bool)CallStackHint; }
-
- /// Produce the hint for the given node. The node contains
- /// information about the call for which the diagnostic can be generated.
- std::string getCallStackMessage(const ExplodedNode *N) {
- if (CallStackHint)
- return CallStackHint->getMessage(N);
- return "";
- }
-
- void dump() const override;
-
- static inline 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), callReturn(callReturnPos) {}
-
- PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller)
- : PathDiagnosticPiece(Call), Caller(caller), Callee(nullptr),
- NoExit(true), path(oldPath) {}
-
- const Decl *Caller;
- const Decl *Callee;
-
- // Flag signifying that this diagnostic has only call enter and no matching
- // call exit.
- bool NoExit;
-
- // The custom string, which should appear after the call Return Diagnostic.
- // TODO: Should we allow multiple diagnostics?
- std::string CallStackMessage;
-
-public:
- PathDiagnosticLocation callEnter;
- PathDiagnosticLocation callEnterWithin;
- PathDiagnosticLocation callReturn;
- PathPieces path;
-
- ~PathDiagnosticCallPiece() override;
-
- const Decl *getCaller() const { return Caller; }
-
- const Decl *getCallee() const { return Callee; }
- void setCallee(const CallEnter &CE, const SourceManager &SM);
-
- bool hasCallStackMessage() { return !CallStackMessage.empty(); }
- void setCallStackMessage(StringRef st) {
- CallStackMessage = st;
- }
-
- PathDiagnosticLocation getLocation() const override {
- return callEnter;
- }
-
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallEnterEvent() const;
- IntrusiveRefCntPtr<PathDiagnosticEventPiece>
- getCallEnterWithinCallerEvent() const;
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallExitEvent() const;
-
- void flattenLocations() override {
- callEnter.flatten();
- callReturn.flatten();
- for (PathPieces::iterator I = path.begin(),
- E = path.end(); I != E; ++I) (*I)->flattenLocations();
- }
-
- static PathDiagnosticCallPiece *construct(const ExplodedNode *N,
- const CallExitEnd &CE,
- const SourceManager &SM);
-
- static PathDiagnosticCallPiece *construct(PathPieces &pieces,
- const Decl *caller);
-
- void dump() const override;
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- static inline 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));
- }
-
- PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
- const PathDiagnosticLocation &endPos)
- : PathDiagnosticPiece(ControlFlow) {
- LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
- }
-
- ~PathDiagnosticControlFlowPiece() override;
-
- PathDiagnosticLocation getStartLocation() const {
- assert(!LPairs.empty() &&
- "PathDiagnosticControlFlowPiece needs at least one location.");
- return LPairs[0].getStart();
- }
-
- PathDiagnosticLocation getEndLocation() const {
- assert(!LPairs.empty() &&
- "PathDiagnosticControlFlowPiece needs at least one location.");
- return LPairs[0].getEnd();
- }
-
- void setStartLocation(const PathDiagnosticLocation &L) {
- LPairs[0].setStart(L);
- }
-
- void setEndLocation(const PathDiagnosticLocation &L) {
- LPairs[0].setEnd(L);
- }
-
- void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
-
- PathDiagnosticLocation getLocation() const override {
- return getStartLocation();
- }
-
- typedef std::vector<PathDiagnosticLocationPair>::iterator iterator;
- iterator begin() { return LPairs.begin(); }
- iterator end() { return LPairs.end(); }
-
- void flattenLocations() override {
- for (iterator I=begin(), E=end(); I!=E; ++I) I->flatten();
- }
-
- typedef std::vector<PathDiagnosticLocationPair>::const_iterator
- const_iterator;
- const_iterator begin() const { return LPairs.begin(); }
- const_iterator end() const { return LPairs.end(); }
-
- static inline bool classof(const PathDiagnosticPiece *P) {
- return P->getKind() == ControlFlow;
- }
-
- void dump() const override;
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-};
-
-class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
-public:
- PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
- : PathDiagnosticSpotPiece(pos, "", Macro) {}
-
- ~PathDiagnosticMacroPiece() override;
-
- PathPieces subPieces;
-
- bool containsEvent() const;
-
- void flattenLocations() override {
- PathDiagnosticSpotPiece::flattenLocations();
- for (PathPieces::iterator I = subPieces.begin(),
- E = subPieces.end(); I != E; ++I) (*I)->flattenLocations();
- }
-
- static inline bool classof(const PathDiagnosticPiece *P) {
- return P->getKind() == Macro;
- }
-
- void dump() const override;
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-};
-
-/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
-/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
-/// each which represent the pieces of the path.
-class PathDiagnostic : public llvm::FoldingSetNode {
- std::string CheckName;
- const Decl *DeclWithIssue;
- std::string BugType;
- std::string VerboseDesc;
- std::string ShortDesc;
- std::string Category;
- std::deque<std::string> OtherDesc;
-
- /// \brief Loc The location of the path diagnostic report.
- PathDiagnosticLocation Loc;
-
- PathPieces pathImpl;
- SmallVector<PathPieces *, 3> pathStack;
-
- /// \brief Important bug uniqueing location.
- /// The location info is useful to differentiate between bugs.
- PathDiagnosticLocation UniqueingLoc;
- const Decl *UniqueingDecl;
-
- PathDiagnostic() = delete;
-public:
- PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue,
- StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
- StringRef category, PathDiagnosticLocation LocationToUnique,
- const Decl *DeclToUnique);
-
- ~PathDiagnostic();
-
- const PathPieces &path;
-
- /// Return the path currently used by builders for constructing the
- /// PathDiagnostic.
- PathPieces &getActivePath() {
- if (pathStack.empty())
- return pathImpl;
- return *pathStack.back();
- }
-
- /// Return a mutable version of 'path'.
- PathPieces &getMutablePieces() {
- return pathImpl;
- }
-
- /// Return the unrolled size of the path.
- unsigned full_size();
-
- void pushActivePath(PathPieces *p) { pathStack.push_back(p); }
- void popActivePath() { if (!pathStack.empty()) pathStack.pop_back(); }
-
- bool isWithinCall() const { return !pathStack.empty(); }
-
- void setEndOfPath(std::unique_ptr<PathDiagnosticPiece> EndPiece) {
- assert(!Loc.isValid() && "End location already set!");
- Loc = EndPiece->getLocation();
- assert(Loc.isValid() && "Invalid location for end-of-path piece");
- getActivePath().push_back(EndPiece.release());
- }
-
- void appendToDesc(StringRef S) {
- if (!ShortDesc.empty())
- ShortDesc.append(S);
- VerboseDesc.append(S);
- }
-
- void resetPath() {
- pathStack.clear();
- pathImpl.clear();
- Loc = PathDiagnosticLocation();
- }
-
- /// \brief 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; }
-
- /// Return the semantic context where an issue occurred. If the
- /// issue occurs along a path, this represents the "central" area
- /// where the bug manifests.
- const Decl *getDeclWithIssue() const { return DeclWithIssue; }
-
- typedef std::deque<std::string>::const_iterator meta_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); }
-
- PathDiagnosticLocation getLocation() const {
- assert(Loc.isValid() && "No report location set yet!");
- return Loc;
- }
-
- /// \brief Get the location on which the report should be uniqued.
- PathDiagnosticLocation getUniqueingLoc() const {
- return UniqueingLoc;
- }
-
- /// \brief 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();
- }
-
- /// Profiles the diagnostic, independent of the path it references.
- ///
- /// This can be used to merge diagnostics that refer to the same issue
- /// along different paths.
- void Profile(llvm::FoldingSetNodeID &ID) const;
-
- /// Profiles the diagnostic, including its path.
- ///
- /// Two diagnostics with the same issue along different paths will generate
- /// different profiles.
- void FullProfile(llvm::FoldingSetNodeID &ID) const;
-};
-
-} // end GR namespace
-
-} //end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
deleted file mode 100644
index 1410af1..0000000
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ /dev/null
@@ -1,554 +0,0 @@
-//== Checker.h - Registration mechanism for checkers -------------*- 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 Checker, used to create and register checkers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
-
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/Support/Casting.h"
-
-namespace clang {
-namespace ento {
- class BugReporter;
-
-namespace check {
-
-template <typename DECL>
-class ASTDecl {
- template <typename CHECKER>
- static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
- BugReporter &BR) {
- ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
- }
-
- static bool _handlesDecl(const Decl *D) {
- return isa<DECL>(D);
- }
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
- _checkDecl<CHECKER>),
- _handlesDecl);
- }
-};
-
-class ASTCodeBody {
- template <typename CHECKER>
- static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
- BugReporter &BR) {
- ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
- _checkBody<CHECKER>));
- }
-};
-
-class EndOfTranslationUnit {
- template <typename CHECKER>
- static void _checkEndOfTranslationUnit(void *checker,
- const TranslationUnitDecl *TU,
- AnalysisManager& mgr,
- BugReporter &BR) {
- ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr){
- mgr._registerForEndOfTranslationUnit(
- CheckerManager::CheckEndOfTranslationUnit(checker,
- _checkEndOfTranslationUnit<CHECKER>));
- }
-};
-
-template <typename STMT>
-class PreStmt {
- template <typename CHECKER>
- static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
- ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
- }
-
- static bool _handlesStmt(const Stmt *S) {
- return isa<STMT>(S);
- }
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
- _checkStmt<CHECKER>),
- _handlesStmt);
- }
-};
-
-template <typename STMT>
-class PostStmt {
- template <typename CHECKER>
- static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
- ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
- }
-
- static bool _handlesStmt(const Stmt *S) {
- return isa<STMT>(S);
- }
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
- _checkStmt<CHECKER>),
- _handlesStmt);
- }
-};
-
-class PreObjCMessage {
- template <typename CHECKER>
- static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForPreObjCMessage(
- CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
- }
-};
-
-class ObjCMessageNil {
- template <typename CHECKER>
- static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkObjCMessageNil(msg, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForObjCMessageNil(
- CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
- }
-};
-
-class PostObjCMessage {
- template <typename CHECKER>
- static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForPostObjCMessage(
- CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
- }
-};
-
-class PreCall {
- template <typename CHECKER>
- static void _checkCall(void *checker, const CallEvent &msg,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkPreCall(msg, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForPreCall(
- CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
- }
-};
-
-class PostCall {
- template <typename CHECKER>
- static void _checkCall(void *checker, const CallEvent &msg,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkPostCall(msg, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForPostCall(
- CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
- }
-};
-
-class Location {
- template <typename CHECKER>
- static void _checkLocation(void *checker,
- const SVal &location, bool isLoad, const Stmt *S,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForLocation(
- CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
- }
-};
-
-class Bind {
- template <typename CHECKER>
- static void _checkBind(void *checker,
- const SVal &location, const SVal &val, const Stmt *S,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkBind(location, val, S, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForBind(
- CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
- }
-};
-
-class EndAnalysis {
- template <typename CHECKER>
- static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
- BugReporter &BR, ExprEngine &Eng) {
- ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForEndAnalysis(
- CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
- }
-};
-
-class EndFunction {
- template <typename CHECKER>
- static void _checkEndFunction(void *checker,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkEndFunction(C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForEndFunction(
- CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
- }
-};
-
-class BranchCondition {
- template <typename CHECKER>
- static void _checkBranchCondition(void *checker, const Stmt *Condition,
- CheckerContext & C) {
- ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForBranchCondition(
- CheckerManager::CheckBranchConditionFunc(checker,
- _checkBranchCondition<CHECKER>));
- }
-};
-
-class LiveSymbols {
- template <typename CHECKER>
- static void _checkLiveSymbols(void *checker, ProgramStateRef state,
- SymbolReaper &SR) {
- ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForLiveSymbols(
- CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
- }
-};
-
-class DeadSymbols {
- template <typename CHECKER>
- static void _checkDeadSymbols(void *checker,
- SymbolReaper &SR, CheckerContext &C) {
- ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForDeadSymbols(
- CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
- }
-};
-
-class RegionChanges {
- template <typename CHECKER>
- static ProgramStateRef
- _checkRegionChanges(void *checker,
- ProgramStateRef state,
- const InvalidatedSymbols *invalidated,
- ArrayRef<const MemRegion *> Explicits,
- ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) {
- return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
- Explicits, Regions, Call);
- }
- template <typename CHECKER>
- static bool _wantsRegionChangeUpdate(void *checker,
- ProgramStateRef state) {
- return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForRegionChanges(
- CheckerManager::CheckRegionChangesFunc(checker,
- _checkRegionChanges<CHECKER>),
- CheckerManager::WantsRegionChangeUpdateFunc(checker,
- _wantsRegionChangeUpdate<CHECKER>));
- }
-};
-
-class PointerEscape {
- template <typename CHECKER>
- static ProgramStateRef
- _checkPointerEscape(void *Checker,
- ProgramStateRef State,
- const InvalidatedSymbols &Escaped,
- const CallEvent *Call,
- PointerEscapeKind Kind,
- RegionAndSymbolInvalidationTraits *ETraits) {
-
- if (!ETraits)
- return ((const CHECKER *)Checker)->checkPointerEscape(State,
- Escaped,
- Call,
- Kind);
-
- InvalidatedSymbols RegularEscape;
- for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
- E = Escaped.end(); I != E; ++I)
- if (!ETraits->hasTrait(*I,
- RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
- !ETraits->hasTrait(*I,
- RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
- RegularEscape.insert(*I);
-
- if (RegularEscape.empty())
- return State;
-
- return ((const CHECKER *)Checker)->checkPointerEscape(State,
- RegularEscape,
- Call,
- Kind);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForPointerEscape(
- CheckerManager::CheckPointerEscapeFunc(checker,
- _checkPointerEscape<CHECKER>));
- }
-};
-
-class ConstPointerEscape {
- template <typename CHECKER>
- static ProgramStateRef
- _checkConstPointerEscape(void *Checker,
- ProgramStateRef State,
- const InvalidatedSymbols &Escaped,
- const CallEvent *Call,
- PointerEscapeKind Kind,
- RegionAndSymbolInvalidationTraits *ETraits) {
-
- if (!ETraits)
- return State;
-
- InvalidatedSymbols ConstEscape;
- for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
- E = Escaped.end(); I != E; ++I)
- if (ETraits->hasTrait(*I,
- RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
- !ETraits->hasTrait(*I,
- RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
- ConstEscape.insert(*I);
-
- if (ConstEscape.empty())
- return State;
-
- return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
- ConstEscape,
- Call,
- Kind);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForPointerEscape(
- CheckerManager::CheckPointerEscapeFunc(checker,
- _checkConstPointerEscape<CHECKER>));
- }
-};
-
-
-template <typename EVENT>
-class Event {
- template <typename CHECKER>
- static void _checkEvent(void *checker, const void *event) {
- ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
- }
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerListenerForEvent<EVENT>(
- CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
- }
-};
-
-} // end check namespace
-
-namespace eval {
-
-class Assume {
- template <typename CHECKER>
- static ProgramStateRef _evalAssume(void *checker,
- ProgramStateRef state,
- const SVal &cond,
- bool assumption) {
- return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForEvalAssume(
- CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
- }
-};
-
-class Call {
- template <typename CHECKER>
- static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
- return ((const CHECKER *)checker)->evalCall(CE, C);
- }
-
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForEvalCall(
- CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
- }
-};
-
-} // end eval namespace
-
-class CheckerBase : public ProgramPointTag {
- CheckName Name;
- friend class ::clang::ento::CheckerManager;
-
-public:
- StringRef getTagDescription() const override;
- CheckName getCheckName() const;
-
- /// See CheckerManager::runCheckersForPrintState.
- virtual void printState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep) const { }
-};
-
-/// Dump checker name to stream.
-raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
-
-/// Tag that can use a checker name as a message provider
-/// (see SimpleProgramPointTag).
-class CheckerProgramPointTag : public SimpleProgramPointTag {
-public:
- CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
- CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
-};
-
-template <typename CHECK1, typename... CHECKs>
-class Checker : public CHECK1, public CHECKs..., public CheckerBase {
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- CHECK1::_register(checker, mgr);
- Checker<CHECKs...>::_register(checker, mgr);
- }
-};
-
-template <typename CHECK1>
-class Checker<CHECK1> : public CHECK1, public CheckerBase {
-public:
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- CHECK1::_register(checker, mgr);
- }
-};
-
-template <typename EVENT>
-class EventDispatcher {
- CheckerManager *Mgr;
-public:
- EventDispatcher() : Mgr(nullptr) { }
-
- template <typename CHECKER>
- static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerDispatcherForEvent<EVENT>();
- static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
- }
-
- void dispatchEvent(const EVENT &event) const {
- Mgr->_dispatchEvent(event);
- }
-};
-
-/// \brief We dereferenced a location that may be null.
-struct ImplicitNullDerefEvent {
- SVal Location;
- bool IsLoad;
- ExplodedNode *SinkNode;
- BugReporter *BR;
- // When true, the dereference is in the source code directly. When false, the
- // dereference might happen later (for example pointer passed to a parameter
- // that is marked with nonnull attribute.)
- bool IsDirectDereference;
-};
-
-/// \brief 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.
-struct DefaultBool {
- bool val;
- DefaultBool() : val(false) {}
- /*implicit*/ operator bool&() { return val; }
- /*implicit*/ operator const bool&() const { return val; }
- DefaultBool &operator=(bool b) { val = b; return *this; }
-};
-
-} // end ento namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
deleted file mode 100644
index bc9af49..0000000
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ /dev/null
@@ -1,632 +0,0 @@
-//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines the Static Analyzer Checker Manager.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
-
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include <vector>
-
-namespace clang {
- class Decl;
- class Stmt;
- class CallExpr;
-
-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;
-
-template <typename T> class CheckerFn;
-
-template <typename RET, typename... Ps>
-class CheckerFn<RET(Ps...)> {
- typedef RET (*Func)(void *, Ps...);
- Func Fn;
-public:
- CheckerBase *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
-/// during analysis.
-enum PointerEscapeKind {
- /// A pointer escapes due to binding its value to a location
- /// that the analyzer cannot track.
- PSK_EscapeOnBind,
-
- /// The pointer has been passed to a function call directly.
- PSK_DirectEscapeOnCall,
-
- /// The pointer has been passed to a function indirectly.
- /// For example, the pointer is accessible through an
- /// argument to a function.
- PSK_IndirectEscapeOnCall,
-
- /// The reason for pointer escape is unknown. For example,
- /// a region containing this pointer is invalidated.
- PSK_EscapeOther
-};
-
-// This wrapper is used to ensure that only StringRefs originating from the
-// CheckerRegistry are used as check names. We want to make sure all check
-// 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;
- explicit CheckName(StringRef Name) : Name(Name) {}
-
-public:
- CheckName() = default;
- StringRef getName() const { return Name; }
-};
-
-enum class ObjCMessageVisitKind {
- Pre,
- Post,
- MessageNil
-};
-
-class CheckerManager {
- const LangOptions LangOpts;
- AnalyzerOptionsRef AOptions;
- CheckName CurrentCheckName;
-
-public:
- CheckerManager(const LangOptions &langOpts,
- AnalyzerOptionsRef AOptions)
- : LangOpts(langOpts),
- AOptions(AOptions) {}
-
- ~CheckerManager();
-
- void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
- CheckName getCurrentCheckName() const { return CurrentCheckName; }
-
- bool hasPathSensitiveCheckers() const;
-
- void finishedCheckerRegistration();
-
- const LangOptions &getLangOpts() const { return LangOpts; }
- AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
-
- typedef CheckerBase *CheckerRef;
- typedef const void *CheckerTag;
- typedef CheckerFn<void ()> CheckerDtor;
-
-//===----------------------------------------------------------------------===//
-// registerChecker
-//===----------------------------------------------------------------------===//
-
- /// \brief Used to register checkers.
- ///
- /// \returns a pointer to the checker object.
- template <typename CHECKER>
- CHECKER *registerChecker() {
- 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->Name = CurrentCheckName;
- CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
- CHECKER::_register(checker, *this);
- ref = checker;
- return checker;
- }
-
-//===----------------------------------------------------------------------===//
-// Functions for running checkers for AST traversing..
-//===----------------------------------------------------------------------===//
-
- /// \brief Run checkers handling Decls.
- void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
- BugReporter &BR);
-
- /// \brief Run checkers handling Decls containing a Stmt body.
- void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
- BugReporter &BR);
-
-//===----------------------------------------------------------------------===//
-// Functions for running checkers for path-sensitive checking.
-//===----------------------------------------------------------------------===//
-
- /// \brief 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.
- ///
- /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
- void runCheckersForPreStmt(ExplodedNodeSet &Dst,
- const ExplodedNodeSet &Src,
- const Stmt *S,
- ExprEngine &Eng) {
- runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
- }
-
- /// \brief 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.
- ///
- /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
- void runCheckersForPostStmt(ExplodedNodeSet &Dst,
- const ExplodedNodeSet &Src,
- const Stmt *S,
- ExprEngine &Eng,
- bool wasInlined = false) {
- runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
- }
-
- /// \brief 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.
- void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
- const ExplodedNodeSet &Src,
- const ObjCMethodCall &msg,
- ExprEngine &Eng) {
- runCheckersForObjCMessage(ObjCMessageVisitKind::Pre, Dst, Src, msg, Eng);
- }
-
- /// \brief Run checkers for post-visiting obj-c messages.
- void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
- const ExplodedNodeSet &Src,
- const ObjCMethodCall &msg,
- ExprEngine &Eng,
- bool wasInlined = false) {
- runCheckersForObjCMessage(ObjCMessageVisitKind::Post, Dst, Src, msg, Eng,
- wasInlined);
- }
-
- /// \brief Run checkers for visiting an obj-c message to nil.
- void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst,
- const ExplodedNodeSet &Src,
- const ObjCMethodCall &msg,
- ExprEngine &Eng) {
- runCheckersForObjCMessage(ObjCMessageVisitKind::MessageNil, Dst, Src, msg,
- Eng);
- }
-
-
- /// \brief 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.
- 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.
- void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
- const CallEvent &Call, ExprEngine &Eng,
- bool wasInlined = false) {
- runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
- wasInlined);
- }
-
- /// \brief 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.
- void runCheckersForLocation(ExplodedNodeSet &Dst,
- const ExplodedNodeSet &Src,
- SVal location,
- bool isLoad,
- const Stmt *NodeEx,
- const Stmt *BoundEx,
- ExprEngine &Eng);
-
- /// \brief 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.
- void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
- ExprEngine &Eng);
-
- /// \brief Run checkers on end of function.
- void runCheckersForEndFunction(NodeBuilderContext &BC,
- ExplodedNodeSet &Dst,
- ExplodedNode *Pred,
- ExprEngine &Eng);
-
- /// \brief Run checkers for branch condition.
- void runCheckersForBranchCondition(const Stmt *condition,
- ExplodedNodeSet &Dst, ExplodedNode *Pred,
- ExprEngine &Eng);
-
- /// \brief 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
- /// dead and removed.
- void runCheckersForLiveSymbols(ProgramStateRef state,
- SymbolReaper &SymReaper);
-
- /// \brief 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
- /// precise diagnostics.
- void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
- const ExplodedNodeSet &Src,
- SymbolReaper &SymReaper, const Stmt *S,
- ExprEngine &Eng,
- ProgramPoint::Kind K);
-
- /// \brief True if at least one checker wants to check region changes.
- bool wantsRegionChangeUpdate(ProgramStateRef state);
-
- /// \brief Run checkers for region changes.
- ///
- /// This corresponds to the check::RegionChanges callback.
- /// \param state The current program state.
- /// \param invalidated A set of all symbols potentially touched by the change.
- /// \param ExplicitRegions The regions explicitly requested for invalidation.
- /// For example, in the case of a function call, these would be arguments.
- /// \param Regions The transitive closure of accessible regions,
- /// i.e. all regions that may have been touched by this change.
- /// \param Call The call expression wrapper if the regions are invalidated
- /// by a call.
- ProgramStateRef
- runCheckersForRegionChanges(ProgramStateRef state,
- const InvalidatedSymbols *invalidated,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call);
-
- /// \brief 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
- /// result of assigning a pointer into a global or when it's passed to a
- /// function call the analyzer cannot model.
- ///
- /// \param State The state at the point of escape.
- /// \param Escaped The list of escaped symbols.
- /// \param Call The corresponding CallEvent, if the symbols escape as
- /// parameters to the given call.
- /// \param Kind The reason of pointer escape.
- /// \param ITraits Information about invalidation for a particular
- /// region/symbol.
- /// \returns Checkers can modify the state by returning a new one.
- ProgramStateRef
- runCheckersForPointerEscape(ProgramStateRef State,
- const InvalidatedSymbols &Escaped,
- const CallEvent *Call,
- PointerEscapeKind Kind,
- RegionAndSymbolInvalidationTraits *ITraits);
-
- /// \brief Run checkers for handling assumptions on symbolic values.
- ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
- SVal Cond, bool Assumption);
-
- /// \brief 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.
- void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
- AnalysisManager &mgr,
- BugReporter &BR);
-
- /// \brief 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.
- /// \param Out The output stream
- /// \param State The state being printed
- /// \param NL The preferred representation of a newline.
- /// \param Sep The preferred separator between different kinds of data.
- void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep);
-
-//===----------------------------------------------------------------------===//
-// Internal registration functions for AST traversing.
-//===----------------------------------------------------------------------===//
-
- // Functions used by the registration mechanism, checkers should not touch
- // these directly.
-
- typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
- CheckDeclFunc;
-
- typedef bool (*HandlesDeclFunc)(const Decl *D);
- void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
-
- void _registerForBody(CheckDeclFunc checkfn);
-
-//===----------------------------------------------------------------------===//
-// Internal registration functions for path-sensitive checking.
-//===----------------------------------------------------------------------===//
-
- typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
-
- typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
- CheckObjCMessageFunc;
-
- typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
- CheckCallFunc;
-
- typedef CheckerFn<void (const SVal &location, bool isLoad,
- const Stmt *S,
- CheckerContext &)>
- CheckLocationFunc;
-
- typedef CheckerFn<void (const SVal &location, const SVal &val,
- const Stmt *S, CheckerContext &)>
- CheckBindFunc;
-
- typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
- CheckEndAnalysisFunc;
-
- typedef CheckerFn<void (CheckerContext &)>
- CheckEndFunctionFunc;
-
- typedef CheckerFn<void (const Stmt *, CheckerContext &)>
- CheckBranchConditionFunc;
-
- typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
- CheckDeadSymbolsFunc;
-
- typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
-
- typedef CheckerFn<ProgramStateRef (ProgramStateRef,
- const InvalidatedSymbols *symbols,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call)>
- CheckRegionChangesFunc;
-
- typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
-
- typedef CheckerFn<ProgramStateRef (ProgramStateRef,
- const InvalidatedSymbols &Escaped,
- const CallEvent *Call,
- PointerEscapeKind Kind,
- RegionAndSymbolInvalidationTraits *ITraits)>
- CheckPointerEscapeFunc;
-
- typedef CheckerFn<ProgramStateRef (ProgramStateRef,
- const SVal &cond, bool assumption)>
- EvalAssumeFunc;
-
- typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
- EvalCallFunc;
-
- typedef CheckerFn<void (const TranslationUnitDecl *,
- AnalysisManager&, BugReporter &)>
- CheckEndOfTranslationUnit;
-
- typedef bool (*HandlesStmtFunc)(const Stmt *D);
- void _registerForPreStmt(CheckStmtFunc checkfn,
- HandlesStmtFunc isForStmtFn);
- void _registerForPostStmt(CheckStmtFunc checkfn,
- HandlesStmtFunc isForStmtFn);
-
- void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
- void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
-
- void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn);
-
- void _registerForPreCall(CheckCallFunc checkfn);
- void _registerForPostCall(CheckCallFunc checkfn);
-
- void _registerForLocation(CheckLocationFunc checkfn);
-
- void _registerForBind(CheckBindFunc checkfn);
-
- void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
-
- void _registerForEndFunction(CheckEndFunctionFunc checkfn);
-
- void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
-
- void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
-
- void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
-
- void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
- WantsRegionChangeUpdateFunc wantUpdateFn);
-
- void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
-
- void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
-
- void _registerForEvalAssume(EvalAssumeFunc checkfn);
-
- void _registerForEvalCall(EvalCallFunc checkfn);
-
- void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
-
-//===----------------------------------------------------------------------===//
-// Internal registration functions for events.
-//===----------------------------------------------------------------------===//
-
- typedef void *EventTag;
- typedef CheckerFn<void (const void *event)> CheckEventFunc;
-
- template <typename EVENT>
- void _registerListenerForEvent(CheckEventFunc checkfn) {
- EventInfo &info = Events[getTag<EVENT>()];
- info.Checkers.push_back(checkfn);
- }
-
- template <typename EVENT>
- void _registerDispatcherForEvent() {
- EventInfo &info = Events[getTag<EVENT>()];
- info.HasDispatcher = true;
- }
-
- template <typename EVENT>
- void _dispatchEvent(const EVENT &event) const {
- EventsTy::const_iterator I = Events.find(getTag<EVENT>());
- 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);
- }
-
-//===----------------------------------------------------------------------===//
-// Implementation details.
-//===----------------------------------------------------------------------===//
-
-private:
- template <typename CHECKER>
- static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
-
- template <typename T>
- static void *getTag() { static int tag; return &tag; }
-
- llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
-
- std::vector<CheckerDtor> CheckerDtors;
-
- struct DeclCheckerInfo {
- CheckDeclFunc CheckFn;
- HandlesDeclFunc IsForDeclFn;
- };
- std::vector<DeclCheckerInfo> DeclCheckers;
-
- std::vector<CheckDeclFunc> BodyCheckers;
-
- typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
- typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
- CachedDeclCheckersMapTy CachedDeclCheckersMap;
-
- struct StmtCheckerInfo {
- CheckStmtFunc CheckFn;
- HandlesStmtFunc IsForStmtFn;
- bool IsPreVisit;
- };
- std::vector<StmtCheckerInfo> StmtCheckers;
-
- typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
- typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
- CachedStmtCheckersMapTy CachedStmtCheckersMap;
-
- const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
- bool isPreVisit);
-
- /// Returns the checkers that have registered for callbacks of the
- /// given \p Kind.
- const std::vector<CheckObjCMessageFunc> &
- getObjCMessageCheckers(ObjCMessageVisitKind Kind);
-
- std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
- std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
- std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers;
-
- std::vector<CheckCallFunc> PreCallCheckers;
- std::vector<CheckCallFunc> PostCallCheckers;
-
- std::vector<CheckLocationFunc> LocationCheckers;
-
- std::vector<CheckBindFunc> BindCheckers;
-
- std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
-
- std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
-
- std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
-
- std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
-
- std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
-
- struct RegionChangesCheckerInfo {
- CheckRegionChangesFunc CheckFn;
- WantsRegionChangeUpdateFunc WantUpdateFn;
- };
- std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
-
- std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
-
- std::vector<EvalAssumeFunc> EvalAssumeCheckers;
-
- std::vector<EvalCallFunc> EvalCallCheckers;
-
- std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
-
- struct EventInfo {
- SmallVector<CheckEventFunc, 4> Checkers;
- bool HasDispatcher;
- EventInfo() : HasDispatcher(false) { }
- };
-
- typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
- EventsTy Events;
-};
-
-} // end ento namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h b/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
deleted file mode 100644
index e981871..0000000
--- a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- CheckerOptInfo.h - Specifies which checkers to use -----*- 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_STATICANALYZER_CORE_CHECKEROPTINFO_H
-#define LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace ento {
-
-/// Represents a request to include or exclude a checker or package from a
-/// specific analysis run.
-///
-/// \sa CheckerRegistry::initializeManager
-class CheckerOptInfo {
- StringRef Name;
- bool Enable;
- bool Claimed;
-
-public:
- CheckerOptInfo(StringRef name, bool enable)
- : Name(name), Enable(enable), Claimed(false) { }
-
- StringRef getName() const { return Name; }
- bool isEnabled() const { return Enable; }
- bool isDisabled() const { return !isEnabled(); }
-
- bool isClaimed() const { return Claimed; }
- bool isUnclaimed() const { return !isClaimed(); }
- void claim() { Claimed = true; }
-};
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
deleted file mode 100644
index c9724c0..0000000
--- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//===--- CheckerRegistry.h - Maintains all available checkers ---*- 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_STATICANALYZER_CORE_CHECKERREGISTRY_H
-#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include <vector>
-
-// FIXME: move this information to an HTML file in docs/.
-// At the very least, a checker plugin is a dynamic library that exports
-// clang_analyzerAPIVersionString. This should be defined as follows:
-//
-// extern "C"
-// const char clang_analyzerAPIVersionString[] =
-// CLANG_ANALYZER_API_VERSION_STRING;
-//
-// This is used to check whether the current version of the analyzer is known to
-// be incompatible with a plugin. Plugins with incompatible version strings,
-// or without a version string at all, will not be loaded.
-//
-// To add a custom checker to the analyzer, the plugin must also define the
-// function clang_registerCheckers. For example:
-//
-// extern "C"
-// void clang_registerCheckers (CheckerRegistry &registry) {
-// registry.addChecker<MainCallChecker>("example.MainCallChecker",
-// "Disallows calls to functions called main");
-// }
-//
-// The first method argument is the full name of the checker, including its
-// enclosing package. By convention, the registered name of a checker is the
-// name of the associated class (the template argument).
-// The second method argument is a short human-readable description of the
-// checker.
-//
-// The clang_registerCheckers function may add any number of checkers to the
-// registry. If any checkers require additional initialization, use the three-
-// argument form of CheckerRegistry::addChecker.
-//
-// To load a checker plugin, specify the full path to the dynamic library as
-// the argument to the -load option in the cc1 frontend. You can then enable
-// your custom checker using the -analyzer-checker:
-//
-// clang -cc1 -load </path/to/plugin.dylib> -analyze
-// -analyzer-checker=<example.MainCallChecker>
-//
-// For a complete working example, see examples/analyzer-plugin.
-
-#ifndef CLANG_ANALYZER_API_VERSION_STRING
-// FIXME: The Clang version string is not particularly granular;
-// the analyzer infrastructure can change a lot between releases.
-// Unfortunately, this string has to be statically embedded in each plugin,
-// so we can't just use the functions defined in Version.h.
-#include "clang/Basic/Version.h"
-#define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING
-#endif
-
-namespace clang {
-class DiagnosticsEngine;
-class AnalyzerOptions;
-
-namespace ento {
-
-class CheckerOptInfo;
-
-/// Manages a set of available checkers for running a static analysis.
-/// The checkers are organized into packages by full name, where including
-/// a package will recursively include all subpackages and checkers within it.
-/// For example, the checker "core.builtin.NoReturnFunctionChecker" will be
-/// included if initializeManager() is called with an option of "core",
-/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
-class CheckerRegistry {
-public:
- /// Initialization functions perform any necessary setup for a checker.
- /// They should include a call to CheckerManager::registerChecker.
- typedef void (*InitializationFunction)(CheckerManager &);
- struct CheckerInfo {
- InitializationFunction Initialize;
- StringRef FullName;
- StringRef Desc;
-
- CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc)
- : Initialize(fn), FullName(name), Desc(desc) {}
- };
-
- typedef std::vector<CheckerInfo> CheckerInfoList;
-
-private:
- template <typename T>
- static void initializeManager(CheckerManager &mgr) {
- mgr.registerChecker<T>();
- }
-
-public:
- /// Adds a checker to the registry. Use this non-templated overload when your
- /// checker requires custom initialization.
- void addChecker(InitializationFunction fn, StringRef fullName,
- StringRef desc);
-
- /// Adds a checker to the registry. Use this templated overload when your
- /// checker does not require any custom initialization.
- template <class T>
- void addChecker(StringRef fullName, StringRef desc) {
- // Avoid MSVC's Compiler Error C2276:
- // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
- addChecker(&CheckerRegistry::initializeManager<T>, fullName, desc);
- }
-
- /// Initializes a CheckerManager by calling the initialization functions for
- /// all checkers specified by the given CheckerOptInfo list. The order of this
- /// list is significant; later options can be used to reverse earlier ones.
- /// This can be used to exclude certain checkers in an included package.
- void initializeManager(CheckerManager &mgr,
- SmallVectorImpl<CheckerOptInfo> &opts) const;
-
- /// Check if every option corresponds to a specific checker or package.
- void validateCheckerOptions(const AnalyzerOptions &opts,
- DiagnosticsEngine &diags) const;
-
- /// Prints the name and description of all checkers in this registry.
- /// This output is not intended to be machine-parseable.
- void printHelp(raw_ostream &out, size_t maxNameChars = 30) const ;
-
-private:
- mutable CheckerInfoList Checkers;
- mutable llvm::StringMap<size_t> Packages;
-};
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/IssueHash.h b/include/clang/StaticAnalyzer/Core/IssueHash.h
deleted file mode 100644
index b3c4f14..0000000
--- a/include/clang/StaticAnalyzer/Core/IssueHash.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===---------- IssueHash.h - Generate identification hashes ----*- 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_STATICANALYZER_CORE_ISSUE_HASH_H
-#define LLVM_CLANG_STATICANALYZER_CORE_ISSUE_HASH_H
-
-#include "llvm/ADT/SmallString.h"
-
-namespace clang {
-class Decl;
-class SourceManager;
-class FullSourceLoc;
-class LangOptions;
-
-/// \brief 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
-/// snapshots of a projects, or maintain a database of suppressed diagnotics.
-///
-/// The hash contains the normalized text of the location associated with the
-/// diagnostic. Normalization means removing the whitespaces. The associated
-/// location is the either the last location of a diagnostic path or a uniqueing
-/// location. The bugtype and the name of the checker is also part of the hash.
-/// The last component is the string representation of the enclosing declaration
-/// of the associated location.
-///
-/// In case a new hash is introduced, the old one should still be maintained for
-/// a while. One should not introduce a new hash for every change, it is
-/// possible to introduce experimental hashes that may change in the future.
-/// Such hashes should be marked as experimental using a comment in the plist
-/// files.
-llvm::SmallString<32> GetIssueHash(const SourceManager &SM,
- FullSourceLoc &IssueLoc,
- llvm::StringRef CheckerName,
- llvm::StringRef BugType, const Decl *D,
- const LangOptions &LangOpts);
-
-/// \brief 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,
- const Decl *D, const LangOptions &LangOpts);
-} // namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
deleted file mode 100644
index ce512fd..0000000
--- a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===--- PathDiagnosticClients.h - Path Diagnostic Clients ------*- 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 interface to create different path diagostic clients.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHDIAGNOSTICCONSUMERS_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHDIAGNOSTICCONSUMERS_H
-
-#include <string>
-#include <vector>
-
-namespace clang {
-
-class AnalyzerOptions;
-class Preprocessor;
-
-namespace ento {
-
-class PathDiagnosticConsumer;
-typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
-
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)\
-void CREATEFN(AnalyzerOptions &AnalyzerOpts,\
- PathDiagnosticConsumers &C,\
- const std::string &Prefix,\
- const Preprocessor &PP);
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-
-} // end 'ento' namespace
-} // end 'clang' namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
deleted file mode 100644
index cc8a9b8..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
+++ /dev/null
@@ -1,109 +0,0 @@
-//== APSIntType.h - Simple record of the type of APSInts --------*- 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_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H
-
-#include "llvm/ADT/APSInt.h"
-#include <tuple>
-
-namespace clang {
-namespace ento {
-
-/// \brief A record of the "type" of an APSInt, used for conversions.
-class APSIntType {
- uint32_t BitWidth;
- bool IsUnsigned;
-
-public:
- APSIntType(uint32_t Width, bool Unsigned)
- : BitWidth(Width), IsUnsigned(Unsigned) {}
-
- /* implicit */ APSIntType(const llvm::APSInt &Value)
- : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {}
-
- uint32_t getBitWidth() const { return BitWidth; }
- bool isUnsigned() const { return IsUnsigned; }
-
- /// \brief 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).
- void apply(llvm::APSInt &Value) const {
- // Note the order here. We extend first to preserve the sign, if this value
- // is signed, /then/ match the signedness of the result type.
- Value = Value.extOrTrunc(BitWidth);
- Value.setIsUnsigned(IsUnsigned);
- }
-
- /// Convert and return a new APSInt with the given value, but this
- /// type's bit width and signedness.
- ///
- /// \see apply
- llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY {
- llvm::APSInt Result(Value, Value.isUnsigned());
- apply(Result);
- return Result;
- }
-
- /// Returns an all-zero value for this type.
- llvm::APSInt getZeroValue() const LLVM_READONLY {
- return llvm::APSInt(BitWidth, IsUnsigned);
- }
-
- /// Returns the minimum value for this type.
- llvm::APSInt getMinValue() const LLVM_READONLY {
- return llvm::APSInt::getMinValue(BitWidth, IsUnsigned);
- }
-
- /// Returns the maximum value for this type.
- llvm::APSInt getMaxValue() const LLVM_READONLY {
- return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned);
- }
-
- llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY {
- return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue);
- }
-
- /// Used to classify whether a value is representable using this type.
- ///
- /// \see testInRange
- enum RangeTestResultKind {
- RTR_Below = -1, ///< Value is less than the minimum representable value.
- RTR_Within = 0, ///< Value is representable using this type.
- RTR_Above = 1 ///< Value is greater than the maximum representable value.
- };
-
- /// Tests whether a given value is losslessly representable using this type.
- ///
- /// \param Val The value to test.
- /// \param AllowMixedSign Whether or not to allow signedness conversions.
- /// This determines whether -1s8 is considered in range
- /// for 'unsigned char' (u8).
- RangeTestResultKind testInRange(const llvm::APSInt &Val,
- bool AllowMixedSign) const LLVM_READONLY;
-
- bool operator==(const APSIntType &Other) const {
- return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned;
- }
-
- /// \brief 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.
- bool operator<(const APSIntType &Other) const {
- return std::tie(BitWidth, IsUnsigned) <
- std::tie(Other.BitWidth, Other.IsUnsigned);
- }
-};
-
-} // end ento namespace
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
deleted file mode 100644
index 3e0913e..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ /dev/null
@@ -1,135 +0,0 @@
-//== AnalysisManager.h - Path sensitive analysis data manager ------*- 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 AnalysisManager class that manages the data and policy
-// for path sensitive analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H
-
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
-
-namespace clang {
-
-class CodeInjector;
-
-namespace ento {
- class CheckerManager;
-
-class AnalysisManager : public BugReporterData {
- virtual void anchor();
- AnalysisDeclContextManager AnaCtxMgr;
-
- ASTContext &Ctx;
- DiagnosticsEngine &Diags;
- const LangOptions &LangOpts;
- PathDiagnosticConsumers PathConsumers;
-
- // Configurable components creators.
- StoreManagerCreator CreateStoreMgr;
- ConstraintManagerCreator CreateConstraintMgr;
-
- CheckerManager *CheckerMgr;
-
-public:
- AnalyzerOptions &options;
-
- AnalysisManager(ASTContext &ctx,DiagnosticsEngine &diags,
- const LangOptions &lang,
- const PathDiagnosticConsumers &Consumers,
- StoreManagerCreator storemgr,
- ConstraintManagerCreator constraintmgr,
- CheckerManager *checkerMgr,
- AnalyzerOptions &Options,
- CodeInjector* injector = nullptr);
-
- ~AnalysisManager() override;
-
- void ClearContexts() {
- AnaCtxMgr.clear();
- }
-
- AnalysisDeclContextManager& getAnalysisDeclContextManager() {
- return AnaCtxMgr;
- }
-
- StoreManagerCreator getStoreManagerCreator() {
- return CreateStoreMgr;
- }
-
- AnalyzerOptions& getAnalyzerOptions() override {
- return options;
- }
-
- ConstraintManagerCreator getConstraintManagerCreator() {
- return CreateConstraintMgr;
- }
-
- CheckerManager *getCheckerManager() const { return CheckerMgr; }
-
- ASTContext &getASTContext() override {
- return Ctx;
- }
-
- SourceManager &getSourceManager() override {
- return getASTContext().getSourceManager();
- }
-
- DiagnosticsEngine &getDiagnostic() override {
- return Diags;
- }
-
- const LangOptions &getLangOpts() const {
- return LangOpts;
- }
-
- ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() override {
- return PathConsumers;
- }
-
- void FlushDiagnostics();
-
- bool shouldVisualize() const {
- return options.visualizeExplodedGraphWithGraphViz ||
- options.visualizeExplodedGraphWithUbiGraph;
- }
-
- bool shouldInlineCall() const {
- return options.getIPAMode() != IPAK_None;
- }
-
- CFG *getCFG(Decl const *D) {
- return AnaCtxMgr.getContext(D)->getCFG();
- }
-
- template <typename T>
- T *getAnalysis(Decl const *D) {
- return AnaCtxMgr.getContext(D)->getAnalysis<T>();
- }
-
- ParentMap &getParentMap(Decl const *D) {
- return AnaCtxMgr.getContext(D)->getParentMap();
- }
-
- AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) {
- return AnaCtxMgr.getContext(D);
- }
-};
-
-} // enAnaCtxMgrspace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
deleted file mode 100644
index 5b007f1..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ /dev/null
@@ -1,200 +0,0 @@
-//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- 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 BasicValueFactory, a class that manages the lifetime
-// of APSInt objects and symbolic constraints used by ExprEngine
-// and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
-
-namespace clang {
-namespace ento {
-
-class CompoundValData : public llvm::FoldingSetNode {
- QualType T;
- llvm::ImmutableList<SVal> L;
-
-public:
- CompoundValData(QualType t, llvm::ImmutableList<SVal> l)
- : T(t), L(l) {}
-
- typedef llvm::ImmutableList<SVal>::iterator iterator;
- iterator begin() const { return L.begin(); }
- iterator end() const { return L.end(); }
-
- static void Profile(llvm::FoldingSetNodeID& ID, QualType T,
- llvm::ImmutableList<SVal> L);
-
- void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); }
-};
-
-class LazyCompoundValData : public llvm::FoldingSetNode {
- StoreRef store;
- const TypedValueRegion *region;
-public:
- LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r)
- : store(st), region(r) {}
-
- const void *getStore() const { return store.getStore(); }
- const TypedValueRegion *getRegion() const { return region; }
-
- static void Profile(llvm::FoldingSetNodeID& ID,
- const StoreRef &store,
- const TypedValueRegion *region);
-
- void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
-};
-
-class BasicValueFactory {
- typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
- APSIntSetTy;
-
- ASTContext &Ctx;
- llvm::BumpPtrAllocator& BPAlloc;
-
- APSIntSetTy APSIntSet;
- void * PersistentSVals;
- void * PersistentSValPairs;
-
- llvm::ImmutableList<SVal>::Factory SValListFactory;
- llvm::FoldingSet<CompoundValData> CompoundValDataSet;
- llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
-
- // This is private because external clients should use the factory
- // method that takes a QualType.
- const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
-
-public:
- BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
- : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(nullptr),
- PersistentSValPairs(nullptr), SValListFactory(Alloc) {}
-
- ~BasicValueFactory();
-
- ASTContext &getContext() const { return Ctx; }
-
- const llvm::APSInt& getValue(const llvm::APSInt& X);
- const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned);
- const llvm::APSInt& getValue(uint64_t X, QualType T);
-
- /// Returns the type of the APSInt used to store values of the given QualType.
- APSIntType getAPSIntType(QualType T) const {
- assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T));
- return APSIntType(Ctx.getTypeSize(T),
- !T->isSignedIntegerOrEnumerationType());
- }
-
- /// Convert - Create a new persistent APSInt with the same value as 'From'
- /// but with the bitwidth and signedness of 'To'.
- const llvm::APSInt &Convert(const llvm::APSInt& To,
- const llvm::APSInt& From) {
- APSIntType TargetType(To);
- if (TargetType == APSIntType(From))
- return From;
-
- return getValue(TargetType.convert(From));
- }
-
- const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
- APSIntType TargetType = getAPSIntType(T);
- if (TargetType == APSIntType(From))
- return From;
-
- return getValue(TargetType.convert(From));
- }
-
- 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) {
- return getValue(APSIntType(v).getMaxValue());
- }
-
- inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) {
- return getValue(APSIntType(v).getMinValue());
- }
-
- inline const llvm::APSInt& getMaxValue(QualType T) {
- return getValue(getAPSIntType(T).getMaxValue());
- }
-
- inline const llvm::APSInt& getMinValue(QualType T) {
- return getValue(getAPSIntType(T).getMinValue());
- }
-
- inline 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) {
- llvm::APSInt X = V;
- --X;
- return getValue(X);
- }
-
- inline 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) {
- 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);
- }
-
- inline const llvm::APSInt& getTruthValue(bool b) {
- return getTruthValue(b, Ctx.getLogicalOperationType());
- }
-
- const CompoundValData *getCompoundValData(QualType T,
- llvm::ImmutableList<SVal> Vals);
-
- const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store,
- const TypedValueRegion *region);
-
- llvm::ImmutableList<SVal> getEmptySValList() {
- return SValListFactory.getEmptyList();
- }
-
- llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) {
- return SValListFactory.add(X, L);
- }
-
- const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op,
- const llvm::APSInt& V1,
- const llvm::APSInt& V2);
-
- const std::pair<SVal, uintptr_t>&
- getPersistentSValWithData(const SVal& V, uintptr_t Data);
-
- const std::pair<SVal, SVal>&
- getPersistentSValPair(const SVal& V1, const SVal& V2);
-
- const SVal* getPersistentSVal(SVal X);
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
deleted file mode 100644
index 1d779e6..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//==- BlockCounter.h - ADT for counting block visits ---------------*- 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 BlockCounter, an abstract data type used to count
-// the number of times a given block has been visited along a path
-// analyzed by CoreEngine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BLOCKCOUNTER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BLOCKCOUNTER_H
-
-#include "llvm/Support/Allocator.h"
-
-namespace clang {
-
-class StackFrameContext;
-
-namespace ento {
-
-/// \class BlockCounter
-/// \brief 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;
-
- BlockCounter(void *D) : Data(D) {}
-
-public:
- BlockCounter() : Data(nullptr) {}
-
- unsigned getNumVisited(const StackFrameContext *CallSite,
- unsigned BlockID) const;
-
- class Factory {
- void *F;
- public:
- Factory(llvm::BumpPtrAllocator& Alloc);
- ~Factory();
-
- BlockCounter GetEmptyCounter();
- BlockCounter IncrementCount(BlockCounter BC,
- const StackFrameContext *CallSite,
- unsigned BlockID);
- };
-
- friend class Factory;
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
deleted file mode 100644
index b09dffa..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ /dev/null
@@ -1,1091 +0,0 @@
-//===- CallEvent.h - Wrapper for all function and method calls ----*- C++ -*--//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file This file defines CallEvent and its subclasses, which represent path-
-/// sensitive instances of different kinds of function and method calls
-/// (C, C++, and Objective-C).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/ADT/PointerIntPair.h"
-
-namespace clang {
-class ProgramPoint;
-class ProgramPointTag;
-
-namespace ento {
-
-enum CallEventKind {
- CE_Function,
- CE_CXXMember,
- CE_CXXMemberOperator,
- CE_CXXDestructor,
- CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember,
- CE_END_CXX_INSTANCE_CALLS = CE_CXXDestructor,
- CE_CXXConstructor,
- CE_CXXAllocator,
- CE_BEG_FUNCTION_CALLS = CE_Function,
- CE_END_FUNCTION_CALLS = CE_CXXAllocator,
- CE_Block,
- CE_ObjCMessage
-};
-
-class CallEvent;
-class CallEventManager;
-
-template<typename T = CallEvent>
-class CallEventRef : public IntrusiveRefCntPtr<const T> {
-public:
- CallEventRef(const T *Call) : IntrusiveRefCntPtr<const T>(Call) {}
- CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {}
-
- CallEventRef<T> cloneWithState(ProgramStateRef State) const {
- return this->get()->template cloneWithState<T>(State);
- }
-
- // Allow implicit conversions to a superclass type, since CallEventRef
- // behaves like a pointer-to-const.
- template <typename SuperT>
- operator CallEventRef<SuperT> () const {
- return this->get();
- }
-};
-
-/// \class RuntimeDefinition
-/// \brief 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
-/// dispatch, the information is based on DynamicTypeInfo and might not be
-/// precise.
-class RuntimeDefinition {
- /// The Declaration of the function which could be called at runtime.
- /// NULL if not available.
- const Decl *D;
-
- /// 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;
-
-public:
- RuntimeDefinition(): D(nullptr), R(nullptr) {}
- RuntimeDefinition(const Decl *InD): D(InD), R(nullptr) {}
- 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.
- /// If not, it is possible that the call dispatches to another definition at
- /// execution time.
- bool mayHaveOtherDefinitions() { return R != nullptr; }
-
- /// When other definitions are possible, returns the region whose runtime type
- /// determines the method definition.
- const MemRegion *getDispatchRegion() { return R; }
-};
-
-/// \brief Represents an abstract call to a function or method along a
-/// particular path.
-///
-/// CallEvents are created through the factory methods of CallEventManager.
-///
-/// CallEvents should always be cheap to create and destroy. In order for
-/// CallEventManager to be able to re-use CallEvent-sized memory blocks,
-/// subclasses of CallEvent may not add any data members to the base class.
-/// Use the "Data" and "Location" fields instead.
-class CallEvent {
-public:
- typedef CallEventKind Kind;
-
-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;
-
- // This is user data for subclasses.
- // This should come right before RefCount, so that the two fields can be
- // packed together on LP64 platforms.
- SourceLocation Location;
-
-private:
- mutable unsigned RefCount;
-
- template <typename T> friend struct llvm::IntrusiveRefCntPtrInfo;
- void Retain() const { ++RefCount; }
- void Release() const;
-
-protected:
- friend class CallEventManager;
-
- CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx)
- : State(state), LCtx(lctx), Origin(E), RefCount(0) {}
-
- CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx)
- : State(state), LCtx(lctx), Origin(D), RefCount(0) {}
-
- // 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) {}
-
- /// 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.
- SVal getSVal(const Stmt *S) const {
- return getState()->getSVal(S, getLocationContext());
- }
-
-
- typedef SmallVectorImpl<SVal> ValueList;
-
- /// \brief 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() {}
-
- /// \brief Returns the kind of call this is.
- virtual Kind getKind() const = 0;
-
- /// \brief 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.
- const ProgramStateRef &getState() const {
- return State;
- }
-
- /// \brief 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
- /// called.
- virtual RuntimeDefinition getRuntimeDefinition() const = 0;
-
- /// \brief 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).
- ///
- /// 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.
- bool isInSystemHeader() const {
- const Decl *D = getDecl();
- if (!D)
- return false;
-
- SourceLocation Loc = D->getLocation();
- if (Loc.isValid()) {
- const SourceManager &SM =
- getState()->getStateManager().getContext().getSourceManager();
- return SM.isInSystemHeader(D->getLocation());
- }
-
- // Special case for implicitly-declared global operator new/delete.
- // These should be considered system functions.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal();
-
- return false;
- }
-
- /// \brief 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.
- virtual SVal getArgSVal(unsigned Index) const;
-
- /// \brief 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.
- ///
- /// 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.
- QualType getResultType() const;
-
- /// \brief 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
- /// the condition.
- bool hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const;
-
- /// \brief Returns true if any of the arguments appear to represent callbacks.
- bool hasNonZeroCallbackArg() const;
-
- /// \brief 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-
- /// 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,
- // but we don't want duplicated lists of known APIs in the short term either.
- virtual bool argumentsMayEscape() const {
- return hasNonZeroCallbackArg();
- }
-
- /// \brief 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
- /// a library function and not, say, a C++ member function with the same name.
- ///
- /// If a name is provided, the function must additionally match the given
- /// name.
- ///
- /// Note that this deliberately excludes C++ library functions in the \c std
- /// namespace, but will include C library functions accessed through the
- /// \c std namespace. This also does not check if the function is declared
- /// as 'extern "C"', or if it uses C++ name mangling.
- // FIXME: Add a helper for checking namespaces.
- // FIXME: Move this down to AnyFunctionCall once checkers have more
- // precise callbacks.
- bool isGlobalCFunction(StringRef SpecificName = StringRef()) const;
-
- /// \brief 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
- /// simple identifier, and the latter two do not have names.
- // 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());
- if (!ND)
- return nullptr;
- return ND->getIdentifier();
- }
-
- /// \brief 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.
- ///
- /// 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;
-
- /// Populates the given SmallVector with the bindings in the callee's stack
- /// frame at the start of this call.
- virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const = 0;
-
- /// Returns a copy of this CallEvent, but using the given state.
- template <typename T>
- CallEventRef<T> cloneWithState(ProgramStateRef NewState) const;
-
- /// Returns a copy of this CallEvent, but using the given state.
- CallEventRef<> cloneWithState(ProgramStateRef NewState) const {
- return cloneWithState<CallEvent>(NewState);
- }
-
- /// \brief 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.
- ///
- /// 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.
- ///
- /// \p D must not be null.
- static bool isVariadic(const Decl *D);
-
- // Iterator access to formal parameters and their types.
-private:
- typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;
-
-public:
- /// Return call's formal parameters.
- ///
- /// 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;
-
- typedef llvm::mapped_iterator<ArrayRef<ParmVarDecl*>::iterator, get_type_fun>
- param_type_iterator;
-
- /// Returns an iterator over the types of the call's formal parameters.
- ///
- /// This uses the callee decl found by default name lookup rather than the
- /// definition because it represents a public interface, and probably has
- /// more annotations.
- param_type_iterator param_type_begin() const {
- return llvm::map_iterator(parameters().begin(),
- get_type_fun(&ParmVarDecl::getType));
- }
- /// \sa param_type_begin()
- param_type_iterator param_type_end() const {
- return llvm::map_iterator(parameters().end(),
- get_type_fun(&ParmVarDecl::getType));
- }
-
- // For debugging purposes only
- void dump(raw_ostream &Out) const;
- void dump() const;
-};
-
-
-/// \brief 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) {}
- AnyFunctionCall(const Decl *D, ProgramStateRef St,
- const LocationContext *LCtx)
- : CallEvent(D, St, LCtx) {}
- AnyFunctionCall(const AnyFunctionCall &Other) : CallEvent(Other) {}
-
-public:
- // This function is overridden by subclasses, but they must return
- // a FunctionDecl.
- const FunctionDecl *getDecl() const override {
- return cast<FunctionDecl>(CallEvent::getDecl());
- }
-
- RuntimeDefinition getRuntimeDefinition() const override {
- const FunctionDecl *FD = getDecl();
- // Note that the AnalysisDeclContext will have the FunctionDecl with
- // the definition (if one exists).
- if (FD) {
- AnalysisDeclContext *AD =
- getLocationContext()->getAnalysisDeclContext()->
- getManager()->getContext(FD);
- if (AD->getBody())
- return RuntimeDefinition(AD->getDecl());
- }
-
- return RuntimeDefinition();
- }
-
- bool argumentsMayEscape() const override;
-
- void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const override;
-
- ArrayRef<ParmVarDecl *> parameters() const override;
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&
- CA->getKind() <= CE_END_FUNCTION_CALLS;
- }
-};
-
-/// \brief Represents a C function or static C++ member function call.
-///
-/// Example: \c fun()
-class SimpleFunctionCall : public AnyFunctionCall {
- friend class CallEventManager;
-
-protected:
- SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {}
- SimpleFunctionCall(const SimpleFunctionCall &Other)
- : AnyFunctionCall(Other) {}
- void cloneTo(void *Dest) const override {
- new (Dest) SimpleFunctionCall(*this);
- }
-
-public:
- virtual const CallExpr *getOriginExpr() const {
- return cast<CallExpr>(AnyFunctionCall::getOriginExpr());
- }
-
- const FunctionDecl *getDecl() const override;
-
- unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
-
- const Expr *getArgExpr(unsigned Index) const override {
- return getOriginExpr()->getArg(Index);
- }
-
- Kind getKind() const override { return CE_Function; }
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() == CE_Function;
- }
-};
-
-/// \brief Represents a call to a block.
-///
-/// Example: <tt>^{ /* ... */ }()</tt>
-class BlockCall : public CallEvent {
- friend class CallEventManager;
-
-protected:
- BlockCall(const CallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : CallEvent(CE, St, LCtx) {}
-
- BlockCall(const BlockCall &Other) : CallEvent(Other) {}
- void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); }
-
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
-
-public:
- virtual const CallExpr *getOriginExpr() const {
- return cast<CallExpr>(CallEvent::getOriginExpr());
- }
-
- unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
-
- const Expr *getArgExpr(unsigned Index) const override {
- return getOriginExpr()->getArg(Index);
- }
-
- /// \brief 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;
-
- const BlockDecl *getDecl() const override {
- const BlockDataRegion *BR = getBlockRegion();
- if (!BR)
- return nullptr;
- return BR->getDecl();
- }
-
- bool isConversionFromLambda() const {
- const BlockDecl *BD = getDecl();
- if (!BD)
- return false;
-
- return BD->isConversionFromLambda();
- }
-
- /// \brief 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());
- const BlockDataRegion *BR = getBlockRegion();
- assert(BR && "Block converted from lambda must have a block region");
-
- auto I = BR->referenced_vars_begin();
- assert(I != BR->referenced_vars_end());
-
- return I.getCapturedRegion();
- }
-
- RuntimeDefinition getRuntimeDefinition() const override {
- if (!isConversionFromLambda())
- return RuntimeDefinition(getDecl());
-
- // Clang converts lambdas to blocks with an implicit user-defined
- // conversion operator method on the lambda record that looks (roughly)
- // like:
- //
- // typedef R(^block_type)(P1, P2, ...);
- // operator block_type() const {
- // auto Lambda = *this;
- // return ^(P1 p1, P2 p2, ...){
- // /* return Lambda(p1, p2, ...); */
- // };
- // }
- //
- // Here R is the return type of the lambda and P1, P2, ... are
- // its parameter types. 'Lambda' is a fake VarDecl captured by the block
- // that is initialized to a copy of the lambda.
- //
- // Sema leaves the body of a lambda-converted block empty (it is
- // produced by CodeGen), so we can't analyze it directly. Instead, we skip
- // the block body and analyze the operator() method on the captured lambda.
- const VarDecl *LambdaVD = getRegionStoringCapturedLambda()->getDecl();
- const CXXRecordDecl *LambdaDecl = LambdaVD->getType()->getAsCXXRecordDecl();
- CXXMethodDecl* LambdaCallOperator = LambdaDecl->getLambdaCallOperator();
-
- return RuntimeDefinition(LambdaCallOperator);
- }
-
- bool argumentsMayEscape() const override {
- return true;
- }
-
- void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const override;
-
- ArrayRef<ParmVarDecl*> parameters() const override;
-
- Kind getKind() const override { return CE_Block; }
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() == CE_Block;
- }
-};
-
-/// \brief 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) {}
- CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyFunctionCall(D, St, LCtx) {}
-
-
- CXXInstanceCall(const CXXInstanceCall &Other) : AnyFunctionCall(Other) {}
-
-public:
- /// \brief Returns the expression representing the implicit 'this' object.
- virtual const Expr *getCXXThisExpr() const { return nullptr; }
-
- /// \brief Returns the value of the implicit 'this' object.
- virtual SVal getCXXThisVal() const;
-
- const FunctionDecl *getDecl() const override;
-
- RuntimeDefinition getRuntimeDefinition() const override;
-
- void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const override;
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
- CA->getKind() <= CE_END_CXX_INSTANCE_CALLS;
- }
-};
-
-/// \brief Represents a non-static C++ member function call.
-///
-/// Example: \c obj.fun()
-class CXXMemberCall : public CXXInstanceCall {
- friend class CallEventManager;
-
-protected:
- CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : CXXInstanceCall(CE, St, LCtx) {}
-
- CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
- void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); }
-
-public:
- virtual const CXXMemberCallExpr *getOriginExpr() const {
- return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr());
- }
-
- unsigned getNumArgs() const override {
- if (const CallExpr *CE = getOriginExpr())
- return CE->getNumArgs();
- return 0;
- }
-
- const Expr *getArgExpr(unsigned Index) const override {
- return getOriginExpr()->getArg(Index);
- }
-
- const Expr *getCXXThisExpr() const override;
-
- RuntimeDefinition getRuntimeDefinition() const override;
-
- Kind getKind() const override { return CE_CXXMember; }
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() == CE_CXXMember;
- }
-};
-
-/// \brief Represents a C++ overloaded operator call where the operator is
-/// implemented as a non-static member function.
-///
-/// Example: <tt>iter + 1</tt>
-class CXXMemberOperatorCall : public CXXInstanceCall {
- friend class CallEventManager;
-
-protected:
- CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : CXXInstanceCall(CE, St, LCtx) {}
-
- CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
- : CXXInstanceCall(Other) {}
- void cloneTo(void *Dest) const override {
- new (Dest) CXXMemberOperatorCall(*this);
- }
-
-public:
- virtual const CXXOperatorCallExpr *getOriginExpr() const {
- return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr());
- }
-
- unsigned getNumArgs() const override {
- return getOriginExpr()->getNumArgs() - 1;
- }
- const Expr *getArgExpr(unsigned Index) const override {
- return getOriginExpr()->getArg(Index + 1);
- }
-
- const Expr *getCXXThisExpr() const override;
-
- Kind getKind() const override { return CE_CXXMemberOperator; }
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() == CE_CXXMemberOperator;
- }
-};
-
-/// \brief 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.
-class CXXDestructorCall : public CXXInstanceCall {
- friend class CallEventManager;
-
-protected:
- typedef llvm::PointerIntPair<const MemRegion *, 1, bool> DtorDataTy;
-
- /// Creates an implicit destructor.
- ///
- /// \param DD The destructor that will be called.
- /// \param Trigger The statement whose completion causes this destructor call.
- /// \param Target The object region to be destructed.
- /// \param St The path-sensitive state at this point in the program.
- /// \param LCtx The location context at this point in the program.
- CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
- const MemRegion *Target, bool IsBaseDestructor,
- ProgramStateRef St, const LocationContext *LCtx)
- : CXXInstanceCall(DD, St, LCtx) {
- Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue();
- Location = Trigger->getLocEnd();
- }
-
- CXXDestructorCall(const CXXDestructorCall &Other) : CXXInstanceCall(Other) {}
- void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);}
-
-public:
- SourceRange getSourceRange() const override { return Location; }
- unsigned getNumArgs() const override { return 0; }
-
- RuntimeDefinition getRuntimeDefinition() const override;
-
- /// \brief Returns the value of the implicit 'this' object.
- SVal getCXXThisVal() const override;
-
- /// Returns true if this is a call to a base class destructor.
- bool isBaseDestructor() const {
- return DtorDataTy::getFromOpaqueValue(Data).getInt();
- }
-
- Kind getKind() const override { return CE_CXXDestructor; }
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() == CE_CXXDestructor;
- }
-};
-
-/// \brief Represents a call to a C++ constructor.
-///
-/// Example: \c T(1)
-class CXXConstructorCall : public AnyFunctionCall {
- friend class CallEventManager;
-
-protected:
- /// Creates a constructor call.
- ///
- /// \param CE The constructor expression as written in the source.
- /// \param Target The region where the object should be constructed. If NULL,
- /// a new symbolic region will be used.
- /// \param St The path-sensitive state at this point in the program.
- /// \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) {
- Data = Target;
- }
-
- CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){}
- void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); }
-
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
-
-public:
- virtual const CXXConstructExpr *getOriginExpr() const {
- return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());
- }
-
- const CXXConstructorDecl *getDecl() const override {
- return getOriginExpr()->getConstructor();
- }
-
- unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
-
- const Expr *getArgExpr(unsigned Index) const override {
- return getOriginExpr()->getArg(Index);
- }
-
- /// \brief Returns the value of the implicit 'this' object.
- SVal getCXXThisVal() const;
-
- void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const override;
-
- Kind getKind() const override { return CE_CXXConstructor; }
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() == CE_CXXConstructor;
- }
-};
-
-/// \brief Represents the memory allocation call in a C++ new-expression.
-///
-/// This is a call to "operator new".
-class CXXAllocatorCall : public AnyFunctionCall {
- friend class CallEventManager;
-
-protected:
- CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyFunctionCall(E, St, LCtx) {}
-
- CXXAllocatorCall(const CXXAllocatorCall &Other) : AnyFunctionCall(Other) {}
- void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); }
-
-public:
- virtual const CXXNewExpr *getOriginExpr() const {
- return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());
- }
-
- const FunctionDecl *getDecl() const override {
- return getOriginExpr()->getOperatorNew();
- }
-
- unsigned getNumArgs() const override {
- return getOriginExpr()->getNumPlacementArgs() + 1;
- }
-
- const Expr *getArgExpr(unsigned Index) const override {
- // The first argument of an allocator call is the size of the allocation.
- if (Index == 0)
- return nullptr;
- return getOriginExpr()->getPlacementArg(Index - 1);
- }
-
- Kind getKind() const override { return CE_CXXAllocator; }
-
- static bool classof(const CallEvent *CE) {
- return CE->getKind() == CE_CXXAllocator;
- }
-};
-
-/// \brief 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.
-enum ObjCMessageKind {
- OCM_PropertyAccess,
- OCM_Subscript,
- OCM_Message
-};
-
-/// \brief Represents any expression that calls an Objective-C method.
-///
-/// This includes all of the kinds listed in ObjCMessageKind.
-class ObjCMethodCall : public CallEvent {
- friend class CallEventManager;
-
- const PseudoObjectExpr *getContainingPseudoObjectExpr() const;
-
-protected:
- ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
- const LocationContext *LCtx)
- : CallEvent(Msg, St, LCtx) {
- Data = nullptr;
- }
-
- ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
- void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); }
-
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
-
- /// Check if the selector may have multiple definitions (may have overrides).
- virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
- Selector Sel) const;
-
-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);
- }
-
- 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.
- SVal getReceiverSVal() const;
-
- /// \brief Return the value of 'self' if available.
- SVal getSelfSVal() const;
-
- /// \brief 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.
- const ObjCInterfaceDecl *getReceiverInterface() const {
- return getOriginExpr()->getReceiverInterface();
- }
-
- /// \brief Checks if the receiver refers to 'self' or 'super'.
- bool isReceiverSelfOrSuper() const;
-
- /// Returns how the message was written in the source (property access,
- /// subscript, or explicit message send).
- ObjCMessageKind getMessageKind() const;
-
- /// Returns true if this property access or subscript is a setter (has the
- /// form of an assignment).
- bool isSetter() const {
- switch (getMessageKind()) {
- case OCM_Message:
- llvm_unreachable("This is not a pseudo-object access!");
- case OCM_PropertyAccess:
- return getNumArgs() > 0;
- case OCM_Subscript:
- return getNumArgs() > 1;
- }
- llvm_unreachable("Unknown message kind");
- }
-
- RuntimeDefinition getRuntimeDefinition() const override;
-
- bool argumentsMayEscape() const override;
-
- void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const override;
-
- ArrayRef<ParmVarDecl*> parameters() const override;
-
- Kind getKind() const override { return CE_ObjCMessage; }
-
- static bool classof(const CallEvent *CA) {
- return CA->getKind() == CE_ObjCMessage;
- }
-};
-
-
-/// \brief 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
-/// memory blocks. The CallEvents created by CallEventManager are only valid
-/// for the lifetime of the OwnedCallEvent that holds them; right now these
-/// objects cannot be copied and ownership cannot be transferred.
-class CallEventManager {
- friend class CallEvent;
-
- llvm::BumpPtrAllocator &Alloc;
- SmallVector<void *, 8> Cache;
- typedef SimpleFunctionCall CallEventTemplateTy;
-
- void reclaim(const void *Memory) {
- Cache.push_back(const_cast<void *>(Memory));
- }
-
- /// Returns memory that can be initialized as a CallEvent.
- void *allocate() {
- if (Cache.empty())
- return Alloc.Allocate<CallEventTemplateTy>();
- else
- return Cache.pop_back_val();
- }
-
- template <typename T, typename Arg>
- T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) {
- static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
- "CallEvent subclasses are not all the same size");
- return new (allocate()) T(A, St, LCtx);
- }
-
- template <typename T, typename Arg1, typename Arg2>
- T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) {
- static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
- "CallEvent subclasses are not all the same size");
- return new (allocate()) T(A1, A2, St, LCtx);
- }
-
- template <typename T, typename Arg1, typename Arg2, typename Arg3>
- T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St,
- const LocationContext *LCtx) {
- static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
- "CallEvent subclasses are not all the same size");
- return new (allocate()) T(A1, A2, A3, St, LCtx);
- }
-
- template <typename T, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4>
- T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St,
- const LocationContext *LCtx) {
- static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
- "CallEvent subclasses are not all the same size");
- return new (allocate()) T(A1, A2, A3, A4, St, LCtx);
- }
-
-public:
- CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
-
-
- CallEventRef<>
- getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
-
-
- CallEventRef<>
- getSimpleCall(const CallExpr *E, ProgramStateRef State,
- const LocationContext *LCtx);
-
- CallEventRef<ObjCMethodCall>
- getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State,
- const LocationContext *LCtx) {
- return create<ObjCMethodCall>(E, State, LCtx);
- }
-
- CallEventRef<CXXConstructorCall>
- getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target,
- ProgramStateRef State, const LocationContext *LCtx) {
- return create<CXXConstructorCall>(E, Target, State, LCtx);
- }
-
- CallEventRef<CXXDestructorCall>
- getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
- const MemRegion *Target, bool IsBase,
- ProgramStateRef State, const LocationContext *LCtx) {
- return create<CXXDestructorCall>(DD, Trigger, Target, IsBase, State, LCtx);
- }
-
- CallEventRef<CXXAllocatorCall>
- getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State,
- const LocationContext *LCtx) {
- return create<CXXAllocatorCall>(E, State, LCtx);
- }
-};
-
-
-template <typename T>
-CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {
- assert(isa<T>(*this) && "Cloning to unrelated type");
- static_assert(sizeof(T) == sizeof(CallEvent),
- "Subclasses may not add fields");
-
- if (NewState == State)
- return cast<T>(this);
-
- CallEventManager &Mgr = State->getStateManager().getCallEventManager();
- T *Copy = static_cast<T *>(Mgr.allocate());
- cloneTo(Copy);
- assert(Copy->getKind() == this->getKind() && "Bad copy");
-
- Copy->State = NewState;
- return Copy;
-}
-
-inline void CallEvent::Release() const {
- assert(RefCount > 0 && "Reference count is already zero.");
- --RefCount;
-
- if (RefCount > 0)
- return;
-
- CallEventManager &Mgr = State->getStateManager().getCallEventManager();
- Mgr.reclaim(this);
-
- this->~CallEvent();
-}
-
-} // end namespace ento
-} // end 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();
- }
- };
-}
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
deleted file mode 100644
index d4f014d..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ /dev/null
@@ -1,349 +0,0 @@
-//== CheckerContext.h - Context info for path-sensitive checkers--*- 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 CheckerContext that provides contextual info for
-// path-sensitive checkers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-
-namespace clang {
-namespace ento {
-
- /// Declares an immutable map of type \p NameTy, suitable for placement into
- /// the ProgramState. This is implementing using llvm::ImmutableMap.
- ///
- /// \code
- /// State = State->set<Name>(K, V);
- /// const Value *V = State->get<Name>(K); // Returns NULL if not in the map.
- /// State = State->remove<Name>(K);
- /// NameTy Map = State->get<Name>();
- /// \endcode
- ///
- /// The macro should not be used inside namespaces, or for traits that must
- /// be accessible from more than one translation unit.
- #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \
- REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \
- CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value))
-
- /// Declares an immutable set of type \p NameTy, suitable for placement into
- /// the ProgramState. This is implementing using llvm::ImmutableSet.
- ///
- /// \code
- /// State = State->add<Name>(E);
- /// State = State->remove<Name>(E);
- /// bool Present = State->contains<Name>(E);
- /// NameTy Set = State->get<Name>();
- /// \endcode
- ///
- /// The macro should not be used inside namespaces, or for traits that must
- /// be accessible from more than one translation unit.
- #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \
- REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>)
-
- /// Declares an immutable list of type \p NameTy, suitable for placement into
- /// the ProgramState. This is implementing using llvm::ImmutableList.
- ///
- /// \code
- /// State = State->add<Name>(E); // Adds to the /end/ of the list.
- /// bool Present = State->contains<Name>(E);
- /// NameTy List = State->get<Name>();
- /// \endcode
- ///
- /// The macro should not be used inside namespaces, or for traits that must
- /// be accessible from more than one translation unit.
- #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \
- REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>)
-
-
-class CheckerContext {
- ExprEngine &Eng;
- /// The current exploded(symbolic execution) graph node.
- ExplodedNode *Pred;
- /// The flag is true if the (state of the execution) has been modified
- /// by the checker using this context. For example, a new transition has been
- /// added or a bug report issued.
- bool Changed;
- /// The tagged location, which is used to generate all new nodes.
- const ProgramPoint Location;
- NodeBuilder &NB;
-
-public:
- /// If we are post visiting a call, this flag will be set if the
- /// call was inlined. In all other cases it will be false.
- const bool wasInlined;
-
- CheckerContext(NodeBuilder &builder,
- ExprEngine &eng,
- ExplodedNode *pred,
- const ProgramPoint &loc,
- bool wasInlined = false)
- : Eng(eng),
- Pred(pred),
- Changed(false),
- Location(loc),
- NB(builder),
- wasInlined(wasInlined) {
- assert(Pred->getState() &&
- "We should not call the checkers on an empty state.");
- }
-
- AnalysisManager &getAnalysisManager() {
- return Eng.getAnalysisManager();
- }
-
- ConstraintManager &getConstraintManager() {
- return Eng.getConstraintManager();
- }
-
- StoreManager &getStoreManager() {
- return Eng.getStoreManager();
- }
-
- /// \brief 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
- /// a new transition or a bug report.
- bool isDifferent() { return Changed; }
-
- /// \brief Returns the number of times the current block has been visited
- /// along the analyzed path.
- unsigned blockCount() const {
- return NB.getContext().blockCount();
- }
-
- ASTContext &getASTContext() {
- return Eng.getContext();
- }
-
- const LangOptions &getLangOpts() const {
- return Eng.getContext().getLangOpts();
- }
-
- const LocationContext *getLocationContext() const {
- return Pred->getLocationContext();
- }
-
- const StackFrameContext *getStackFrame() const {
- return Pred->getStackFrame();
- }
-
- /// Return true if the current LocationContext has no caller context.
- bool inTopFrame() const { return getLocationContext()->inTopFrame(); }
-
- BugReporter &getBugReporter() {
- return Eng.getBugReporter();
- }
-
- SourceManager &getSourceManager() {
- return getBugReporter().getSourceManager();
- }
-
- SValBuilder &getSValBuilder() {
- return Eng.getSValBuilder();
- }
-
- SymbolManager &getSymbolManager() {
- return getSValBuilder().getSymbolManager();
- }
-
- bool isObjCGCEnabled() const {
- return Eng.isObjCGCEnabled();
- }
-
- ProgramStateManager &getStateManager() {
- return Eng.getStateManager();
- }
-
- AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
- return Pred->getLocationContext()->getAnalysisDeclContext();
- }
-
- /// \brief Get the blockID.
- unsigned getBlockID() const {
- return NB.getContext().getBlock()->getBlockID();
- }
-
- /// \brief 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
- /// example, for finding variables that the given symbol was assigned to.
- static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
- ProgramPoint L = N->getLocation();
- if (Optional<PostStore> PSL = L.getAs<PostStore>())
- return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
- return nullptr;
- }
-
- /// \brief Get the value of arbitrary expressions at this point in the path.
- SVal getSVal(const Stmt *S) const {
- return getState()->getSVal(S, getLocationContext());
- }
-
- /// \brief 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
- /// will not be changed, but the new node will have the checker's tag.
- /// @param Tag The tag is used to uniquely identify the creation site. If no
- /// tag is specified, a default tag, unique to the given checker,
- /// will be used. Tags are used to prevent states generated at
- /// different sites from caching out.
- ExplodedNode *addTransition(ProgramStateRef State = nullptr,
- const ProgramPointTag *Tag = nullptr) {
- return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
- }
-
- /// \brief Generates a new transition with the given predecessor.
- /// Allows checkers to generate a chain of nodes.
- ///
- /// @param State The state of the generated node.
- /// @param Pred The transition will be generated from the specified Pred node
- /// to the newly generated node.
- /// @param Tag The tag to uniquely identify the creation site.
- ExplodedNode *addTransition(ProgramStateRef State,
- ExplodedNode *Pred,
- const ProgramPointTag *Tag = nullptr) {
- return addTransitionImpl(State, false, Pred, Tag);
- }
-
- /// \brief 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,
- const ProgramPointTag *Tag = nullptr) {
- return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
- }
-
- /// \brief 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.
- ///
- /// @param State The state of the generated node.
- /// @param Tag The tag to uniquely identify the creation site. If null,
- /// the default tag for the checker will be used.
- ExplodedNode *generateErrorNode(ProgramStateRef State = nullptr,
- const ProgramPointTag *Tag = nullptr) {
- return generateSink(State, Pred,
- (Tag ? Tag : Location.getTag()));
- }
-
- /// \brief 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.
- ///
- /// @param State The state of the generated node.
- /// @param Tag The tag to uniquely identify the creation site. If null,
- /// the default tag for the checker will be used.
- ExplodedNode *
- generateNonFatalErrorNode(ProgramStateRef State = nullptr,
- const ProgramPointTag *Tag = nullptr) {
- return addTransition(State, (Tag ? Tag : Location.getTag()));
- }
-
- /// \brief Emit the diagnostics report.
- void emitReport(std::unique_ptr<BugReport> R) {
- Changed = true;
- Eng.getBugReporter().emitReport(std::move(R));
- }
-
- /// \brief 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).
- StringRef getCalleeName(const FunctionDecl *FunDecl) const;
-
- /// \brief Get the identifier of the called function (path-sensitive).
- const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const {
- const FunctionDecl *FunDecl = getCalleeDecl(CE);
- if (FunDecl)
- return FunDecl->getIdentifier();
- else
- return nullptr;
- }
-
- /// \brief 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
- /// top-level namespace, such as \c malloc.
- ///
- /// If a name is provided, the function must additionally match the given
- /// name.
- ///
- /// Note that this deliberately excludes C++ library functions in the \c std
- /// namespace, but will include C library functions accessed through the
- /// \c std namespace. This also does not check if the function is declared
- /// as 'extern "C"', or if it uses C++ name mangling.
- static bool isCLibraryFunction(const FunctionDecl *FD,
- StringRef Name = StringRef());
-
- /// \brief 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
- /// is called with a given macro argument. For example:
- /// s = socket(AF_INET,..)
- /// If AF_INET is a macro, the result should be treated as a source of taint.
- ///
- /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
- StringRef getMacroNameOrSpelling(SourceLocation &Loc);
-
-private:
- ExplodedNode *addTransitionImpl(ProgramStateRef State,
- bool MarkAsSink,
- ExplodedNode *P = nullptr,
- const ProgramPointTag *Tag = nullptr) {
- // The analyzer may stop exploring if it sees a state it has previously
- // visited ("cache out"). The early return here is a defensive check to
- // prevent accidental caching out by checker API clients. Unless there is a
- // tag or the client checker has requested that the generated node be
- // marked as a sink, we assume that a client requesting a transition to a
- // state that is the same as the predecessor state has made a mistake. We
- // return the predecessor rather than cache out.
- //
- // TODO: We could potentially change the return to an assertion to alert
- // clients to their mistake, but several checkers (including
- // DereferenceChecker, CallAndMessageChecker, and DynamicTypePropagation)
- // rely upon the defensive behavior and would need to be updated.
- if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
- return Pred;
-
- Changed = true;
- const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
- if (!P)
- P = Pred;
-
- ExplodedNode *node;
- if (MarkAsSink)
- node = NB.generateSink(LocalLoc, State, P);
- else
- node = NB.generateNode(LocalLoc, State, P);
- return node;
- }
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
deleted file mode 100644
index 8dda636..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//== CheckerHelpers.h - Helper functions for checkers ------------*- 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 CheckerVisitor.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H
-
-#include "clang/AST/Stmt.h"
-#include <tuple>
-
-namespace clang {
-
-class Expr;
-class VarDecl;
-
-namespace ento {
-
-bool containsMacro(const Stmt *S);
-bool containsEnum(const Stmt *S);
-bool containsStaticLocal(const Stmt *S);
-bool containsBuiltinOffsetOf(const Stmt *S);
-template <class T> bool containsStmt(const Stmt *S) {
- if (isa<T>(S))
- return true;
-
- for (const Stmt *Child : S->children())
- if (Child && containsStmt<T>(Child))
- return true;
-
- return false;
-}
-
-std::pair<const clang::VarDecl *, const clang::Expr *>
-parseAssignment(const Stmt *S);
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
deleted file mode 100644
index 9a858c2..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ /dev/null
@@ -1,188 +0,0 @@
-//== ConstraintManager.h - Constraints on symbolic values.-------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the interface to manage constraints on symbolic values.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "llvm/Support/SaveAndRestore.h"
-
-namespace llvm {
-class APSInt;
-}
-
-namespace clang {
-namespace ento {
-
-class SubEngine;
-
-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() {}
-
- /// Return true if the constraint is perfectly constrained to 'true'.
- bool isConstrainedTrue() const {
- return Val.hasValue() && Val.getValue();
- }
-
- /// Return true if the constraint is perfectly constrained to 'false'.
- bool isConstrainedFalse() const {
- return Val.hasValue() && !Val.getValue();
- }
-
- /// Return true if the constrained is perfectly constrained.
- bool isConstrained() const {
- return Val.hasValue();
- }
-
- /// Return true if the constrained is underconstrained and we do not know
- /// if the constraint is true of value.
- bool isUnderconstrained() const {
- return !Val.hasValue();
- }
-};
-
-class ConstraintManager {
-public:
- ConstraintManager() : NotifyAssumeClients(true) {}
-
- virtual ~ConstraintManager();
- virtual ProgramStateRef assume(ProgramStateRef state,
- DefinedSVal Cond,
- bool Assumption) = 0;
-
- typedef std::pair<ProgramStateRef, ProgramStateRef> ProgramStatePair;
-
- /// Returns a pair of states (StTrue, StFalse) where the given condition is
- /// assumed to be true or false, respectively.
- ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond) {
- ProgramStateRef StTrue = assume(State, Cond, true);
-
- // If StTrue is infeasible, asserting the falseness of Cond is unnecessary
- // because the existing constraints already establish this.
- if (!StTrue) {
-#ifndef __OPTIMIZE__
- // This check is expensive and should be disabled even in Release+Asserts
- // builds.
- // FIXME: __OPTIMIZE__ is a GNU extension that Clang implements but MSVC
- // does not. Is there a good equivalent there?
- assert(assume(State, Cond, false) && "System is over constrained.");
-#endif
- return ProgramStatePair((ProgramStateRef)nullptr, State);
- }
-
- ProgramStateRef StFalse = assume(State, Cond, false);
- if (!StFalse) {
- // We are careful to return the original state, /not/ StTrue,
- // because we want to avoid having callers generate a new node
- // in the ExplodedGraph.
- return ProgramStatePair(State, (ProgramStateRef)nullptr);
- }
-
- return ProgramStatePair(StTrue, StFalse);
- }
-
- virtual ProgramStateRef assumeWithinInclusiveRange(ProgramStateRef State,
- NonLoc Value,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool InBound) = 0;
-
- virtual ProgramStatePair assumeWithinInclusiveRangeDual(
- ProgramStateRef State, NonLoc Value, const llvm::APSInt &From,
- const llvm::APSInt &To) {
- ProgramStateRef StInRange = assumeWithinInclusiveRange(State, Value, From,
- To, true);
-
- // If StTrue is infeasible, asserting the falseness of Cond is unnecessary
- // because the existing constraints already establish this.
- if (!StInRange)
- return ProgramStatePair((ProgramStateRef)nullptr, State);
-
- ProgramStateRef StOutOfRange = assumeWithinInclusiveRange(State, Value,
- From, To, false);
- if (!StOutOfRange) {
- // We are careful to return the original state, /not/ StTrue,
- // because we want to avoid having callers generate a new node
- // in the ExplodedGraph.
- return ProgramStatePair(State, (ProgramStateRef)nullptr);
- }
-
- return ProgramStatePair(StInRange, StOutOfRange);
- }
-
- /// \brief 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
- /// value for a symbol, even if it is perfectly constrained.
- virtual const llvm::APSInt* getSymVal(ProgramStateRef state,
- SymbolRef sym) const {
- return nullptr;
- }
-
- virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
- SymbolReaper& SymReaper) = 0;
-
- virtual void print(ProgramStateRef state,
- raw_ostream &Out,
- const char* nl,
- const char *sep) = 0;
-
- virtual void EndPath(ProgramStateRef state) {}
-
- /// Convenience method to query the state to see if a symbol is null or
- /// not null, or if neither assumption can be made.
- ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym) {
- SaveAndRestore<bool> DisableNotify(NotifyAssumeClients, false);
-
- return checkNull(State, Sym);
- }
-
-protected:
- /// A flag to indicate that clients should be notified of assumptions.
- /// By default this is the case, but sometimes this needs to be restricted
- /// to avoid infinite recursions within the ConstraintManager.
- ///
- /// Note that this flag allows the ConstraintManager to be re-entrant,
- /// but not thread-safe.
- bool NotifyAssumeClients;
-
- /// canReasonAbout - Not all ConstraintManagers can accurately reason about
- /// all SVal values. This method returns true if the ConstraintManager can
- /// reasonably handle a given SVal value. This is typically queried by
- /// ExprEngine to determine if the value should be replaced with a
- /// conjured symbolic value in order to recover some precision.
- virtual bool canReasonAbout(SVal X) const = 0;
-
- /// Returns whether or not a symbol is known to be null ("true"), known to be
- /// non-null ("false"), or may be either ("underconstrained").
- virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
-};
-
-std::unique_ptr<ConstraintManager>
-CreateRangeConstraintManager(ProgramStateManager &statemgr,
- SubEngine *subengine);
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
deleted file mode 100644
index d5822e2..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ /dev/null
@@ -1,547 +0,0 @@
-//==- CoreEngine.h - Path-Sensitive Dataflow Engine ----------------*- 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 generic engine for intraprocedural, path-sensitive,
-// dataflow analysis via graph reachability.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
-
-#include "clang/AST/Expr.h"
-#include "clang/Analysis/AnalysisContext.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/WorkList.h"
-#include <memory>
-
-namespace clang {
-
-class ProgramPointTag;
-
-namespace ento {
-
-class NodeBuilder;
-
-//===----------------------------------------------------------------------===//
-/// CoreEngine - Implements the core logic of the graph-reachability
-/// analysis. It traverses the CFG and generates the ExplodedGraph.
-/// Program "states" are treated as opaque void pointers.
-/// The template class CoreEngine (which subclasses CoreEngine)
-/// provides the matching component to the engine that knows the actual types
-/// for states. Note that this engine only dispatches to transfer functions
-/// 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 IndirectGotoNodeBuilder;
- friend class SwitchNodeBuilder;
- friend class EndOfFunctionNodeBuilder;
-public:
- typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
- BlocksExhausted;
-
- typedef std::vector<std::pair<const CFGBlock*, const ExplodedNode*> >
- BlocksAborted;
-
-private:
-
- SubEngine& SubEng;
-
- /// G - The simulation graph. Each node is a (location,state) pair.
- mutable ExplodedGraph G;
-
- /// WList - A set of queued nodes that need to be processed by the
- /// worklist algorithm. It is up to the implementation of WList to decide
- /// the order that nodes are processed.
- std::unique_ptr<WorkList> WList;
-
- /// BCounterFactory - A factory object for created BlockCounter objects.
- /// These are used to record for key nodes in the ExplodedGraph the
- /// number of times different CFGBlocks have been visited along a path.
- BlockCounter::Factory BCounterFactory;
-
- /// The locations where we stopped doing work because we visited a location
- /// too many times.
- BlocksExhausted blocksExhausted;
-
- /// The locations where we stopped because the engine aborted analysis,
- /// usually because it could not reason about something.
- BlocksAborted blocksAborted;
-
- /// The information about functions shared by the whole translation unit.
- /// (This data is owned by AnalysisConsumer.)
- FunctionSummariesTy *FunctionSummaries;
-
- void generateNode(const ProgramPoint &Loc,
- ProgramStateRef State,
- ExplodedNode *Pred);
-
- void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred);
- void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred);
- void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred);
- void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred);
-
- void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B,
- ExplodedNode *Pred);
- void HandleCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
- const CFGBlock *B, ExplodedNode *Pred);
-
- /// Handle conditional logic for running static initializers.
- void HandleStaticInit(const DeclStmt *DS, const CFGBlock *B,
- ExplodedNode *Pred);
-
-private:
- CoreEngine(const CoreEngine &) = delete;
- void operator=(const CoreEngine &) = delete;
-
- ExplodedNode *generateCallExitBeginNode(ExplodedNode *N);
-
-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) {}
-
- /// getGraph - Returns the exploded graph.
- ExplodedGraph &getGraph() { return G; }
-
- /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
- /// 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,
- ProgramStateRef InitState,
- ExplodedNodeSet &Dst);
-
- /// Dispatch the work list item based on the given location information.
- /// Use Pred parameter as the predecessor state.
- void dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc,
- const WorkListUnit& WU);
-
- // Functions for external checking of whether we have unfinished work
- bool wasBlockAborted() const { return !blocksAborted.empty(); }
- bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
- bool hasWorkRemaining() const { return wasBlocksExhausted() ||
- WList->hasWork() ||
- wasBlockAborted(); }
-
- /// Inform the CoreEngine that a basic block was aborted because
- /// it could not be completely analyzed.
- void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) {
- blocksAborted.push_back(std::make_pair(block, node));
- }
-
- WorkList *getWorkList() const { return WList.get(); }
-
- 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.
- void enqueue(ExplodedNodeSet &Set);
-
- /// \brief 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
- /// end of path / work list.
- void enqueueEndOfFunction(ExplodedNodeSet &Set);
-
- /// \brief Enqueue a single node created as a result of statement processing.
- void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx);
-};
-
-// TODO: Turn into a calss.
-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); }
-
- /// \brief 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
- /// visited on the exploded graph path.
- unsigned blockCount() const {
- return Eng.WList->getBlockCounter().getNumVisited(
- LC->getCurrentStackFrame(),
- Block->getBlockID());
- }
-};
-
-/// \class NodeBuilder
-/// \brief This is the simplest builder which generates nodes in the
-/// ExplodedGraph.
-///
-/// The main benefit of the builder is that it automatically tracks the
-/// frontier nodes (or destination set). This is the set of nodes which should
-/// be propagated to the next step / builder. They are the nodes which have been
-/// added to the builder (either as the input node set or as the newly
-/// 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
- /// the builder dies.
- ExplodedNodeSet &Frontier;
-
- /// Checkes if the results are ready.
- virtual bool checkResults() {
- if (!Finalized)
- return false;
- return true;
- }
-
- bool hasNoSinksInFrontier() {
- for (iterator I = Frontier.begin(), E = Frontier.end(); I != E; ++I) {
- if ((*I)->isSink())
- return false;
- }
- return true;
- }
-
- /// Allow subclasses to finalize results before result_begin() is executed.
- virtual void finalizeResults() {}
-
- ExplodedNode *generateNodeImpl(const ProgramPoint &PP,
- ProgramStateRef State,
- ExplodedNode *Pred,
- bool MarkAsSink = false);
-
-public:
- NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
- const NodeBuilderContext &Ctx, bool F = true)
- : C(Ctx), Finalized(F), HasGeneratedNodes(false), 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) {
- Frontier.insert(SrcSet);
- assert(hasNoSinksInFrontier());
- }
-
- virtual ~NodeBuilder() {}
-
- /// \brief 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.
- ///
- /// 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
- /// suppressed.
- ExplodedNode *generateSink(const ProgramPoint &PP,
- ProgramStateRef State,
- ExplodedNode *Pred) {
- return generateNodeImpl(PP, State, Pred, true);
- }
-
- const ExplodedNodeSet &getResults() {
- finalizeResults();
- assert(checkResults());
- return Frontier;
- }
-
- typedef ExplodedNodeSet::iterator iterator;
- /// \brief Iterators through the results frontier.
- inline iterator begin() {
- finalizeResults();
- assert(checkResults());
- return Frontier.begin();
- }
- inline iterator end() {
- finalizeResults();
- return Frontier.end();
- }
-
- const NodeBuilderContext &getContext() { return C; }
- bool hasGeneratedNodes() { return HasGeneratedNodes; }
-
- void takeNodes(const ExplodedNodeSet &S) {
- for (ExplodedNodeSet::iterator I = S.begin(), E = S.end(); I != E; ++I )
- 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.
-class NodeBuilderWithSinks: public NodeBuilder {
- void anchor() override;
-protected:
- SmallVector<ExplodedNode*, 2> sinksGenerated;
- ProgramPoint &Location;
-
-public:
- NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet,
- const NodeBuilderContext &Ctx, ProgramPoint &L)
- : NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
-
- ExplodedNode *generateNode(ProgramStateRef State,
- ExplodedNode *Pred,
- const ProgramPointTag *Tag = nullptr) {
- const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
- return NodeBuilder::generateNode(LocalLoc, State, Pred);
- }
-
- ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred,
- const ProgramPointTag *Tag = nullptr) {
- const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
- ExplodedNode *N = NodeBuilder::generateSink(LocalLoc, State, Pred);
- if (N && N->isSink())
- sinksGenerated.push_back(N);
- return N;
- }
-
- const SmallVectorImpl<ExplodedNode*> &getSinks() const {
- return sinksGenerated;
- }
-};
-
-/// \class StmtNodeBuilder
-/// \brief 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
- /// 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) {
- if (EnclosingBldr)
- EnclosingBldr->takeNodes(SrcNode);
- }
-
- StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
- const NodeBuilderContext &Ctx,
- NodeBuilder *Enclosing = nullptr)
- : NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
- if (EnclosingBldr)
- for (ExplodedNodeSet::iterator I = SrcSet.begin(),
- E = SrcSet.end(); I != E; ++I )
- EnclosingBldr->takeNodes(*I);
- }
-
- ~StmtNodeBuilder() override;
-
- using NodeBuilder::generateNode;
- using NodeBuilder::generateSink;
-
- ExplodedNode *generateNode(const Stmt *S,
- ExplodedNode *Pred,
- ProgramStateRef St,
- const ProgramPointTag *tag = nullptr,
- ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
- const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
- Pred->getLocationContext(), tag);
- return NodeBuilder::generateNode(L, St, Pred);
- }
-
- ExplodedNode *generateSink(const Stmt *S,
- ExplodedNode *Pred,
- ProgramStateRef St,
- const ProgramPointTag *tag = nullptr,
- ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
- const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
- Pred->getLocationContext(), tag);
- return NodeBuilder::generateSink(L, St, Pred);
- }
-};
-
-/// \brief 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;
-
-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) {
- // The branch node builder does not generate autotransitions.
- // If there are no successors it means that both branches are infeasible.
- takeNodes(SrcNode);
- }
-
- 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) {
- takeNodes(SrcSet);
- }
-
- ExplodedNode *generateNode(ProgramStateRef State, bool branch,
- ExplodedNode *Pred);
-
- const CFGBlock *getTargetBlock(bool branch) const {
- return branch ? DstT : DstF;
- }
-
- void markInfeasible(bool branch) {
- if (branch)
- InFeasibleTrue = true;
- else
- InFeasibleFalse = true;
- }
-
- bool isFeasible(bool branch) {
- return branch ? !InFeasibleTrue : !InFeasibleFalse;
- }
-};
-
-class IndirectGotoNodeBuilder {
- CoreEngine& Eng;
- const CFGBlock *Src;
- const CFGBlock &DispatchBlock;
- const Expr *E;
- ExplodedNode *Pred;
-
-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) {}
-
- class iterator {
- CFGBlock::const_succ_iterator I;
-
- friend class IndirectGotoNodeBuilder;
- iterator(CFGBlock::const_succ_iterator i) : I(i) {}
- public:
-
- iterator &operator++() { ++I; return *this; }
- bool operator!=(const iterator &X) const { return I != X.I; }
-
- const LabelDecl *getLabel() const {
- return cast<LabelStmt>((*I)->getLabel())->getDecl();
- }
-
- const CFGBlock *getBlock() const {
- return *I;
- }
- };
-
- iterator begin() { return iterator(DispatchBlock.succ_begin()); }
- iterator end() { return iterator(DispatchBlock.succ_end()); }
-
- ExplodedNode *generateNode(const iterator &I,
- ProgramStateRef State,
- bool isSink = false);
-
- const Expr *getTarget() const { return E; }
-
- ProgramStateRef getState() const { return Pred->State; }
-
- const LocationContext *getLocationContext() const {
- return Pred->getLocationContext();
- }
-};
-
-class SwitchNodeBuilder {
- CoreEngine& Eng;
- const CFGBlock *Src;
- const Expr *Condition;
- ExplodedNode *Pred;
-
-public:
- SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src,
- const Expr *condition, CoreEngine* eng)
- : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
-
- class iterator {
- CFGBlock::const_succ_reverse_iterator I;
-
- friend class SwitchNodeBuilder;
- iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
-
- public:
- iterator &operator++() { ++I; return *this; }
- bool operator!=(const iterator &X) const { return I != X.I; }
- bool operator==(const iterator &X) const { return I == X.I; }
-
- const CaseStmt *getCase() const {
- return cast<CaseStmt>((*I)->getLabel());
- }
-
- const CFGBlock *getBlock() const {
- return *I;
- }
- };
-
- iterator begin() { return iterator(Src->succ_rbegin()+1); }
- iterator end() { return iterator(Src->succ_rend()); }
-
- const SwitchStmt *getSwitch() const {
- return cast<SwitchStmt>(Src->getTerminator());
- }
-
- ExplodedNode *generateCaseStmtNode(const iterator &I,
- ProgramStateRef State);
-
- ExplodedNode *generateDefaultCaseNode(ProgramStateRef State,
- bool isSink = false);
-
- const Expr *getCondition() const { return Condition; }
-
- ProgramStateRef getState() const { return Pred->State; }
-
- const LocationContext *getLocationContext() const {
- return Pred->getLocationContext();
- }
-};
-
-} // end ento namespace
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
deleted file mode 100644
index e13c641..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//== DynamicTypeInfo.h - Runtime type information ----------------*- 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_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H
-
-#include "clang/AST/Type.h"
-
-namespace clang {
-namespace ento {
-
-/// \brief Stores the currently inferred strictest bound on the runtime type
-/// of a region in a given state along the analysis path.
-class DynamicTypeInfo {
-private:
- QualType T;
- bool CanBeASubClass;
-
-public:
-
- DynamicTypeInfo() : T(QualType()) {}
- DynamicTypeInfo(QualType WithType, bool CanBeSub = true)
- : T(WithType), CanBeASubClass(CanBeSub) {}
-
- /// \brief 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.
- QualType getType() const { return T; }
-
- /// \brief 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; }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.Add(T);
- ID.AddInteger((unsigned)CanBeASubClass);
- }
- bool operator==(const DynamicTypeInfo &X) const {
- return T == X.T && CanBeASubClass == X.CanBeASubClass;
- }
-};
-
-} // end ento
-} // end clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
deleted file mode 100644
index 555191d..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
+++ /dev/null
@@ -1,57 +0,0 @@
-//== DynamicTypeMap.h - Dynamic type map ----------------------- -*- 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 APIs for tracking dynamic type information.
-//
-//===----------------------------------------------------------------------===//
-
-#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/ProgramState.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "llvm/ADT/ImmutableMap.h"
-
-namespace clang {
-namespace ento {
-
-/// 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;
-template <>
-struct ProgramStateTrait<DynamicTypeMap>
- : public ProgramStatePartialTrait<DynamicTypeMapImpl> {
- static void *GDMIndex() {
- static int index = 0;
- return &index;
- }
-};
-
-/// \brief 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.
-ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg,
- DynamicTypeInfo NewTy);
-
-/// \brief Set dynamic type information of the region; return the new state.
-inline ProgramStateRef setDynamicTypeInfo(ProgramStateRef State,
- const MemRegion *Reg, QualType NewTy,
- bool CanBeSubClassed = true) {
- return setDynamicTypeInfo(State, Reg,
- DynamicTypeInfo(NewTy, CanBeSubClassed));
-}
-
-} // ento
-} // 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
deleted file mode 100644
index cc3779d..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ /dev/null
@@ -1,127 +0,0 @@
-//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the Environment and EnvironmentManager classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
-
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/ADT/ImmutableMap.h"
-
-namespace clang {
-
-class LiveVariables;
-
-namespace ento {
-
-class EnvironmentManager;
-class SValBuilder;
-
-/// An entry in the environment consists of a Stmt and an LocationContext.
-/// 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*,
- const StackFrameContext *> {
-public:
- EnvironmentEntry(const Stmt *s, const LocationContext *L);
-
- const Stmt *getStmt() const { return first; }
- const LocationContext *getLocationContext() const { return second; }
-
- /// Profile an EnvironmentEntry for inclusion in a FoldingSet.
- static void Profile(llvm::FoldingSetNodeID &ID,
- const EnvironmentEntry &E) {
- ID.AddPointer(E.getStmt());
- ID.AddPointer(E.getLocationContext());
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, *this);
- }
-};
-
-/// An immutable map from EnvironemntEntries to SVals.
-class Environment {
-private:
- friend class EnvironmentManager;
-
- // Type definitions.
- typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy;
-
- // Data.
- BindingsTy ExprBindings;
-
- Environment(BindingsTy eb)
- : ExprBindings(eb) {}
-
- SVal lookupExpr(const EnvironmentEntry &E) const;
-
-public:
- typedef BindingsTy::iterator iterator;
- iterator begin() const { return ExprBindings.begin(); }
- iterator end() const { return ExprBindings.end(); }
-
- /// Fetches the current binding of the expression in the
- /// Environment.
- SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const;
-
- /// Profile - Profile the contents of an Environment object for use
- /// in a FoldingSet.
- static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) {
- env->ExprBindings.Profile(ID);
- }
-
- /// Profile - Used to profile the contents of this object for inclusion
- /// in a FoldingSet.
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, this);
- }
-
- 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;
-};
-
-class EnvironmentManager {
-private:
- typedef Environment::BindingsTy::Factory FactoryTy;
- FactoryTy F;
-
-public:
- EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
-
- Environment getInitialEnvironment() {
- return Environment(F.getEmptyMap());
- }
-
- /// Bind a symbolic value to the given environment entry.
- Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V,
- bool Invalidate);
-
- Environment removeDeadBindings(Environment Env,
- SymbolReaper &SymReaper,
- ProgramStateRef state);
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
deleted file mode 100644
index cfb1b92..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ /dev/null
@@ -1,497 +0,0 @@
-//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- 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 template classes ExplodedNode and ExplodedGraph,
-// which represent a path-sensitive, intra-procedural "exploded graph."
-// See "Precise interprocedural dataflow analysis via graph reachability"
-// by Reps, Horwitz, and Sagiv
-// (http://portal.acm.org/citation.cfm?id=199462) for the definition of an
-// exploded graph.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/Analysis/Support/BumpVector.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
-#include <memory>
-#include <vector>
-
-namespace clang {
-
-class CFG;
-
-namespace ento {
-
-class ExplodedGraph;
-
-//===----------------------------------------------------------------------===//
-// ExplodedGraph "implementation" classes. These classes are not typed to
-// contain a specific kind of state. Typed-specialized versions are defined
-// on top of these classes.
-//===----------------------------------------------------------------------===//
-
-// ExplodedNode is not constified all over the engine because we need to add
-// 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 IndirectGotoNodeBuilder;
- friend class SwitchNodeBuilder;
- friend class EndOfFunctionNodeBuilder;
-
- /// Efficiently stores a list of ExplodedNodes, or an optional flag.
- ///
- /// NodeGroup provides opaque storage for a list of ExplodedNodes, optimizing
- /// for the case when there is only one node in the group. This is a fairly
- /// common case in an ExplodedGraph, where most nodes have only one
- /// predecessor and many have only one successor. It can also be used to
- /// store a flag rather than a node list, which ExplodedNode uses to mark
- /// whether a node is a sink. If the flag is set, the group is implicitly
- /// empty and no nodes may be added.
- class NodeGroup {
- // Conceptually a discriminated union. If the low bit is set, the node is
- // a sink. If the low bit is not set, the pointer refers to the storage
- // for the nodes in the group.
- // This is not a PointerIntPair in order to keep the storage type opaque.
- uintptr_t P;
-
- public:
- NodeGroup(bool Flag = false) : P(Flag) {
- assert(getFlag() == Flag);
- }
-
- ExplodedNode * const *begin() const;
-
- ExplodedNode * const *end() const;
-
- unsigned size() const;
-
- bool empty() const { return P == 0 || getFlag() != 0; }
-
- /// Adds a node to the list.
- ///
- /// The group must not have been created with its flag set.
- void addNode(ExplodedNode *N, ExplodedGraph &G);
-
- /// Replaces the single node in this group with a new node.
- ///
- /// Note that this should only be used when you know the group was not
- /// created with its flag set, and that the group is empty or contains
- /// only a single node.
- void replaceNode(ExplodedNode *node);
-
- /// Returns whether this group was created with its flag set.
- bool getFlag() const {
- return (P & 1);
- }
- };
-
- /// Location - The program location (within a function body) associated
- /// with this node.
- const ProgramPoint Location;
-
- /// State - The state associated with this node.
- ProgramStateRef State;
-
- /// Preds - The predecessors of this node.
- NodeGroup Preds;
-
- /// Succs - The successors of this node.
- NodeGroup Succs;
-
-public:
-
- explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state,
- bool IsSink)
- : Location(loc), State(state), Succs(IsSink) {
- assert(isSink() == IsSink);
- }
-
- /// getLocation - Returns the edge associated with the given node.
- ProgramPoint getLocation() const { return Location; }
-
- const LocationContext *getLocationContext() const {
- return getLocation().getLocationContext();
- }
-
- const StackFrameContext *getStackFrame() const {
- return getLocationContext()->getCurrentStackFrame();
- }
-
- const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
-
- CFG &getCFG() const { return *getLocationContext()->getCFG(); }
-
- ParentMap &getParentMap() const {return getLocationContext()->getParentMap();}
-
- template <typename T>
- T &getAnalysis() const {
- return *getLocationContext()->getAnalysis<T>();
- }
-
- const ProgramStateRef &getState() const { return State; }
-
- template <typename T>
- Optional<T> getLocationAs() const LLVM_LVALUE_FUNCTION {
- return Location.getAs<T>();
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- const ProgramPoint &Loc,
- const ProgramStateRef &state,
- bool IsSink) {
- ID.Add(Loc);
- ID.AddPointer(state.get());
- ID.AddBoolean(IsSink);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- // We avoid copy constructors by not using accessors.
- Profile(ID, Location, State, isSink());
- }
-
- /// addPredeccessor - Adds a predecessor to the current node, and
- /// in tandem add this node as a successor of the other node.
- void addPredecessor(ExplodedNode *V, ExplodedGraph &G);
-
- unsigned succ_size() const { return Succs.size(); }
- unsigned pred_size() const { return Preds.size(); }
- bool succ_empty() const { return Succs.empty(); }
- bool pred_empty() const { return Preds.empty(); }
-
- bool isSink() const { return Succs.getFlag(); }
-
- bool hasSinglePred() const {
- return (pred_size() == 1);
- }
-
- ExplodedNode *getFirstPred() {
- return pred_empty() ? nullptr : *(pred_begin());
- }
-
- const ExplodedNode *getFirstPred() const {
- return const_cast<ExplodedNode*>(this)->getFirstPred();
- }
-
- const ExplodedNode *getFirstSucc() const {
- return succ_empty() ? nullptr : *(succ_begin());
- }
-
- // 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;
-
- pred_iterator pred_begin() { return Preds.begin(); }
- pred_iterator pred_end() { return Preds.end(); }
-
- const_pred_iterator pred_begin() const {
- return const_cast<ExplodedNode*>(this)->pred_begin();
- }
- const_pred_iterator pred_end() const {
- return const_cast<ExplodedNode*>(this)->pred_end();
- }
-
- succ_iterator succ_begin() { return Succs.begin(); }
- succ_iterator succ_end() { return Succs.end(); }
-
- const_succ_iterator succ_begin() const {
- return const_cast<ExplodedNode*>(this)->succ_begin();
- }
- const_succ_iterator succ_end() const {
- return const_cast<ExplodedNode*>(this)->succ_end();
- }
-
- // For debugging.
-
-public:
-
- class Auditor {
- public:
- virtual ~Auditor();
- virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) = 0;
- };
-
- static void SetAuditor(Auditor* A);
-
-private:
- void replaceSuccessor(ExplodedNode *node) { Succs.replaceNode(node); }
- void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); }
-};
-
-typedef llvm::DenseMap<const ExplodedNode *, const ExplodedNode *>
- InterExplodedGraphMap;
-
-class ExplodedGraph {
-protected:
- friend class CoreEngine;
-
- // Type definitions.
- typedef std::vector<ExplodedNode *> NodeVector;
-
- /// The roots of the simulation graph. Usually there will be only
- /// one, but clients are free to establish multiple subgraphs within a single
- /// SimulGraph. Moreover, these subgraphs can often merge when paths from
- /// different roots reach the same state at the same program location.
- NodeVector Roots;
-
- /// The nodes in the simulation graph which have been
- /// specially marked as the endpoint of an abstract simulation path.
- NodeVector EndNodes;
-
- /// Nodes - The nodes in the graph.
- llvm::FoldingSet<ExplodedNode> Nodes;
-
- /// BVC - Allocator and context for allocating nodes and their predecessor
- /// and successor groups.
- BumpVectorContext BVC;
-
- /// NumNodes - The number of nodes in the graph.
- unsigned NumNodes;
-
- /// A list of recently allocated nodes that can potentially be recycled.
- NodeVector ChangedNodes;
-
- /// A list of nodes that can be reused.
- NodeVector FreeNodes;
-
- /// Determines how often nodes are reclaimed.
- ///
- /// If this is 0, nodes will never be reclaimed.
- unsigned ReclaimNodeInterval;
-
- /// Counter to determine when to reclaim nodes.
- unsigned ReclaimCounter;
-
-public:
-
- /// \brief 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.
- ExplodedNode *getNode(const ProgramPoint &L, ProgramStateRef State,
- bool IsSink = false,
- bool* IsNew = nullptr);
-
- std::unique_ptr<ExplodedGraph> MakeEmptyGraph() const {
- return llvm::make_unique<ExplodedGraph>();
- }
-
- /// addRoot - Add an untyped node to the set of roots.
- ExplodedNode *addRoot(ExplodedNode *V) {
- Roots.push_back(V);
- return V;
- }
-
- /// addEndOfPath - Add an untyped node to the set of EOP nodes.
- ExplodedNode *addEndOfPath(ExplodedNode *V) {
- EndNodes.push_back(V);
- return V;
- }
-
- ExplodedGraph();
-
- ~ExplodedGraph();
-
- unsigned num_roots() const { return Roots.size(); }
- unsigned num_eops() const { return EndNodes.size(); }
-
- bool empty() const { return NumNodes == 0; }
- unsigned size() const { return NumNodes; }
-
- // 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;
-
- node_iterator nodes_begin() { return Nodes.begin(); }
-
- node_iterator nodes_end() { return Nodes.end(); }
-
- const_node_iterator nodes_begin() const { return Nodes.begin(); }
-
- const_node_iterator nodes_end() const { return Nodes.end(); }
-
- roots_iterator roots_begin() { return Roots.begin(); }
-
- roots_iterator roots_end() { return Roots.end(); }
-
- const_roots_iterator roots_begin() const { return Roots.begin(); }
-
- const_roots_iterator roots_end() const { return Roots.end(); }
-
- eop_iterator eop_begin() { return EndNodes.begin(); }
-
- eop_iterator eop_end() { return EndNodes.end(); }
-
- const_eop_iterator eop_begin() const { return EndNodes.begin(); }
-
- const_eop_iterator eop_end() const { return EndNodes.end(); }
-
- llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
- BumpVectorContext &getNodeAllocator() { return BVC; }
-
- typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
-
- /// Creates a trimmed version of the graph that only contains paths leading
- /// to the given nodes.
- ///
- /// \param Nodes The nodes which must appear in the final graph. Presumably
- /// these are end-of-path nodes (i.e. they have no successors).
- /// \param[out] ForwardMap A optional map from nodes in this graph to nodes in
- /// the returned graph.
- /// \param[out] InverseMap An optional map from nodes in the returned graph to
- /// nodes in this graph.
- /// \returns The trimmed graph
- std::unique_ptr<ExplodedGraph>
- trim(ArrayRef<const NodeTy *> Nodes,
- InterExplodedGraphMap *ForwardMap = nullptr,
- InterExplodedGraphMap *InverseMap = nullptr) const;
-
- /// Enable tracking of recently allocated nodes for potential reclamation
- /// when calling reclaimRecentlyAllocatedNodes().
- void enableNodeReclamation(unsigned Interval) {
- ReclaimCounter = ReclaimNodeInterval = Interval;
- }
-
- /// Reclaim "uninteresting" nodes created since the last time this method
- /// was called.
- void reclaimRecentlyAllocatedNodes();
-
- /// \brief Returns true if nodes for the given expression kind are always
- /// kept around.
- static bool isInterestingLValueExpr(const Expr *Ex);
-
-private:
- bool shouldCollect(const ExplodedNode *node);
- void collectNode(ExplodedNode *node);
-};
-
-class ExplodedNodeSet {
- typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy;
- ImplTy Impl;
-
-public:
- ExplodedNodeSet(ExplodedNode *N) {
- assert (N && !static_cast<ExplodedNode*>(N)->isSink());
- Impl.insert(N);
- }
-
- ExplodedNodeSet() {}
-
- inline void Add(ExplodedNode *N) {
- if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
- }
-
- typedef ImplTy::iterator iterator;
- typedef ImplTy::const_iterator const_iterator;
-
- unsigned size() const { return Impl.size(); }
- bool empty() const { return Impl.empty(); }
- bool erase(ExplodedNode *N) { return Impl.erase(N); }
-
- void clear() { Impl.clear(); }
- void insert(const ExplodedNodeSet &S) {
- assert(&S != this);
- if (empty())
- Impl = S.Impl;
- else
- Impl.insert(S.begin(), S.end());
- }
-
- inline iterator begin() { return Impl.begin(); }
- inline iterator end() { return Impl.end(); }
-
- inline const_iterator begin() const { return Impl.begin(); }
- inline const_iterator end() const { return Impl.end(); }
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-// GraphTraits
-
-namespace llvm {
- template<> struct GraphTraits<clang::ento::ExplodedNode*> {
- typedef clang::ento::ExplodedNode NodeType;
- typedef NodeType::succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeType*> nodes_iterator;
-
- static inline NodeType* getEntryNode(NodeType* N) {
- return N;
- }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->succ_begin();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->succ_end();
- }
-
- static inline nodes_iterator nodes_begin(NodeType* N) {
- return df_begin(N);
- }
-
- static inline nodes_iterator nodes_end(NodeType* N) {
- return df_end(N);
- }
- };
-
- template<> struct GraphTraits<const clang::ento::ExplodedNode*> {
- typedef const clang::ento::ExplodedNode NodeType;
- typedef NodeType::const_succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeType*> nodes_iterator;
-
- static inline NodeType* getEntryNode(NodeType* N) {
- return N;
- }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->succ_begin();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->succ_end();
- }
-
- static inline nodes_iterator nodes_begin(NodeType* N) {
- return df_begin(N);
- }
-
- static inline nodes_iterator nodes_end(NodeType* N) {
- return df_end(N);
- }
- };
-
-} // end llvm namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
deleted file mode 100644
index 99083c9..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ /dev/null
@@ -1,646 +0,0 @@
-//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- 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 meta-engine for path-sensitive dataflow analysis that
-// is built on CoreEngine, but provides the boilerplate to execute transfer
-// functions and build the ExplodedGraph at the expression level.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
-#include "clang/Analysis/DomainSpecific/ObjCNoReturn.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/ProgramState.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
-
-namespace clang {
-
-class AnalysisDeclContextManager;
-class CXXCatchStmt;
-class CXXConstructExpr;
-class CXXDeleteExpr;
-class CXXNewExpr;
-class CXXTemporaryObjectExpr;
-class CXXThisExpr;
-class MaterializeTemporaryExpr;
-class ObjCAtSynchronizedStmt;
-class ObjCForCollectionStmt;
-
-namespace ento {
-
-class AnalysisManager;
-class CallEvent;
-class CXXConstructorCall;
-
-class ExprEngine : public SubEngine {
-public:
- /// The modes of inlining, which override the default analysis-wide settings.
- enum InliningModes {
- /// Follow the default settings for inlining callees.
- Inline_Regular = 0,
- /// Do minimal inlining of callees.
- Inline_Minimal = 0x1
- };
-
-private:
- AnalysisManager &AMgr;
-
- AnalysisDeclContextManager &AnalysisDeclContexts;
-
- CoreEngine Engine;
-
- /// G - the simulation graph.
- ExplodedGraph& G;
-
- /// StateMgr - Object that manages the data for all created states.
- ProgramStateManager StateMgr;
-
- /// SymMgr - Object that manages the symbol information.
- SymbolManager& SymMgr;
-
- /// svalBuilder - SValBuilder object that creates SVals from expressions.
- SValBuilder &svalBuilder;
-
- unsigned int currStmtIdx;
- const NodeBuilderContext *currBldrCtx;
-
- /// Helper object to determine if an Objective-C message expression
- /// implicitly never returns.
- ObjCNoReturn ObjCNoRet;
-
- /// Whether or not GC is enabled in this analysis.
- bool ObjCGCEnabled;
-
- /// The BugReporter associated with this engine. It is important that
- /// this object be placed at the very end of member variables so that its
- /// destructor is called before the rest of the ExprEngine is destroyed.
- GRBugReporter BR;
-
- /// The functions which have been analyzed through inlining. This is owned by
- /// AnalysisConsumer. It can be null.
- SetOfConstDecls *VisitedCallees;
-
- /// The flag, which specifies the mode of inlining for the engine.
- InliningModes HowToInline;
-
-public:
- ExprEngine(AnalysisManager &mgr, bool gcEnabled,
- SetOfConstDecls *VisitedCalleesIn,
- FunctionSummariesTy *FS,
- InliningModes HowToInlineIn);
-
- ~ExprEngine() override;
-
- /// Returns true if there is still simulation state on the worklist.
- bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
- return Engine.ExecuteWorkList(L, Steps, nullptr);
- }
-
- /// Execute the work list with an initial state. Nodes that reaches the exit
- /// of the function are added into the Dst set, which represent the exit
- /// state of the function call. Returns true if there is still simulation
- /// state on the worklist.
- bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
- ProgramStateRef InitState,
- ExplodedNodeSet &Dst) {
- return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
- }
-
- /// getContext - Return the ASTContext associated with this analysis.
- ASTContext &getContext() const { return AMgr.getASTContext(); }
-
- AnalysisManager &getAnalysisManager() override { return AMgr; }
-
- CheckerManager &getCheckerManager() const {
- return *AMgr.getCheckerManager();
- }
-
- SValBuilder &getSValBuilder() { return svalBuilder; }
-
- BugReporter& getBugReporter() { return BR; }
-
- const NodeBuilderContext &getBuilderContext() {
- assert(currBldrCtx);
- return *currBldrCtx;
- }
-
- bool isObjCGCEnabled() { return ObjCGCEnabled; }
-
- const Stmt *getStmt() const;
-
- void GenerateAutoTransition(ExplodedNode *N);
- void enqueueEndOfPath(ExplodedNodeSet &S);
- void GenerateCallExitNode(ExplodedNode *N);
-
- /// Visualize the ExplodedGraph created by executing the simulation.
- void ViewGraph(bool trim = false);
-
- /// Visualize a trimmed ExplodedGraph that only contains paths to the given
- /// 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; }
-
- /// \brief Run the analyzer's garbage collection - remove dead symbols and
- /// bindings from the state.
- ///
- /// Checkers can participate in this process with two callbacks:
- /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation
- /// class for more information.
- ///
- /// \param Node The predecessor node, from which the processing should start.
- /// \param Out The returned set of output nodes.
- /// \param ReferenceStmt The statement which is about to be processed.
- /// Everything needed for this statement should be considered live.
- /// A null statement means that everything in child LocationContexts
- /// is dead.
- /// \param LC The location context of the \p ReferenceStmt. A null location
- /// context means that we have reached the end of analysis and that
- /// all statements and local variables should be considered dead.
- /// \param DiagnosticStmt Used as a location for any warnings that should
- /// occur while removing the dead (e.g. leaks). By default, the
- /// \p ReferenceStmt is used.
- /// \param K Denotes whether this is a pre- or post-statement purge. This
- /// must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an
- /// entire location context is being cleared, in which case the
- /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise,
- /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default)
- /// and \p ReferenceStmt must be valid (non-null).
- void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
- const Stmt *ReferenceStmt, const LocationContext *LC,
- const Stmt *DiagnosticStmt = nullptr,
- ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
-
- /// processCFGElement - Called by CoreEngine. Used to generate new successor
- /// nodes by processing the 'effects' of a CFG element.
- void processCFGElement(const CFGElement E, ExplodedNode *Pred,
- unsigned StmtIdx, NodeBuilderContext *Ctx) override;
-
- void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
-
- void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
-
- void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
-
- void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred);
-
- void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
- void ProcessDeleteDtor(const CFGDeleteDtor D,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
- void ProcessBaseDtor(const CFGBaseDtor D,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
- void ProcessMemberDtor(const CFGMemberDtor D,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
- void ProcessTemporaryDtor(const CFGTemporaryDtor D,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- /// Called by CoreEngine when processing the entrance of a CFGBlock.
- void processCFGBlockEntrance(const BlockEdge &L,
- NodeBuilderWithSinks &nodeBuilder,
- ExplodedNode *Pred) override;
-
- /// ProcessBranch - Called by CoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a branch condition.
- void processBranch(const Stmt *Condition, const Stmt *Term,
- NodeBuilderContext& BuilderCtx,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst,
- const CFGBlock *DstT,
- const CFGBlock *DstF) override;
-
- /// Called by CoreEngine.
- /// Used to generate successor nodes for temporary destructors depending
- /// on whether the corresponding constructor was visited.
- void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
- NodeBuilderContext &BldCtx,
- ExplodedNode *Pred, ExplodedNodeSet &Dst,
- const CFGBlock *DstT,
- const CFGBlock *DstF) override;
-
- /// Called by CoreEngine. Used to processing branching behavior
- /// at static initalizers.
- void processStaticInitializer(const DeclStmt *DS,
- NodeBuilderContext& BuilderCtx,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst,
- const CFGBlock *DstT,
- const CFGBlock *DstF) override;
-
- /// processIndirectGoto - Called by CoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a computed goto jump.
- void processIndirectGoto(IndirectGotoNodeBuilder& builder) override;
-
- /// ProcessSwitch - Called by CoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a switch statement.
- void processSwitch(SwitchNodeBuilder& builder) override;
-
- /// Called by CoreEngine. Used to generate end-of-path
- /// nodes when the control reaches the end of a function.
- void processEndOfFunction(NodeBuilderContext& BC,
- ExplodedNode *Pred) override;
-
- /// Remove dead bindings/symbols before exiting a function.
- void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// Generate the entry node of the callee.
- void processCallEnter(CallEnter CE, ExplodedNode *Pred) override;
-
- /// Generate the sequence of nodes that simulate the call exit and the post
- /// visit for CallExpr.
- void processCallExit(ExplodedNode *Pred) override;
-
- /// Called by CoreEngine when the analysis worklist has terminated.
- void processEndWorklist(bool hasWorkRemaining) override;
-
- /// evalAssume - Callback function invoked by the ConstraintManager when
- /// making assumptions about state values.
- ProgramStateRef processAssume(ProgramStateRef state, SVal cond,
- bool assumption) override;
-
- /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
- /// region change should trigger a processRegionChanges update.
- bool wantsRegionChangeUpdate(ProgramStateRef state) override;
-
- /// processRegionChanges - Called by ProgramStateManager whenever a change is made
- /// to the store. Used to update checkers that track region values.
- ProgramStateRef
- processRegionChanges(ProgramStateRef state,
- const InvalidatedSymbols *invalidated,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- 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;
-
- ProgramStateManager& getStateManager() override { return StateMgr; }
-
- StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
-
- ConstraintManager& getConstraintManager() {
- return StateMgr.getConstraintManager();
- }
-
- // FIXME: Remove when we migrate over to just using SValBuilder.
- 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; }
-
- // Functions for external checking of whether we have unfinished work
- bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
- bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
- bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
-
- const CoreEngine &getCoreEngine() const { return Engine; }
-
-public:
- /// Visit - Transfer function logic for all statements. Dispatches to
- /// other functions that handle specific kinds of statements.
- void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- /// VisitArraySubscriptExpr - Transfer function for array accesses.
- void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitGCCAsmStmt - Transfer function logic for inline asm.
- void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitMSAsmStmt - Transfer function logic for MS inline asm.
- void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitBlockExpr - Transfer function logic for BlockExprs.
- void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitLambdaExpr - Transfer function logic for LambdaExprs.
- void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitBinaryOperator - Transfer function logic for binary operators.
- void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
-
- /// VisitCall - Transfer function for function calls.
- void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitCast - Transfer function logic for all casts (implicit and explicit).
- void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
- void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
- void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- /// VisitDeclStmt - Transfer function logic for DeclStmts.
- void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
- void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitLogicalExpr - Transfer function logic for '&&', '||'
- void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitMemberExpr - Transfer function for member expressions.
- void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// Transfer function logic for ObjCAtSynchronizedStmts.
- void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- /// Transfer function logic for computing the lvalue of an Objective-C ivar.
- void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitObjCForCollectionStmt - Transfer function logic for
- /// ObjCForCollectionStmt.
- void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitReturnStmt - Transfer function logic for return statements.
- void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitOffsetOfExpr - Transfer function for offsetof.
- void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
- void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- /// VisitUnaryOperator - Transfer function logic for unary operators.
- void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// Handle ++ and -- (both pre- and post-increment).
- void VisitIncrementDecrementOperator(const UnaryOperator* U,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
- ExplodedNodeSet &PreVisit,
- ExplodedNodeSet &Dst);
-
- void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
- ExplodedNodeSet & Dst);
-
- void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest,
- const Stmt *S, bool IsBaseDtor,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// Create a C++ temporary object for an rvalue.
- void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic
- /// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
- /// with those assumptions.
- void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
- const Expr *Ex);
-
- std::pair<const ProgramPointTag *, const ProgramPointTag*>
- geteagerlyAssumeBinOpBifurcationTags();
-
- SVal evalMinus(SVal X) {
- return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X;
- }
-
- SVal evalComplement(SVal X) {
- return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
- }
-
-public:
-
- SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
- NonLoc L, NonLoc R, QualType T) {
- return svalBuilder.evalBinOpNN(state, op, L, R, T);
- }
-
- SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
- NonLoc L, SVal R, QualType T) {
- return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L,
- R.castAs<NonLoc>(), T) : R;
- }
-
- SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
- SVal LHS, SVal RHS, QualType T) {
- return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
- }
-
-protected:
- /// evalBind - Handle the semantics of binding a value to a specific location.
- /// This method is used by evalStore, VisitDeclStmt, and others.
- void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
- SVal location, SVal Val, bool atDeclInit = false,
- const ProgramPoint *PP = nullptr);
-
- /// Call PointerEscape callback when a value escapes as a result of bind.
- ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
- SVal Loc, SVal Val) override;
- /// Call PointerEscape callback when a value escapes as a result of
- /// region invalidation.
- /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
- ProgramStateRef notifyCheckersOfPointerEscape(
- ProgramStateRef State,
- const InvalidatedSymbols *Invalidated,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call,
- RegionAndSymbolInvalidationTraits &ITraits) override;
-
-public:
- // FIXME: 'tag' should be removed, and a LocationContext should be used
- // instead.
- // FIXME: Comment on the meaning of the arguments, when 'St' may not
- // be the same as Pred->state, and when 'location' may not be the
- // same as state->getLValue(Ex).
- /// Simulate a read of the result of Ex.
- void evalLoad(ExplodedNodeSet &Dst,
- const Expr *NodeEx, /* Eventually will be a CFGStmt */
- const Expr *BoundExpr,
- ExplodedNode *Pred,
- ProgramStateRef St,
- SVal location,
- const ProgramPointTag *tag = nullptr,
- QualType LoadTy = QualType());
-
- // FIXME: 'tag' should be removed, and a LocationContext should be used
- // instead.
- void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
- 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
- /// call origin expression.
- ProgramStateRef bindReturnValue(const CallEvent &Call,
- const LocationContext *LCtx,
- ProgramStateRef State);
-
- /// Evaluate a call, running pre- and post-call checks and allowing checkers
- /// to be responsible for handling the evaluation of the call itself.
- void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
- const CallEvent &Call);
-
- /// \brief Default implementation of call evaluation.
- void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
- const CallEvent &Call);
-private:
- void evalLoadCommon(ExplodedNodeSet &Dst,
- const Expr *NodeEx, /* Eventually will be a CFGStmt */
- const Expr *BoundEx,
- ExplodedNode *Pred,
- ProgramStateRef St,
- SVal location,
- const ProgramPointTag *tag,
- QualType LoadTy);
-
- // FIXME: 'tag' should be removed, and a LocationContext should be used
- // instead.
- void evalLocation(ExplodedNodeSet &Dst,
- const Stmt *NodeEx, /* This will eventually be a CFGStmt */
- const Stmt *BoundEx,
- ExplodedNode *Pred,
- ProgramStateRef St, SVal location,
- const ProgramPointTag *tag, bool isLoad);
-
- /// Count the stack depth and determine if the call is recursive.
- void examineStackFrames(const Decl *D, const LocationContext *LCtx,
- bool &IsRecursive, unsigned &StackDepth);
-
- /// Checks our policies and decides weither the given call should be inlined.
- bool shouldInlineCall(const CallEvent &Call, const Decl *D,
- const ExplodedNode *Pred);
-
- bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
- ExplodedNode *Pred, ProgramStateRef State);
-
- /// \brief 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
- /// on DynamicDispatchBifurcation data.
- void BifurcateCall(const MemRegion *BifurReg,
- const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
- ExplodedNode *Pred);
-
- bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
-
- /// Models a trivial copy or move constructor or trivial assignment operator
- /// call with a simple bind.
- void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
- const CallEvent &Call);
-
- /// If the value of the given expression is a NonLoc, copy it into a new
- /// temporary object region, and replace the value of the expression with
- /// that.
- ///
- /// If \p ResultE is provided, the new region will be bound to this expression
- /// instead of \p E.
- ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
- const LocationContext *LC,
- const Expr *E,
- const Expr *ResultE = nullptr);
-
- /// 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
- /// statement created a temporary object region rather than directly
- /// 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);
-};
-
-/// Traits for storing the call processing policy inside GDM.
-/// The GDM stores the corresponding CallExpr pointer.
-// FIXME: This does not use the nice trait macros because it must be accessible
-// from multiple translation units.
-struct ReplayWithoutInlining{};
-template <>
-struct ProgramStateTrait<ReplayWithoutInlining> :
- public ProgramStatePartialTrait<const void*> {
- static void *GDMIndex() { static int index = 0; return &index; }
-};
-
-} // end ento namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
deleted file mode 100644
index ce81c98..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//== FunctionSummary.h - Stores summaries of functions. ------------*- 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 summary of a function gathered/used by static analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallBitVector.h"
-#include <deque>
-
-namespace clang {
-
-namespace ento {
-typedef std::deque<Decl*> SetOfDecls;
-typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
-
-class FunctionSummariesTy {
- class FunctionSummary {
- public:
- /// Marks the IDs of the basic blocks visited during the analyzes.
- llvm::SmallBitVector VisitedBasicBlocks;
-
- /// Total number of blocks in the function.
- unsigned TotalBasicBlocks : 30;
-
- /// True if this function has been checked against the rules for which
- /// functions may be inlined.
- unsigned InlineChecked : 1;
-
- /// True if this function may be inlined.
- unsigned MayInline : 1;
-
- /// The number of times the function has been inlined.
- unsigned TimesInlined : 32;
-
- FunctionSummary() :
- TotalBasicBlocks(0),
- InlineChecked(0),
- TimesInlined(0) {}
- };
-
- typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
- MapTy Map;
-
-public:
- MapTy::iterator findOrInsertSummary(const Decl *D) {
- MapTy::iterator I = Map.find(D);
- if (I != Map.end())
- return I;
-
- typedef std::pair<const Decl *, FunctionSummary> KVPair;
- I = Map.insert(KVPair(D, FunctionSummary())).first;
- assert(I != Map.end());
- return I;
- }
-
- void markMayInline(const Decl *D) {
- MapTy::iterator I = findOrInsertSummary(D);
- I->second.InlineChecked = 1;
- I->second.MayInline = 1;
- }
-
- void markShouldNotInline(const Decl *D) {
- MapTy::iterator I = findOrInsertSummary(D);
- I->second.InlineChecked = 1;
- I->second.MayInline = 0;
- }
-
- void markReachedMaxBlockCount(const Decl *D) {
- markShouldNotInline(D);
- }
-
- Optional<bool> mayInline(const Decl *D) {
- MapTy::const_iterator I = Map.find(D);
- if (I != Map.end() && I->second.InlineChecked)
- return I->second.MayInline;
- return None;
- }
-
- void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
- MapTy::iterator I = findOrInsertSummary(D);
- llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
- assert(ID < TotalIDs);
- if (TotalIDs > Blocks.size()) {
- Blocks.resize(TotalIDs);
- I->second.TotalBasicBlocks = TotalIDs;
- }
- Blocks.set(ID);
- }
-
- unsigned getNumVisitedBasicBlocks(const Decl* D) {
- MapTy::const_iterator I = Map.find(D);
- if (I != Map.end())
- return I->second.VisitedBasicBlocks.count();
- return 0;
- }
-
- unsigned getNumTimesInlined(const Decl* D) {
- MapTy::const_iterator I = Map.find(D);
- if (I != Map.end())
- return I->second.TimesInlined;
- return 0;
- }
-
- void bumpNumTimesInlined(const Decl* D) {
- MapTy::iterator I = findOrInsertSummary(D);
- I->second.TimesInlined++;
- }
-
- /// Get the percentage of the reachable blocks.
- unsigned getPercentBlocksReachable(const Decl *D) {
- MapTy::const_iterator I = Map.find(D);
- if (I != Map.end())
- return ((I->second.VisitedBasicBlocks.count() * 100) /
- I->second.TotalBasicBlocks);
- return 0;
- }
-
- unsigned getTotalNumBasicBlocks();
- unsigned getTotalNumVisitedBasicBlocks();
-
-};
-
-}} // end clang ento namespaces
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
deleted file mode 100644
index 3168733..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===--- LoopWidening.h - Widen loops ---------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// This header contains the declarations of functions which are used to widen
-/// loops which do not otherwise exit. The widening is done by invalidating
-/// anything which might be modified by the body of the loop.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPWIDENING_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPWIDENING_H
-
-#include "clang/Analysis/CFG.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-
-namespace clang {
-namespace ento {
-
-/// \brief 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.
-ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState,
- const LocationContext *LCtx,
- unsigned BlockCount, const Stmt *LoopStmt);
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
deleted file mode 100644
index bb835c4..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ /dev/null
@@ -1,1370 +0,0 @@
-//== MemRegion.h - Abstract memory regions for static analysis --*- 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 MemRegion and its subclasses. MemRegion defines a
-// partially-typed abstraction of memory useful for path-sensitive dataflow
-// analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <string>
-
-namespace clang {
-
-class LocationContext;
-class StackFrameContext;
-
-namespace ento {
-
-class CodeTextRegion;
-class MemRegionManager;
-class MemSpaceRegion;
-class SValBuilder;
-class SymbolicRegion;
-class VarRegion;
-
-/// Represent a region's offset within the top level base region.
-class RegionOffset {
- /// The base region.
- const MemRegion *R;
-
- /// The bit offset within the base region. Can be negative.
- int64_t Offset;
-
-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;
-
- RegionOffset() : R(nullptr) {}
- RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
-
- const MemRegion *getRegion() const { return R; }
-
- bool hasSymbolicOffset() const { return Offset == Symbolic; }
-
- int64_t getOffset() const {
- assert(!hasSymbolicOffset());
- return Offset;
- }
-
- bool isValid() const { return R; }
-};
-
-//===----------------------------------------------------------------------===//
-// Base region classes.
-//===----------------------------------------------------------------------===//
-
-/// MemRegion - The root abstract class for all memory regions.
-class MemRegion : public llvm::FoldingSetNode {
- friend class MemRegionManager;
-public:
- enum Kind {
- // Memory spaces.
- GenericMemSpaceRegionKind,
- StackLocalsSpaceRegionKind,
- StackArgumentsSpaceRegionKind,
- HeapSpaceRegionKind,
- UnknownSpaceRegionKind,
- StaticGlobalSpaceRegionKind,
- GlobalInternalSpaceRegionKind,
- GlobalSystemSpaceRegionKind,
- GlobalImmutableSpaceRegionKind,
- BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind,
- END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
- BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
- END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
- BEG_MEMSPACES = GenericMemSpaceRegionKind,
- END_MEMSPACES = GlobalImmutableSpaceRegionKind,
- // Untyped regions.
- SymbolicRegionKind,
- AllocaRegionKind,
- // Typed regions.
- BEG_TYPED_REGIONS,
- FunctionTextRegionKind = BEG_TYPED_REGIONS,
- BlockTextRegionKind,
- BlockDataRegionKind,
- BEG_TYPED_VALUE_REGIONS,
- CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
- CXXThisRegionKind,
- StringRegionKind,
- ObjCStringRegionKind,
- ElementRegionKind,
- // Decl Regions.
- BEG_DECL_REGIONS,
- VarRegionKind = BEG_DECL_REGIONS,
- FieldRegionKind,
- ObjCIvarRegionKind,
- END_DECL_REGIONS = ObjCIvarRegionKind,
- CXXTempObjectRegionKind,
- CXXBaseObjectRegionKind,
- END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
- END_TYPED_REGIONS = CXXBaseObjectRegionKind
- };
-
-private:
- const Kind kind;
-
-protected:
- MemRegion(Kind k) : kind(k) {}
- virtual ~MemRegion();
-
-public:
- ASTContext &getContext() const;
-
- virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
-
- virtual MemRegionManager* getMemRegionManager() const = 0;
-
- const MemSpaceRegion *getMemorySpace() const;
-
- const MemRegion *getBaseRegion() const;
-
- /// Check if the region is a subregion of the given region.
- 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,
- /// goes up the base chain looking for the first symbolic base region.
- const SymbolicRegion *getSymbolicBase() const;
-
- bool hasGlobalsOrParametersStorage() const;
-
- bool hasStackStorage() const;
-
- bool hasStackNonParametersStorage() const;
-
- bool hasStackParametersStorage() const;
-
- /// Compute the offset within the top level memory object.
- RegionOffset getAsOffset() const;
-
- /// \brief 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.
- virtual bool canPrintPretty() const;
-
- /// \brief 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
- /// as part of a larger expression.
- virtual bool canPrintPrettyAsExpr() const;
-
- /// \brief Print the region as expression.
- ///
- /// When this region represents a subexpression, the method is for printing
- /// an expression containing it.
- virtual void printPrettyAsExpr(raw_ostream &os) const;
-
- Kind getKind() const { return kind; }
-
- template<typename RegionTy> const RegionTy* getAs() const;
-
- virtual bool isBoundable() const { return false; }
-};
-
-/// MemSpaceRegion - A memory region that represents a "memory space";
-/// for example, the set of global variables, the stack frame, etc.
-class MemSpaceRegion : public MemRegion {
-protected:
- friend class MemRegionManager;
-
- MemRegionManager *Mgr;
-
- MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
- : MemRegion(k), Mgr(mgr) {
- assert(classof(this));
- }
-
- MemRegionManager* getMemRegionManager() const override { return Mgr; }
-
-public:
- bool isBoundable() const override { return false; }
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- static bool classof(const MemRegion *R) {
- Kind k = R->getKind();
- return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
- }
-};
-
-class GlobalsSpaceRegion : public MemSpaceRegion {
- virtual void anchor();
-protected:
- GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
- : MemSpaceRegion(mgr, k) {}
-public:
- static bool classof(const MemRegion *R) {
- Kind k = R->getKind();
- return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
- }
-};
-
-/// \brief The region of the static variables within the current CodeTextRegion
-/// scope.
-///
-/// Currently, only the static locals are placed there, so we know that these
-/// variables do not get invalidated by calls to other functions.
-class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
- friend class MemRegionManager;
-
- const CodeTextRegion *CR;
-
- StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
- : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
-
-public:
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- void dumpToStream(raw_ostream &os) const override;
-
- const CodeTextRegion *getCodeRegion() const { return CR; }
-
- static bool classof(const MemRegion *R) {
- return R->getKind() == StaticGlobalSpaceRegionKind;
- }
-};
-
-/// \brief 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 {
- friend class MemRegionManager;
-
-protected:
- NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
- : GlobalsSpaceRegion(mgr, k) {}
-
-public:
-
- static bool classof(const MemRegion *R) {
- Kind k = R->getKind();
- return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES &&
- k <= END_NON_STATIC_GLOBAL_MEMSPACES;
- }
-};
-
-/// \brief 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) {}
-
-public:
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion *R) {
- return R->getKind() == GlobalSystemSpaceRegionKind;
- }
-};
-
-/// \brief 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
-/// low chance of being modified.
-class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
- friend class MemRegionManager;
-
- GlobalImmutableSpaceRegion(MemRegionManager *mgr)
- : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
-
-public:
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion *R) {
- return R->getKind() == GlobalImmutableSpaceRegionKind;
- }
-};
-
-/// \brief 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) {}
-
-public:
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion *R) {
- return R->getKind() == GlobalInternalSpaceRegionKind;
- }
-};
-
-class HeapSpaceRegion : public MemSpaceRegion {
- virtual void anchor();
- friend class MemRegionManager;
-
- HeapSpaceRegion(MemRegionManager *mgr)
- : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
-public:
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion *R) {
- return R->getKind() == HeapSpaceRegionKind;
- }
-};
-
-class UnknownSpaceRegion : public MemSpaceRegion {
- virtual void anchor();
- friend class MemRegionManager;
- UnknownSpaceRegion(MemRegionManager *mgr)
- : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
-public:
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion *R) {
- return R->getKind() == UnknownSpaceRegionKind;
- }
-};
-
-class StackSpaceRegion : public MemSpaceRegion {
-private:
- const StackFrameContext *SFC;
-
-protected:
- StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
- : MemSpaceRegion(mgr, k), SFC(sfc) {
- assert(classof(this));
- }
-
-public:
- const StackFrameContext *getStackFrame() const { return SFC; }
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- static bool classof(const MemRegion *R) {
- Kind k = R->getKind();
- return k >= StackLocalsSpaceRegionKind &&
- k <= StackArgumentsSpaceRegionKind;
- }
-};
-
-class StackLocalsSpaceRegion : public StackSpaceRegion {
- virtual void anchor();
- friend class MemRegionManager;
- StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
- : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
-public:
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion *R) {
- return R->getKind() == StackLocalsSpaceRegionKind;
- }
-};
-
-class StackArgumentsSpaceRegion : public StackSpaceRegion {
-private:
- virtual void anchor();
- friend class MemRegionManager;
- StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
- : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
-public:
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion *R) {
- return R->getKind() == StackArgumentsSpaceRegionKind;
- }
-};
-
-
-/// SubRegion - A region that subsets another larger region. Most regions
-/// are subclasses of SubRegion.
-class SubRegion : public MemRegion {
-private:
- virtual void anchor();
-protected:
- const MemRegion* superRegion;
- SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
-public:
- const MemRegion* getSuperRegion() const {
- return superRegion;
- }
-
- /// getExtent - Returns the size of the region in bytes.
- virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
- return UnknownVal();
- }
-
- MemRegionManager* getMemRegionManager() const override;
-
- bool isSubRegionOf(const MemRegion* R) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() > END_MEMSPACES;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// MemRegion subclasses.
-//===----------------------------------------------------------------------===//
-
-/// AllocaRegion - A region that represents an untyped blob of bytes created
-/// by a call to 'alloca'.
-class AllocaRegion : public SubRegion {
- friend class MemRegionManager;
-protected:
- unsigned Cnt; // Block counter. Used to distinguish different pieces of
- // memory allocated by alloca at the same call site.
- const Expr *Ex;
-
- AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
- : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
-
-public:
-
- const Expr *getExpr() const { return Ex; }
-
- bool isBoundable() const override { return true; }
-
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
- unsigned Cnt, const MemRegion *superRegion);
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == AllocaRegionKind;
- }
-};
-
-/// TypedRegion - An abstract class representing regions that are typed.
-class TypedRegion : public SubRegion {
-public:
- void anchor() override;
-protected:
- TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
-
-public:
- virtual QualType getLocationType() const = 0;
-
- QualType getDesugaredLocationType(ASTContext &Context) const {
- return getLocationType().getDesugaredType(Context);
- }
-
- bool isBoundable() const override { return true; }
-
- static bool classof(const MemRegion* R) {
- unsigned k = R->getKind();
- return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
- }
-};
-
-/// TypedValueRegion - An abstract class representing regions having a typed value.
-class TypedValueRegion : public TypedRegion {
-public:
- void anchor() override;
-protected:
- TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
-
-public:
- virtual QualType getValueType() const = 0;
-
- QualType getLocationType() const override {
- // FIXME: We can possibly optimize this later to cache this value.
- QualType T = getValueType();
- ASTContext &ctx = getContext();
- if (T->getAs<ObjCObjectType>())
- return ctx.getObjCObjectPointerType(T);
- return ctx.getPointerType(getValueType());
- }
-
- QualType getDesugaredValueType(ASTContext &Context) const {
- QualType T = getValueType();
- return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
- }
-
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
- static bool classof(const MemRegion* R) {
- unsigned k = R->getKind();
- return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
- }
-};
-
-
-class CodeTextRegion : public TypedRegion {
-public:
- void anchor() override;
-protected:
- CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
-public:
- bool isBoundable() const override { return false; }
-
- static bool classof(const MemRegion* R) {
- Kind k = R->getKind();
- return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
- }
-};
-
-/// FunctionTextRegion - A region that represents code texts of function.
-class FunctionTextRegion : public CodeTextRegion {
- const NamedDecl *FD;
-public:
- FunctionTextRegion(const NamedDecl *fd, const MemRegion* sreg)
- : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {
- assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
- }
-
- QualType getLocationType() const override {
- const ASTContext &Ctx = getContext();
- if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) {
- return Ctx.getPointerType(D->getType());
- }
-
- assert(isa<ObjCMethodDecl>(FD));
- assert(false && "Getting the type of ObjCMethod is not supported yet");
-
- // TODO: We might want to return a different type here (ex: id (*ty)(...))
- // depending on how it is used.
- return QualType();
- }
-
- const NamedDecl *getDecl() const {
- return FD;
- }
-
- void dumpToStream(raw_ostream &os) const override;
-
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
- const MemRegion*);
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == FunctionTextRegionKind;
- }
-};
-
-
-/// BlockTextRegion - A region that represents code texts of blocks (closures).
-/// Blocks are represented with two kinds of regions. BlockTextRegions
-/// represent the "code", while BlockDataRegions represent instances of blocks,
-/// which correspond to "code+data". The distinction is important, because
-/// like a closure a block captures the values of externally referenced
-/// variables.
-class BlockTextRegion : public CodeTextRegion {
- friend class MemRegionManager;
-
- const BlockDecl *BD;
- AnalysisDeclContext *AC;
- CanQualType locTy;
-
- BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
- AnalysisDeclContext *ac, const MemRegion* sreg)
- : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
-
-public:
- QualType getLocationType() const override {
- return locTy;
- }
-
- const BlockDecl *getDecl() const {
- return BD;
- }
-
- AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
-
- void dumpToStream(raw_ostream &os) const override;
-
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
- CanQualType, const AnalysisDeclContext*,
- const MemRegion*);
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == BlockTextRegionKind;
- }
-};
-
-/// BlockDataRegion - A region that represents a block instance.
-/// Blocks are represented with two kinds of regions. BlockTextRegions
-/// represent the "code", while BlockDataRegions represent instances of blocks,
-/// which correspond to "code+data". The distinction is important, because
-/// like a closure a block captures the values of externally referenced
-/// variables.
-class BlockDataRegion : public TypedRegion {
- friend class MemRegionManager;
- const BlockTextRegion *BC;
- const LocationContext *LC; // Can be null */
- unsigned BlockCount;
- void *ReferencedVars;
- void *OriginalVars;
-
- BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
- unsigned count, const MemRegion *sreg)
- : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
- BlockCount(count),
- ReferencedVars(nullptr), OriginalVars(nullptr) {}
-
-public:
- const BlockTextRegion *getCodeRegion() const { return BC; }
-
- const BlockDecl *getDecl() const { return BC->getDecl(); }
-
- QualType getLocationType() const override { return BC->getLocationType(); }
-
- 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) {}
-
- const VarRegion *getCapturedRegion() const {
- return cast<VarRegion>(*R);
- }
- const VarRegion *getOriginalRegion() const {
- return cast<VarRegion>(*OriginalR);
- }
-
- bool operator==(const referenced_vars_iterator &I) const {
- 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;
- return *this;
- }
- };
-
- /// Return the original region for a captured region, if
- /// one exists.
- const VarRegion *getOriginalRegion(const VarRegion *VR) const;
-
- referenced_vars_iterator referenced_vars_begin() const;
- referenced_vars_iterator referenced_vars_end() const;
-
- void dumpToStream(raw_ostream &os) const override;
-
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
- static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
- const LocationContext *, unsigned,
- const MemRegion *);
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == BlockDataRegionKind;
- }
-private:
- void LazyInitializeReferencedVars();
- std::pair<const VarRegion *, const VarRegion *>
- getCaptureRegions(const VarDecl *VD);
-};
-
-/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
-/// classes, SymbolicRegion represents a region that serves as an alias for
-/// either a real region, a NULL pointer, etc. It essentially is used to
-/// map the concept of symbolic values into the domain of regions. Symbolic
-/// regions do not need to be typed.
-class SymbolicRegion : public SubRegion {
-protected:
- const SymbolRef sym;
-
-public:
- SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
- : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
-
- SymbolRef getSymbol() const {
- return sym;
- }
-
- bool isBoundable() const override { return true; }
-
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- SymbolRef sym,
- const MemRegion* superRegion);
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == SymbolicRegionKind;
- }
-};
-
-/// StringRegion - Region associated with a StringLiteral.
-class StringRegion : public TypedValueRegion {
- friend class MemRegionManager;
- const StringLiteral* Str;
-protected:
-
- StringRegion(const StringLiteral* str, const MemRegion* sreg)
- : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const StringLiteral* Str,
- const MemRegion* superRegion);
-
-public:
-
- const StringLiteral* getStringLiteral() const { return Str; }
-
- QualType getValueType() const override {
- return Str->getType();
- }
-
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
- bool isBoundable() const override { return false; }
-
- void Profile(llvm::FoldingSetNodeID& ID) const override {
- ProfileRegion(ID, Str, superRegion);
- }
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == StringRegionKind;
- }
-};
-
-/// The region associated with an ObjCStringLiteral.
-class ObjCStringRegion : public TypedValueRegion {
- friend class MemRegionManager;
- const ObjCStringLiteral* Str;
-protected:
-
- ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
- : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const ObjCStringLiteral* Str,
- const MemRegion* superRegion);
-
-public:
-
- const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
-
- QualType getValueType() const override {
- return Str->getType();
- }
-
- bool isBoundable() const override { return false; }
-
- void Profile(llvm::FoldingSetNodeID& ID) const override {
- ProfileRegion(ID, Str, superRegion);
- }
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == ObjCStringRegionKind;
- }
-};
-
-/// CompoundLiteralRegion - A memory region representing a compound literal.
-/// Compound literals are essentially temporaries that are stack allocated
-/// or in the global constant pool.
-class CompoundLiteralRegion : public TypedValueRegion {
-private:
- friend class MemRegionManager;
- const CompoundLiteralExpr *CL;
-
- CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
- : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const CompoundLiteralExpr *CL,
- const MemRegion* superRegion);
-public:
- QualType getValueType() const override {
- return CL->getType();
- }
-
- bool isBoundable() const override { return !CL->isFileScope(); }
-
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
- void dumpToStream(raw_ostream &os) const override;
-
- const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == CompoundLiteralRegionKind;
- }
-};
-
-class DeclRegion : public TypedValueRegion {
-protected:
- const Decl *D;
-
- DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
- : TypedValueRegion(sReg, k), D(d) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
- const MemRegion* superRegion, Kind k);
-
-public:
- const Decl *getDecl() const { return D; }
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
- static bool classof(const MemRegion* R) {
- unsigned k = R->getKind();
- return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
- }
-};
-
-class VarRegion : public DeclRegion {
- friend class MemRegionManager;
-
- // Constructors and private methods.
- VarRegion(const VarDecl *vd, const MemRegion* sReg)
- : DeclRegion(vd, sReg, VarRegionKind) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
- const MemRegion *superRegion) {
- DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
-public:
- const VarDecl *getDecl() const { return cast<VarDecl>(D); }
-
- const StackFrameContext *getStackFrame() const;
-
- QualType getValueType() const override {
- // FIXME: We can cache this if needed.
- return getDecl()->getType();
- }
-
- 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;
-};
-
-/// CXXThisRegion - Represents the region for the implicit 'this' parameter
-/// in a call to a C++ method. This region doesn't represent the object
-/// referred to by 'this', but rather 'this' itself.
-class CXXThisRegion : public TypedValueRegion {
- friend class MemRegionManager;
- CXXThisRegion(const PointerType *thisPointerTy,
- const MemRegion *sReg)
- : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID &ID,
- const PointerType *PT,
- const MemRegion *sReg);
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
-public:
- QualType getValueType() const override {
- return QualType(ThisPointerTy, 0);
- }
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == CXXThisRegionKind;
- }
-
-private:
- const PointerType *ThisPointerTy;
-};
-
-class FieldRegion : public DeclRegion {
- friend class MemRegionManager;
-
- FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
- : DeclRegion(fd, sReg, FieldRegionKind) {}
-
-public:
- const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
-
- QualType getValueType() const override {
- // FIXME: We can cache this if needed.
- return getDecl()->getType();
- }
-
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
- const MemRegion* superRegion) {
- DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
- }
-
- 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;
-};
-
-class ObjCIvarRegion : public DeclRegion {
-
- friend class MemRegionManager;
-
- ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
- const MemRegion* superRegion);
-
-public:
- const ObjCIvarDecl *getDecl() const;
- QualType getValueType() const override;
-
- bool canPrintPrettyAsExpr() const override;
- void printPrettyAsExpr(raw_ostream &os) const override;
-
- void dumpToStream(raw_ostream &os) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == ObjCIvarRegionKind;
- }
-};
-//===----------------------------------------------------------------------===//
-// Auxiliary data classes for use with MemRegions.
-//===----------------------------------------------------------------------===//
-
-class ElementRegion;
-
-class RegionRawOffset {
-private:
- friend class ElementRegion;
-
- const MemRegion *Region;
- CharUnits Offset;
-
- RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
- : Region(reg), Offset(offset) {}
-
-public:
- // FIXME: Eventually support symbolic offsets.
- CharUnits getOffset() const { return Offset; }
- const MemRegion *getRegion() const { return Region; }
-
- void dumpToStream(raw_ostream &os) const;
- void dump() const;
-};
-
-/// \brief ElementRegin is used to represent both array elements and casts.
-class ElementRegion : public TypedValueRegion {
- friend class MemRegionManager;
-
- QualType ElementType;
- NonLoc Index;
-
- ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
- : TypedValueRegion(sReg, ElementRegionKind),
- ElementType(elementType), Index(Idx) {
- assert((!Idx.getAs<nonloc::ConcreteInt>() ||
- Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
- "The index must be signed");
- }
-
- 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 getElementType() const {
- return ElementType;
- }
- /// Compute the offset within the array. The array might also be a subobject.
- RegionRawOffset getAsArrayOffset() const;
-
- void dumpToStream(raw_ostream &os) const override;
-
- void Profile(llvm::FoldingSetNodeID& ID) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == ElementRegionKind;
- }
-};
-
-// C++ temporary object associated with an expression.
-class CXXTempObjectRegion : public TypedValueRegion {
- friend class MemRegionManager;
-
- Expr const *Ex;
-
- CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
- : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID &ID,
- Expr const *E, const MemRegion *sReg);
-
-public:
- const Expr *getExpr() const { return Ex; }
-
- QualType getValueType() const override {
- return Ex->getType();
- }
-
- void dumpToStream(raw_ostream &os) const override;
-
- void Profile(llvm::FoldingSetNodeID &ID) const override;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == CXXTempObjectRegionKind;
- }
-};
-
-// CXXBaseObjectRegion represents a base object within a C++ object. It is
-// identified by the base class declaration and the region of its parent object.
-class CXXBaseObjectRegion : public TypedValueRegion {
- friend class MemRegionManager;
-
- llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
-
- CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
- const MemRegion *SReg)
- : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
- bool IsVirtual, const MemRegion *SReg);
-
-public:
- const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
- bool isVirtual() const { return Data.getInt(); }
-
- QualType getValueType() const override;
-
- void dumpToStream(raw_ostream &os) const override;
-
- 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;
-};
-
-template<typename RegionTy>
-const RegionTy* MemRegion::getAs() const {
- if (const RegionTy* RT = dyn_cast<RegionTy>(this))
- return RT;
-
- return nullptr;
-}
-
-//===----------------------------------------------------------------------===//
-// MemRegionManager - Factory object for creating regions.
-//===----------------------------------------------------------------------===//
-
-class MemRegionManager {
- ASTContext &C;
- llvm::BumpPtrAllocator& A;
- llvm::FoldingSet<MemRegion> Regions;
-
- GlobalInternalSpaceRegion *InternalGlobals;
- GlobalSystemSpaceRegion *SystemGlobals;
- GlobalImmutableSpaceRegion *ImmutableGlobals;
-
-
- llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
- StackLocalsSpaceRegions;
- llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
- StackArgumentsSpaceRegions;
- llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
- StaticsGlobalSpaceRegions;
-
- HeapSpaceRegion *heap;
- UnknownSpaceRegion *unknown;
- MemSpaceRegion *code;
-
-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 &getContext() { return C; }
-
- llvm::BumpPtrAllocator &getAllocator() { return A; }
-
- /// getStackLocalsRegion - Retrieve the memory region associated with the
- /// specified stack frame.
- const StackLocalsSpaceRegion *
- getStackLocalsRegion(const StackFrameContext *STC);
-
- /// getStackArgumentsRegion - Retrieve the memory region associated with
- /// function/method arguments of the specified stack frame.
- const StackArgumentsSpaceRegion *
- getStackArgumentsRegion(const StackFrameContext *STC);
-
- /// getGlobalsRegion - Retrieve the memory region associated with
- /// global variables.
- const GlobalsSpaceRegion *getGlobalsRegion(
- MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
- const CodeTextRegion *R = nullptr);
-
- /// getHeapRegion - Retrieve the memory region associated with the
- /// generic "heap".
- const HeapSpaceRegion *getHeapRegion();
-
- /// getUnknownRegion - Retrieve the memory region associated with unknown
- /// memory space.
- const MemSpaceRegion *getUnknownRegion();
-
- const MemSpaceRegion *getCodeRegion();
-
- /// getAllocaRegion - Retrieve a region associated with a call to alloca().
- const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
- const LocationContext *LC);
-
- /// getCompoundLiteralRegion - Retrieve the region associated with a
- /// given CompoundLiteral.
- const CompoundLiteralRegion*
- getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
- const LocationContext *LC);
-
- /// getCXXThisRegion - Retrieve the [artificial] region associated with the
- /// parameter 'this'.
- const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
- const LocationContext *LC);
-
- /// \brief Retrieve or create a "symbolic" memory region.
- const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
-
- /// \brief Return a unique symbolic region belonging to heap memory space.
- const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
-
- const StringRegion *getStringRegion(const StringLiteral* Str);
-
- const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
-
- /// getVarRegion - Retrieve or create the memory region associated with
- /// a specified VarDecl and LocationContext.
- const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
-
- /// getVarRegion - Retrieve or create the memory region associated with
- /// a specified VarDecl and super region.
- const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
-
- /// getElementRegion - Retrieve the memory region associated with the
- /// associated element type, index, and super region.
- const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
- const MemRegion *superRegion,
- ASTContext &Ctx);
-
- const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
- const MemRegion *superRegion) {
- return getElementRegion(ER->getElementType(), ER->getIndex(),
- superRegion, ER->getContext());
- }
-
- /// getFieldRegion - Retrieve or create the memory region associated with
- /// a specified FieldDecl. 'superRegion' corresponds to the containing
- /// memory region (which typically represents the memory representing
- /// a structure or class).
- const FieldRegion *getFieldRegion(const FieldDecl *fd,
- const MemRegion* superRegion);
-
- const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
- const MemRegion *superRegion) {
- return getFieldRegion(FR->getDecl(), superRegion);
- }
-
- /// getObjCIvarRegion - Retrieve or create the memory region associated with
- /// a specified Objective-c instance variable. 'superRegion' corresponds
- /// to the containing region (which typically represents the Objective-C
- /// object).
- const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
- const MemRegion* superRegion);
-
- const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
- LocationContext const *LC);
-
- /// Create a CXXBaseObjectRegion with the given base class for region
- /// \p Super.
- ///
- /// The type of \p Super is assumed be a class deriving from \p BaseClass.
- const CXXBaseObjectRegion *
- getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
- bool IsVirtual);
-
- /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
- /// super region.
- const CXXBaseObjectRegion *
- getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
- const MemRegion *superRegion) {
- return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
- baseReg->isVirtual());
- }
-
- const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD);
- const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
- CanQualType locTy,
- AnalysisDeclContext *AC);
-
- /// getBlockDataRegion - Get the memory region associated with an instance
- /// of a block. Unlike many other MemRegions, the LocationContext*
- /// argument is allowed to be NULL for cases where we have no known
- /// context.
- const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
- const LocationContext *lc,
- unsigned blockCount);
-
- /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
- /// by static references. This differs from getCXXTempObjectRegion in the
- /// super-region used.
- const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
-
-private:
- template <typename RegionTy, typename A1>
- RegionTy* getRegion(const A1 a1);
-
- template <typename RegionTy, typename A1>
- RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
-
- template <typename RegionTy, typename A1, typename A2>
- RegionTy* getRegion(const A1 a1, const A2 a2);
-
- template <typename RegionTy, typename A1, typename A2>
- RegionTy* getSubRegion(const A1 a1, const A2 a2,
- const MemRegion* superRegion);
-
- template <typename RegionTy, typename A1, typename A2, typename A3>
- RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
- const MemRegion* superRegion);
-
- template <typename REG>
- const REG* LazyAllocate(REG*& region);
-
- template <typename REG, typename ARG>
- const REG* LazyAllocate(REG*& region, ARG a);
-};
-
-//===----------------------------------------------------------------------===//
-// Out-of-line member definitions.
-//===----------------------------------------------------------------------===//
-
-inline ASTContext &MemRegion::getContext() const {
- return getMemRegionManager()->getContext();
-}
-
-//===----------------------------------------------------------------------===//
-// Means for storing region/symbol handling traits.
-//===----------------------------------------------------------------------===//
-
-/// Information about invalidation for a particular region/symbol.
-class RegionAndSymbolInvalidationTraits {
- typedef unsigned char StorageTypeForKinds;
- 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;
-
-public:
- /// \brief 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
-
- // Do not forget to extend StorageTypeForKinds if number of traits exceed
- // the number of bits StorageTypeForKinds can store.
- };
-
- void setTrait(SymbolRef Sym, InvalidationKinds IK);
- void setTrait(const MemRegion *MR, InvalidationKinds IK);
- bool hasTrait(SymbolRef Sym, InvalidationKinds IK);
- bool hasTrait(const MemRegion *MR, InvalidationKinds IK);
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-//===----------------------------------------------------------------------===//
-// Pretty-printing regions.
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
- const clang::ento::MemRegion* R) {
- R->dumpToStream(os);
- return os;
-}
-} // end llvm namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
deleted file mode 100644
index c4a62ec..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ /dev/null
@@ -1,854 +0,0 @@
-//== ProgramState.h - Path-sensitive "State" for tracking values -*- 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 state of the program along the analysisa path.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Allocator.h"
-
-namespace llvm {
-class APSInt;
-}
-
-namespace clang {
-class ASTContext;
-
-namespace ento {
-
-class CallEvent;
-class CallEventManager;
-
-typedef std::unique_ptr<ConstraintManager>(*ConstraintManagerCreator)(
- ProgramStateManager &, SubEngine *);
-typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)(
- ProgramStateManager &);
-
-//===----------------------------------------------------------------------===//
-// ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
-//===----------------------------------------------------------------------===//
-
-template <typename T> struct ProgramStatePartialTrait;
-
-template <typename T> struct ProgramStateTrait {
- typedef typename T::data_type data_type;
- static inline void *MakeVoidPtr(data_type D) { return (void*) D; }
- static inline data_type MakeData(void *const* P) {
- return P ? (data_type) *P : (data_type) 0;
- }
-};
-
-/// \class ProgramState
-/// ProgramState - This class encapsulates:
-///
-/// 1. A mapping from expressions to values (Environment)
-/// 2. A mapping from locations to values (Store)
-/// 3. Constraints on symbolic values (GenericDataMap)
-///
-/// Together these represent the "abstract state" of a program.
-///
-/// ProgramState is intended to be used as a functional object; that is,
-/// once it is created and made "persistent" in a FoldingSet, its
-/// values will never change.
-class ProgramState : public llvm::FoldingSetNode {
-public:
- typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
- typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
-
-private:
- void operator=(const ProgramState& R) = delete;
-
- friend class ProgramStateManager;
- friend class ExplodedGraph;
- friend class ExplodedNode;
-
- ProgramStateManager *stateMgr;
- Environment Env; // Maps a Stmt to its current SVal.
- Store store; // Maps a location to its current value.
- GenericDataMap GDM; // Custom data stored by a client of this class.
- unsigned refCount;
-
- /// makeWithStore - Return a ProgramState with the same values as the current
- /// state with the exception of using the specified Store.
- ProgramStateRef makeWithStore(const StoreRef &store) const;
-
- void setStore(const StoreRef &storeRef);
-
-public:
- /// This ctor is used when creating the first ProgramState object.
- ProgramState(ProgramStateManager *mgr, const Environment& env,
- StoreRef st, GenericDataMap gdm);
-
- /// Copy ctor - We must explicitly define this or else the "Next" ptr
- /// in FoldingSetNode will also get copied.
- ProgramState(const ProgramState &RHS);
-
- ~ProgramState();
-
- /// Return the ProgramStateManager associated with this state.
- ProgramStateManager &getStateManager() const {
- return *stateMgr;
- }
-
- /// Return the ConstraintManager.
- ConstraintManager &getConstraintManager() const;
-
- /// getEnvironment - Return the environment associated with this state.
- /// The environment is the mapping from expressions to values.
- const Environment& getEnvironment() const { return Env; }
-
- /// Return the store associated with this state. The store
- /// is a mapping from locations to values.
- Store getStore() const { return store; }
-
-
- /// getGDM - Return the generic data map associated with this state.
- GenericDataMap getGDM() const { return GDM; }
-
- void setGDM(GenericDataMap gdm) { GDM = gdm; }
-
- /// Profile - Profile the contents of a ProgramState object for use in a
- /// FoldingSet. Two ProgramState objects are considered equal if they
- /// have the same Environment, Store, and GenericDataMap.
- static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
- V->Env.Profile(ID);
- ID.AddPointer(V->store);
- V->GDM.Profile(ID);
- }
-
- /// Profile - Used to profile the contents of this object for inclusion
- /// in a FoldingSet.
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, this);
- }
-
- BasicValueFactory &getBasicVals() const;
- SymbolManager &getSymbolManager() const;
-
- //==---------------------------------------------------------------------==//
- // Constraints on values.
- //==---------------------------------------------------------------------==//
- //
- // Each ProgramState records constraints on symbolic values. These constraints
- // are managed using the ConstraintManager associated with a ProgramStateManager.
- // As constraints gradually accrue on symbolic values, added constraints
- // may conflict and indicate that a state is infeasible (as no real values
- // could satisfy all the constraints). This is the principal mechanism
- // for modeling path-sensitivity in ExprEngine/ProgramState.
- //
- // Various "assume" methods form the interface for adding constraints to
- // symbolic values. A call to 'assume' indicates an assumption being placed
- // on one or symbolic values. 'assume' methods take the following inputs:
- //
- // (1) A ProgramState object representing the current state.
- //
- // (2) The assumed constraint (which is specific to a given "assume" method).
- //
- // (3) A binary value "Assumption" that indicates whether the constraint is
- // assumed to be true or false.
- //
- // The output of "assume*" is a new ProgramState object with the added constraints.
- // If no new state is feasible, NULL is returned.
- //
-
- /// Assumes that the value of \p cond is zero (if \p assumption is "false")
- /// or non-zero (if \p assumption is "true").
- ///
- /// 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;
-
- /// 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>
- assume(DefinedOrUnknownSVal cond) const;
-
- 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
- /// (if \p assumption is "false").
- ///
- /// This returns a new state with the added constraint on \p cond.
- /// If no new state is feasible, NULL is returned.
- ProgramStateRef assumeWithinInclusiveRange(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>
- assumeWithinInclusiveRange(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
- /// constant.
- ConditionTruthVal isNull(SVal V) const;
-
- /// Utility method for getting regions.
- const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
-
- //==---------------------------------------------------------------------==//
- // Binding and retrieving values to/from the environment and symbolic store.
- //==---------------------------------------------------------------------==//
-
- /// 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,
- bool notifyChanges = true) const;
-
- ProgramStateRef bindLoc(SVal location, SVal V) const;
-
- ProgramStateRef bindDefault(SVal loc, SVal V) const;
-
- ProgramStateRef killBinding(Loc LV) const;
-
- /// \brief Returns the state with bindings for the given regions
- /// cleared from the store.
- ///
- /// Optionally invalidates global regions as well.
- ///
- /// \param Regions the set of regions to be invalidated.
- /// \param E the expression that caused the invalidation.
- /// \param BlockCount The number of times the current basic block has been
- // visited.
- /// \param CausesPointerEscape the flag is set to true when
- /// the invalidation entails escape of a symbol (representing a
- /// pointer). For example, due to it being passed as an argument in a
- /// call.
- /// \param IS the set of invalidated symbols.
- /// \param Call if non-null, the invalidated regions represent parameters to
- /// the call and should be considered directly invalidated.
- /// \param ITraits information about special handling for a particular
- /// region/symbol.
- 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
- invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
- unsigned BlockCount, const LocationContext *LCtx,
- bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
- const CallEvent *Call = nullptr,
- RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
-
- /// enterStackFrame - Returns the state for entry to the given stack frame,
- /// preserving the current state.
- ProgramStateRef enterStackFrame(const CallEvent &Call,
- const StackFrameContext *CalleeCtx) const;
-
- /// Get the lvalue for a variable reference.
- Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
-
- Loc getLValue(const CompoundLiteralExpr *literal,
- const LocationContext *LC) const;
-
- /// Get the lvalue for an ivar reference.
- SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
-
- /// Get the lvalue for a field reference.
- SVal getLValue(const FieldDecl *decl, SVal Base) const;
-
- /// Get the lvalue for an indirect field reference.
- SVal getLValue(const IndirectFieldDecl *decl, SVal Base) const;
-
- /// Get the lvalue for an array index.
- SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
-
- /// Returns the SVal bound to the statement 'S' in the state's environment.
- SVal getSVal(const Stmt *S, const LocationContext *LCtx) const;
-
- SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
-
- /// \brief 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.
- /// Returns UnknownVal() if none found.
- SVal getSVal(const MemRegion* R) const;
-
- SVal getSValAsScalarOrLoc(const MemRegion *R) const;
-
- /// \brief Visits the symbols reachable from the given SVal using the provided
- /// SymbolVisitor.
- ///
- /// This is a convenience API. Consider using ScanReachableSymbols class
- /// directly when making multiple scans on the same state with the same
- /// visitor to avoid repeated initialization cost.
- /// \sa ScanReachableSymbols
- bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
-
- /// \brief 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
- /// MemRegions range using the provided SymbolVisitor.
- bool scanReachableSymbols(const MemRegion * const *I,
- const MemRegion * const *E,
- SymbolVisitor &visitor) const;
-
- template <typename CB> CB scanReachableSymbols(SVal val) const;
- template <typename CB> CB scanReachableSymbols(const SVal *beg,
- const SVal *end) const;
-
- template <typename CB> CB
- scanReachableSymbols(const MemRegion * const *beg,
- 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;
-
- /// Create a new state in which the symbol is marked as tainted.
- 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;
-
- /// Check if the statement is tainted in the current state.
- bool isTainted(const Stmt *S, const LocationContext *LCtx,
- TaintTagType Kind = TaintTagGeneric) const;
- bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const;
- bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const;
- bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
-
- //==---------------------------------------------------------------------==//
- // Accessing the Generic Data Map (GDM).
- //==---------------------------------------------------------------------==//
-
- void *const* FindGDM(void *K) const;
-
- template<typename T>
- ProgramStateRef add(typename ProgramStateTrait<T>::key_type K) const;
-
- template <typename T>
- typename ProgramStateTrait<T>::data_type
- get() const {
- return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex()));
- }
-
- template<typename T>
- typename ProgramStateTrait<T>::lookup_type
- get(typename ProgramStateTrait<T>::key_type key) const {
- void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
- return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key);
- }
-
- template <typename T>
- typename ProgramStateTrait<T>::context_type get_context() 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;
-
- template<typename T>
- 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) 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>
- bool contains(typename ProgramStateTrait<T>::key_type key) const {
- void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
- return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key);
- }
-
- // Pretty-printing.
- void print(raw_ostream &Out, const char *nl = "\n",
- const char *sep = "") const;
- void printDOT(raw_ostream &Out) const;
- void printTaint(raw_ostream &Out, const char *nl = "\n",
- const char *sep = "") const;
-
- void dump() const;
- void dumpTaint() const;
-
-private:
- friend void ProgramStateRetain(const ProgramState *state);
- friend void ProgramStateRelease(const ProgramState *state);
-
- /// \sa invalidateValues()
- /// \sa invalidateRegions()
- ProgramStateRef
- invalidateRegionsImpl(ArrayRef<SVal> Values,
- const Expr *E, unsigned BlockCount,
- const LocationContext *LCtx,
- bool ResultsInSymbolEscape,
- InvalidatedSymbols *IS,
- RegionAndSymbolInvalidationTraits *HTraits,
- const CallEvent *Call) const;
-};
-
-//===----------------------------------------------------------------------===//
-// ProgramStateManager - Factory object for ProgramStates.
-//===----------------------------------------------------------------------===//
-
-class ProgramStateManager {
- friend class ProgramState;
- friend void ProgramStateRelease(const ProgramState *state);
-private:
- /// Eng - The SubEngine that owns this state manager.
- SubEngine *Eng; /* Can be null. */
-
- EnvironmentManager EnvMgr;
- std::unique_ptr<StoreManager> StoreMgr;
- std::unique_ptr<ConstraintManager> ConstraintMgr;
-
- ProgramState::GenericDataMap::Factory GDMFactory;
-
- typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
- GDMContextsTy GDMContexts;
-
- /// StateSet - FoldingSet containing all the states created for analyzing
- /// a particular function. This is used to unique states.
- llvm::FoldingSet<ProgramState> StateSet;
-
- /// Object that manages the data for all created SVals.
- std::unique_ptr<SValBuilder> svalBuilder;
-
- /// Manages memory for created CallEvents.
- std::unique_ptr<CallEventManager> CallEventMgr;
-
- /// A BumpPtrAllocator to allocate states.
- llvm::BumpPtrAllocator &Alloc;
-
- /// A vector of ProgramStates that we can reuse.
- std::vector<ProgramState *> freeStates;
-
-public:
- ProgramStateManager(ASTContext &Ctx,
- StoreManagerCreator CreateStoreManager,
- ConstraintManagerCreator CreateConstraintManager,
- llvm::BumpPtrAllocator& alloc,
- SubEngine *subeng);
-
- ~ProgramStateManager();
-
- ProgramStateRef getInitialState(const LocationContext *InitLoc);
-
- ASTContext &getContext() { return svalBuilder->getContext(); }
- const ASTContext &getContext() const { return svalBuilder->getContext(); }
-
- BasicValueFactory &getBasicVals() {
- return svalBuilder->getBasicValueFactory();
- }
-
- SValBuilder &getSValBuilder() {
- return *svalBuilder;
- }
-
- SymbolManager &getSymbolManager() {
- return svalBuilder->getSymbolManager();
- }
- const SymbolManager &getSymbolManager() const {
- return svalBuilder->getSymbolManager();
- }
-
- llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
-
- MemRegionManager& getRegionManager() {
- return svalBuilder->getRegionManager();
- }
- const MemRegionManager& getRegionManager() const {
- return svalBuilder->getRegionManager();
- }
-
- CallEventManager &getCallEventManager() { return *CallEventMgr; }
-
- StoreManager& getStoreManager() { return *StoreMgr; }
- ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
- SubEngine* getOwningEngine() { return Eng; }
-
- ProgramStateRef removeDeadBindings(ProgramStateRef St,
- const StackFrameContext *LCtx,
- SymbolReaper& SymReaper);
-
-public:
-
- SVal ArrayToPointer(Loc Array, QualType ElementTy) {
- return StoreMgr->ArrayToPointer(Array, ElementTy);
- }
-
- // Methods that manipulate the GDM.
- ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data);
- ProgramStateRef removeGDM(ProgramStateRef state, void *Key);
-
- // Methods that query & manipulate the Store.
-
- void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) {
- StoreMgr->iterBindings(state->getStore(), F);
- }
-
- ProgramStateRef getPersistentState(ProgramState &Impl);
- ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState,
- ProgramStateRef GDMState);
-
- bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) {
- return S1->Env == S2->Env;
- }
-
- bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) {
- return S1->store == S2->store;
- }
-
- //==---------------------------------------------------------------------==//
- // Generic Data Map methods.
- //==---------------------------------------------------------------------==//
- //
- // ProgramStateManager and ProgramState support a "generic data map" that allows
- // different clients of ProgramState objects to embed arbitrary data within a
- // ProgramState object. The generic data map is essentially an immutable map
- // from a "tag" (that acts as the "key" for a client) and opaque values.
- // Tags/keys and values are simply void* values. The typical way that clients
- // generate unique tags are by taking the address of a static variable.
- // Clients are responsible for ensuring that data values referred to by a
- // the data pointer are immutable (and thus are essentially purely functional
- // data).
- //
- // The templated methods below use the ProgramStateTrait<T> class
- // to resolve keys into the GDM and to return data values to clients.
- //
-
- // Trait based GDM dispatch.
- template <typename T>
- ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait<T>::data_type D) {
- return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
- ProgramStateTrait<T>::MakeVoidPtr(D));
- }
-
- template<typename T>
- ProgramStateRef set(ProgramStateRef st,
- typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::value_type V,
- typename ProgramStateTrait<T>::context_type C) {
-
- return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
- ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C)));
- }
-
- template <typename T>
- ProgramStateRef add(ProgramStateRef st,
- typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::context_type C) {
- return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
- ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C)));
- }
-
- template <typename T>
- ProgramStateRef remove(ProgramStateRef st,
- typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::context_type C) {
-
- return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
- ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C)));
- }
-
- template <typename T>
- ProgramStateRef remove(ProgramStateRef st) {
- return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
- }
-
- void *FindGDMContext(void *index,
- void *(*CreateContext)(llvm::BumpPtrAllocator&),
- void (*DeleteContext)(void*));
-
- template <typename T>
- typename ProgramStateTrait<T>::context_type get_context() {
- void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(),
- ProgramStateTrait<T>::CreateContext,
- ProgramStateTrait<T>::DeleteContext);
-
- return ProgramStateTrait<T>::MakeContext(p);
- }
-
- void EndPath(ProgramStateRef St) {
- ConstraintMgr->EndPath(St);
- }
-};
-
-
-//===----------------------------------------------------------------------===//
-// Out-of-line method definitions for ProgramState.
-//===----------------------------------------------------------------------===//
-
-inline ConstraintManager &ProgramState::getConstraintManager() const {
- return stateMgr->getConstraintManager();
-}
-
-inline const VarRegion* ProgramState::getRegion(const VarDecl *D,
- const LocationContext *LC) const
-{
- return getStateManager().getRegionManager().getVarRegion(D, LC);
-}
-
-inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
- bool Assumption) const {
- if (Cond.isUnknown())
- return this;
-
- return getStateManager().ConstraintMgr
- ->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
-}
-
-inline std::pair<ProgramStateRef , ProgramStateRef >
-ProgramState::assume(DefinedOrUnknownSVal Cond) const {
- if (Cond.isUnknown())
- return std::make_pair(this, this);
-
- return getStateManager().ConstraintMgr
- ->assumeDual(this, Cond.castAs<DefinedSVal>());
-}
-
-inline ProgramStateRef
-ProgramState::assumeWithinInclusiveRange(DefinedOrUnknownSVal Val,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool Assumption) const {
- if (Val.isUnknown())
- return this;
-
- assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!");
-
- return getStateManager().ConstraintMgr->assumeWithinInclusiveRange(
- this, Val.castAs<NonLoc>(), From, To, Assumption);
-}
-
-inline std::pair<ProgramStateRef, ProgramStateRef>
-ProgramState::assumeWithinInclusiveRange(DefinedOrUnknownSVal Val,
- const llvm::APSInt &From,
- const llvm::APSInt &To) const {
- if (Val.isUnknown())
- return std::make_pair(this, this);
-
- assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!");
-
- return getStateManager().ConstraintMgr
- ->assumeWithinInclusiveRangeDual(this, Val.castAs<NonLoc>(), From, To);
-}
-
-inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
- if (Optional<Loc> L = LV.getAs<Loc>())
- return bindLoc(*L, V);
- return this;
-}
-
-inline Loc ProgramState::getLValue(const VarDecl *VD,
- const LocationContext *LC) const {
- return getStateManager().StoreMgr->getLValueVar(VD, LC);
-}
-
-inline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal,
- const LocationContext *LC) const {
- return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
-}
-
-inline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
- return getStateManager().StoreMgr->getLValueIvar(D, Base);
-}
-
-inline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const {
- return getStateManager().StoreMgr->getLValueField(D, Base);
-}
-
-inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
- SVal Base) const {
- StoreManager &SM = *getStateManager().StoreMgr;
- for (const auto *I : D->chain()) {
- Base = SM.getLValueField(cast<FieldDecl>(I), Base);
- }
-
- return Base;
-}
-
-inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
- if (Optional<NonLoc> N = Idx.getAs<NonLoc>())
- return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
- return UnknownVal();
-}
-
-inline SVal ProgramState::getSVal(const Stmt *Ex,
- const LocationContext *LCtx) const{
- return Env.getSVal(EnvironmentEntry(Ex, LCtx),
- *getStateManager().svalBuilder);
-}
-
-inline SVal
-ProgramState::getSValAsScalarOrLoc(const Stmt *S,
- const LocationContext *LCtx) const {
- if (const Expr *Ex = dyn_cast<Expr>(S)) {
- QualType T = Ex->getType();
- if (Ex->isGLValue() || Loc::isLocType(T) ||
- T->isIntegralOrEnumerationType())
- return getSVal(S, LCtx);
- }
-
- return UnknownVal();
-}
-
-inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
- return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
-}
-
-inline SVal ProgramState::getSVal(const MemRegion* R) const {
- return getStateManager().StoreMgr->getBinding(getStore(),
- loc::MemRegionVal(R));
-}
-
-inline BasicValueFactory &ProgramState::getBasicVals() const {
- return getStateManager().getBasicVals();
-}
-
-inline SymbolManager &ProgramState::getSymbolManager() const {
- return getStateManager().getSymbolManager();
-}
-
-template<typename T>
-ProgramStateRef ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
- return getStateManager().add<T>(this, K, get_context<T>());
-}
-
-template <typename T>
-typename ProgramStateTrait<T>::context_type ProgramState::get_context() const {
- return getStateManager().get_context<T>();
-}
-
-template<typename T>
-ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
- return getStateManager().remove<T>(this, K, get_context<T>());
-}
-
-template<typename T>
-ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::context_type C) const {
- return getStateManager().remove<T>(this, K, C);
-}
-
-template <typename T>
-ProgramStateRef ProgramState::remove() const {
- return getStateManager().remove<T>(this);
-}
-
-template<typename T>
-ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
- return getStateManager().set<T>(this, D);
-}
-
-template<typename T>
-ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::value_type E) const {
- return getStateManager().set<T>(this, K, E, get_context<T>());
-}
-
-template<typename T>
-ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::value_type E,
- typename ProgramStateTrait<T>::context_type C) const {
- return getStateManager().set<T>(this, K, E, C);
-}
-
-template <typename CB>
-CB ProgramState::scanReachableSymbols(SVal val) const {
- CB cb(this);
- scanReachableSymbols(val, cb);
- return cb;
-}
-
-template <typename CB>
-CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
- CB cb(this);
- scanReachableSymbols(beg, end, cb);
- return cb;
-}
-
-template <typename CB>
-CB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
- const MemRegion * const *end) const {
- CB cb(this);
- scanReachableSymbols(beg, end, cb);
- return cb;
-}
-
-/// \class ScanReachableSymbols
-/// A Utility class that allows to visit the reachable symbols using a custom
-/// SymbolVisitor.
-class ScanReachableSymbols {
- typedef llvm::DenseSet<const void*> VisitedItems;
-
- VisitedItems visited;
- ProgramStateRef state;
- SymbolVisitor &visitor;
-public:
-
- ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v)
- : state(st), visitor(v) {}
-
- bool scan(nonloc::LazyCompoundVal val);
- bool scan(nonloc::CompoundVal val);
- bool scan(SVal val);
- bool scan(const MemRegion *R);
- bool scan(const SymExpr *sym);
-};
-
-} // end ento namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
deleted file mode 100644
index 6b4da7d..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ /dev/null
@@ -1,245 +0,0 @@
-//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- 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 partial implementations of template specializations of
-// the class ProgramStateTrait<>. ProgramStateTrait<> is used by ProgramState
-// to implement set/get methods for manipulating a ProgramState's
-// generic data map.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_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;
-}
-
-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.
- /// 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; \
- } \
- namespace clang { \
- namespace ento { \
- template <> \
- struct ProgramStateTrait<Name> \
- : public ProgramStatePartialTrait<Name ## Ty> { \
- static void *GDMIndex() { static int Index; return &Index; } \
- }; \
- } \
- }
-
-
- // 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)
- : data_type(nullptr);
- }
- static inline 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){
- return F.add(B, K, E);
- }
-
- static data_type Remove(data_type B, key_type K, context_type F) {
- return F.remove(B, K);
- }
-
- static inline context_type MakeContext(void *p) {
- return *((typename data_type::Factory*) p);
- }
-
- static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
- return new typename data_type::Factory(Alloc);
- }
-
- static void DeleteContext(void *Ctx) {
- delete (typename data_type::Factory*) Ctx;
- }
- };
-
- /// Helper for registering a map trait.
- ///
- /// If the map type were written directly in the invocation of
- /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
- /// would be treated as a macro argument separator, which is wrong.
- /// This allows the user to specify a map type in a way that the preprocessor
- /// 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;
-
- static inline 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) {
- return B.getRoot();
- }
-
- static data_type Add(data_type B, key_type K, context_type F) {
- return F.add(B, K);
- }
-
- static data_type Remove(data_type B, key_type K, context_type F) {
- return F.remove(B, K);
- }
-
- static bool Contains(data_type B, key_type K) {
- return B.contains(K);
- }
-
- static inline context_type MakeContext(void *p) {
- return *((typename data_type::Factory*) p);
- }
-
- static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
- return new typename data_type::Factory(Alloc);
- }
-
- static void DeleteContext(void *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;
-
- static data_type Add(data_type L, key_type K, context_type F) {
- return F.add(K, L);
- }
-
- static bool Contains(data_type L, key_type K) {
- return L.contains(K);
- }
-
- static inline 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) {
- return const_cast<llvm::ImmutableListImpl<T> *>(D.getInternalPointer());
- }
-
- static inline context_type MakeContext(void *p) {
- return *((typename data_type::Factory*) p);
- }
-
- static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
- return new typename data_type::Factory(Alloc);
- }
-
- static void DeleteContext(void *Ctx) {
- delete (typename data_type::Factory*) Ctx;
- }
- };
-
-
- // Partial specialization for bool.
- template <> struct ProgramStatePartialTrait<bool> {
- typedef bool data_type;
-
- static inline 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;
- }
- };
-
- // Partial specialization for unsigned.
- template <> struct ProgramStatePartialTrait<unsigned> {
- typedef unsigned data_type;
-
- static inline 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;
- }
- };
-
- // Partial specialization for void*.
- template <> struct ProgramStatePartialTrait<void*> {
- typedef void *data_type;
-
- static inline data_type MakeData(void *const* p) {
- return p ? *p
- : data_type();
- }
- static inline void *MakeVoidPtr(data_type d) {
- return d;
- }
- };
-
- // Partial specialization for const void *.
- template <> struct ProgramStatePartialTrait<const void *> {
- typedef const void *data_type;
-
- static inline data_type MakeData(void * const *p) {
- return p ? *p : data_type();
- }
-
- static inline void *MakeVoidPtr(data_type d) {
- return const_cast<void *>(d);
- }
- };
-
-} // end ento namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
deleted file mode 100644
index 415bb77..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//== ProgramState_Fwd.h - Incomplete declarations of ProgramState -*- 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_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_FWD_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_FWD_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-
-namespace clang {
-namespace ento {
- class ProgramState;
- class ProgramStateManager;
- void ProgramStateRetain(const ProgramState *state);
- void ProgramStateRelease(const ProgramState *state);
-}
-}
-
-namespace llvm {
- template <> struct IntrusiveRefCntPtrInfo<const clang::ento::ProgramState> {
- static void retain(const clang::ento::ProgramState *state) {
- clang::ento::ProgramStateRetain(state);
- }
- static void release(const clang::ento::ProgramState *state) {
- clang::ento::ProgramStateRelease(state);
- }
- };
-}
-
-namespace clang {
-namespace ento {
- typedef IntrusiveRefCntPtr<const ProgramState> ProgramStateRef;
-}
-}
-
-#endif
-
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
deleted file mode 100644
index a68d341..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ /dev/null
@@ -1,333 +0,0 @@
-// SValBuilder.h - Construction of SVals from evaluating expressions -*- 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 SValBuilder, a class that defines the interface for
-// "symbolical evaluators" which construct an SVal from an expression.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALBUILDER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALBUILDER_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-
-namespace clang {
-
-class CXXBoolLiteralExpr;
-
-namespace ento {
-
-class SValBuilder {
- virtual void anchor();
-protected:
- ASTContext &Context;
-
- /// Manager of APSInt values.
- BasicValueFactory BasicVals;
-
- /// Manages the creation of symbols.
- SymbolManager SymMgr;
-
- /// Manages the creation of memory regions.
- MemRegionManager MemMgr;
-
- ProgramStateManager &StateMgr;
-
- /// The scalar type to use for array indices.
- const QualType ArrayIndexTy;
-
- /// The width of the scalar type used for array indices.
- const unsigned ArrayIndexWidth;
-
- virtual SVal evalCastFromNonLoc(NonLoc val, QualType castTy) = 0;
- virtual SVal evalCastFromLoc(Loc val, QualType castTy) = 0;
-
-public:
- // FIXME: Make these protected again once RegionStoreManager correctly
- // handles loads from different bound value types.
- virtual SVal dispatchCast(SVal val, QualType castTy) = 0;
-
-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.IntTy),
- ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
-
- virtual ~SValBuilder() {}
-
- bool haveSameType(const SymExpr *Sym1, const SymExpr *Sym2) {
- return haveSameType(Sym1->getType(), Sym2->getType());
- }
-
- bool haveSameType(QualType Ty1, QualType Ty2) {
- // FIXME: Remove the second disjunct when we support symbolic
- // truncation/extension.
- return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) ||
- (Ty1->isIntegralOrEnumerationType() &&
- Ty2->isIntegralOrEnumerationType()));
- }
-
- SVal evalCast(SVal val, QualType castTy, QualType originalType);
-
- virtual SVal evalMinus(NonLoc val) = 0;
-
- virtual SVal evalComplement(NonLoc val) = 0;
-
- /// Create a new value which represents a binary expression with two non-
- /// location operands.
- virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
- NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
-
- /// Create a new value which represents a binary expression with two memory
- /// location operands.
- virtual SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op,
- Loc lhs, Loc rhs, QualType resultTy) = 0;
-
- /// Create a new value which represents a binary expression with a memory
- /// location and non-location operands. For example, this would be used to
- /// evaluate a pointer arithmetic operation.
- virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
- Loc lhs, NonLoc rhs, QualType resultTy) = 0;
-
- /// Evaluates a given SVal. If the SVal has only one possible (integer) value,
- /// that value is returned. Otherwise, returns NULL.
- virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0;
-
- /// Constructs a symbolic expression for two non-location values.
- SVal makeSymExprValNN(ProgramStateRef state, BinaryOperator::Opcode op,
- NonLoc lhs, NonLoc rhs, QualType resultTy);
-
- SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
- SVal lhs, SVal rhs, QualType type);
-
- DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs,
- DefinedOrUnknownSVal rhs);
-
- ASTContext &getContext() { return Context; }
- const ASTContext &getContext() const { return Context; }
-
- ProgramStateManager &getStateManager() { return StateMgr; }
-
- QualType getConditionType() const {
- return Context.getLangOpts().CPlusPlus ? Context.BoolTy : Context.IntTy;
- }
-
- QualType getArrayIndexType() const {
- return ArrayIndexTy;
- }
-
- BasicValueFactory &getBasicValueFactory() { return BasicVals; }
- const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
-
- SymbolManager &getSymbolManager() { return SymMgr; }
- const SymbolManager &getSymbolManager() const { return SymMgr; }
-
- MemRegionManager &getRegionManager() { return MemMgr; }
- const MemRegionManager &getRegionManager() const { return MemMgr; }
-
- // Forwarding methods to SymbolManager.
-
- const SymbolConjured* conjureSymbol(const Stmt *stmt,
- const LocationContext *LCtx,
- QualType type,
- unsigned visitCount,
- const void *symbolTag = nullptr) {
- return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag);
- }
-
- const SymbolConjured* conjureSymbol(const Expr *expr,
- const LocationContext *LCtx,
- unsigned visitCount,
- const void *symbolTag = nullptr) {
- return SymMgr.conjureSymbol(expr, LCtx, visitCount, symbolTag);
- }
-
- /// Construct an SVal representing '0' for the specified type.
- DefinedOrUnknownSVal makeZeroVal(QualType type);
-
- /// Make a unique symbol for value of region.
- DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region);
-
- /// \brief 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
- /// preserve the relation between related(or even equivalent) expressions, so
- /// conjured symbols should be used sparingly.
- DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag,
- const Expr *expr,
- const LocationContext *LCtx,
- unsigned count);
- DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag,
- const Expr *expr,
- 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.
- ///
- /// Note, the expression should represent a location.
- DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E,
- const LocationContext *LCtx,
- unsigned Count);
-
- DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
- SymbolRef parentSymbol, const TypedValueRegion *region);
-
- DefinedSVal getMetadataSymbolVal(
- const void *symbolTag, const MemRegion *region,
- const Expr *expr, QualType type, unsigned count);
-
- DefinedSVal getFunctionPointer(const FunctionDecl *func);
-
- DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy,
- const LocationContext *locContext,
- unsigned blockCount);
-
- /// Returns the value of \p E, if it can be determined in a non-path-sensitive
- /// manner.
- ///
- /// If \p E is not a constant or cannot be modeled, returns \c None.
- Optional<SVal> getConstantVal(const Expr *E);
-
- NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) {
- return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals));
- }
-
- NonLoc makeLazyCompoundVal(const StoreRef &store,
- const TypedValueRegion *region) {
- return nonloc::LazyCompoundVal(
- BasicVals.getLazyCompoundValData(store, region));
- }
-
- NonLoc makeZeroArrayIndex() {
- return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
- }
-
- NonLoc makeArrayIndex(uint64_t idx) {
- return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
- }
-
- SVal convertToArrayIndex(SVal val);
-
- nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) {
- return nonloc::ConcreteInt(
- BasicVals.getValue(integer->getValue(),
- integer->getType()->isUnsignedIntegerOrEnumerationType()));
- }
-
- nonloc::ConcreteInt makeBoolVal(const ObjCBoolLiteralExpr *boolean) {
- return makeTruthVal(boolean->getValue(), boolean->getType());
- }
-
- nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *boolean);
-
- nonloc::ConcreteInt makeIntVal(const llvm::APSInt& integer) {
- return nonloc::ConcreteInt(BasicVals.getValue(integer));
- }
-
- loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer) {
- return loc::ConcreteInt(BasicVals.getValue(integer));
- }
-
- NonLoc makeIntVal(const llvm::APInt& integer, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getValue(integer, isUnsigned));
- }
-
- DefinedSVal makeIntVal(uint64_t integer, QualType type) {
- if (Loc::isLocType(type))
- return loc::ConcreteInt(BasicVals.getValue(integer, type));
-
- return nonloc::ConcreteInt(BasicVals.getValue(integer, type));
- }
-
- NonLoc makeIntVal(uint64_t integer, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getIntValue(integer, isUnsigned));
- }
-
- NonLoc makeIntValWithPtrWidth(uint64_t integer, bool isUnsigned) {
- return nonloc::ConcreteInt(
- BasicVals.getIntWithPtrWidth(integer, isUnsigned));
- }
-
- NonLoc makeLocAsInteger(Loc loc, unsigned bits) {
- return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits));
- }
-
- NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType type);
-
- NonLoc makeNonLoc(const llvm::APSInt& rhs, BinaryOperator::Opcode op,
- const SymExpr *lhs, QualType type);
-
- NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const SymExpr *rhs, QualType type);
-
- /// \brief Create a NonLoc value for cast.
- NonLoc makeNonLoc(const SymExpr *operand, QualType fromTy, QualType toTy);
-
- nonloc::ConcreteInt makeTruthVal(bool b, QualType type) {
- return nonloc::ConcreteInt(BasicVals.getTruthValue(b, type));
- }
-
- nonloc::ConcreteInt makeTruthVal(bool b) {
- return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
- }
-
- Loc makeNull() {
- return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
- }
-
- Loc makeLoc(SymbolRef sym) {
- return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
- }
-
- Loc makeLoc(const MemRegion* region) {
- return loc::MemRegionVal(region);
- }
-
- Loc makeLoc(const AddrLabelExpr *expr) {
- return loc::GotoLabel(expr->getLabel());
- }
-
- Loc makeLoc(const llvm::APSInt& integer) {
- return loc::ConcreteInt(BasicVals.getValue(integer));
- }
-
- /// Return a memory region for the 'this' object reference.
- loc::MemRegionVal getCXXThis(const CXXMethodDecl *D,
- const StackFrameContext *SFC);
-
- /// Return a memory region for the 'this' object reference.
- loc::MemRegionVal getCXXThis(const CXXRecordDecl *D,
- const StackFrameContext *SFC);
-};
-
-SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
- ASTContext &context,
- ProgramStateManager &stateMgr);
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
deleted file mode 100644
index 642e11a..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ /dev/null
@@ -1,574 +0,0 @@
-//== SVals.h - Abstract Values for Static Analysis ---------*- 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 SVal, Loc, and NonLoc, classes that represent
-// abstract r-values for use with path-sensitive value tracking.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "llvm/ADT/ImmutableList.h"
-
-//==------------------------------------------------------------------------==//
-// Base SVal types.
-//==------------------------------------------------------------------------==//
-
-namespace clang {
-
-namespace ento {
-
-class CompoundValData;
-class LazyCompoundValData;
-class ProgramState;
-class BasicValueFactory;
-class MemRegion;
-class TypedValueRegion;
-class MemRegionManager;
-class ProgramStateManager;
-class SValBuilder;
-
-/// SVal - This represents a symbolic expression, which can be either
-/// an L-value or an R-value.
-///
-class SVal {
-public:
- enum BaseKind {
- // The enumerators must be representable using 2 bits.
- UndefinedKind = 0, // for subclass UndefinedVal (an uninitialized value)
- UnknownKind = 1, // for subclass UnknownVal (a void value)
- LocKind = 2, // for subclass Loc (an L-value)
- NonLocKind = 3 // for subclass NonLoc (an R-value that's not
- // an L-value)
- };
- enum { BaseBits = 2, BaseMask = 0x3 };
-
-protected:
- const void *Data;
-
- /// The lowest 2 bits are a BaseKind (0 -- 3).
- /// The higher bits are an unsigned "kind" value.
- unsigned Kind;
-
- explicit SVal(const void *d, bool isLoc, unsigned ValKind)
- : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
-
- explicit SVal(BaseKind k, const void *D = nullptr)
- : Data(D), Kind(k) {}
-
-public:
- explicit SVal() : Data(nullptr), Kind(0) {}
-
- /// \brief Convert to the specified SVal type, asserting that this SVal is of
- /// the desired type.
- template<typename T>
- T castAs() const {
- assert(T::isKind(*this));
- T t;
- SVal& sv = t;
- sv = *this;
- return t;
- }
-
- /// \brief Convert to the specified SVal type, returning None if this SVal is
- /// not of the desired type.
- template<typename T>
- Optional<T> getAs() const {
- if (!T::isKind(*this))
- return None;
- T t;
- SVal& sv = t;
- sv = *this;
- return t;
- }
-
- /// BufferTy - A temporary buffer to hold a set of SVals.
- typedef SmallVector<SVal,5> BufferTy;
-
- inline unsigned getRawKind() const { return Kind; }
- inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
- inline 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 {
- ID.AddInteger((unsigned) getRawKind());
- ID.AddPointer(Data);
- }
-
- inline bool operator==(const SVal& R) const {
- return getRawKind() == R.getRawKind() && Data == R.Data;
- }
-
- inline bool operator!=(const SVal& R) const {
- return !(*this == R);
- }
-
- inline bool isUnknown() const {
- return getRawKind() == UnknownKind;
- }
-
- inline bool isUndef() const {
- return getRawKind() == UndefinedKind;
- }
-
- inline bool isUnknownOrUndef() const {
- return getRawKind() <= UnknownKind;
- }
-
- inline bool isValid() const {
- return getRawKind() > UnknownKind;
- }
-
- bool isConstant() const;
-
- bool isConstant(int I) const;
-
- bool isZeroConstant() const;
-
- /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
- bool hasConjuredSymbol() const;
-
- /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
- /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
- /// Otherwise return 0.
- const FunctionDecl *getAsFunctionDecl() const;
-
- /// \brief If this SVal is a location and wraps a symbol, return that
- /// SymbolRef. Otherwise return 0.
- ///
- /// Casts are ignored during lookup.
- /// \param IncludeBaseRegions The boolean that controls whether the search
- /// should continue to the base regions if the region is not symbolic.
- SymbolRef getAsLocSymbol(bool IncludeBaseRegions = false) const;
-
- /// Get the symbol in the SVal or its base region.
- SymbolRef getLocSymbolInBase() const;
-
- /// \brief If this SVal wraps a symbol return that SymbolRef.
- /// Otherwise, return 0.
- ///
- /// Casts are ignored during lookup.
- /// \param IncludeBaseRegions The boolean that controls whether the search
- /// should continue to the base regions if the region is not symbolic.
- SymbolRef getAsSymbol(bool IncludeBaseRegions = false) const;
-
- /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
- /// return that expression. Otherwise return NULL.
- const SymExpr *getAsSymbolicExpression() const;
-
- const SymExpr* getAsSymExpr() const;
-
- const MemRegion *getAsRegion() const;
-
- void dumpToStream(raw_ostream &OS) const;
- void dump() const;
-
- SymExpr::symbol_iterator symbol_begin() const {
- const SymExpr *SE = getAsSymbolicExpression();
- if (SE)
- return SE->symbol_begin();
- else
- return SymExpr::symbol_iterator();
- }
-
- SymExpr::symbol_iterator symbol_end() const {
- return SymExpr::symbol_end();
- }
-};
-
-
-class UndefinedVal : public SVal {
-public:
- UndefinedVal() : SVal(UndefinedKind) {}
-
-private:
- friend class SVal;
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == UndefinedKind;
- }
-};
-
-class DefinedOrUnknownSVal : public SVal {
-private:
- // 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() {}
- explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
- : 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();
- }
-};
-
-class UnknownVal : public DefinedOrUnknownSVal {
-public:
- explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
-
-private:
- friend class SVal;
- static bool isKind(const SVal &V) {
- return V.getBaseKind() == UnknownKind;
- }
-};
-
-class DefinedSVal : public DefinedOrUnknownSVal {
-private:
- // 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() {}
- explicit DefinedSVal(const void *d, bool isLoc, unsigned 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.
-class KnownSVal : public SVal {
- KnownSVal() {}
- friend class SVal;
- static bool isKind(const SVal &V) {
- return !V.isUnknown();
- }
-public:
- KnownSVal(const DefinedSVal &V) : SVal(V) {}
- KnownSVal(const UndefinedVal &V) : SVal(V) {}
-};
-
-class NonLoc : public DefinedSVal {
-protected:
- NonLoc() {}
- explicit NonLoc(unsigned SubKind, const void *d)
- : DefinedSVal(d, false, SubKind) {}
-
-public:
- void dumpToStream(raw_ostream &Out) const;
-
-private:
- friend class SVal;
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind;
- }
-};
-
-class Loc : public DefinedSVal {
-protected:
- Loc() {}
- explicit Loc(unsigned SubKind, const void *D)
- : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
-
-public:
- void dumpToStream(raw_ostream &Out) const;
-
- static inline 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;
- }
-};
-
-//==------------------------------------------------------------------------==//
-// Subclasses of NonLoc.
-//==------------------------------------------------------------------------==//
-
-namespace nonloc {
-
-enum Kind { ConcreteIntKind, SymbolValKind,
- LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
-
-/// \brief Represents symbolic expression.
-class SymbolVal : public NonLoc {
-public:
- SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
-
- SymbolRef getSymbol() const {
- return (const SymExpr*) Data;
- }
-
- bool isExpression() const {
- return !isa<SymbolData>(getSymbol());
- }
-
-private:
- friend class SVal;
- SymbolVal() {}
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == SymbolValKind;
- }
-
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == SymbolValKind;
- }
-};
-
-/// \brief 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);
- }
-
- // Transfer functions for binary/unary operations on ConcreteInts.
- SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op,
- const ConcreteInt& R) const;
-
- ConcreteInt evalComplement(SValBuilder &svalBuilder) const;
-
- ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
-
-private:
- friend class SVal;
- ConcreteInt() {}
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == ConcreteIntKind;
- }
-
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == ConcreteIntKind;
- }
-};
-
-class LocAsInteger : public NonLoc {
- friend class ento::SValBuilder;
-
- explicit LocAsInteger(const std::pair<SVal, uintptr_t> &data)
- : NonLoc(LocAsIntegerKind, &data) {
- assert (data.first.getAs<Loc>());
- }
-
-public:
-
- Loc getLoc() const {
- const std::pair<SVal, uintptr_t> *D =
- static_cast<const std::pair<SVal, uintptr_t> *>(Data);
- return D->first.castAs<Loc>();
- }
-
- Loc getPersistentLoc() const {
- const std::pair<SVal, uintptr_t> *D =
- static_cast<const std::pair<SVal, uintptr_t> *>(Data);
- const SVal& V = D->first;
- return V.castAs<Loc>();
- }
-
- unsigned getNumBits() const {
- const std::pair<SVal, uintptr_t> *D =
- static_cast<const std::pair<SVal, uintptr_t> *>(Data);
- return D->second;
- }
-
-private:
- friend class SVal;
- LocAsInteger() {}
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == LocAsIntegerKind;
- }
-
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == LocAsIntegerKind;
- }
-};
-
-class CompoundVal : public NonLoc {
- friend class ento::SValBuilder;
-
- explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
-
-public:
- const CompoundValData* getValue() const {
- return static_cast<const CompoundValData*>(Data);
- }
-
- typedef llvm::ImmutableList<SVal>::iterator iterator;
- iterator begin() const;
- iterator end() const;
-
-private:
- friend class SVal;
- CompoundVal() {}
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind && V.getSubKind() == CompoundValKind;
- }
-
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == CompoundValKind;
- }
-};
-
-class LazyCompoundVal : public NonLoc {
- friend class ento::SValBuilder;
-
- explicit LazyCompoundVal(const LazyCompoundValData *D)
- : NonLoc(LazyCompoundValKind, D) {}
-public:
- const LazyCompoundValData *getCVData() const {
- return static_cast<const LazyCompoundValData*>(Data);
- }
- const void *getStore() const;
- const TypedValueRegion *getRegion() const;
-
-private:
- friend class SVal;
- LazyCompoundVal() {}
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == LazyCompoundValKind;
- }
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == LazyCompoundValKind;
- }
-};
-
-} // end namespace ento::nonloc
-
-//==------------------------------------------------------------------------==//
-// Subclasses of Loc.
-//==------------------------------------------------------------------------==//
-
-namespace loc {
-
-enum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind };
-
-class GotoLabel : public Loc {
-public:
- explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {}
-
- const LabelDecl *getLabel() const {
- return static_cast<const LabelDecl*>(Data);
- }
-
-private:
- friend class SVal;
- GotoLabel() {}
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == LocKind && V.getSubKind() == GotoLabelKind;
- }
-
- static bool isKind(const Loc& V) {
- return V.getSubKind() == GotoLabelKind;
- }
-};
-
-
-class MemRegionVal : public Loc {
-public:
- explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
-
- /// \brief Get the underlining region.
- const MemRegion* getRegion() const {
- return static_cast<const MemRegion*>(Data);
- }
-
- /// \brief Get the underlining region and strip casts.
- const MemRegion* stripCasts(bool StripBaseCasts = true) const;
-
- template <typename REGION>
- const REGION* getRegionAs() const {
- return dyn_cast<REGION>(getRegion());
- }
-
- inline bool operator==(const MemRegionVal& R) const {
- return getRegion() == R.getRegion();
- }
-
- inline bool operator!=(const MemRegionVal& R) const {
- return getRegion() != R.getRegion();
- }
-
-private:
- friend class SVal;
- MemRegionVal() {}
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == LocKind &&
- V.getSubKind() == MemRegionKind;
- }
-
- static bool isKind(const Loc& V) {
- return V.getSubKind() == MemRegionKind;
- }
-};
-
-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);
- }
-
- // Transfer functions for binary/unary operations on ConcreteInts.
- SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
- const ConcreteInt& R) const;
-
-private:
- friend class SVal;
- ConcreteInt() {}
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == LocKind &&
- V.getSubKind() == ConcreteIntKind;
- }
-
- static bool isKind(const Loc& V) {
- return V.getSubKind() == ConcreteIntKind;
- }
-};
-
-} // end ento::loc namespace
-
-} // end ento namespace
-
-} // end clang namespace
-
-namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
- clang::ento::SVal V) {
- V.dumpToStream(os);
- return os;
-}
-
-template <typename T> struct isPodLike;
-template <> struct isPodLike<clang::ento::SVal> {
- static const bool value = true;
-};
-
-} // end llvm namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
deleted file mode 100644
index a03b630..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ /dev/null
@@ -1,288 +0,0 @@
-//== Store.h - Interface for maps from Locations to Values ------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the types Store and StoreManager.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
-
-namespace clang {
-
-class Stmt;
-class Expr;
-class ObjCIvarDecl;
-class CXXBasePath;
-class StackFrameContext;
-
-namespace ento {
-
-class CallEvent;
-class ProgramState;
-class ProgramStateManager;
-class ScanReachableSymbols;
-
-typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
-
-class StoreManager {
-protected:
- SValBuilder &svalBuilder;
- ProgramStateManager &StateMgr;
-
- /// MRMgr - Manages region objects associated with this StoreManager.
- MemRegionManager &MRMgr;
- ASTContext &Ctx;
-
- StoreManager(ProgramStateManager &stateMgr);
-
-public:
- virtual ~StoreManager() {}
-
- /// Return the value bound to specified location in a given state.
- /// \param[in] store The analysis state.
- /// \param[in] loc The symbolic memory location.
- /// \param[in] T An optional type that provides a hint indicating the
- /// expected type of the returned value. This is used if the value is
- /// lazily computed.
- /// \return The value bound to the location \c loc.
- virtual SVal getBinding(Store store, Loc loc, QualType T = QualType()) = 0;
-
- /// Return a state with the specified value bound to the given location.
- /// \param[in] store The analysis state.
- /// \param[in] loc The symbolic memory location.
- /// \param[in] val The value to bind to location \c loc.
- /// \return A pointer to a ProgramState object that contains the same
- /// bindings as \c state with the addition of having the value specified
- /// 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);
-
- /// \brief 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;
-
- /// getInitialStore - Returns the initial "empty" store representing the
- /// value bindings upon entry to an analyzed function.
- virtual StoreRef getInitialStore(const LocationContext *InitLoc) = 0;
-
- /// getRegionManager - Returns the internal RegionManager object that is
- /// used to query and manipulate MemRegion objects.
- MemRegionManager& getRegionManager() { return MRMgr; }
-
- virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) {
- return svalBuilder.makeLoc(MRMgr.getVarRegion(VD, LC));
- }
-
- Loc getLValueCompoundLiteral(const CompoundLiteralExpr *CL,
- const LocationContext *LC) {
- return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
- }
-
- virtual SVal getLValueIvar(const ObjCIvarDecl *decl, SVal base);
-
- virtual SVal getLValueField(const FieldDecl *D, SVal Base) {
- return getLValueFieldOrIvar(D, Base);
- }
-
- virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base);
-
- // FIXME: This should soon be eliminated altogether; clients should deal with
- // region extents directly.
- virtual DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state,
- const MemRegion *region,
- QualType EleTy) {
- return UnknownVal();
- }
-
- /// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit
- /// conversions between arrays and pointers.
- virtual SVal ArrayToPointer(Loc Array, QualType ElementTy) = 0;
-
- /// Evaluates a chain of derived-to-base casts through the path specified in
- /// \p Cast.
- SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast);
-
- /// Evaluates a chain of derived-to-base casts through the specified path.
- SVal evalDerivedToBase(SVal Derived, const CXXBasePath &CastPath);
-
- /// Evaluates a derived-to-base cast through a single level of derivation.
- SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType,
- bool IsVirtual);
-
- /// \brief Evaluates C++ dynamic_cast cast.
- /// The callback may result in the following 3 scenarios:
- /// - Successful cast (ex: derived is subclass of base).
- /// - Failed cast (ex: derived is definitely not a subclass of base).
- /// - We don't know (base is a symbolic region and we don't have
- /// enough info to determine if the cast will succeed at run time).
- /// The function returns an SVal representing the derived class; it's
- /// valid only if Failed flag is set to false.
- SVal evalDynamicCast(SVal Base, QualType DerivedPtrType, bool &Failed);
-
- const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
-
- /// castRegion - Used by ExprEngine::VisitCast to handle casts from
- /// a MemRegion* to a specific location type. 'R' is the region being
- /// casted and 'CastToTy' the result type of the cast.
- const MemRegion *castRegion(const MemRegion *region, QualType CastToTy);
-
- virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
- SymbolReaper& SymReaper) = 0;
-
- virtual bool includedInBindings(Store store,
- const MemRegion *region) const = 0;
-
- /// If the StoreManager supports it, increment the reference count of
- /// the specified Store object.
- virtual void incrementReferenceCount(Store store) {}
-
- /// If the StoreManager supports it, decrement the reference count of
- /// the specified Store object. If the reference count hits 0, the memory
- /// associated with the object is recycled.
- virtual void decrementReferenceCount(Store store) {}
-
- typedef SmallVector<const MemRegion *, 8> InvalidatedRegions;
-
- /// invalidateRegions - Clears out the specified regions from the store,
- /// marking their values as unknown. Depending on the store, this may also
- /// invalidate additional regions that may have changed based on accessing
- /// the given regions. Optionally, invalidates non-static globals as well.
- /// \param[in] store The initial store
- /// \param[in] Values The values to invalidate.
- /// \param[in] E The current statement being evaluated. Used to conjure
- /// symbols to mark the values of invalidated regions.
- /// \param[in] Count The current block count. Used to conjure
- /// symbols to mark the values of invalidated regions.
- /// \param[in] Call The call expression which will be used to determine which
- /// globals should get invalidated.
- /// \param[in,out] IS A set to fill with any symbols that are no longer
- /// accessible. Pass \c NULL if this information will not be used.
- /// \param[in] ITraits Information about invalidation for a particular
- /// region/symbol.
- /// \param[in,out] InvalidatedTopLevel A vector to fill with regions
- //// explicitly being invalidated. Pass \c NULL if this
- /// information will not be used.
- /// \param[in,out] Invalidated A vector to fill with any regions being
- /// invalidated. This should include any regions explicitly invalidated
- /// even if they do not currently have bindings. Pass \c NULL if this
- /// information will not be used.
- virtual StoreRef invalidateRegions(Store store,
- ArrayRef<SVal> Values,
- const Expr *E, unsigned Count,
- const LocationContext *LCtx,
- const CallEvent *Call,
- InvalidatedSymbols &IS,
- RegionAndSymbolInvalidationTraits &ITraits,
- InvalidatedRegions *InvalidatedTopLevel,
- InvalidatedRegions *Invalidated) = 0;
-
- /// enterStackFrame - Let the StoreManager to do something when execution
- /// engine is about to execute into a callee.
- StoreRef enterStackFrame(Store store,
- const CallEvent &Call,
- const StackFrameContext *CalleeCtx);
-
- /// Finds the transitive closure of symbols within the given region.
- ///
- /// Returns false if the visitor aborted the scan.
- virtual bool scanReachableSymbols(Store S, const MemRegion *R,
- ScanReachableSymbols &Visitor) = 0;
-
- virtual void print(Store store, raw_ostream &Out,
- const char* nl, const char *sep) = 0;
-
- class BindingsHandler {
- public:
- virtual ~BindingsHandler();
- virtual bool HandleBinding(StoreManager& SMgr, Store store,
- const MemRegion *region, SVal val) = 0;
- };
-
- class FindUniqueBinding :
- public BindingsHandler {
- SymbolRef Sym;
- const MemRegion* Binding;
- bool First;
-
- public:
- FindUniqueBinding(SymbolRef sym)
- : Sym(sym), Binding(nullptr), First(true) {}
-
- bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
- SVal val) override;
- explicit operator bool() { return First && Binding; }
- const MemRegion *getRegion() { return Binding; }
- };
-
- /// iterBindings - Iterate over the bindings in the Store.
- virtual void iterBindings(Store store, BindingsHandler& f) = 0;
-
-protected:
- const MemRegion *MakeElementRegion(const MemRegion *baseRegion,
- QualType pointeeTy, uint64_t index = 0);
-
- /// 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);
-
-private:
- SVal getLValueFieldOrIvar(const Decl *decl, SVal base);
-};
-
-
-inline StoreRef::StoreRef(Store store, StoreManager & smgr)
- : store(store), mgr(smgr) {
- if (store)
- mgr.incrementReferenceCount(store);
-}
-
-inline StoreRef::StoreRef(const StoreRef &sr)
- : store(sr.store), mgr(sr.mgr)
-{
- if (store)
- mgr.incrementReferenceCount(store);
-}
-
-inline StoreRef::~StoreRef() {
- if (store)
- mgr.decrementReferenceCount(store);
-}
-
-inline StoreRef &StoreRef::operator=(StoreRef const &newStore) {
- assert(&newStore.mgr == &mgr);
- if (store != newStore.store) {
- mgr.incrementReferenceCount(newStore.store);
- mgr.decrementReferenceCount(store);
- store = newStore.getStore();
- }
- return *this;
-}
-
-// FIXME: Do we need to pass ProgramStateManager anymore?
-std::unique_ptr<StoreManager>
-CreateRegionStoreManager(ProgramStateManager &StMgr);
-std::unique_ptr<StoreManager>
-CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr);
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
deleted file mode 100644
index 958c8c3..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//== StoreRef.h - Smart pointer for store objects ---------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the type StoreRef.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STOREREF_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STOREREF_H
-
-#include <cassert>
-
-namespace clang {
-namespace ento {
-
-/// 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;
-
-class StoreRef {
- Store store;
- StoreManager &mgr;
-public:
- StoreRef(Store, StoreManager &);
- StoreRef(const StoreRef &);
- StoreRef &operator=(StoreRef const &);
-
- 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
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
deleted file mode 100644
index 741ba0e..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ /dev/null
@@ -1,162 +0,0 @@
-//== SubEngine.h - Interface of the subengine of CoreEngine --------*- 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 interface of a subengine of the CoreEngine.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H
-
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
-
-namespace clang {
-
-class CFGBlock;
-class CFGElement;
-class LocationContext;
-class Stmt;
-
-namespace ento {
-
-struct NodeBuilderContext;
-class AnalysisManager;
-class ExplodedNodeSet;
-class ExplodedNode;
-class ProgramState;
-class ProgramStateManager;
-class BlockCounter;
-class BranchNodeBuilder;
-class IndirectGotoNodeBuilder;
-class SwitchNodeBuilder;
-class EndOfFunctionNodeBuilder;
-class NodeBuilderWithSinks;
-class MemRegion;
-
-class SubEngine {
- virtual void anchor();
-public:
- virtual ~SubEngine() {}
-
- virtual ProgramStateRef getInitialState(const LocationContext *InitLoc) = 0;
-
- virtual AnalysisManager &getAnalysisManager() = 0;
-
- virtual ProgramStateManager &getStateManager() = 0;
-
- /// Called by CoreEngine. Used to generate new successor
- /// nodes by processing the 'effects' of a block-level statement.
- virtual void processCFGElement(const CFGElement E, ExplodedNode* Pred,
- unsigned StmtIdx, NodeBuilderContext *Ctx)=0;
-
- /// Called by CoreEngine when it starts processing a CFGBlock. The
- /// SubEngine is expected to populate dstNodes with new nodes representing
- /// updated analysis state, or generate no nodes at all if it doesn't.
- virtual void processCFGBlockEntrance(const BlockEdge &L,
- NodeBuilderWithSinks &nodeBuilder,
- ExplodedNode *Pred) = 0;
-
- /// Called by CoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a branch condition.
- virtual void processBranch(const Stmt *Condition, const Stmt *Term,
- NodeBuilderContext& BuilderCtx,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst,
- const CFGBlock *DstT,
- const CFGBlock *DstF) = 0;
-
- /// Called by CoreEngine.
- /// Used to generate successor nodes for temporary destructors depending
- /// on whether the corresponding constructor was visited.
- virtual void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
- NodeBuilderContext &BldCtx,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst,
- const CFGBlock *DstT,
- const CFGBlock *DstF) = 0;
-
- /// Called by CoreEngine. Used to processing branching behavior
- /// at static initalizers.
- virtual void processStaticInitializer(const DeclStmt *DS,
- NodeBuilderContext& BuilderCtx,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst,
- const CFGBlock *DstT,
- const CFGBlock *DstF) = 0;
-
- /// Called by CoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a computed goto jump.
- virtual void processIndirectGoto(IndirectGotoNodeBuilder& builder) = 0;
-
- /// Called by CoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a switch statement.
- virtual void processSwitch(SwitchNodeBuilder& builder) = 0;
-
- /// Called by CoreEngine. Used to generate end-of-path
- /// nodes when the control reaches the end of a function.
- virtual void processEndOfFunction(NodeBuilderContext& BC,
- ExplodedNode *Pred) = 0;
-
- // Generate the entry node of the callee.
- virtual void processCallEnter(CallEnter CE, ExplodedNode *Pred) = 0;
-
- // Generate the first post callsite node.
- virtual void processCallExit(ExplodedNode *Pred) = 0;
-
- /// Called by ConstraintManager. Used to call checker-specific
- /// logic for handling assumptions on symbolic values.
- virtual ProgramStateRef processAssume(ProgramStateRef state,
- SVal cond, bool assumption) = 0;
-
- /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
- /// region change should trigger a processRegionChanges update.
- virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0;
-
- /// processRegionChanges - Called by ProgramStateManager whenever a change is
- /// made to the store. Used to update checkers that track region values.
- virtual ProgramStateRef
- processRegionChanges(ProgramStateRef state,
- const InvalidatedSymbols *invalidated,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) = 0;
-
-
- inline ProgramStateRef
- processRegionChange(ProgramStateRef state,
- const MemRegion* MR) {
- return processRegionChanges(state, nullptr, MR, MR, nullptr);
- }
-
- virtual ProgramStateRef
- processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0;
-
- virtual ProgramStateRef
- notifyCheckersOfPointerEscape(ProgramStateRef State,
- const InvalidatedSymbols *Invalidated,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call,
- RegionAndSymbolInvalidationTraits &HTraits) = 0;
-
- /// printState - Called by ProgramStateManager to print checker-specific data.
- virtual void printState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep) = 0;
-
- /// Called by CoreEngine when the analysis worklist is either empty or the
- // maximum number of analysis steps have been reached.
- virtual void processEndWorklist(bool hasWorkRemaining) = 0;
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
deleted file mode 100644
index ed87851..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//== SummaryManager.h - Generic handling of function summaries --*- 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 SummaryManager and related classes, which provides
-// a generic mechanism for managing function summaries.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_GR_SUMMARY
-#define LLVM_CLANG_GR_SUMMARY
-
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
-
-namespace clang {
-
-namespace ento {
-
-namespace summMgr {
-
-
-/* Key kinds:
-
- - C functions
- - C++ functions (name + parameter types)
- - ObjC methods:
- - Class, selector (class method)
- - Class, selector (instance method)
- - Category, selector (instance method)
- - Protocol, selector (instance method)
- - C++ methods
- - Class, function name + parameter types + const
- */
-
-class SummaryKey {
-
-};
-
-} // end namespace clang::summMgr
-
-class SummaryManagerImpl {
-
-};
-
-
-template <typename T>
-class SummaryManager : SummaryManagerImpl {
-
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
deleted file mode 100644
index 9dbfab2..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ /dev/null
@@ -1,681 +0,0 @@
-//== SymbolManager.h - Management of Symbolic Values ------------*- 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 SymbolManager, a class that manages symbolic values
-// created for use by ExprEngine and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#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/Analysis/AnalysisContext.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace clang {
- class ASTContext;
- class StackFrameContext;
-
-namespace ento {
- class BasicValueFactory;
- class MemRegion;
- class SubRegion;
- class TypedValueRegion;
- class VarRegion;
-
-/// \brief Symbolic value. These values used to capture symbolic execution of
-/// the program.
-class SymExpr : public llvm::FoldingSetNode {
- virtual void anchor();
-public:
- enum Kind { RegionValueKind, ConjuredKind, DerivedKind, ExtentKind,
- MetadataKind,
- BEGIN_SYMBOLS = RegionValueKind,
- END_SYMBOLS = MetadataKind,
- SymIntKind, IntSymKind, SymSymKind,
- BEGIN_BINARYSYMEXPRS = SymIntKind,
- END_BINARYSYMEXPRS = SymSymKind,
- CastSymbolKind };
-private:
- Kind K;
-
-protected:
- SymExpr(Kind k) : K(k) {}
-
-public:
- virtual ~SymExpr() {}
-
- Kind getKind() const { return K; }
-
- virtual void dump() const;
-
- virtual void dumpToStream(raw_ostream &os) const {}
-
- virtual QualType getType() const = 0;
- virtual void Profile(llvm::FoldingSetNodeID& profile) = 0;
-
- /// \brief 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(const SymExpr *SE);
-
- symbol_iterator &operator++();
- const SymExpr* operator*();
-
- bool operator==(const symbol_iterator &X) const;
- bool operator!=(const symbol_iterator &X) const;
- };
-
- symbol_iterator symbol_begin() const {
- return symbol_iterator(this);
- }
- static symbol_iterator symbol_end() { return symbol_iterator(); }
-
- unsigned computeComplexity() const;
-};
-
-typedef const SymExpr* SymbolRef;
-typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
-
-typedef unsigned SymbolID;
-/// \brief A symbol representing data which can be stored in a memory location
-/// (region).
-class SymbolData : public SymExpr {
- void anchor() override;
- const SymbolID Sym;
-
-protected:
- SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {}
-
-public:
- ~SymbolData() override {}
-
- SymbolID getSymbolID() const { return Sym; }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- Kind k = SE->getKind();
- return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS;
- }
-};
-
-///\brief A symbol representing the value stored at a MemRegion.
-class SymbolRegionValue : public SymbolData {
- const TypedValueRegion *R;
-
-public:
- SymbolRegionValue(SymbolID sym, const TypedValueRegion *r)
- : SymbolData(RegionValueKind, sym), R(r) {}
-
- const TypedValueRegion* getRegion() const { return R; }
-
- static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) {
- profile.AddInteger((unsigned) RegionValueKind);
- profile.AddPointer(R);
- }
-
- void Profile(llvm::FoldingSetNodeID& profile) override {
- Profile(profile, R);
- }
-
- void dumpToStream(raw_ostream &os) const override;
-
- QualType getType() const override;
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == RegionValueKind;
- }
-};
-
-/// A symbol representing the result of an expression in the case when we do
-/// not know anything about what the expression is.
-class SymbolConjured : public SymbolData {
- const Stmt *S;
- QualType T;
- unsigned Count;
- const LocationContext *LCtx;
- const void *SymbolTag;
-
-public:
- SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx,
- QualType t, unsigned count,
- const void *symbolTag)
- : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count),
- LCtx(lctx),
- SymbolTag(symbolTag) {}
-
- const Stmt *getStmt() const { return S; }
- unsigned getCount() const { return Count; }
- const void *getTag() const { return SymbolTag; }
-
- QualType getType() const override;
-
- void dumpToStream(raw_ostream &os) const override;
-
- static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S,
- QualType T, unsigned Count, const LocationContext *LCtx,
- const void *SymbolTag) {
- profile.AddInteger((unsigned) ConjuredKind);
- profile.AddPointer(S);
- profile.AddPointer(LCtx);
- profile.Add(T);
- profile.AddInteger(Count);
- profile.AddPointer(SymbolTag);
- }
-
- void Profile(llvm::FoldingSetNodeID& profile) override {
- Profile(profile, S, T, Count, LCtx, SymbolTag);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == ConjuredKind;
- }
-};
-
-/// A symbol representing the value of a MemRegion whose parent region has
-/// symbolic value.
-class SymbolDerived : public SymbolData {
- SymbolRef parentSymbol;
- const TypedValueRegion *R;
-
-public:
- SymbolDerived(SymbolID sym, SymbolRef parent, const TypedValueRegion *r)
- : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {}
-
- SymbolRef getParentSymbol() const { return parentSymbol; }
- const TypedValueRegion *getRegion() const { return R; }
-
- QualType getType() const override;
-
- void dumpToStream(raw_ostream &os) const override;
-
- static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
- const TypedValueRegion *r) {
- profile.AddInteger((unsigned) DerivedKind);
- profile.AddPointer(r);
- profile.AddPointer(parent);
- }
-
- void Profile(llvm::FoldingSetNodeID& profile) override {
- Profile(profile, parentSymbol, R);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == DerivedKind;
- }
-};
-
-/// SymbolExtent - Represents the extent (size in bytes) of a bounded region.
-/// Clients should not ask the SymbolManager for a region's extent. Always use
-/// SubRegion::getExtent instead -- the value returned may not be a symbol.
-class SymbolExtent : public SymbolData {
- const SubRegion *R;
-
-public:
- SymbolExtent(SymbolID sym, const SubRegion *r)
- : SymbolData(ExtentKind, sym), R(r) {}
-
- const SubRegion *getRegion() const { return R; }
-
- QualType getType() const override;
-
- void dumpToStream(raw_ostream &os) const override;
-
- static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) {
- profile.AddInteger((unsigned) ExtentKind);
- profile.AddPointer(R);
- }
-
- void Profile(llvm::FoldingSetNodeID& profile) override {
- Profile(profile, R);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == ExtentKind;
- }
-};
-
-/// SymbolMetadata - Represents path-dependent metadata about a specific region.
-/// Metadata symbols remain live as long as they are marked as in use before
-/// dead-symbol sweeping AND their associated regions are still alive.
-/// Intended for use by checkers.
-class SymbolMetadata : public SymbolData {
- const MemRegion* R;
- const Stmt *S;
- QualType T;
- unsigned Count;
- const void *Tag;
-public:
- SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t,
- unsigned count, const void *tag)
- : SymbolData(MetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {}
-
- const MemRegion *getRegion() const { return R; }
- const Stmt *getStmt() const { return S; }
- unsigned getCount() const { return Count; }
- const void *getTag() const { return Tag; }
-
- QualType getType() const override;
-
- void dumpToStream(raw_ostream &os) const override;
-
- static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R,
- const Stmt *S, QualType T, unsigned Count,
- const void *Tag) {
- profile.AddInteger((unsigned) MetadataKind);
- profile.AddPointer(R);
- profile.AddPointer(S);
- profile.Add(T);
- profile.AddInteger(Count);
- profile.AddPointer(Tag);
- }
-
- void Profile(llvm::FoldingSetNodeID& profile) override {
- Profile(profile, R, S, T, Count, Tag);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == MetadataKind;
- }
-};
-
-/// \brief Represents a cast expression.
-class SymbolCast : public SymExpr {
- const SymExpr *Operand;
- /// Type of the operand.
- QualType FromTy;
- /// The type of the result.
- QualType ToTy;
-
-public:
- SymbolCast(const SymExpr *In, QualType From, QualType To) :
- SymExpr(CastSymbolKind), Operand(In), FromTy(From), ToTy(To) { }
-
- QualType getType() const override { return ToTy; }
-
- const SymExpr *getOperand() const { return Operand; }
-
- void dumpToStream(raw_ostream &os) const override;
-
- static void Profile(llvm::FoldingSetNodeID& ID,
- const SymExpr *In, QualType From, QualType To) {
- ID.AddInteger((unsigned) CastSymbolKind);
- ID.AddPointer(In);
- ID.Add(From);
- ID.Add(To);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) override {
- Profile(ID, Operand, FromTy, ToTy);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == CastSymbolKind;
- }
-};
-
-/// \brief Represents a symbolic expression involving a binary operator
-class BinarySymExpr : public SymExpr {
- BinaryOperator::Opcode Op;
- QualType T;
-
-protected:
- BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t)
- : SymExpr(k), Op(op), T(t) {}
-
-public:
- // FIXME: We probably need to make this out-of-line to avoid redundant
- // generation of virtual functions.
- QualType getType() const override { return T; }
-
- BinaryOperator::Opcode getOpcode() const { return Op; }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- Kind k = SE->getKind();
- return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS;
- }
-};
-
-/// \brief Represents a symbolic expression like 'x' + 3.
-class SymIntExpr : public BinarySymExpr {
- const SymExpr *LHS;
- const llvm::APSInt& RHS;
-
-public:
- SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t)
- : BinarySymExpr(SymIntKind, op, t), LHS(lhs), RHS(rhs) {}
-
- void dumpToStream(raw_ostream &os) const override;
-
- const SymExpr *getLHS() const { return LHS; }
- const llvm::APSInt &getRHS() const { return RHS; }
-
- static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
- BinaryOperator::Opcode op, const llvm::APSInt& rhs,
- QualType t) {
- ID.AddInteger((unsigned) SymIntKind);
- ID.AddPointer(lhs);
- ID.AddInteger(op);
- ID.AddPointer(&rhs);
- ID.Add(t);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) override {
- Profile(ID, LHS, getOpcode(), RHS, getType());
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == SymIntKind;
- }
-};
-
-/// \brief Represents a symbolic expression like 3 - 'x'.
-class IntSymExpr : public BinarySymExpr {
- const llvm::APSInt& LHS;
- const SymExpr *RHS;
-
-public:
- IntSymExpr(const llvm::APSInt& lhs, BinaryOperator::Opcode op,
- const SymExpr *rhs, QualType t)
- : BinarySymExpr(IntSymKind, op, t), LHS(lhs), RHS(rhs) {}
-
- void dumpToStream(raw_ostream &os) const override;
-
- const SymExpr *getRHS() const { return RHS; }
- const llvm::APSInt &getLHS() const { return LHS; }
-
- static void Profile(llvm::FoldingSetNodeID& ID, const llvm::APSInt& lhs,
- BinaryOperator::Opcode op, const SymExpr *rhs,
- QualType t) {
- ID.AddInteger((unsigned) IntSymKind);
- ID.AddPointer(&lhs);
- ID.AddInteger(op);
- ID.AddPointer(rhs);
- ID.Add(t);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) override {
- Profile(ID, LHS, getOpcode(), RHS, getType());
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == IntSymKind;
- }
-};
-
-/// \brief Represents a symbolic expression like 'x' + 'y'.
-class SymSymExpr : public BinarySymExpr {
- const SymExpr *LHS;
- const SymExpr *RHS;
-
-public:
- SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs,
- QualType t)
- : BinarySymExpr(SymSymKind, op, t), LHS(lhs), RHS(rhs) {}
-
- const SymExpr *getLHS() const { return LHS; }
- const SymExpr *getRHS() const { return RHS; }
-
- void dumpToStream(raw_ostream &os) const override;
-
- static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
- BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) {
- ID.AddInteger((unsigned) SymSymKind);
- ID.AddPointer(lhs);
- ID.AddInteger(op);
- ID.AddPointer(rhs);
- ID.Add(t);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) override {
- Profile(ID, LHS, getOpcode(), RHS, getType());
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
- return SE->getKind() == SymSymKind;
- }
-};
-
-class SymbolManager {
- typedef llvm::FoldingSet<SymExpr> DataSetTy;
- typedef llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy*> SymbolDependTy;
-
- 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;
- llvm::BumpPtrAllocator& BPAlloc;
- BasicValueFactory &BV;
- ASTContext &Ctx;
-
-public:
- SymbolManager(ASTContext &ctx, BasicValueFactory &bv,
- llvm::BumpPtrAllocator& bpalloc)
- : SymbolDependencies(16), SymbolCounter(0),
- BPAlloc(bpalloc), BV(bv), Ctx(ctx) {}
-
- ~SymbolManager();
-
- static bool canSymbolicate(QualType T);
-
- /// \brief Make a unique symbol for MemRegion R according to its kind.
- const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R);
-
- const SymbolConjured* conjureSymbol(const Stmt *E,
- const LocationContext *LCtx,
- QualType T,
- unsigned VisitCount,
- const void *SymbolTag = nullptr);
-
- const SymbolConjured* conjureSymbol(const Expr *E,
- const LocationContext *LCtx,
- unsigned VisitCount,
- const void *SymbolTag = nullptr) {
- return conjureSymbol(E, LCtx, E->getType(), VisitCount, SymbolTag);
- }
-
- const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,
- const TypedValueRegion *R);
-
- const SymbolExtent *getExtentSymbol(const SubRegion *R);
-
- /// \brief 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.
- const SymbolMetadata *getMetadataSymbol(const MemRegion *R, const Stmt *S,
- QualType T, unsigned VisitCount,
- const void *SymbolTag = nullptr);
-
- const SymbolCast* getCastSymbol(const SymExpr *Operand,
- QualType From, QualType To);
-
- const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t);
-
- const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t) {
- return getSymIntExpr(&lhs, op, rhs, t);
- }
-
- const IntSymExpr *getIntSymExpr(const llvm::APSInt& lhs,
- BinaryOperator::Opcode op,
- const SymExpr *rhs, QualType t);
-
- const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
- const SymExpr *rhs, QualType t);
-
- QualType getType(const SymExpr *SE) const {
- return SE->getType();
- }
-
- /// \brief 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);
-
- const SymbolRefSmallVectorTy *getDependentSymbols(const SymbolRef Primary);
-
- ASTContext &getContext() { return Ctx; }
- BasicValueFactory &getBasicVals() { return BV; }
-};
-
-/// \brief 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;
-
- SymbolMapTy TheLiving;
- SymbolSetTy MetadataInUse;
- SymbolSetTy TheDead;
-
- RegionSetTy RegionRoots;
-
- const StackFrameContext *LCtx;
- const Stmt *Loc;
- SymbolManager& SymMgr;
- StoreRef reapedStore;
- llvm::DenseMap<const MemRegion *, unsigned> includedRegionCache;
-
-public:
- /// \brief 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) {}
-
- const LocationContext *getLocationContext() const { return LCtx; }
-
- bool isLive(SymbolRef sym);
- bool isLiveRegion(const MemRegion *region);
- 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.
- ///
- /// 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.
- ///
- /// For metadata symbols,
- /// this will keep the symbol alive as long as its associated region is also
- /// live. For other symbols, this has no effect; checkers are not permitted
- /// to influence the life of other symbols. This should be used before any
- /// 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.
- ///
- /// 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;
- dead_iterator dead_begin() const { return TheDead.begin(); }
- dead_iterator dead_end() const { return TheDead.end(); }
-
- bool hasDeadSymbols() const {
- return !TheDead.empty();
- }
-
- typedef RegionSetTy::const_iterator region_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.
- ///
- /// This should only be called once all marking of dead symbols has completed.
- /// (For checkers, this means only in the evalDeadSymbols callback.)
- bool isDead(SymbolRef sym) const {
- return TheDead.count(sym);
- }
-
- void markLive(const MemRegion *region);
- void markElementIndicesLive(const MemRegion *region);
-
- /// \brief Set to the value of the symbolic store after
- /// StoreManager::removeDeadBindings has been called.
- void setReapedStore(StoreRef st) { reapedStore = st; }
-
-private:
- /// Mark the symbols dependent on the input symbol as live.
- void markDependentsLive(SymbolRef sym);
-};
-
-class SymbolVisitor {
-protected:
- ~SymbolVisitor() = default;
-
-public:
- SymbolVisitor() = default;
- SymbolVisitor(const SymbolVisitor &) = default;
- SymbolVisitor(SymbolVisitor &&) {}
-
- /// \brief A visitor method invoked by ProgramStateManager::scanReachableSymbols.
- ///
- /// The method returns \c true if symbols should continue be scanned and \c
- /// false otherwise.
- virtual bool VisitSymbol(SymbolRef sym) = 0;
- virtual bool VisitMemRegion(const MemRegion *region) { return true; }
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
- const clang::ento::SymExpr *SE) {
- SE->dumpToStream(os);
- return os;
-}
-} // end llvm namespace
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
deleted file mode 100644
index d39b501..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//== TaintManager.h - Managing taint --------------------------- -*- 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 APIs for adding, removing, querying symbol taint.
-//
-//===----------------------------------------------------------------------===//
-
-#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/TaintTag.h"
-#include "llvm/ADT/ImmutableMap.h"
-
-namespace clang {
-namespace ento {
-
-/// The GDM component containing the tainted root symbols. We lazily infer the
-/// taint of the dependent symbols. Currently, this is a map from a symbol to
-/// tag kind. TODO: Should support multiple tag kinds.
-// 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;
-template<> struct ProgramStateTrait<TaintMap>
- : public ProgramStatePartialTrait<TaintMapImpl> {
- static void *GDMIndex() { static int index = 0; return &index; }
-};
-
-class TaintManager {
-
- TaintManager() {}
-};
-
-}
-}
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
deleted file mode 100644
index 0c56e7d..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//== TaintTag.h - Path-sensitive "State" for tracking values -*- C++ -*--=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines a set of taint tags. Several tags are used to differentiate kinds
-// of taint.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
-
-namespace clang {
-namespace ento {
-
-/// The type of taint, which helps to differentiate between different types of
-/// taint.
-typedef unsigned TaintTagType;
-static const TaintTagType TaintTagGeneric = 0;
-
-}}
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
deleted file mode 100644
index 4f1a60e..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
+++ /dev/null
@@ -1,100 +0,0 @@
-//==- WorkList.h - Worklist class used by CoreEngine ---------------*- 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 WorkList, a pure virtual class that represents an opaque
-// worklist used by CoreEngine to explore the reachability state space.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_WORKLIST_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_WORKLIST_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
-#include <cassert>
-
-namespace clang {
-
-class CFGBlock;
-
-namespace ento {
-
-class WorkListUnit {
- ExplodedNode *node;
- BlockCounter counter;
- const CFGBlock *block;
- unsigned blockIdx; // This is the index of the next statement.
-
-public:
- WorkListUnit(ExplodedNode *N, BlockCounter C,
- const CFGBlock *B, unsigned idx)
- : node(N),
- counter(C),
- block(B),
- blockIdx(idx) {}
-
- explicit WorkListUnit(ExplodedNode *N, BlockCounter C)
- : node(N),
- counter(C),
- block(nullptr),
- blockIdx(0) {}
-
- /// Returns the node associated with the worklist unit.
- ExplodedNode *getNode() const { return node; }
-
- /// Returns the block counter map associated with the worklist unit.
- BlockCounter getBlockCounter() const { return counter; }
-
- /// Returns the CFGblock associated with the worklist unit.
- const CFGBlock *getBlock() const { return block; }
-
- /// Return the index within the CFGBlock for the worklist unit.
- unsigned getIndex() const { return blockIdx; }
-};
-
-class WorkList {
- BlockCounter CurrentCounter;
-public:
- virtual ~WorkList();
- virtual bool hasWork() const = 0;
-
- virtual void enqueue(const WorkListUnit& U) = 0;
-
- void enqueue(ExplodedNode *N, const CFGBlock *B, unsigned idx) {
- enqueue(WorkListUnit(N, CurrentCounter, B, idx));
- }
-
- void enqueue(ExplodedNode *N) {
- assert(N->getLocation().getKind() != ProgramPoint::PostStmtKind);
- enqueue(WorkListUnit(N, CurrentCounter));
- }
-
- virtual WorkListUnit dequeue() = 0;
-
- 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();
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
deleted file mode 100644
index 37ea05f..0000000
--- a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header contains the functions necessary for a front-end to run various
-// analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_ANALYSISCONSUMER_H
-#define LLVM_CLANG_STATICANALYZER_FRONTEND_ANALYSISCONSUMER_H
-
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include <string>
-
-namespace clang {
-
-class Preprocessor;
-class DiagnosticsEngine;
-class CodeInjector;
-class CompilerInstance;
-
-namespace ento {
-class CheckerManager;
-
-class AnalysisASTConsumer : public ASTConsumer {
-public:
- virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) = 0;
-};
-
-/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
-/// analysis passes. (The set of analyses run is controlled by command-line
-/// options.)
-std::unique_ptr<AnalysisASTConsumer>
-CreateAnalysisConsumer(CompilerInstance &CI);
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
deleted file mode 100644
index 2985b7c..0000000
--- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===-- CheckerRegistration.h - Checker Registration Function ---*- 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_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H
-#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H
-
-#include "clang/Basic/LLVM.h"
-#include <memory>
-#include <string>
-
-namespace clang {
- class AnalyzerOptions;
- class LangOptions;
- class DiagnosticsEngine;
-
-namespace ento {
- class CheckerManager;
-
- std::unique_ptr<CheckerManager>
- createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts,
- ArrayRef<std::string> plugins, DiagnosticsEngine &diags);
-
-} // end ento namespace
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
deleted file mode 100644
index 36afb4b..0000000
--- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//===-- FrontendActions.h - Useful Frontend Actions -------------*- 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_STATICANALYZER_FRONTEND_FRONTENDACTIONS_H
-#define LLVM_CLANG_STATICANALYZER_FRONTEND_FRONTENDACTIONS_H
-
-#include "clang/Frontend/FrontendAction.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-
-class Stmt;
-
-namespace ento {
-
-//===----------------------------------------------------------------------===//
-// AST Consumer Actions
-//===----------------------------------------------------------------------===//
-
-class AnalysisAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
-/// \brief 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
-/// in another translation unit. The parsing of model files is done by a
-/// separate compiler instance that reuses the ASTContext and othen information
-/// from the main translation unit that is being compiled. After a model file is
-/// parsed, the function definitions will be collected into a StringMap.
-class ParseModelFileAction : public ASTFrontendAction {
-public:
- ParseModelFileAction(llvm::StringMap<Stmt *> &Bodies);
- bool isModelParsingAction() const override { return true; }
-
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
-private:
- llvm::StringMap<Stmt *> &Bodies;
-};
-
-void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
-
-} // end GR namespace
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
deleted file mode 100644
index 24f8042..0000000
--- a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- ModelConsumer.h -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file implements clang::ento::ModelConsumer which is an
-/// ASTConsumer for model files.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_GR_MODELCONSUMER_H
-#define LLVM_CLANG_GR_MODELCONSUMER_H
-
-#include "clang/AST/ASTConsumer.h"
-#include "llvm/ADT/StringMap.h"
-
-namespace clang {
-
-class Stmt;
-
-namespace ento {
-
-/// \brief ASTConsumer to consume model files' AST.
-///
-/// This consumer collects the bodies of function definitions into a StringMap
-/// from a model file.
-class ModelConsumer : public ASTConsumer {
-public:
- ModelConsumer(llvm::StringMap<Stmt *> &Bodies);
-
- bool HandleTopLevelDecl(DeclGroupRef D) override;
-
-private:
- llvm::StringMap<Stmt *> &Bodies;
-};
-}
-}
-
-#endif
diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h
deleted file mode 100644
index 1fd7be6..0000000
--- a/include/clang/Tooling/ArgumentsAdjusters.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===--- ArgumentsAdjusters.h - Command line arguments adjuster -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares typedef 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.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
-#define LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-#include <functional>
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace tooling {
-
-/// \brief A sequence of command line arguments.
-typedef std::vector<std::string> CommandLineArguments;
-
-/// \brief 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;
-
-/// \brief 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
-/// arguments.
-ArgumentsAdjuster getClangStripOutputAdjuster();
-
-enum class ArgumentInsertPosition { BEGIN, END };
-
-/// \brief 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
-/// specified position.
-ArgumentsAdjuster getInsertArgumentAdjuster(
- const char *Extra,
- ArgumentInsertPosition Pos = ArgumentInsertPosition::END);
-
-/// \brief 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);
-
-} // namespace tooling
-} // namespace clang
-
-#endif // LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
-
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
deleted file mode 100644
index 1e8462c..0000000
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//===- CommonOptionsParser.h - common options for clang tools -*- C++ -*-=====//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the CommonOptionsParser class used to parse common
-// command-line options for clang tools, so that they can be run as separate
-// command-line applications with a consistent common interface for handling
-// compilation database and input files.
-//
-// It provides a common subset of command-line options, common algorithm
-// for locating a compilation database and source files, and help messages
-// for the basic command-line interface.
-//
-// It creates a CompilationDatabase and reads common command-line options.
-//
-// This class uses the Clang Tooling infrastructure, see
-// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
-// for details on setting it up with LLVM source tree.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
-#define LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
-
-#include "clang/Tooling/CompilationDatabase.h"
-#include "llvm/Support/CommandLine.h"
-
-namespace clang {
-namespace tooling {
-/// \brief 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
-/// also contains a help message for the common command-line options.
-///
-/// An example of usage:
-/// \code
-/// #include "clang/Frontend/FrontendActions.h"
-/// #include "clang/Tooling/CommonOptionsParser.h"
-/// #include "clang/Tooling/Tooling.h"
-/// #include "llvm/Support/CommandLine.h"
-///
-/// using namespace clang::tooling;
-/// using namespace llvm;
-///
-/// static cl::OptionCategory MyToolCategory("My tool options");
-/// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
-/// static cl::extrahelp MoreHelp("\nMore help text...");
-/// static cl::opt<bool> YourOwnOption(...);
-/// ...
-///
-/// int main(int argc, const char **argv) {
-/// CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
-/// ClangTool Tool(OptionsParser.getCompilations(),
-/// OptionsParser.getSourcePathList());
-/// return Tool.run(newFrontendActionFactory<SyntaxOnlyAction>().get());
-/// }
-/// \endcode
-class CommonOptionsParser {
-public:
- /// \brief 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.
- ///
- /// All options not belonging to \p Category become hidden.
- ///
- /// This constructor exits program in case of error.
- CommonOptionsParser(int &argc, const char **argv,
- llvm::cl::OptionCategory &Category,
- const char *Overview = nullptr)
- : CommonOptionsParser(argc, argv, Category, llvm::cl::OneOrMore,
- Overview) {}
-
- /// \brief 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.
- ///
- /// All options not belonging to \p Category become hidden.
- ///
- /// I also allows calls to set the required number of positional parameters.
- ///
- /// This constructor exits program in case of error.
- CommonOptionsParser(int &argc, const char **argv,
- llvm::cl::OptionCategory &Category,
- llvm::cl::NumOccurrencesFlag OccurrencesFlag,
- const char *Overview = nullptr);
-
- /// Returns a reference to the loaded compilations database.
- CompilationDatabase &getCompilations() {
- return *Compilations;
- }
-
- /// Returns a list of source file paths to process.
- std::vector<std::string> getSourcePathList() {
- return SourcePathList;
- }
-
- static const char *const HelpMessage;
-
-private:
- std::unique_ptr<CompilationDatabase> Compilations;
- std::vector<std::string> SourcePathList;
- std::vector<std::string> ExtraArgsBefore;
- std::vector<std::string> ExtraArgsAfter;
-};
-
-} // namespace tooling
-} // namespace clang
-
-#endif // LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
deleted file mode 100644
index 08a0ffe..0000000
--- a/include/clang/Tooling/CompilationDatabase.h
+++ /dev/null
@@ -1,222 +0,0 @@
-//===--- CompilationDatabase.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 provides an interface and multiple implementations for
-// CompilationDatabases.
-//
-// While C++ refactoring and analysis tools are not compilers, and thus
-// don't run as part of the build system, they need the exact information
-// of a build in order to be able to correctly understand the C++ code of
-// the project. This information is provided via the CompilationDatabase
-// interface.
-//
-// To create a CompilationDatabase from a build directory one can call
-// CompilationDatabase::loadFromDirectory(), which deduces the correct
-// compilation database from the root of the build tree.
-//
-// See the concrete subclasses of CompilationDatabase for currently supported
-// formats.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
-#define LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace tooling {
-
-/// \brief Specifies the working directory and command of a compilation.
-struct CompileCommand {
- CompileCommand() {}
- CompileCommand(Twine Directory, Twine Filename,
- std::vector<std::string> CommandLine)
- : Directory(Directory.str()),
- Filename(Filename.str()),
- CommandLine(std::move(CommandLine)) {}
-
- /// \brief 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.
- std::vector<std::string> CommandLine;
-
- /// \brief An optional mapping from each file's path to its content for all
- /// files needed for the compilation that are not available via the file
- /// system.
- ///
- /// Note that a tool implementation is required to fall back to the file
- /// system if a source file is not provided in the mapped sources, as
- /// compilation databases will usually not provide all files in mapped sources
- /// for performance reasons.
- std::vector<std::pair<std::string, std::string> > MappedSources;
-};
-
-/// \brief Interface for compilation databases.
-///
-/// A compilation database allows the user to retrieve all compile command lines
-/// that a specified file is compiled with in a project.
-/// The retrieved compile command lines can be used to run clang tools over
-/// a subset of the files in a project.
-class CompilationDatabase {
-public:
- virtual ~CompilationDatabase();
-
- /// \brief 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
- /// corresponding source tree.
- ///
- /// Returns NULL and sets ErrorMessage if we were not able to build up a
- /// compilation database for the build directory.
- ///
- /// FIXME: Currently only supports JSON compilation databases, which
- /// are named 'compile_commands.json' in the given directory. Extend this
- /// for other build types (like ninja build files).
- static std::unique_ptr<CompilationDatabase>
- loadFromDirectory(StringRef BuildDirectory, std::string &ErrorMessage);
-
- /// \brief 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.
- ///
- /// 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
- /// compiled.
- ///
- /// This includes compile comamnds that span multiple source files.
- /// For example, consider a project with the following compilations:
- /// $ clang++ -o test a.cc b.cc t.cc
- /// $ clang++ -o production a.cc b.cc -DPRODUCTION
- /// 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;
-
- /// \brief Returns the list of all files available in the compilation database.
- virtual std::vector<std::string> getAllFiles() const = 0;
-
- /// \brief 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
- /// over all files in a compilation database. Not all build systems have the
- /// ability to provide a feasible implementation for \c getAllCompileCommands.
- virtual std::vector<CompileCommand> getAllCompileCommands() const = 0;
-};
-
-/// \brief 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
-/// library is linked in. To register a plugin, declare a static variable like:
-///
-/// \code
-/// static CompilationDatabasePluginRegistry::Add<MyDatabasePlugin>
-/// X("my-compilation-database", "Reads my own compilation database");
-/// \endcode
-class CompilationDatabasePlugin {
-public:
- virtual ~CompilationDatabasePlugin();
-
- /// \brief 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.
-///
-/// Useful when we want a tool to behave more like a compiler invocation.
-class FixedCompilationDatabase : public CompilationDatabase {
-public:
- /// \brief 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
- /// FixedCompilationDatabase.
- /// The arguments after "--" must not include positional parameters or the
- /// argv[0] of the tool. Those will be added by the FixedCompilationDatabase
- /// when a CompileCommand is requested. The argv[0] of the returned command
- /// line will be "clang-tool".
- ///
- /// Returns NULL in case "--" is not found.
- ///
- /// The argument list is meant to be compatible with normal llvm command line
- /// parsing in main methods.
- /// int main(int argc, char **argv) {
- /// std::unique_ptr<FixedCompilationDatabase> Compilations(
- /// FixedCompilationDatabase::loadFromCommandLine(argc, argv));
- /// cl::ParseCommandLineOptions(argc, argv);
- /// ...
- /// }
- ///
- /// \param Argc The number of command line arguments - will be changed to
- /// the number of arguments before "--", if "--" was found in the argument
- /// list.
- /// \param Argv Points to the command line arguments.
- /// \param Directory The base directory used in the FixedCompilationDatabase.
- static FixedCompilationDatabase *loadFromCommandLine(int &Argc,
- const char *const *Argv,
- Twine Directory = ".");
-
- /// \brief 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.
- ///
- /// Will always return a vector with one entry that contains the directory
- /// and command line specified at construction with "clang-tool" as argv[0]
- /// and 'FilePath' as positional argument.
- std::vector<CompileCommand>
- getCompileCommands(StringRef FilePath) const override;
-
- /// \brief Returns the list of all files available in the compilation database.
- ///
- /// Note: This is always an empty list for the fixed compilation database.
- std::vector<std::string> getAllFiles() const override;
-
- /// \brief Returns all compile commands for all the files in the compilation
- /// database.
- ///
- /// Note: This is always an empty list for the fixed compilation database.
- std::vector<CompileCommand> getAllCompileCommands() const override;
-
-private:
- /// This is built up to contain a single entry vector to be returned from
- /// getCompileCommands after adding the positional argument.
- std::vector<CompileCommand> CompileCommands;
-};
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
deleted file mode 100644
index 7323ec8..0000000
--- a/include/clang/Tooling/CompilationDatabasePluginRegistry.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//===--- CompilationDatabasePluginRegistry.h - ------------------*- 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_COMPILATIONDATABASEPLUGINREGISTRY_H
-#define LLVM_CLANG_TOOLING_COMPILATIONDATABASEPLUGINREGISTRY_H
-
-#include "clang/Tooling/CompilationDatabase.h"
-#include "llvm/Support/Registry.h"
-
-namespace clang {
-namespace tooling {
-
-class CompilationDatabasePlugin;
-
-typedef llvm::Registry<CompilationDatabasePlugin>
- CompilationDatabasePluginRegistry;
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Tooling/Core/Lookup.h b/include/clang/Tooling/Core/Lookup.h
deleted file mode 100644
index bc2b4db..0000000
--- a/include/clang/Tooling/Core/Lookup.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===--- Lookup.h - Framework for clang refactoring tools --*- 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 helper methods for clang tools performing name lookup.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_CORE_LOOKUP_H
-#define LLVM_CLANG_TOOLING_CORE_LOOKUP_H
-
-#include "clang/Basic/LLVM.h"
-#include <string>
-
-namespace clang {
-
-class DeclContext;
-class NamedDecl;
-class NestedNameSpecifier;
-
-namespace tooling {
-
-/// Emulate a lookup to replace one nested name specifier with another using as
-/// few additional namespace qualifications as possible.
-///
-/// This does not perform a full C++ lookup so ADL will not work.
-///
-/// \param Use The nested name to be replaced.
-/// \param UseContext The context in which the nested name is contained. This
-/// will be used to minimize namespace qualifications.
-/// \param FromDecl The declaration to which the nested name points.
-/// \param ReplacementString The replacement nested name. Must be fully
-/// qualified including a leading "::".
-/// \returns The new name to be inserted in place of the current nested name.
-std::string replaceNestedName(const NestedNameSpecifier *Use,
- const DeclContext *UseContext,
- const NamedDecl *FromDecl,
- StringRef ReplacementString);
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_TOOLING_CORE_LOOKUP_H
diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h
deleted file mode 100644
index 37389ac..0000000
--- a/include/clang/Tooling/Core/Replacement.h
+++ /dev/null
@@ -1,241 +0,0 @@
-//===--- Replacement.h - Framework for clang refactoring tools --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Classes supporting refactorings that span multiple translation units.
-// While single translation unit refactorings are supported via the Rewriter,
-// when refactoring multiple translation units changes must be stored in a
-// SourceManager independent form, duplicate changes need to be removed, and
-// all changes must be applied at once at the end of the refactoring so that
-// the code is always parseable.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
-#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
-
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/StringRef.h"
-#include <set>
-#include <string>
-#include <vector>
-
-namespace clang {
-
-class Rewriter;
-
-namespace tooling {
-
-/// \brief A source range independent of the \c SourceManager.
-class Range {
-public:
- Range() : Offset(0), Length(0) {}
- Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
-
- /// \brief Accessors.
- /// @{
- unsigned getOffset() const { return Offset; }
- unsigned getLength() const { return Length; }
- /// @}
-
- /// \name Range Predicates
- /// @{
- /// \brief 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.
- bool contains(Range RHS) const {
- return RHS.Offset >= Offset &&
- (RHS.Offset + RHS.Length) <= (Offset + Length);
- }
- /// @}
-
-private:
- unsigned Offset;
- unsigned Length;
-};
-
-/// \brief 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.
- Replacement();
-
- /// \brief Creates a replacement of the range [Offset, Offset+Length) in
- /// FilePath with ReplacementText.
- ///
- /// \param FilePath A source file accessible via a SourceManager.
- /// \param Offset The byte offset of the start of the range in the file.
- /// \param Length The length of the range in bytes.
- Replacement(StringRef FilePath, unsigned Offset, unsigned Length,
- StringRef ReplacementText);
-
- /// \brief 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.
- Replacement(const SourceManager &Sources, const CharSourceRange &Range,
- StringRef ReplacementText,
- const LangOptions &LangOpts = LangOptions());
-
- /// \brief 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.
- ///
- /// Only replacements that are in a valid file can be applied.
- bool isApplicable() const;
-
- /// \brief Accessors.
- /// @{
- StringRef getFilePath() const { return FilePath; }
- unsigned getOffset() const { return ReplacementRange.getOffset(); }
- unsigned getLength() const { return ReplacementRange.getLength(); }
- StringRef getReplacementText() const { return ReplacementText; }
- /// @}
-
- /// \brief Applies the replacement on the Rewriter.
- bool apply(Rewriter &Rewrite) const;
-
- /// \brief Returns a human readable string representation.
- std::string toString() const;
-
- private:
- void setFromSourceLocation(const SourceManager &Sources,
- SourceLocation Start, unsigned Length,
- StringRef ReplacementText);
- void setFromSourceRange(const SourceManager &Sources,
- const CharSourceRange &Range,
- StringRef ReplacementText,
- const LangOptions &LangOpts);
-
- std::string FilePath;
- Range ReplacementRange;
- std::string ReplacementText;
-};
-
-/// \brief Less-than operator between two Replacements.
-bool operator<(const Replacement &LHS, const Replacement &RHS);
-
-/// \brief Equal-to operator between two Replacements.
-bool operator==(const Replacement &LHS, const Replacement &RHS);
-
-/// \brief A set of Replacements.
-/// FIXME: Change to a vector and deduplicate in the RefactoringTool.
-typedef std::set<Replacement> Replacements;
-
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
-///
-/// Replacement applications happen independently of the success of
-/// other applications.
-///
-/// \returns true if all replacements apply. false otherwise.
-bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
-
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
-///
-/// Replacement applications happen independently of the success of
-/// other applications.
-///
-/// \returns true if all replacements apply. false otherwise.
-bool applyAllReplacements(const std::vector<Replacement> &Replaces,
- Rewriter &Rewrite);
-
-/// \brief Applies all replacements in \p Replaces to \p Code.
-///
-/// This completely ignores the path stored in each replacement. If one or more
-/// replacements cannot be applied, this returns an empty \c string.
-std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
-
-/// \brief Calculates how a code \p Position is shifted when \p Replaces are
-/// applied.
-unsigned shiftedCodePosition(const Replacements& Replaces, unsigned Position);
-
-/// \brief Calculates how a code \p Position is shifted when \p Replaces are
-/// applied.
-///
-/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset().
-unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
- unsigned Position);
-
-/// \brief Removes duplicate Replacements and reports if Replacements conflict
-/// with one another. All Replacements are assumed to be in the same file.
-///
-/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset().
-///
-/// This function sorts \p Replaces so that conflicts can be reported simply by
-/// offset into \p Replaces and number of elements in the conflict.
-void deduplicate(std::vector<Replacement> &Replaces,
- std::vector<Range> &Conflicts);
-
-/// \brief Collection of Replacements generated from a single translation unit.
-struct TranslationUnitReplacements {
- /// Name of the main source for the translation unit.
- std::string MainSourceFile;
-
- /// A freeform chunk of text to describe the context of the replacements.
- /// Will be printed, for example, when detecting conflicts during replacement
- /// deduplication.
- std::string Context;
-
- std::vector<Replacement> Replacements;
-};
-
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
-///
-/// Replacement applications happen independently of the success of
-/// other applications.
-///
-/// \returns true if all replacements apply. false otherwise.
-bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
-
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
-///
-/// Replacement applications happen independently of the success of
-/// other applications.
-///
-/// \returns true if all replacements apply. false otherwise.
-bool applyAllReplacements(const std::vector<Replacement> &Replaces,
- Rewriter &Rewrite);
-
-/// \brief Applies all replacements in \p Replaces to \p Code.
-///
-/// This completely ignores the path stored in each replacement. If one or more
-/// replacements cannot be applied, this returns an empty \c string.
-std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
-
-/// \brief Merges two sets of replacements with the second set referring to the
-/// code after applying the first set. Within both 'First' and 'Second',
-/// replacements must not overlap.
-Replacements mergeReplacements(const Replacements &First,
- const Replacements &Second);
-
-template <typename Node>
-Replacement::Replacement(const SourceManager &Sources,
- const Node &NodeToReplace, StringRef ReplacementText,
- const LangOptions &LangOpts) {
- const CharSourceRange Range =
- CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
- setFromSourceRange(Sources, Range, ReplacementText, LangOpts);
-}
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
deleted file mode 100644
index 745c164..0000000
--- a/include/clang/Tooling/FileMatchTrie.h
+++ /dev/null
@@ -1,89 +0,0 @@
-//===--- FileMatchTrie.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 implements a match trie to find the matching file in a compilation
-// database based on a given path in the presence of symlinks.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
-#define LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace tooling {
-
-struct PathComparator {
- virtual ~PathComparator() {}
- virtual bool equivalent(StringRef FileA, StringRef FileB) const = 0;
-};
-class FileMatchTrieNode;
-
-/// \brief 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
-/// find the corresponding file in the compilation database. Although entries
-/// in the compilation database are keyed by filename, a simple string match
-/// is insufficient because of symlinks. Commonly, a project hierarchy looks
-/// like this:
-/// /<project-root>/src/<path>/<somefile>.cc (used as input for the tool)
-/// /<project-root>/build/<symlink-to-src>/<path>/<somefile>.cc (stored in DB)
-///
-/// Furthermore, there might be symlinks inside the source folder or inside the
-/// database, so that the same source file is translated with different build
-/// options.
-///
-/// For a given input file, the \c FileMatchTrie finds its entries in order
-/// of matching suffix length. For each suffix length, there might be one or
-/// more entries in the database. For each of those entries, it calls
-/// \c llvm::sys::fs::equivalent() (injected as \c PathComparator). There might
-/// be zero or more entries with the same matching suffix length that are
-/// equivalent to the input file. Three cases are distinguished:
-/// 0 equivalent files: Continue with the next suffix length.
-/// 1 equivalent file: Best match found, return it.
-/// >1 equivalent files: Match is ambiguous, return error.
-class FileMatchTrie {
-public:
- FileMatchTrie();
-
- /// \brief 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.
- void insert(StringRef NewPath);
-
- /// \brief 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
- /// 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;
-};
-
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
deleted file mode 100644
index 2a13fc1..0000000
--- a/include/clang/Tooling/JSONCompilationDatabase.h
+++ /dev/null
@@ -1,133 +0,0 @@
-//===--- JSONCompilationDatabase.h - ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The JSONCompilationDatabase finds compilation databases supplied as a file
-// 'compile_commands.json'.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H
-#define LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Tooling/CompilationDatabase.h"
-#include "clang/Tooling/FileMatchTrie.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/YAMLParser.h"
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace tooling {
-
-/// \brief 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',
-/// 'arguments' and 'file':
-/// [
-/// { "directory": "<working directory of the compile>",
-/// "command": "<compile command line>",
-/// "file": "<path to source file>"
-/// },
-/// { "directory": "<working directory of the compile>",
-/// "arguments": ["<raw>", "<command>" "<line>" "<parameters>"],
-/// "file": "<path to source file>"
-/// },
-/// ...
-/// ]
-/// Each object entry defines one compile action. The specified file is
-/// considered to be the main source file for the translation unit.
-///
-/// 'command' is a full command line that will be unescaped.
-///
-/// 'arguments' is a list of command line arguments that will not be unescaped.
-///
-/// JSON compilation databases can for example be generated in CMake projects
-/// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS.
-class JSONCompilationDatabase : public CompilationDatabase {
-public:
- /// \brief 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.
- static std::unique_ptr<JSONCompilationDatabase>
- loadFromFile(StringRef FilePath, std::string &ErrorMessage);
-
- /// \brief 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);
-
- /// \brief Returns all compile comamnds in which the specified file was
- /// compiled.
- ///
- /// FIXME: Currently FilePath must be an absolute path inside the
- /// source directory which does not have symlinks resolved.
- std::vector<CompileCommand>
- getCompileCommands(StringRef FilePath) const override;
-
- /// \brief 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
- /// database.
- std::vector<CompileCommand> getAllCompileCommands() const override;
-
-private:
- /// \brief Constructs a JSON compilation database on a memory buffer.
- JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database)
- : Database(std::move(Database)),
- YAMLStream(this->Database->getBuffer(), SM) {}
-
- /// \brief Parses the database file and creates the index.
- ///
- /// Returns whether parsing succeeded. Sets ErrorMessage if parsing
- /// failed.
- bool parse(std::string &ErrorMessage);
-
- // Tuple (directory, filename, commandline) where 'commandline' points to the
- // corresponding scalar nodes in the YAML stream.
- // If the command line contains a single argument, it is a shell-escaped
- // command line.
- // Otherwise, each entry in the command line vector is a literal
- // argument to the compiler.
- typedef std::tuple<llvm::yaml::ScalarNode *,
- llvm::yaml::ScalarNode *,
- std::vector<llvm::yaml::ScalarNode *>> CompileCommandRef;
-
- /// \brief Converts the given array of CompileCommandRefs to CompileCommands.
- void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
- std::vector<CompileCommand> &Commands) const;
-
- // Maps file paths to the compile command lines for that file.
- llvm::StringMap<std::vector<CompileCommandRef>> IndexByFile;
-
- /// All the compile commands in the order that they were provided in the
- /// JSON stream.
- std::vector<CompileCommandRef> AllCommands;
-
- FileMatchTrie MatchTrie;
-
- std::unique_ptr<llvm::MemoryBuffer> Database;
- llvm::SourceMgr SM;
- llvm::yaml::Stream YAMLStream;
-};
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
deleted file mode 100644
index 54deff6..0000000
--- a/include/clang/Tooling/Refactoring.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//===--- Refactoring.h - Framework for clang refactoring tools --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Interfaces supporting refactorings that span multiple translation units.
-// While single translation unit refactorings are supported via the Rewriter,
-// when refactoring multiple translation units changes must be stored in a
-// SourceManager independent form, duplicate changes need to be removed, and
-// all changes must be applied at once at the end of the refactoring so that
-// the code is always parseable.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_REFACTORING_H
-#define LLVM_CLANG_TOOLING_REFACTORING_H
-
-#include "clang/Tooling/Core/Replacement.h"
-#include "clang/Tooling/Tooling.h"
-#include <string>
-
-namespace clang {
-
-class Rewriter;
-
-namespace tooling {
-
-/// \brief A tool to run refactorings.
-///
-/// This is a refactoring specific version of \see ClangTool. FrontendActions
-/// passed to run() and runAndSave() should add replacements to
-/// getReplacements().
-class RefactoringTool : public ClangTool {
-public:
- /// \see ClangTool::ClangTool.
- RefactoringTool(const CompilationDatabase &Compilations,
- ArrayRef<std::string> SourcePaths,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps =
- std::make_shared<PCHContainerOperations>());
-
- /// \brief Returns the set of replacements to which replacements should
- /// be added during the run of the tool.
- Replacements &getReplacements();
-
- /// \brief 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.
- ///
- /// Replacement applications happen independently of the success of other
- /// applications.
- ///
- /// \returns true if all replacements apply. false otherwise.
- bool applyAllReplacements(Rewriter &Rewrite);
-
-private:
- /// \brief Write all refactored files to disk.
- int saveRewrittenFiles(Rewriter &Rewrite);
-
-private:
- Replacements Replace;
-};
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_TOOLING_REFACTORING_H
diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h
deleted file mode 100644
index 6ef9ea1..0000000
--- a/include/clang/Tooling/RefactoringCallbacks.h
+++ /dev/null
@@ -1,90 +0,0 @@
-//===--- RefactoringCallbacks.h - Structural query framework ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Provides callbacks to make common kinds of refactorings easy.
-//
-// The general idea is to construct a matcher expression that describes a
-// subtree match on the AST and then replace the corresponding source code
-// either by some specific text or some other AST node.
-//
-// Example:
-// int main(int argc, char **argv) {
-// ClangTool Tool(argc, argv);
-// MatchFinder Finder;
-// ReplaceStmtWithText Callback("integer", "42");
-// Finder.AddMatcher(id("integer", expression(integerLiteral())), Callback);
-// return Tool.run(newFrontendActionFactory(&Finder));
-// }
-//
-// This will replace all integer literals with "42".
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
-#define LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
-
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Tooling/Refactoring.h"
-
-namespace clang {
-namespace tooling {
-
-/// \brief Base class for RefactoringCallbacks.
-///
-/// Collects \c tooling::Replacements while running.
-class RefactoringCallback : public ast_matchers::MatchFinder::MatchCallback {
-public:
- RefactoringCallback();
- Replacements &getReplacements();
-
-protected:
- Replacements Replace;
-};
-
-/// \brief Replace the text of the statement bound to \c FromId with the text in
-/// \c ToText.
-class ReplaceStmtWithText : public RefactoringCallback {
-public:
- ReplaceStmtWithText(StringRef FromId, StringRef ToText);
- void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
-
-private:
- std::string FromId;
- std::string ToText;
-};
-
-/// \brief 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:
- ReplaceStmtWithStmt(StringRef FromId, StringRef ToId);
- void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
-
-private:
- std::string FromId;
- std::string ToId;
-};
-
-/// \brief 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 {
-public:
- ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch);
- void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
-
-private:
- std::string Id;
- const bool PickTrueBranch;
-};
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
deleted file mode 100644
index 4a7666d..0000000
--- a/include/clang/Tooling/ReplacementsYaml.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===-- ReplacementsYaml.h -- Serialiazation for Replacements ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file defines the structure of a YAML document for serializing
-/// replacements.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_REPLACEMENTSYAML_H
-#define LLVM_CLANG_TOOLING_REPLACEMENTSYAML_H
-
-#include "clang/Tooling/Refactoring.h"
-#include "llvm/Support/YAMLTraits.h"
-#include <string>
-#include <vector>
-
-LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement)
-
-namespace llvm {
-namespace yaml {
-
-/// \brief 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
- /// access to its data members.
- struct NormalizedReplacement {
- NormalizedReplacement(const IO &)
- : FilePath(""), Offset(0), Length(0), ReplacementText("") {}
-
- NormalizedReplacement(const IO &, const clang::tooling::Replacement &R)
- : FilePath(R.getFilePath()), Offset(R.getOffset()),
- Length(R.getLength()), ReplacementText(R.getReplacementText()) {}
-
- clang::tooling::Replacement denormalize(const IO &) {
- return clang::tooling::Replacement(FilePath, Offset, Length,
- ReplacementText);
- }
-
- std::string FilePath;
- unsigned int Offset;
- unsigned int Length;
- std::string ReplacementText;
- };
-
- static void mapping(IO &Io, clang::tooling::Replacement &R) {
- MappingNormalization<NormalizedReplacement, clang::tooling::Replacement>
- Keys(Io, R);
- Io.mapRequired("FilePath", Keys->FilePath);
- Io.mapRequired("Offset", Keys->Offset);
- Io.mapRequired("Length", Keys->Length);
- Io.mapRequired("ReplacementText", Keys->ReplacementText);
- }
-};
-
-/// \brief Specialized MappingTraits to describe how a
-/// TranslationUnitReplacements is (de)serialized.
-template <> struct MappingTraits<clang::tooling::TranslationUnitReplacements> {
- static void mapping(IO &Io,
- clang::tooling::TranslationUnitReplacements &Doc) {
- Io.mapRequired("MainSourceFile", Doc.MainSourceFile);
- Io.mapOptional("Context", Doc.Context, std::string());
- Io.mapRequired("Replacements", Doc.Replacements);
- }
-};
-} // end namespace yaml
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
deleted file mode 100644
index b7a9b25..0000000
--- a/include/clang/Tooling/Tooling.h
+++ /dev/null
@@ -1,455 +0,0 @@
-//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements functions to run clang tools standalone instead
-// of running them as a plugin.
-//
-// A ClangTool is initialized with a CompilationDatabase and a set of files
-// to run over. The tool will then run a user-specified FrontendAction over
-// all TUs in which the given files are compiled.
-//
-// It is also possible to run a FrontendAction over a snippet of code by
-// calling runToolOnCode, which is useful for unit testing.
-//
-// Applications that need more fine grained control over how to run
-// multiple FrontendActions over code can use ToolInvocation.
-//
-// Example tools:
-// - running clang -fsyntax-only over source code from an editor to get
-// fast syntax checks
-// - running match/replace tools over C++ code
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_TOOLING_H
-#define LLVM_CLANG_TOOLING_TOOLING_H
-
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Frontend/PCHContainerOperations.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Driver/Util.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Lex/ModuleLoader.h"
-#include "clang/Tooling/ArgumentsAdjusters.h"
-#include "clang/Tooling/CompilationDatabase.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Option/Option.h"
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace clang {
-
-namespace driver {
-class Compilation;
-} // end namespace driver
-
-class CompilerInvocation;
-class SourceManager;
-class FrontendAction;
-
-namespace tooling {
-
-/// \brief Interface to process a clang::CompilerInvocation.
-///
-/// If your tool is based on FrontendAction, you should be deriving from
-/// FrontendActionFactory instead.
-class ToolAction {
-public:
- virtual ~ToolAction();
-
- /// \brief Perform an action for an invocation.
- virtual bool
- runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- DiagnosticConsumer *DiagConsumer) = 0;
-};
-
-/// \brief 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
-/// also a ToolAction which uses the FrontendActions created by create() to
-/// process each translation unit.
-class FrontendActionFactory : public ToolAction {
-public:
- ~FrontendActionFactory() override;
-
- /// \brief Invokes the compiler with a FrontendAction created by create().
- bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- DiagnosticConsumer *DiagConsumer) override;
-
- /// \brief Returns a new clang::FrontendAction.
- ///
- /// The caller takes ownership of the returned action.
- virtual clang::FrontendAction *create() = 0;
-};
-
-/// \brief Returns a new FrontendActionFactory for a given type.
-///
-/// T must derive from clang::FrontendAction.
-///
-/// Example:
-/// FrontendActionFactory *Factory =
-/// newFrontendActionFactory<clang::SyntaxOnlyAction>();
-template <typename T>
-std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
-
-/// \brief 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() {}
-
- /// \brief Called before a source file is processed by a FrontEndAction.
- /// \see clang::FrontendAction::BeginSourceFileAction
- virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) {
- return true;
- }
-
- /// \brief 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
-/// implementation of newASTConsumer().
-///
-/// FactoryT must implement: ASTConsumer *newASTConsumer().
-///
-/// Example:
-/// struct ProvidesASTConsumers {
-/// clang::ASTConsumer *newASTConsumer();
-/// } Factory;
-/// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
-/// newFrontendActionFactory(&Factory));
-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.
-///
-/// \param ToolAction The action to run over the code.
-/// \param Code C++ code.
-/// \param FileName The file name which 'Code' will be mapped as.
-/// \param PCHContainerOps The PCHContainerOperations for loading and creating
-/// clang modules.
-///
-/// \return - True if 'ToolAction' was successfully executed.
-bool runToolOnCode(clang::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;
-
-/// \brief 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.
-/// \param Code C++ code.
-/// \param Args Additional flags to pass on.
-/// \param FileName The file name which 'Code' will be mapped as.
-/// \param PCHContainerOps The PCHContainerOperations for loading and creating
-/// clang modules.
-///
-/// \return - True if 'ToolAction' was successfully executed.
-bool runToolOnCodeWithArgs(
- clang::FrontendAction *ToolAction, const Twine &Code,
- const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
- std::shared_ptr<PCHContainerOperations> PCHContainerOps =
- std::make_shared<PCHContainerOperations>(),
- const FileContentMappings &VirtualMappedFiles = FileContentMappings());
-
-/// \brief Builds an AST for 'Code'.
-///
-/// \param Code C++ code.
-/// \param FileName The file name which 'Code' will be mapped as.
-/// \param PCHContainerOps The PCHContainerOperations for loading and creating
-/// clang modules.
-///
-/// \return The resulting AST or null if an error occurred.
-std::unique_ptr<ASTUnit>
-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.
-///
-/// \param Code C++ code.
-/// \param Args Additional flags to pass on.
-/// \param FileName The file name which 'Code' will be mapped as.
-/// \param PCHContainerOps The PCHContainerOperations for loading and creating
-/// clang modules.
-///
-/// \return The resulting AST or null if an error occurred.
-std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
- const Twine &Code, const std::vector<std::string> &Args,
- const Twine &FileName = "input.cc",
- std::shared_ptr<PCHContainerOperations> PCHContainerOps =
- std::make_shared<PCHContainerOperations>());
-
-/// \brief Utility to run a FrontendAction in a single clang invocation.
-class ToolInvocation {
-public:
- /// \brief 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.
- /// Callers have to ensure that they are installed in a compatible location
- /// (see clang driver implementation) or mapped in via mapVirtualFile.
- /// \param FAction The action to be executed. Class takes ownership.
- /// \param Files The FileManager used for the execution. Class does not take
- /// ownership.
- /// \param PCHContainerOps The PCHContainerOperations for loading and creating
- /// clang modules.
- ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
- FileManager *Files,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps =
- std::make_shared<PCHContainerOperations>());
-
- /// \brief Create a tool invocation.
- ///
- /// \param CommandLine The command line arguments to clang.
- /// \param Action The action to be executed.
- /// \param Files The FileManager used for the execution.
- /// \param PCHContainerOps The PCHContainerOperations for loading and creating
- /// clang modules.
- ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
- FileManager *Files,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps);
-
- ~ToolInvocation();
-
- /// \brief 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.
- ///
- /// \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.
- ///
- /// \returns True if there were no errors during execution.
- bool run();
-
- private:
- void addFileMappingsTo(SourceManager &SourceManager);
-
- bool runInvocation(const char *BinaryName,
- clang::driver::Compilation *Compilation,
- clang::CompilerInvocation *Invocation,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps);
-
- std::vector<std::string> CommandLine;
- ToolAction *Action;
- bool OwnsAction;
- FileManager *Files;
- std::shared_ptr<PCHContainerOperations> PCHContainerOps;
- // Maps <file name> -> <file content>.
- llvm::StringMap<StringRef> MappedFileContents;
- DiagnosticConsumer *DiagConsumer;
-};
-
-/// \brief 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
-/// command line arguments before the arguments are used to run
-/// 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.
- ///
- /// \param Compilations The CompilationDatabase which contains the compile
- /// command lines for the given source paths.
- /// \param SourcePaths The source files to run over. If a source files is
- /// not found in Compilations, it is skipped.
- /// \param PCHContainerOps The PCHContainerOperations for loading and creating
- /// clang modules.
- ClangTool(const CompilationDatabase &Compilations,
- ArrayRef<std::string> SourcePaths,
- std::shared_ptr<PCHContainerOperations> PCHContainerOps =
- std::make_shared<PCHContainerOperations>());
-
- ~ClangTool();
-
- /// \brief 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.
- ///
- /// \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.
- ///
- /// \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.
- void clearArgumentsAdjusters();
-
- /// Runs an action over all files specified in the command line.
- ///
- /// \param Action Tool action.
- int run(ToolAction *Action);
-
- /// \brief 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.
- ///
- /// The file manager is shared between all translation units.
- FileManager &getFiles() { return *Files; }
-
- private:
- const CompilationDatabase &Compilations;
- std::vector<std::string> SourcePaths;
- std::shared_ptr<PCHContainerOperations> PCHContainerOps;
-
- 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;
- llvm::StringSet<> SeenWorkingDirectories;
-
- ArgumentsAdjuster ArgsAdjuster;
-
- DiagnosticConsumer *DiagConsumer;
-};
-
-template <typename T>
-std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
- class SimpleFrontendActionFactory : public FrontendActionFactory {
- public:
- clang::FrontendAction *create() override { return new T; }
- };
-
- return std::unique_ptr<FrontendActionFactory>(
- new SimpleFrontendActionFactory);
-}
-
-template <typename FactoryT>
-inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
- FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
- class FrontendActionFactoryAdapter : public FrontendActionFactory {
- public:
- explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
- SourceFileCallbacks *Callbacks)
- : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
-
- clang::FrontendAction *create() override {
- return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
- }
-
- private:
- class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
- public:
- ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
- SourceFileCallbacks *Callbacks)
- : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
-
- std::unique_ptr<clang::ASTConsumer>
- CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
- return ConsumerFactory->newASTConsumer();
- }
-
- protected:
- bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename) override {
- if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
- return false;
- if (Callbacks)
- return Callbacks->handleBeginSource(CI, Filename);
- return true;
- }
- void EndSourceFileAction() override {
- if (Callbacks)
- Callbacks->handleEndSource();
- clang::ASTFrontendAction::EndSourceFileAction();
- }
-
- private:
- FactoryT *ConsumerFactory;
- SourceFileCallbacks *Callbacks;
- };
- FactoryT *ConsumerFactory;
- SourceFileCallbacks *Callbacks;
- };
-
- return std::unique_ptr<FrontendActionFactory>(
- new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
-}
-
-/// \brief Returns the absolute path of \c File, by prepending it with
-/// the current directory if \c File is not absolute.
-///
-/// Otherwise returns \c File.
-/// If 'File' starts with "./", the returned path will not contain the "./".
-/// Otherwise, the returned path will contain the literal path-concatenation of
-/// the current directory and \c File.
-///
-/// The difference to llvm::sys::fs::make_absolute is the canonicalization this
-/// does by removing "./" and computing native paths.
-///
-/// \param File Either an absolute or relative path.
-std::string getAbsolutePath(StringRef File);
-
-/// \brief 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++`,
-/// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will
-/// be inserted after the first argument in \c CommandLine.
-///
-/// This function will not add new `-target` or `--driver-mode` flags if they
-/// are already present in `CommandLine` (even if they have different settings
-/// than would have been inserted).
-///
-/// \pre `llvm::InitializeAllTargets()` has been called.
-///
-/// \param CommandLine the command line used to invoke the compiler driver or
-/// Clang tool, including the path to the executable as \c CommandLine[0].
-/// \param InvokedAs the path to the driver used to infer implicit flags.
-///
-/// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling
-/// infrastructure expects that CommandLine[0] is a tool path relative to which
-/// the builtin headers can be found.
-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);
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_TOOLING_TOOLING_H
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
deleted file mode 100644
index 28b6d16..0000000
--- a/include/clang/module.modulemap
+++ /dev/null
@@ -1,134 +0,0 @@
-module Clang_Analysis {
- requires cplusplus
- umbrella "Analysis"
-
- textual header "Analysis/Analyses/ThreadSafetyOps.def"
-
- module * { export * }
-}
-
-module Clang_AST {
- requires cplusplus
- umbrella "AST"
-
- textual header "AST/BuiltinTypes.def"
- textual header "AST/TypeLocNodes.def"
- textual header "AST/TypeNodes.def"
-
- module * { export * }
-}
-
-module Clang_ASTMatchers { requires cplusplus umbrella "ASTMatchers" module * { export * } }
-
-module Clang_Basic {
- requires cplusplus
- umbrella "Basic"
-
- textual header "Basic/BuiltinsAArch64.def"
- textual header "Basic/BuiltinsAMDGPU.def"
- textual header "Basic/BuiltinsARM.def"
- textual header "Basic/Builtins.def"
- textual header "Basic/BuiltinsHexagon.def"
- textual header "Basic/BuiltinsLe64.def"
- textual header "Basic/BuiltinsMips.def"
- textual header "Basic/BuiltinsNEON.def"
- textual header "Basic/BuiltinsNVPTX.def"
- textual header "Basic/BuiltinsPPC.def"
- textual header "Basic/BuiltinsSystemZ.def"
- textual header "Basic/BuiltinsWebAssembly.def"
- textual header "Basic/BuiltinsX86.def"
- textual header "Basic/BuiltinsXCore.def"
- textual header "Basic/DiagnosticOptions.def"
- textual header "Basic/LangOptions.def"
- textual header "Basic/OpenCLExtensions.def"
- textual header "Basic/OpenMPKinds.def"
- textual header "Basic/OperatorKinds.def"
- textual header "Basic/Sanitizers.def"
- textual header "Basic/TokenKinds.def"
-
- module * { export * }
-}
-
-module Clang_CodeGen { requires cplusplus umbrella "CodeGen" module * { export * } }
-module Clang_Config { requires cplusplus umbrella "Config" module * { export * } }
-
-// Files for diagnostic groups are spread all over the include/clang/ tree, but
-// logically form a single module.
-module Clang_Diagnostics {
- requires cplusplus
-
- module All { header "Basic/AllDiagnostics.h" export * }
- module Analysis { header "Analysis/AnalysisDiagnostic.h" export * }
- module AST { header "AST/ASTDiagnostic.h" export * }
- module Comment { header "AST/CommentDiagnostic.h" export * }
- module Driver { header "Driver/DriverDiagnostic.h" export * }
- module Frontend { header "Frontend/FrontendDiagnostic.h" export * }
- module Lex { header "Lex/LexDiagnostic.h" export * }
- module Parse { header "Parse/ParseDiagnostic.h" export * }
- // FIXME: This breaks the build of Clang_Sema, for unknown reasons.
- //module Sema { header "Sema/SemaDiagnostic.h" export * }
- module Serialization { header "Serialization/SerializationDiagnostic.h" export * }
-}
-
-module Clang_Driver {
- requires cplusplus
- umbrella "Driver"
-
- textual header "Driver/Types.def"
-
- module * { export * }
-}
-
-module Clang_Edit { requires cplusplus umbrella "Edit" module * { export * } }
-module Clang_Format { requires cplusplus umbrella "Format" module * { export * } }
-
-module Clang_Frontend {
- requires cplusplus
- umbrella "Frontend"
-
- textual header "Frontend/CodeGenOptions.def"
- textual header "Frontend/LangStandards.def"
-
- module * { export * }
-
- // FIXME: This violates layers.
- exclude header "Frontend/PCHContainerOperations.h"
-}
-
-module Clang_FrontendTool { requires cplusplus umbrella "FrontendTool" module * { export * } }
-module Clang_Index { requires cplusplus umbrella "Index" module * { export * } }
-module Clang_Lex { requires cplusplus umbrella "Lex" module * { export * } }
-module Clang_Parse { requires cplusplus umbrella "Parse" module * { export * } }
-module Clang_Rewrite { requires cplusplus umbrella "Rewrite" module * { export * } }
-module Clang_Sema { requires cplusplus umbrella "Sema" module * { export * } }
-module Clang_Serialization { requires cplusplus umbrella "Serialization" module * { export * } }
-
-module Clang_StaticAnalyzer_Core {
- requires cplusplus
- umbrella "StaticAnalyzer/Core"
-
- textual header "StaticAnalyzer/Core/Analyses.def"
-
- module * { export * }
-}
-
-module Clang_StaticAnalyzer_Checkers {
- requires cplusplus
- umbrella "StaticAnalyzer/Checkers"
- module * { export * }
-}
-
-module Clang_StaticAnalyzer_Frontend {
- requires cplusplus
- umbrella "StaticAnalyzer/Frontend"
- module * { export * }
-}
-
-module Clang_Tooling {
- requires cplusplus umbrella "Tooling" module * { export * }
- // FIXME: Exclude this header to avoid pulling all of the AST matchers
- // library into clang-format. Due to inline key functions in the headers,
- // importing the AST matchers library gives a link dependency on the AST
- // matchers (and thus the AST), which clang-format should not have.
- exclude header "Tooling/RefactoringCallbacks.h"
-}
OpenPOWER on IntegriCloud