summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/include
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/include')
-rw-r--r--contrib/llvm/tools/clang/include/CMakeLists.txt1
-rw-r--r--contrib/llvm/tools/clang/include/Makefile4
-rw-r--r--contrib/llvm/tools/clang/include/clang-c/Index.h2012
-rw-r--r--contrib/llvm/tools/clang/include/clang-c/Makefile31
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/APValue.h243
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/AST.h28
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h92
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ASTContext.h1404
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h47
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h240
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ASTVector.h397
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/Attr.h614
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/CMakeLists.txt5
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h365
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h742
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/CharUnits.h149
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/Decl.h2196
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h72
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclBase.h1211
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h2111
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h289
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h159
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclGroup.h152
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclNodes.def165
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h1489
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h1433
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclVisitor.h55
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h416
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/DependentDiagnostic.h192
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/Expr.h3347
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h2262
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h815
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h192
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/FullExpr.h89
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/Makefile13
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h202
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/ParentMap.h50
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h110
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h251
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h768
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h179
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/Stmt.h1381
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h113
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/StmtGraphTraits.h83
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h150
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/StmtNodes.def165
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/StmtNodes.td127
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h344
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h177
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h482
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TemplateName.h372
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/Type.h3527
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h1308
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TypeLocBuilder.h148
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TypeLocNodes.def41
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TypeLocVisitor.h62
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def119
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h56
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h52
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h186
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/UsuallyTinyPtrVector.h105
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Analyses/LiveVariables.h121
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Analyses/PrintfFormatString.h313
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ReachableCode.h55
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h77
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h263
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h27
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/CFG.h512
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h320
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h172
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h380
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h307
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h216
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Support/SaveAndRestore.h47
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h92
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h54
-rw-r--r--contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h168
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Builtins.def562
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Builtins.h142
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def20
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/BuiltinsPPC.def114
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def328
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/CMakeLists.txt20
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h159
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h968
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td87
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td84
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticAnalysisKinds.td15
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCategories.td10
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td77
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td102
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td253
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td198
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td300
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td387
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td3100
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/FileManager.h216
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h569
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h202
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Linkage.h57
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/MacroBuilder.h46
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Makefile22
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h347
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.def106
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.h35
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h287
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/PrettyStackTrace.h37
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h305
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h848
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/SourceManagerInternals.h130
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h83
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h50
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h474
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h39
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TemplateKinds.h39
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def429
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.h64
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h41
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Version.h71
-rw-r--r--contrib/llvm/tools/clang/include/clang/CMakeLists.txt3
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/BugReporter/BugReporter.h479
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/BugReporter/BugType.h72
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/BugReporter/PathDiagnostic.h494
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/Checkers/DereferenceChecker.h31
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/Checkers/LocalCheckers.h61
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/DomainSpecific/CocoaConventions.h39
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/ManagerRegistry.h53
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/AnalysisManager.h164
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/BasicValueFactory.h197
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Checker.h285
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/CheckerVisitor.def37
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/CheckerVisitor.h102
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ConstraintManager.h75
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Environment.h96
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ExplodedGraph.h436
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRAuditor.h35
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRBlockCounter.h55
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRCoreEngine.h487
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRExprEngine.h465
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h76
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h31
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRState.h750
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRStateTrait.h148
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRSubEngine.h84
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRTransferFuncs.h87
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRWorkList.h79
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/MemRegion.h967
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SVals.h502
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SValuator.h66
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Store.h237
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SummaryManager.h57
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SymbolManager.h379
-rw-r--r--contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ValueManager.h213
-rw-r--r--contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenOptions.h131
-rw-r--r--contrib/llvm/tools/clang/include/clang/CodeGen/ModuleBuilder.h42
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Action.h217
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Arg.h230
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/ArgList.h359
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h32
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td71
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/CC1Options.h32
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td511
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/CMakeLists.txt17
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Compilation.h136
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Driver.h318
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h27
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/HostInfo.h91
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Job.h157
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Makefile18
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/OptParser.td135
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/OptSpecifier.h39
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/OptTable.h188
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Option.h311
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Options.h32
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Options.td715
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Phases.h32
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Tool.h80
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h141
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Types.def81
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Types.h92
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Util.h30
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h87
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h266
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def85
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/AnalysisConsumer.h104
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticClient.h58
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/CodeGenAction.h70
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h80
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h589
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h162
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/DeclContextXML.def113
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/DeclXML.def367
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h43
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h91
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/DocumentXML.def75
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/DocumentXML.h186
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/FixItRewriter.h104
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h204
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h230
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h27
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h146
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/FrontendPluginRegistry.h23
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h95
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h83
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def83
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/PCHBitCodes.h783
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/PCHReader.h827
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/PCHWriter.h362
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/PathDiagnosticClients.h32
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h102
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h37
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/StmtXML.def520
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h52
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h85
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/TypeXML.def299
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/Utils.h93
-rw-r--r--contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticsClient.h98
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h174
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/Analyzer.h56
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/CallGraph.h146
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/DeclReferenceMap.h50
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/Entity.h144
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/GlobalSelector.h100
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/Handlers.h81
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/IndexProvider.h38
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/Indexer.h64
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/Program.h45
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/STLExtras.h63
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/SelectorMap.h57
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h37
-rw-r--r--contrib/llvm/tools/clang/include/clang/Index/Utils.h36
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h134
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/ExternalPreprocessorSource.h34
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h67
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h235
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h27
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/Lexer.h384
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h172
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h218
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/MultipleIncludeOpt.h130
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h148
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h104
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h140
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/Pragma.h90
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h274
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h939
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h162
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/ScratchBuffer.h45
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/Token.h257
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/TokenConcatenation.h75
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h154
-rw-r--r--contrib/llvm/tools/clang/include/clang/Makefile31
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/Action.h3122
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/AttributeList.h227
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/DeclSpec.h1323
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/Designator.h239
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/Ownership.h845
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h27
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/Parser.h1503
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/Scope.h329
-rw-r--r--contrib/llvm/tools/clang/include/clang/Parse/Template.h183
-rw-r--r--contrib/llvm/tools/clang/include/clang/Rewrite/DeltaTree.h48
-rw-r--r--contrib/llvm/tools/clang/include/clang/Rewrite/HTMLRewrite.h81
-rw-r--r--contrib/llvm/tools/clang/include/clang/Rewrite/RewriteRope.h230
-rw-r--r--contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h225
-rw-r--r--contrib/llvm/tools/clang/include/clang/Rewrite/TokenRewriter.h79
-rw-r--r--contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h555
-rw-r--r--contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h59
-rw-r--r--contrib/llvm/tools/clang/include/clang/Sema/ParseAST.h43
-rw-r--r--contrib/llvm/tools/clang/include/clang/Sema/SemaConsumer.h48
-rw-r--r--contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h27
271 files changed, 80509 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/include/CMakeLists.txt b/contrib/llvm/tools/clang/include/CMakeLists.txt
new file mode 100644
index 0000000..253a09b
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(clang)
diff --git a/contrib/llvm/tools/clang/include/Makefile b/contrib/llvm/tools/clang/include/Makefile
new file mode 100644
index 0000000..f686d6a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../..
+DIRS := clang clang-c
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/clang/include/clang-c/Index.h b/contrib/llvm/tools/clang/include/clang-c/Index.h
new file mode 100644
index 0000000..86926bd
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang-c/Index.h
@@ -0,0 +1,2012 @@
+/*===-- clang-c/Index.h - Indexing Public C Interface -------------*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This header provides a public inferface to a Clang library for extracting *|
+|* high-level symbol information from source files without exposing the full *|
+|* Clang C++ API. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_INDEX_H
+#define CLANG_C_INDEX_H
+
+#include <sys/stat.h>
+#include <time.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MSVC DLL import/export. */
+#ifdef _MSC_VER
+ #ifdef _CINDEX_LIB_
+ #define CINDEX_LINKAGE __declspec(dllexport)
+ #else
+ #define CINDEX_LINKAGE __declspec(dllimport)
+ #endif
+#else
+ #define CINDEX_LINKAGE
+#endif
+
+/** \defgroup CINDEX C Interface to Clang
+ *
+ * The C Interface to Clang provides a relatively small API that exposes
+ * facilities for parsing source code into an abstract syntax tree (AST),
+ * loading already-parsed ASTs, traversing the AST, associating
+ * physical source locations with elements within the AST, and other
+ * facilities that support Clang-based development tools.
+ *
+ * This C interface to Clang will never provide all of the information
+ * representation stored in Clang's C++ AST, nor should it: the intent is to
+ * maintain an API that is relatively stable from one release to the next,
+ * providing only the basic functionality needed to support development tools.
+ *
+ * To avoid namespace pollution, data types are prefixed with "CX" and
+ * functions are prefixed with "clang_".
+ *
+ * @{
+ */
+
+/**
+ * \brief An "index" that consists of a set of translation units that would
+ * typically be linked together into an executable or library.
+ */
+typedef void *CXIndex;
+
+/**
+ * \brief A single translation unit, which resides in an index.
+ */
+typedef void *CXTranslationUnit; /* A translation unit instance. */
+
+/**
+ * \brief Opaque pointer representing client data that will be passed through
+ * to various callbacks and visitors.
+ */
+typedef void *CXClientData;
+
+/**
+ * \brief Provides the contents of a file that has not yet been saved to disk.
+ *
+ * Each CXUnsavedFile instance provides the name of a file on the
+ * system along with the current contents of that file that have not
+ * yet been saved to disk.
+ */
+struct CXUnsavedFile {
+ /**
+ * \brief The file whose contents have not yet been saved.
+ *
+ * This file must already exist in the file system.
+ */
+ const char *Filename;
+
+ /**
+ * \brief A buffer containing the unsaved contents of this file.
+ */
+ const char *Contents;
+
+ /**
+ * \brief The length of the unsaved contents of this buffer.
+ */
+ unsigned long Length;
+};
+
+/**
+ * \defgroup CINDEX_STRING String manipulation routines
+ *
+ * @{
+ */
+
+/**
+ * \brief A character string.
+ *
+ * The \c CXString type is used to return strings from the interface when
+ * the ownership of that string might different from one call to the next.
+ * Use \c clang_getCString() to retrieve the string data and, once finished
+ * with the string data, call \c clang_disposeString() to free the string.
+ */
+typedef struct {
+ const char *Spelling;
+ /* A 1 value indicates the clang_ indexing API needed to allocate the string
+ (and it must be freed by clang_disposeString()). */
+ int MustFreeString;
+} CXString;
+
+/**
+ * \brief Retrieve the character data associated with the given string.
+ */
+CINDEX_LINKAGE const char *clang_getCString(CXString string);
+
+/**
+ * \brief Free the given string,
+ */
+CINDEX_LINKAGE void clang_disposeString(CXString string);
+
+/**
+ * @}
+ */
+
+/**
+ * \brief clang_createIndex() provides a shared context for creating
+ * translation units. It provides two options:
+ *
+ * - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
+ * declarations (when loading any new translation units). A "local" declaration
+ * is one that belongs in the translation unit itself and not in a precompiled
+ * header that was used by the translation unit. If zero, all declarations
+ * will be enumerated.
+ *
+ * Here is an example:
+ *
+ * // excludeDeclsFromPCH = 1, displayDiagnostics=1
+ * Idx = clang_createIndex(1, 1);
+ *
+ * // IndexTest.pch was produced with the following command:
+ * // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
+ * TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
+ *
+ * // This will load all the symbols from 'IndexTest.pch'
+ * clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ * TranslationUnitVisitor, 0);
+ * clang_disposeTranslationUnit(TU);
+ *
+ * // This will load all the symbols from 'IndexTest.c', excluding symbols
+ * // from 'IndexTest.pch'.
+ * char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
+ * TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
+ * 0, 0);
+ * clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ * TranslationUnitVisitor, 0);
+ * clang_disposeTranslationUnit(TU);
+ *
+ * This process of creating the 'pch', loading it separately, and using it (via
+ * -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
+ * (which gives the indexer the same performance benefit as the compiler).
+ */
+CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+ int displayDiagnostics);
+
+/**
+ * \brief Destroy the given index.
+ *
+ * The index must not be destroyed until all of the translation units created
+ * within that index have been destroyed.
+ */
+CINDEX_LINKAGE void clang_disposeIndex(CXIndex index);
+
+/**
+ * \brief Request that AST's be generated externally for API calls which parse
+ * source code on the fly, e.g. \see createTranslationUnitFromSourceFile.
+ *
+ * Note: This is for debugging purposes only, and may be removed at a later
+ * date.
+ *
+ * \param index - The index to update.
+ * \param value - The new flag value.
+ */
+CINDEX_LINKAGE void clang_setUseExternalASTGeneration(CXIndex index,
+ int value);
+/**
+ * \defgroup CINDEX_FILES File manipulation routines
+ *
+ * @{
+ */
+
+/**
+ * \brief A particular source file that is part of a translation unit.
+ */
+typedef void *CXFile;
+
+
+/**
+ * \brief Retrieve the complete file and path name of the given file.
+ */
+CINDEX_LINKAGE CXString clang_getFileName(CXFile SFile);
+
+/**
+ * \brief Retrieve the last modification time of the given file.
+ */
+CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile);
+
+/**
+ * \brief Retrieve a file handle within the given translation unit.
+ *
+ * \param tu the translation unit
+ *
+ * \param file_name the name of the file.
+ *
+ * \returns the file handle for the named file in the translation unit \p tu,
+ * or a NULL file handle if the file was not a part of this translation unit.
+ */
+CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
+ const char *file_name);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_LOCATIONS Physical source locations
+ *
+ * Clang represents physical source locations in its abstract syntax tree in
+ * great detail, with file, line, and column information for the majority of
+ * the tokens parsed in the source code. These data types and functions are
+ * used to represent source location information, either for a particular
+ * point in the program or for a range of points in the program, and extract
+ * specific location information from those data types.
+ *
+ * @{
+ */
+
+/**
+ * \brief Identifies a specific source location within a translation
+ * unit.
+ *
+ * Use clang_getInstantiationLocation() to map a source location to a
+ * particular file, line, and column.
+ */
+typedef struct {
+ void *ptr_data[2];
+ unsigned int_data;
+} CXSourceLocation;
+
+/**
+ * \brief Identifies a half-open character range in the source code.
+ *
+ * Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
+ * starting and end locations from a source range, respectively.
+ */
+typedef struct {
+ void *ptr_data[2];
+ unsigned begin_int_data;
+ unsigned end_int_data;
+} CXSourceRange;
+
+/**
+ * \brief Retrieve a NULL (invalid) source location.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getNullLocation();
+
+/**
+ * \determine Determine whether two source locations, which must refer into
+ * the same translation unit, refer to exactly the same point in the source
+ * code.
+ *
+ * \returns non-zero if the source locations refer to the same location, zero
+ * if they refer to different locations.
+ */
+CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1,
+ CXSourceLocation loc2);
+
+/**
+ * \brief Retrieves the source location associated with a given file/line/column
+ * in a particular translation unit.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getLocation(CXTranslationUnit tu,
+ CXFile file,
+ unsigned line,
+ unsigned column);
+
+/**
+ * \brief Retrieve a NULL (invalid) source range.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getNullRange();
+
+/**
+ * \brief Retrieve a source range given the beginning and ending source
+ * locations.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin,
+ CXSourceLocation end);
+
+/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset);
+
+/**
+ * \brief Retrieve a source location representing the first character within a
+ * source range.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getRangeStart(CXSourceRange range);
+
+/**
+ * \brief Retrieve a source location representing the last character within a
+ * source range.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range);
+
+/**
+ * \brief Determine if the source location occurs within the main file
+ * of the translation unit (as opposed to an included header).
+ */
+CINDEX_LINKAGE unsigned clang_isFromMainFile(CXSourceLocation loc);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_DIAG Diagnostic reporting
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes the severity of a particular diagnostic.
+ */
+enum CXDiagnosticSeverity {
+ /**
+ * \brief A diagnostic that has been suppressed, e.g., by a command-line
+ * option.
+ */
+ CXDiagnostic_Ignored = 0,
+
+ /**
+ * \brief This diagnostic is a note that should be attached to the
+ * previous (non-note) diagnostic.
+ */
+ CXDiagnostic_Note = 1,
+
+ /**
+ * \brief This diagnostic indicates suspicious code that may not be
+ * wrong.
+ */
+ CXDiagnostic_Warning = 2,
+
+ /**
+ * \brief This diagnostic indicates that the code is ill-formed.
+ */
+ CXDiagnostic_Error = 3,
+
+ /**
+ * \brief This diagnostic indicates that the code is ill-formed such
+ * that future parser recovery is unlikely to produce useful
+ * results.
+ */
+ CXDiagnostic_Fatal = 4
+};
+
+/**
+ * \brief A single diagnostic, containing the diagnostic's severity,
+ * location, text, source ranges, and fix-it hints.
+ */
+typedef void *CXDiagnostic;
+
+/**
+ * \brief Determine the number of diagnostics produced for the given
+ * translation unit.
+ */
+CINDEX_LINKAGE unsigned clang_getNumDiagnostics(CXTranslationUnit Unit);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given translation unit.
+ *
+ * \param Unit the translation unit to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit,
+ unsigned Index);
+
+/**
+ * \brief Destroy a diagnostic.
+ */
+CINDEX_LINKAGE void clang_disposeDiagnostic(CXDiagnostic Diagnostic);
+
+/**
+ * \brief Options to control the display of diagnostics.
+ *
+ * The values in this enum are meant to be combined to customize the
+ * behavior of \c clang_displayDiagnostic().
+ */
+enum CXDiagnosticDisplayOptions {
+ /**
+ * \brief Display the source-location information where the
+ * diagnostic was located.
+ *
+ * When set, diagnostics will be prefixed by the file, line, and
+ * (optionally) column to which the diagnostic refers. For example,
+ *
+ * \code
+ * test.c:28: warning: extra tokens at end of #endif directive
+ * \endcode
+ *
+ * This option corresponds to the clang flag \c -fshow-source-location.
+ */
+ CXDiagnostic_DisplaySourceLocation = 0x01,
+
+ /**
+ * \brief If displaying the source-location information of the
+ * diagnostic, also include the column number.
+ *
+ * This option corresponds to the clang flag \c -fshow-column.
+ */
+ CXDiagnostic_DisplayColumn = 0x02,
+
+ /**
+ * \brief If displaying the source-location information of the
+ * diagnostic, also include information about source ranges in a
+ * machine-parsable format.
+ *
+ * This option corresponds to the clang flag
+ * \c -fdiagnostics-print-source-range-info.
+ */
+ CXDiagnostic_DisplaySourceRanges = 0x04
+};
+
+/**
+ * \brief Format the given diagnostic in a manner that is suitable for display.
+ *
+ * This routine will format the given diagnostic to a string, rendering
+ * the diagnostic according to the various options given. The
+ * \c clang_defaultDiagnosticDisplayOptions() function returns the set of
+ * options that most closely mimics the behavior of the clang compiler.
+ *
+ * \param Diagnostic The diagnostic to print.
+ *
+ * \param Options A set of options that control the diagnostic display,
+ * created by combining \c CXDiagnosticDisplayOptions values.
+ *
+ * \returns A new string containing for formatted diagnostic.
+ */
+CINDEX_LINKAGE CXString clang_formatDiagnostic(CXDiagnostic Diagnostic,
+ unsigned Options);
+
+/**
+ * \brief Retrieve the set of display options most similar to the
+ * default behavior of the clang compiler.
+ *
+ * \returns A set of display options suitable for use with \c
+ * clang_displayDiagnostic().
+ */
+CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void);
+
+/**
+ * \brief Print a diagnostic to the given file.
+ */
+
+/**
+ * \brief Determine the severity of the given diagnostic.
+ */
+CINDEX_LINKAGE enum CXDiagnosticSeverity
+clang_getDiagnosticSeverity(CXDiagnostic);
+
+/**
+ * \brief Retrieve the source location of the given diagnostic.
+ *
+ * This location is where Clang would print the caret ('^') when
+ * displaying the diagnostic on the command line.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic);
+
+/**
+ * \brief Retrieve the text of the given diagnostic.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticSpelling(CXDiagnostic);
+
+/**
+ * \brief Determine the number of source ranges associated with the given
+ * diagnostic.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticNumRanges(CXDiagnostic);
+
+/**
+ * \brief Retrieve a source range associated with the diagnostic.
+ *
+ * A diagnostic's source ranges highlight important elements in the source
+ * code. On the command line, Clang displays source ranges by
+ * underlining them with '~' characters.
+ *
+ * \param Diagnostic the diagnostic whose range is being extracted.
+ *
+ * \param Range the zero-based index specifying which range to
+ *
+ * \returns the requested source range.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic,
+ unsigned Range);
+
+/**
+ * \brief Determine the number of fix-it hints associated with the
+ * given diagnostic.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic);
+
+/**
+ * \brief Retrieve the replacement information for a given fix-it.
+ *
+ * Fix-its are described in terms of a source range whose contents
+ * should be replaced by a string. This approach generalizes over
+ * three kinds of operations: removal of source code (the range covers
+ * the code to be removed and the replacement string is empty),
+ * replacement of source code (the range covers the code to be
+ * replaced and the replacement string provides the new code), and
+ * insertion (both the start and end of the range point at the
+ * insertion location, and the replacement string provides the text to
+ * insert).
+ *
+ * \param Diagnostic The diagnostic whose fix-its are being queried.
+ *
+ * \param FixIt The zero-based index of the fix-it.
+ *
+ * \param ReplacementRange The source range whose contents will be
+ * replaced with the returned replacement string. Note that source
+ * ranges are half-open ranges [a, b), so the source code should be
+ * replaced from a and up to (but not including) b.
+ *
+ * \returns A string containing text that should be replace the source
+ * code indicated by the \c ReplacementRange.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic,
+ unsigned FixIt,
+ CXSourceRange *ReplacementRange);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_TRANSLATION_UNIT Translation unit manipulation
+ *
+ * The routines in this group provide the ability to create and destroy
+ * translation units from files, either by parsing the contents of the files or
+ * by reading in a serialized representation of a translation unit.
+ *
+ * @{
+ */
+
+/**
+ * \brief Get the original translation unit source file name.
+ */
+CINDEX_LINKAGE CXString
+clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
+
+/**
+ * \brief Return the CXTranslationUnit for a given source file and the provided
+ * command line arguments one would pass to the compiler.
+ *
+ * Note: The 'source_filename' argument is optional. If the caller provides a
+ * NULL pointer, the name of the source file is expected to reside in the
+ * specified command line arguments.
+ *
+ * Note: When encountered in 'clang_command_line_args', the following options
+ * are ignored:
+ *
+ * '-c'
+ * '-emit-ast'
+ * '-fsyntax-only'
+ * '-o <output file>' (both '-o' and '<output file>' are ignored)
+ *
+ *
+ * \param source_filename - The name of the source file to load, or NULL if the
+ * source file is included in clang_command_line_args.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for code completion, including the contents of
+ * those files. The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param diag_callback callback function that will receive any diagnostics
+ * emitted while processing this source file. If NULL, diagnostics will be
+ * suppressed.
+ *
+ * \param diag_client_data client data that will be passed to the diagnostic
+ * callback function.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+ CXIndex CIdx,
+ const char *source_filename,
+ int num_clang_command_line_args,
+ const char **clang_command_line_args,
+ unsigned num_unsaved_files,
+ struct CXUnsavedFile *unsaved_files);
+
+/**
+ * \brief Create a translation unit from an AST file (-emit-ast).
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(CXIndex,
+ const char *ast_filename);
+
+/**
+ * \brief Destroy the specified CXTranslationUnit object.
+ */
+CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
+
+/**
+ * @}
+ */
+
+/**
+ * \brief Describes the kind of entity that a cursor refers to.
+ */
+enum CXCursorKind {
+ /* Declarations */
+ /**
+ * \brief A declaration whose specific kind is not exposed via this
+ * interface.
+ *
+ * Unexposed declarations have the same operations as any other kind
+ * of declaration; one can extract their location information,
+ * spelling, find their definitions, etc. However, the specific kind
+ * of the declaration is not reported.
+ */
+ CXCursor_UnexposedDecl = 1,
+ /** \brief A C or C++ struct. */
+ CXCursor_StructDecl = 2,
+ /** \brief A C or C++ union. */
+ CXCursor_UnionDecl = 3,
+ /** \brief A C++ class. */
+ CXCursor_ClassDecl = 4,
+ /** \brief An enumeration. */
+ CXCursor_EnumDecl = 5,
+ /**
+ * \brief A field (in C) or non-static data member (in C++) in a
+ * struct, union, or C++ class.
+ */
+ CXCursor_FieldDecl = 6,
+ /** \brief An enumerator constant. */
+ CXCursor_EnumConstantDecl = 7,
+ /** \brief A function. */
+ CXCursor_FunctionDecl = 8,
+ /** \brief A variable. */
+ CXCursor_VarDecl = 9,
+ /** \brief A function or method parameter. */
+ CXCursor_ParmDecl = 10,
+ /** \brief An Objective-C @interface. */
+ CXCursor_ObjCInterfaceDecl = 11,
+ /** \brief An Objective-C @interface for a category. */
+ CXCursor_ObjCCategoryDecl = 12,
+ /** \brief An Objective-C @protocol declaration. */
+ CXCursor_ObjCProtocolDecl = 13,
+ /** \brief An Objective-C @property declaration. */
+ CXCursor_ObjCPropertyDecl = 14,
+ /** \brief An Objective-C instance variable. */
+ CXCursor_ObjCIvarDecl = 15,
+ /** \brief An Objective-C instance method. */
+ CXCursor_ObjCInstanceMethodDecl = 16,
+ /** \brief An Objective-C class method. */
+ CXCursor_ObjCClassMethodDecl = 17,
+ /** \brief An Objective-C @implementation. */
+ CXCursor_ObjCImplementationDecl = 18,
+ /** \brief An Objective-C @implementation for a category. */
+ CXCursor_ObjCCategoryImplDecl = 19,
+ /** \brief A typedef */
+ CXCursor_TypedefDecl = 20,
+ /** \brief A C++ class method. */
+ CXCursor_CXXMethod = 21,
+ /** \brief A C++ namespace. */
+ CXCursor_Namespace = 22,
+ /** \brief A linkage specification, e.g. 'extern "C"'. */
+ CXCursor_LinkageSpec = 23,
+
+ CXCursor_FirstDecl = CXCursor_UnexposedDecl,
+ CXCursor_LastDecl = CXCursor_LinkageSpec,
+
+ /* References */
+ CXCursor_FirstRef = 40, /* Decl references */
+ CXCursor_ObjCSuperClassRef = 40,
+ CXCursor_ObjCProtocolRef = 41,
+ CXCursor_ObjCClassRef = 42,
+ /**
+ * \brief A reference to a type declaration.
+ *
+ * A type reference occurs anywhere where a type is named but not
+ * declared. For example, given:
+ *
+ * \code
+ * typedef unsigned size_type;
+ * size_type size;
+ * \endcode
+ *
+ * The typedef is a declaration of size_type (CXCursor_TypedefDecl),
+ * while the type of the variable "size" is referenced. The cursor
+ * referenced by the type of size is the typedef for size_type.
+ */
+ CXCursor_TypeRef = 43,
+ CXCursor_LastRef = 43,
+
+ /* Error conditions */
+ CXCursor_FirstInvalid = 70,
+ CXCursor_InvalidFile = 70,
+ CXCursor_NoDeclFound = 71,
+ CXCursor_NotImplemented = 72,
+ CXCursor_InvalidCode = 73,
+ CXCursor_LastInvalid = CXCursor_InvalidCode,
+
+ /* Expressions */
+ CXCursor_FirstExpr = 100,
+
+ /**
+ * \brief An expression whose specific kind is not exposed via this
+ * interface.
+ *
+ * Unexposed expressions have the same operations as any other kind
+ * of expression; one can extract their location information,
+ * spelling, children, etc. However, the specific kind of the
+ * expression is not reported.
+ */
+ CXCursor_UnexposedExpr = 100,
+
+ /**
+ * \brief An expression that refers to some value declaration, such
+ * as a function, varible, or enumerator.
+ */
+ CXCursor_DeclRefExpr = 101,
+
+ /**
+ * \brief An expression that refers to a member of a struct, union,
+ * class, Objective-C class, etc.
+ */
+ CXCursor_MemberRefExpr = 102,
+
+ /** \brief An expression that calls a function. */
+ CXCursor_CallExpr = 103,
+
+ /** \brief An expression that sends a message to an Objective-C
+ object or class. */
+ CXCursor_ObjCMessageExpr = 104,
+
+ /** \brief An expression that represents a block literal. */
+ CXCursor_BlockExpr = 105,
+
+ CXCursor_LastExpr = 105,
+
+ /* Statements */
+ CXCursor_FirstStmt = 200,
+ /**
+ * \brief A statement whose specific kind is not exposed via this
+ * interface.
+ *
+ * Unexposed statements have the same operations as any other kind of
+ * statement; one can extract their location information, spelling,
+ * children, etc. However, the specific kind of the statement is not
+ * reported.
+ */
+ CXCursor_UnexposedStmt = 200,
+ CXCursor_LastStmt = 200,
+
+ /**
+ * \brief Cursor that represents the translation unit itself.
+ *
+ * The translation unit cursor exists primarily to act as the root
+ * cursor for traversing the contents of a translation unit.
+ */
+ CXCursor_TranslationUnit = 300,
+
+ /* Attributes */
+ CXCursor_FirstAttr = 400,
+ /**
+ * \brief An attribute whose specific kind is not exposed via this
+ * interface.
+ */
+ CXCursor_UnexposedAttr = 400,
+
+ CXCursor_IBActionAttr = 401,
+ CXCursor_IBOutletAttr = 402,
+ CXCursor_IBOutletCollectionAttr = 403,
+ CXCursor_LastAttr = CXCursor_IBOutletCollectionAttr,
+
+ /* Preprocessing */
+ CXCursor_PreprocessingDirective = 500,
+ CXCursor_MacroDefinition = 501,
+ CXCursor_MacroInstantiation = 502,
+ CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective,
+ CXCursor_LastPreprocessing = CXCursor_MacroInstantiation
+};
+
+/**
+ * \brief A cursor representing some element in the abstract syntax tree for
+ * a translation unit.
+ *
+ * The cursor abstraction unifies the different kinds of entities in a
+ * program--declaration, statements, expressions, references to declarations,
+ * etc.--under a single "cursor" abstraction with a common set of operations.
+ * Common operation for a cursor include: getting the physical location in
+ * a source file where the cursor points, getting the name associated with a
+ * cursor, and retrieving cursors for any child nodes of a particular cursor.
+ *
+ * Cursors can be produced in two specific ways.
+ * clang_getTranslationUnitCursor() produces a cursor for a translation unit,
+ * from which one can use clang_visitChildren() to explore the rest of the
+ * translation unit. clang_getCursor() maps from a physical source location
+ * to the entity that resides at that location, allowing one to map from the
+ * source code into the AST.
+ */
+typedef struct {
+ enum CXCursorKind kind;
+ void *data[3];
+} CXCursor;
+
+/**
+ * \defgroup CINDEX_CURSOR_MANIP Cursor manipulations
+ *
+ * @{
+ */
+
+/**
+ * \brief Retrieve the NULL cursor, which represents no entity.
+ */
+CINDEX_LINKAGE CXCursor clang_getNullCursor(void);
+
+/**
+ * \brief Retrieve the cursor that represents the given translation unit.
+ *
+ * The translation unit cursor can be used to start traversing the
+ * various declarations within the given translation unit.
+ */
+CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit);
+
+/**
+ * \brief Determine whether two cursors are equivalent.
+ */
+CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor);
+
+/**
+ * \brief Retrieve the kind of the given cursor.
+ */
+CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor);
+
+/**
+ * \brief Determine whether the given cursor kind represents a declaration.
+ */
+CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a simple
+ * reference.
+ *
+ * Note that other kinds of cursors (such as expressions) can also refer to
+ * other cursors. Use clang_getCursorReferenced() to determine whether a
+ * particular cursor refers to another entity.
+ */
+CINDEX_LINKAGE unsigned clang_isReference(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents an expression.
+ */
+CINDEX_LINKAGE unsigned clang_isExpression(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a statement.
+ */
+CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents an invalid
+ * cursor.
+ */
+CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a translation
+ * unit.
+ */
+CINDEX_LINKAGE unsigned clang_isTranslationUnit(enum CXCursorKind);
+
+/***
+ * \brief Determine whether the given cursor represents a preprocessing
+ * element, such as a preprocessor directive or macro instantiation.
+ */
+CINDEX_LINKAGE unsigned clang_isPreprocessing(enum CXCursorKind);
+
+/***
+ * \brief Determine whether the given cursor represents a currently
+ * unexposed piece of the AST (e.g., CXCursor_UnexposedStmt).
+ */
+CINDEX_LINKAGE unsigned clang_isUnexposed(enum CXCursorKind);
+
+/**
+ * \brief Describe the linkage of the entity referred to by a cursor.
+ */
+enum CXLinkageKind {
+ /** \brief This value indicates that no linkage information is available
+ * for a provided CXCursor. */
+ CXLinkage_Invalid,
+ /**
+ * \brief This is the linkage for variables, parameters, and so on that
+ * have automatic storage. This covers normal (non-extern) local variables.
+ */
+ CXLinkage_NoLinkage,
+ /** \brief This is the linkage for static variables and static functions. */
+ CXLinkage_Internal,
+ /** \brief This is the linkage for entities with external linkage that live
+ * in C++ anonymous namespaces.*/
+ CXLinkage_UniqueExternal,
+ /** \brief This is the linkage for entities with true, external linkage. */
+ CXLinkage_External
+};
+
+/**
+ * \brief Determine the linkage of the entity referred to by a given cursor.
+ */
+CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor);
+
+/**
+ * \brief Describe the "language" of the entity referred to by a cursor.
+ */
+CINDEX_LINKAGE enum CXLanguageKind {
+ CXLanguage_Invalid = 0,
+ CXLanguage_C,
+ CXLanguage_ObjC,
+ CXLanguage_CPlusPlus
+};
+
+/**
+ * \brief Determine the "language" of the entity referred to by a given cursor.
+ */
+CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_SOURCE Mapping between cursors and source code
+ *
+ * Cursors represent a location within the Abstract Syntax Tree (AST). These
+ * routines help map between cursors and the physical locations where the
+ * described entities occur in the source code. The mapping is provided in
+ * both directions, so one can map from source code to the AST and back.
+ *
+ * @{
+ */
+
+/**
+ * \brief Map a source location to the cursor that describes the entity at that
+ * location in the source code.
+ *
+ * clang_getCursor() maps an arbitrary source location within a translation
+ * unit down to the most specific cursor that describes the entity at that
+ * location. For example, given an expression \c x + y, invoking
+ * clang_getCursor() with a source location pointing to "x" will return the
+ * cursor for "x"; similarly for "y". If the cursor points anywhere between
+ * "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor()
+ * will return a cursor referring to the "+" expression.
+ *
+ * \returns a cursor representing the entity at the given source location, or
+ * a NULL cursor if no such entity can be found.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, CXSourceLocation);
+
+/**
+ * \brief Retrieve the physical location of the source constructor referenced
+ * by the given cursor.
+ *
+ * The location of a declaration is typically the location of the name of that
+ * declaration, where the name of that declaration would occur if it is
+ * unnamed, or some keyword that introduces that particular declaration.
+ * The location of a reference is where that reference occurs within the
+ * source code.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor);
+
+/**
+ * \brief Retrieve the physical extent of the source construct referenced by
+ * the given cursor.
+ *
+ * The extent of a cursor starts with the file/line/column pointing at the
+ * first character within the source construct that the cursor refers to and
+ * ends with the last character withinin that source construct. For a
+ * declaration, the extent covers the declaration itself. For a reference,
+ * the extent covers the location of the reference (e.g., where the referenced
+ * entity was actually used).
+ */
+CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_TYPES Type information for CXCursors
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes the kind of type
+ */
+enum CXTypeKind {
+ /**
+ * \brief Reprents an invalid type (e.g., where no type is available).
+ */
+ CXType_Invalid = 0,
+
+ /**
+ * \brief A type whose specific kind is not exposed via this
+ * interface.
+ */
+ CXType_Unexposed = 1,
+
+ /* Builtin types */
+ CXType_Void = 2,
+ CXType_Bool = 3,
+ CXType_Char_U = 4,
+ CXType_UChar = 5,
+ CXType_Char16 = 6,
+ CXType_Char32 = 7,
+ CXType_UShort = 8,
+ CXType_UInt = 9,
+ CXType_ULong = 10,
+ CXType_ULongLong = 11,
+ CXType_UInt128 = 12,
+ CXType_Char_S = 13,
+ CXType_SChar = 14,
+ CXType_WChar = 15,
+ CXType_Short = 16,
+ CXType_Int = 17,
+ CXType_Long = 18,
+ CXType_LongLong = 19,
+ CXType_Int128 = 20,
+ CXType_Float = 21,
+ CXType_Double = 22,
+ CXType_LongDouble = 23,
+ CXType_NullPtr = 24,
+ CXType_Overload = 25,
+ CXType_Dependent = 26,
+ CXType_ObjCId = 27,
+ CXType_ObjCClass = 28,
+ CXType_ObjCSel = 29,
+ CXType_FirstBuiltin = CXType_Void,
+ CXType_LastBuiltin = CXType_ObjCSel,
+
+ CXType_Complex = 100,
+ CXType_Pointer = 101,
+ CXType_BlockPointer = 102,
+ CXType_LValueReference = 103,
+ CXType_RValueReference = 104,
+ CXType_Record = 105,
+ CXType_Enum = 106,
+ CXType_Typedef = 107,
+ CXType_ObjCInterface = 108,
+ CXType_ObjCObjectPointer = 109
+};
+
+/**
+ * \brief The type of an element in the abstract syntax tree.
+ *
+ */
+typedef struct {
+ enum CXTypeKind kind;
+ void *data[2];
+} CXType;
+
+/**
+ * \brief Retrieve the type of a CXCursor (if any).
+ */
+CINDEX_LINKAGE CXType clang_getCursorType(CXCursor C);
+
+/**
+ * \determine Determine whether two CXTypes represent the same type.
+ *
+ * \returns non-zero if the CXTypes represent the same type and
+ zero otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_equalTypes(CXType A, CXType B);
+
+/**
+ * \brief Return the canonical type for a CXType.
+ *
+ * Clang's type system explicitly models typedefs and all the ways
+ * a specific type can be represented. The canonical type is the underlying
+ * type with all the "sugar" removed. For example, if 'T' is a typedef
+ * for 'int', the canonical type for 'T' would be 'int'.
+ */
+CINDEX_LINKAGE CXType clang_getCanonicalType(CXType T);
+
+/**
+ * \brief For pointer types, returns the type of the pointee.
+ *
+ */
+CINDEX_LINKAGE CXType clang_getPointeeType(CXType T);
+
+/**
+ * \brief Return the cursor for the declaration of the given type.
+ */
+CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T);
+
+
+/**
+ * \brief Retrieve the spelling of a given CXTypeKind.
+ */
+CINDEX_LINKAGE CXString clang_getTypeKindSpelling(enum CXTypeKind K);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_TRAVERSAL Traversing the AST with cursors
+ *
+ * These routines provide the ability to traverse the abstract syntax tree
+ * using cursors.
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes how the traversal of the children of a particular
+ * cursor should proceed after visiting a particular child cursor.
+ *
+ * A value of this enumeration type should be returned by each
+ * \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
+ */
+enum CXChildVisitResult {
+ /**
+ * \brief Terminates the cursor traversal.
+ */
+ CXChildVisit_Break,
+ /**
+ * \brief Continues the cursor traversal with the next sibling of
+ * the cursor just visited, without visiting its children.
+ */
+ CXChildVisit_Continue,
+ /**
+ * \brief Recursively traverse the children of this cursor, using
+ * the same visitor and client data.
+ */
+ CXChildVisit_Recurse
+};
+
+/**
+ * \brief Visitor invoked for each cursor found by a traversal.
+ *
+ * This visitor function will be invoked for each cursor found by
+ * clang_visitCursorChildren(). Its first argument is the cursor being
+ * visited, its second argument is the parent visitor for that cursor,
+ * and its third argument is the client data provided to
+ * clang_visitCursorChildren().
+ *
+ * The visitor should return one of the \c CXChildVisitResult values
+ * to direct clang_visitCursorChildren().
+ */
+typedef enum CXChildVisitResult (*CXCursorVisitor)(CXCursor cursor,
+ CXCursor parent,
+ CXClientData client_data);
+
+/**
+ * \brief Visit the children of a particular cursor.
+ *
+ * This function visits all the direct children of the given cursor,
+ * invoking the given \p visitor function with the cursors of each
+ * visited child. The traversal may be recursive, if the visitor returns
+ * \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
+ * the visitor returns \c CXChildVisit_Break.
+ *
+ * \param parent the cursor whose child may be visited. All kinds of
+ * cursors can be visited, including invalid cursors (which, by
+ * definition, have no children).
+ *
+ * \param visitor the visitor function that will be invoked for each
+ * child of \p parent.
+ *
+ * \param client_data pointer data supplied by the client, which will
+ * be passed to the visitor each time it is invoked.
+ *
+ * \returns a non-zero value if the traversal was terminated
+ * prematurely by the visitor returning \c CXChildVisit_Break.
+ */
+CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent,
+ CXCursorVisitor visitor,
+ CXClientData client_data);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_XREF Cross-referencing in the AST
+ *
+ * These routines provide the ability to determine references within and
+ * across translation units, by providing the names of the entities referenced
+ * by cursors, follow reference cursors to the declarations they reference,
+ * and associate declarations with their definitions.
+ *
+ * @{
+ */
+
+/**
+ * \brief Retrieve a Unified Symbol Resolution (USR) for the entity referenced
+ * by the given cursor.
+ *
+ * A Unified Symbol Resolution (USR) is a string that identifies a particular
+ * entity (function, class, variable, etc.) within a program. USRs can be
+ * compared across translation units to determine, e.g., when references in
+ * one translation refer to an entity defined in another translation unit.
+ */
+CINDEX_LINKAGE CXString clang_getCursorUSR(CXCursor);
+
+/**
+ * \brief Construct a USR for a specified Objective-C class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCClass(const char *class_name);
+
+/**
+ * \brief Construct a USR for a specified Objective-C category.
+ */
+CINDEX_LINKAGE CXString
+ clang_constructUSR_ObjCCategory(const char *class_name,
+ const char *category_name);
+
+/**
+ * \brief Construct a USR for a specified Objective-C protocol.
+ */
+CINDEX_LINKAGE CXString
+ clang_constructUSR_ObjCProtocol(const char *protocol_name);
+
+
+/**
+ * \brief Construct a USR for a specified Objective-C instance variable and
+ * the USR for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCIvar(const char *name,
+ CXString classUSR);
+
+/**
+ * \brief Construct a USR for a specified Objective-C method and
+ * the USR for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCMethod(const char *name,
+ unsigned isInstanceMethod,
+ CXString classUSR);
+
+/**
+ * \brief Construct a USR for a specified Objective-C property and the USR
+ * for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCProperty(const char *property,
+ CXString classUSR);
+
+/**
+ * \brief Retrieve a name for the entity referenced by this cursor.
+ */
+CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
+
+/** \brief For a cursor that is a reference, retrieve a cursor representing the
+ * entity that it references.
+ *
+ * Reference cursors refer to other entities in the AST. For example, an
+ * Objective-C superclass reference cursor refers to an Objective-C class.
+ * This function produces the cursor for the Objective-C class from the
+ * cursor for the superclass reference. If the input cursor is a declaration or
+ * definition, it returns that declaration or definition unchanged.
+ * Otherwise, returns the NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorReferenced(CXCursor);
+
+/**
+ * \brief For a cursor that is either a reference to or a declaration
+ * of some entity, retrieve a cursor that describes the definition of
+ * that entity.
+ *
+ * Some entities can be declared multiple times within a translation
+ * unit, but only one of those declarations can also be a
+ * definition. For example, given:
+ *
+ * \code
+ * int f(int, int);
+ * int g(int x, int y) { return f(x, y); }
+ * int f(int a, int b) { return a + b; }
+ * int f(int, int);
+ * \endcode
+ *
+ * there are three declarations of the function "f", but only the
+ * second one is a definition. The clang_getCursorDefinition()
+ * function will take any cursor pointing to a declaration of "f"
+ * (the first or fourth lines of the example) or a cursor referenced
+ * that uses "f" (the call to "f' inside "g") and will return a
+ * declaration cursor pointing to the definition (the second "f"
+ * declaration).
+ *
+ * If given a cursor for which there is no corresponding definition,
+ * e.g., because there is no definition of that entity within this
+ * translation unit, returns a NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorDefinition(CXCursor);
+
+/**
+ * \brief Determine whether the declaration pointed to by this cursor
+ * is also a definition of that entity.
+ */
+CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CPP C++ AST introspection
+ *
+ * The routines in this group provide access information in the ASTs specific
+ * to C++ language features.
+ *
+ * @{
+ */
+
+/**
+ * \brief Determine if a C++ member function is declared 'static'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_LEX Token extraction and manipulation
+ *
+ * The routines in this group provide access to the tokens within a
+ * translation unit, along with a semantic mapping of those tokens to
+ * their corresponding cursors.
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes a kind of token.
+ */
+typedef enum CXTokenKind {
+ /**
+ * \brief A token that contains some kind of punctuation.
+ */
+ CXToken_Punctuation,
+
+ /**
+ * \brief A language keyword.
+ */
+ CXToken_Keyword,
+
+ /**
+ * \brief An identifier (that is not a keyword).
+ */
+ CXToken_Identifier,
+
+ /**
+ * \brief A numeric, string, or character literal.
+ */
+ CXToken_Literal,
+
+ /**
+ * \brief A comment.
+ */
+ CXToken_Comment
+} CXTokenKind;
+
+/**
+ * \brief Describes a single preprocessing token.
+ */
+typedef struct {
+ unsigned int_data[4];
+ void *ptr_data;
+} CXToken;
+
+/**
+ * \brief Determine the kind of the given token.
+ */
+CINDEX_LINKAGE CXTokenKind clang_getTokenKind(CXToken);
+
+/**
+ * \brief Determine the spelling of the given token.
+ *
+ * The spelling of a token is the textual representation of that token, e.g.,
+ * the text of an identifier or keyword.
+ */
+CINDEX_LINKAGE CXString clang_getTokenSpelling(CXTranslationUnit, CXToken);
+
+/**
+ * \brief Retrieve the source location of the given token.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getTokenLocation(CXTranslationUnit,
+ CXToken);
+
+/**
+ * \brief Retrieve a source range that covers the given token.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getTokenExtent(CXTranslationUnit, CXToken);
+
+/**
+ * \brief Tokenize the source code described by the given range into raw
+ * lexical tokens.
+ *
+ * \param TU the translation unit whose text is being tokenized.
+ *
+ * \param Range the source range in which text should be tokenized. All of the
+ * tokens produced by tokenization will fall within this source range,
+ *
+ * \param Tokens this pointer will be set to point to the array of tokens
+ * that occur within the given source range. The returned pointer must be
+ * freed with clang_disposeTokens() before the translation unit is destroyed.
+ *
+ * \param NumTokens will be set to the number of tokens in the \c *Tokens
+ * array.
+ *
+ */
+CINDEX_LINKAGE void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
+ CXToken **Tokens, unsigned *NumTokens);
+
+/**
+ * \brief Annotate the given set of tokens by providing cursors for each token
+ * that can be mapped to a specific entity within the abstract syntax tree.
+ *
+ * This token-annotation routine is equivalent to invoking
+ * clang_getCursor() for the source locations of each of the
+ * tokens. The cursors provided are filtered, so that only those
+ * cursors that have a direct correspondence to the token are
+ * accepted. For example, given a function call \c f(x),
+ * clang_getCursor() would provide the following cursors:
+ *
+ * * when the cursor is over the 'f', a DeclRefExpr cursor referring to 'f'.
+ * * when the cursor is over the '(' or the ')', a CallExpr referring to 'f'.
+ * * when the cursor is over the 'x', a DeclRefExpr cursor referring to 'x'.
+ *
+ * Only the first and last of these cursors will occur within the
+ * annotate, since the tokens "f" and "x' directly refer to a function
+ * and a variable, respectively, but the parentheses are just a small
+ * part of the full syntax of the function call expression, which is
+ * not provided as an annotation.
+ *
+ * \param TU the translation unit that owns the given tokens.
+ *
+ * \param Tokens the set of tokens to annotate.
+ *
+ * \param NumTokens the number of tokens in \p Tokens.
+ *
+ * \param Cursors an array of \p NumTokens cursors, whose contents will be
+ * replaced with the cursors corresponding to each token.
+ */
+CINDEX_LINKAGE void clang_annotateTokens(CXTranslationUnit TU,
+ CXToken *Tokens, unsigned NumTokens,
+ CXCursor *Cursors);
+
+/**
+ * \brief Free the given set of tokens.
+ */
+CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU,
+ CXToken *Tokens, unsigned NumTokens);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_DEBUG Debugging facilities
+ *
+ * These routines are used for testing and debugging, only, and should not
+ * be relied upon.
+ *
+ * @{
+ */
+
+/* for debug/testing */
+CINDEX_LINKAGE CXString clang_getCursorKindSpelling(enum CXCursorKind Kind);
+CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,
+ const char **startBuf,
+ const char **endBuf,
+ unsigned *startLine,
+ unsigned *startColumn,
+ unsigned *endLine,
+ unsigned *endColumn);
+CINDEX_LINKAGE void clang_enableStackTraces(void);
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CODE_COMPLET Code completion
+ *
+ * Code completion involves taking an (incomplete) source file, along with
+ * knowledge of where the user is actively editing that file, and suggesting
+ * syntactically- and semantically-valid constructs that the user might want to
+ * use at that particular point in the source code. These data structures and
+ * routines provide support for code completion.
+ *
+ * @{
+ */
+
+/**
+ * \brief A semantic string that describes a code-completion result.
+ *
+ * A semantic string that describes the formatting of a code-completion
+ * result as a single "template" of text that should be inserted into the
+ * source buffer when a particular code-completion result is selected.
+ * Each semantic string is made up of some number of "chunks", each of which
+ * contains some text along with a description of what that text means, e.g.,
+ * the name of the entity being referenced, whether the text chunk is part of
+ * the template, or whether it is a "placeholder" that the user should replace
+ * with actual code,of a specific kind. See \c CXCompletionChunkKind for a
+ * description of the different kinds of chunks.
+ */
+typedef void *CXCompletionString;
+
+/**
+ * \brief A single result of code completion.
+ */
+typedef struct {
+ /**
+ * \brief The kind of entity that this completion refers to.
+ *
+ * The cursor kind will be a macro, keyword, or a declaration (one of the
+ * *Decl cursor kinds), describing the entity that the completion is
+ * referring to.
+ *
+ * \todo In the future, we would like to provide a full cursor, to allow
+ * the client to extract additional information from declaration.
+ */
+ enum CXCursorKind CursorKind;
+
+ /**
+ * \brief The code-completion string that describes how to insert this
+ * code-completion result into the editing buffer.
+ */
+ CXCompletionString CompletionString;
+} CXCompletionResult;
+
+/**
+ * \brief Describes a single piece of text within a code-completion string.
+ *
+ * Each "chunk" within a code-completion string (\c CXCompletionString) is
+ * either a piece of text with a specific "kind" that describes how that text
+ * should be interpreted by the client or is another completion string.
+ */
+enum CXCompletionChunkKind {
+ /**
+ * \brief A code-completion string that describes "optional" text that
+ * could be a part of the template (but is not required).
+ *
+ * The Optional chunk is the only kind of chunk that has a code-completion
+ * string for its representation, which is accessible via
+ * \c clang_getCompletionChunkCompletionString(). The code-completion string
+ * describes an additional part of the template that is completely optional.
+ * For example, optional chunks can be used to describe the placeholders for
+ * arguments that match up with defaulted function parameters, e.g. given:
+ *
+ * \code
+ * void f(int x, float y = 3.14, double z = 2.71828);
+ * \endcode
+ *
+ * The code-completion string for this function would contain:
+ * - a TypedText chunk for "f".
+ * - a LeftParen chunk for "(".
+ * - a Placeholder chunk for "int x"
+ * - an Optional chunk containing the remaining defaulted arguments, e.g.,
+ * - a Comma chunk for ","
+ * - a Placeholder chunk for "float y"
+ * - an Optional chunk containing the last defaulted argument:
+ * - a Comma chunk for ","
+ * - a Placeholder chunk for "double z"
+ * - a RightParen chunk for ")"
+ *
+ * There are many ways to handle Optional chunks. Two simple approaches are:
+ * - Completely ignore optional chunks, in which case the template for the
+ * function "f" would only include the first parameter ("int x").
+ * - Fully expand all optional chunks, in which case the template for the
+ * function "f" would have all of the parameters.
+ */
+ CXCompletionChunk_Optional,
+ /**
+ * \brief Text that a user would be expected to type to get this
+ * code-completion result.
+ *
+ * There will be exactly one "typed text" chunk in a semantic string, which
+ * will typically provide the spelling of a keyword or the name of a
+ * declaration that could be used at the current code point. Clients are
+ * expected to filter the code-completion results based on the text in this
+ * chunk.
+ */
+ CXCompletionChunk_TypedText,
+ /**
+ * \brief Text that should be inserted as part of a code-completion result.
+ *
+ * A "text" chunk represents text that is part of the template to be
+ * inserted into user code should this particular code-completion result
+ * be selected.
+ */
+ CXCompletionChunk_Text,
+ /**
+ * \brief Placeholder text that should be replaced by the user.
+ *
+ * A "placeholder" chunk marks a place where the user should insert text
+ * into the code-completion template. For example, placeholders might mark
+ * the function parameters for a function declaration, to indicate that the
+ * user should provide arguments for each of those parameters. The actual
+ * text in a placeholder is a suggestion for the text to display before
+ * the user replaces the placeholder with real code.
+ */
+ CXCompletionChunk_Placeholder,
+ /**
+ * \brief Informative text that should be displayed but never inserted as
+ * part of the template.
+ *
+ * An "informative" chunk contains annotations that can be displayed to
+ * help the user decide whether a particular code-completion result is the
+ * right option, but which is not part of the actual template to be inserted
+ * by code completion.
+ */
+ CXCompletionChunk_Informative,
+ /**
+ * \brief Text that describes the current parameter when code-completion is
+ * referring to function call, message send, or template specialization.
+ *
+ * A "current parameter" chunk occurs when code-completion is providing
+ * information about a parameter corresponding to the argument at the
+ * code-completion point. For example, given a function
+ *
+ * \code
+ * int add(int x, int y);
+ * \endcode
+ *
+ * and the source code \c add(, where the code-completion point is after the
+ * "(", the code-completion string will contain a "current parameter" chunk
+ * for "int x", indicating that the current argument will initialize that
+ * parameter. After typing further, to \c add(17, (where the code-completion
+ * point is after the ","), the code-completion string will contain a
+ * "current paremeter" chunk to "int y".
+ */
+ CXCompletionChunk_CurrentParameter,
+ /**
+ * \brief A left parenthesis ('('), used to initiate a function call or
+ * signal the beginning of a function parameter list.
+ */
+ CXCompletionChunk_LeftParen,
+ /**
+ * \brief A right parenthesis (')'), used to finish a function call or
+ * signal the end of a function parameter list.
+ */
+ CXCompletionChunk_RightParen,
+ /**
+ * \brief A left bracket ('[').
+ */
+ CXCompletionChunk_LeftBracket,
+ /**
+ * \brief A right bracket (']').
+ */
+ CXCompletionChunk_RightBracket,
+ /**
+ * \brief A left brace ('{').
+ */
+ CXCompletionChunk_LeftBrace,
+ /**
+ * \brief A right brace ('}').
+ */
+ CXCompletionChunk_RightBrace,
+ /**
+ * \brief A left angle bracket ('<').
+ */
+ CXCompletionChunk_LeftAngle,
+ /**
+ * \brief A right angle bracket ('>').
+ */
+ CXCompletionChunk_RightAngle,
+ /**
+ * \brief A comma separator (',').
+ */
+ CXCompletionChunk_Comma,
+ /**
+ * \brief Text that specifies the result type of a given result.
+ *
+ * This special kind of informative chunk is not meant to be inserted into
+ * the text buffer. Rather, it is meant to illustrate the type that an
+ * expression using the given completion string would have.
+ */
+ CXCompletionChunk_ResultType,
+ /**
+ * \brief A colon (':').
+ */
+ CXCompletionChunk_Colon,
+ /**
+ * \brief A semicolon (';').
+ */
+ CXCompletionChunk_SemiColon,
+ /**
+ * \brief An '=' sign.
+ */
+ CXCompletionChunk_Equal,
+ /**
+ * Horizontal space (' ').
+ */
+ CXCompletionChunk_HorizontalSpace,
+ /**
+ * Vertical space ('\n'), after which it is generally a good idea to
+ * perform indentation.
+ */
+ CXCompletionChunk_VerticalSpace
+};
+
+/**
+ * \brief Determine the kind of a particular chunk within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the kind of the chunk at the index \c chunk_number.
+ */
+CINDEX_LINKAGE enum CXCompletionChunkKind
+clang_getCompletionChunkKind(CXCompletionString completion_string,
+ unsigned chunk_number);
+
+/**
+ * \brief Retrieve the text associated with a particular chunk within a
+ * completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the text associated with the chunk at index \c chunk_number.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionChunkText(CXCompletionString completion_string,
+ unsigned chunk_number);
+
+/**
+ * \brief Retrieve the completion string associated with a particular chunk
+ * within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the completion string associated with the chunk at index
+ * \c chunk_number, or NULL if that chunk is not represented by a completion
+ * string.
+ */
+CINDEX_LINKAGE CXCompletionString
+clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
+ unsigned chunk_number);
+
+/**
+ * \brief Retrieve the number of chunks in the given code-completion string.
+ */
+CINDEX_LINKAGE unsigned
+clang_getNumCompletionChunks(CXCompletionString completion_string);
+
+/**
+ * \brief Determine the priority of this code completion.
+ *
+ * The priority of a code completion indicates how likely it is that this
+ * particular completion is the completion that the user will select. The
+ * priority is selected by various internal heuristics.
+ *
+ * \param completion_string The completion string to query.
+ *
+ * \returns The priority of this completion string. Smaller values indicate
+ * higher-priority (more likely) completions.
+ */
+CINDEX_LINKAGE unsigned
+clang_getCompletionPriority(CXCompletionString completion_string);
+
+/**
+ * \brief Contains the results of code-completion.
+ *
+ * This data structure contains the results of code completion, as
+ * produced by \c clang_codeComplete. Its contents must be freed by
+ * \c clang_disposeCodeCompleteResults.
+ */
+typedef struct {
+ /**
+ * \brief The code-completion results.
+ */
+ CXCompletionResult *Results;
+
+ /**
+ * \brief The number of code-completion results stored in the
+ * \c Results array.
+ */
+ unsigned NumResults;
+} CXCodeCompleteResults;
+
+/**
+ * \brief Perform code completion at a given location in a source file.
+ *
+ * This function performs code completion at a particular file, line, and
+ * column within source code, providing results that suggest potential
+ * code snippets based on the context of the completion. The basic model
+ * for code completion is that Clang will parse a complete source file,
+ * performing syntax checking up to the location where code-completion has
+ * been requested. At that point, a special code-completion token is passed
+ * to the parser, which recognizes this token and determines, based on the
+ * current location in the C/Objective-C/C++ grammar and the state of
+ * semantic analysis, what completions to provide. These completions are
+ * returned via a new \c CXCodeCompleteResults structure.
+ *
+ * Code completion itself is meant to be triggered by the client when the
+ * user types punctuation characters or whitespace, at which point the
+ * code-completion location will coincide with the cursor. For example, if \c p
+ * is a pointer, code-completion might be triggered after the "-" and then
+ * after the ">" in \c p->. When the code-completion location is afer the ">",
+ * the completion results will provide, e.g., the members of the struct that
+ * "p" points to. The client is responsible for placing the cursor at the
+ * beginning of the token currently being typed, then filtering the results
+ * based on the contents of the token. For example, when code-completing for
+ * the expression \c p->get, the client should provide the location just after
+ * the ">" (e.g., pointing at the "g") to this code-completion hook. Then, the
+ * client can filter the results based on the current token text ("get"), only
+ * showing those results that start with "get". The intent of this interface
+ * is to separate the relatively high-latency acquisition of code-completion
+ * results from the filtering of results on a per-character basis, which must
+ * have a lower latency.
+ *
+ * \param CIdx the \c CXIndex instance that will be used to perform code
+ * completion.
+ *
+ * \param source_filename the name of the source file that should be parsed to
+ * perform code-completion. This source file must be the same as or include the
+ * filename described by \p complete_filename, or no code-completion results
+ * will be produced. NOTE: One can also specify NULL for this argument if the
+ * source file is included in command_line_args.
+ *
+ * \param num_command_line_args the number of command-line arguments stored in
+ * \p command_line_args.
+ *
+ * \param command_line_args the command-line arguments to pass to the Clang
+ * compiler to build the given source file. This should include all of the
+ * necessary include paths, language-dialect switches, precompiled header
+ * includes, etc., but should not include any information specific to
+ * code completion.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for code completion, including the contents of
+ * those files. The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param complete_filename the name of the source file where code completion
+ * should be performed. In many cases, this name will be the same as the
+ * source filename. However, the completion filename may also be a file
+ * included by the source file, which is required when producing
+ * code-completion results for a header.
+ *
+ * \param complete_line the line at which code-completion should occur.
+ *
+ * \param complete_column the column at which code-completion should occur.
+ * Note that the column should point just after the syntactic construct that
+ * initiated code completion, and not in the middle of a lexical token.
+ *
+ * \param diag_callback callback function that will receive any diagnostics
+ * emitted while processing this source file. If NULL, diagnostics will be
+ * suppressed.
+ *
+ * \param diag_client_data client data that will be passed to the diagnostic
+ * callback function.
+ *
+ * \returns if successful, a new CXCodeCompleteResults structure
+ * containing code-completion results, which should eventually be
+ * freed with \c clang_disposeCodeCompleteResults(). If code
+ * completion fails, returns NULL.
+ */
+CINDEX_LINKAGE
+CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
+ const char *source_filename,
+ int num_command_line_args,
+ const char **command_line_args,
+ unsigned num_unsaved_files,
+ struct CXUnsavedFile *unsaved_files,
+ const char *complete_filename,
+ unsigned complete_line,
+ unsigned complete_column);
+
+/**
+ * \brief Free the given set of code-completion results.
+ */
+CINDEX_LINKAGE
+void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results);
+
+/**
+ * \brief Determine the number of diagnostics produced prior to the
+ * location where code completion was performed.
+ */
+CINDEX_LINKAGE
+unsigned clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *Results);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given code completion.
+ *
+ * \param Result the code completion results to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE
+CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results,
+ unsigned Index);
+
+/**
+ * @}
+ */
+
+
+/**
+ * \defgroup CINDEX_MISC Miscellaneous utility functions
+ *
+ * @{
+ */
+
+/**
+ * \brief Return a version string, suitable for showing to a user, but not
+ * intended to be parsed (the format is not guaranteed to be stable).
+ */
+CINDEX_LINKAGE CXString clang_getClangVersion();
+
+/**
+ * \brief Return a version string, suitable for showing to a user, but not
+ * intended to be parsed (the format is not guaranteed to be stable).
+ */
+
+
+ /**
+ * \brief Visitor invoked for each file in a translation unit
+ * (used with clang_getInclusions()).
+ *
+ * This visitor function will be invoked by clang_getInclusions() for each
+ * file included (either at the top-level or by #include directives) within
+ * a translation unit. The first argument is the file being included, and
+ * the second and third arguments provide the inclusion stack. The
+ * array is sorted in order of immediate inclusion. For example,
+ * the first element refers to the location that included 'included_file'.
+ */
+typedef void (*CXInclusionVisitor)(CXFile included_file,
+ CXSourceLocation* inclusion_stack,
+ unsigned include_len,
+ CXClientData client_data);
+
+/**
+ * \brief Visit the set of preprocessor inclusions in a translation unit.
+ * The visitor function is called with the provided data for every included
+ * file. This does not include headers included by the PCH file (unless one
+ * is inspecting the inclusions in the PCH file itself).
+ */
+CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu,
+ CXInclusionVisitor visitor,
+ CXClientData client_data);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/contrib/llvm/tools/clang/include/clang-c/Makefile b/contrib/llvm/tools/clang/include/clang-c/Makefile
new file mode 100644
index 0000000..5e3522f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang-c/Makefile
@@ -0,0 +1,31 @@
+LEVEL = ../../../..
+DIRS :=
+
+include $(LEVEL)/Makefile.common
+
+install-local::
+ $(Echo) Installing Clang C API include files
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
+ $(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include/clang-c" ; then \
+ cd $(PROJ_SRC_ROOT)/tools/clang/include && \
+ for hdr in `find clang-c -type f '!' '(' -name '*~' \
+ -o -name '.#*' -o -name '*.in' -o -name '*.txt' \
+ -o -name 'Makefile' -o -name '*.td' ')' -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-c" ; then \
+ cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
+ for hdr in `find clang-c -type f '!' '(' -name 'Makefile' ')' -print \
+ | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
+ $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
+ done ; \
+ fi
+endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/APValue.h b/contrib/llvm/tools/clang/include/clang/AST/APValue.h
new file mode 100644
index 0000000..5effa90
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/APValue.h
@@ -0,0 +1,243 @@
+//===--- 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 "llvm/ADT/APSInt.h"
+#include "llvm/ADT/APFloat.h"
+
+namespace clang {
+ class CharUnits;
+ class Expr;
+
+/// APValue - This class implements a discriminated union of [uninitialized]
+/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
+class APValue {
+ typedef llvm::APSInt APSInt;
+ typedef llvm::APFloat APFloat;
+public:
+ enum ValueKind {
+ Uninitialized,
+ Int,
+ Float,
+ ComplexInt,
+ ComplexFloat,
+ LValue,
+ Vector
+ };
+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 Vec {
+ APValue *Elts;
+ unsigned NumElts;
+ Vec() : Elts(0), NumElts(0) {}
+ ~Vec() { delete[] Elts; }
+ };
+
+ enum {
+ MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
+ sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
+ };
+
+ union {
+ void *Aligner;
+ char Data[MaxSize];
+ };
+
+public:
+ APValue() : Kind(Uninitialized) {}
+ explicit APValue(const APSInt &I) : Kind(Uninitialized) {
+ MakeInt(); setInt(I);
+ }
+ explicit APValue(const APFloat &F) : Kind(Uninitialized) {
+ MakeFloat(); setFloat(F);
+ }
+ explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
+ MakeVector(); setVector(E, N);
+ }
+ APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
+ MakeComplexInt(); setComplexInt(R, I);
+ }
+ APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
+ MakeComplexFloat(); setComplexFloat(R, I);
+ }
+ APValue(const APValue &RHS) : Kind(Uninitialized) {
+ *this = RHS;
+ }
+ APValue(Expr* B, const CharUnits &O) : Kind(Uninitialized) {
+ MakeLValue(); setLValue(B, O);
+ }
+ APValue(Expr* B);
+
+ ~APValue() {
+ MakeUninit();
+ }
+
+ 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; }
+
+ void print(llvm::raw_ostream &OS) const;
+ void dump() const;
+
+ APSInt &getInt() {
+ assert(isInt() && "Invalid accessor");
+ return *(APSInt*)(char*)Data;
+ }
+ const APSInt &getInt() const {
+ return const_cast<APValue*>(this)->getInt();
+ }
+
+ APFloat &getFloat() {
+ assert(isFloat() && "Invalid accessor");
+ return *(APFloat*)(char*)Data;
+ }
+ const APFloat &getFloat() const {
+ return const_cast<APValue*>(this)->getFloat();
+ }
+
+ APValue &getVectorElt(unsigned i) {
+ assert(isVector() && "Invalid accessor");
+ return ((Vec*)(char*)Data)->Elts[i];
+ }
+ const APValue &getVectorElt(unsigned i) const {
+ assert(isVector() && "Invalid accessor");
+ return ((const Vec*)(const char*)Data)->Elts[i];
+ }
+ unsigned getVectorLength() const {
+ assert(isVector() && "Invalid accessor");
+ return ((const Vec*)(const void *)Data)->NumElts;
+ }
+
+ APSInt &getComplexIntReal() {
+ assert(isComplexInt() && "Invalid accessor");
+ return ((ComplexAPSInt*)(char*)Data)->Real;
+ }
+ const APSInt &getComplexIntReal() const {
+ return const_cast<APValue*>(this)->getComplexIntReal();
+ }
+
+ APSInt &getComplexIntImag() {
+ assert(isComplexInt() && "Invalid accessor");
+ return ((ComplexAPSInt*)(char*)Data)->Imag;
+ }
+ const APSInt &getComplexIntImag() const {
+ return const_cast<APValue*>(this)->getComplexIntImag();
+ }
+
+ APFloat &getComplexFloatReal() {
+ assert(isComplexFloat() && "Invalid accessor");
+ return ((ComplexAPFloat*)(char*)Data)->Real;
+ }
+ const APFloat &getComplexFloatReal() const {
+ return const_cast<APValue*>(this)->getComplexFloatReal();
+ }
+
+ APFloat &getComplexFloatImag() {
+ assert(isComplexFloat() && "Invalid accessor");
+ return ((ComplexAPFloat*)(char*)Data)->Imag;
+ }
+ const APFloat &getComplexFloatImag() const {
+ return const_cast<APValue*>(this)->getComplexFloatImag();
+ }
+
+ Expr* getLValueBase() const;
+ CharUnits getLValueOffset() const;
+
+ void setInt(const APSInt &I) {
+ assert(isInt() && "Invalid accessor");
+ *(APSInt*)(char*)Data = I;
+ }
+ void setFloat(const APFloat &F) {
+ assert(isFloat() && "Invalid accessor");
+ *(APFloat*)(char*)Data = F;
+ }
+ void setVector(const APValue *E, unsigned N) {
+ assert(isVector() && "Invalid accessor");
+ ((Vec*)(char*)Data)->Elts = new APValue[N];
+ ((Vec*)(char*)Data)->NumElts = N;
+ for (unsigned i = 0; i != N; ++i)
+ ((Vec*)(char*)Data)->Elts[i] = E[i];
+ }
+ void setComplexInt(const APSInt &R, const APSInt &I) {
+ assert(R.getBitWidth() == I.getBitWidth() &&
+ "Invalid complex int (type mismatch).");
+ assert(isComplexInt() && "Invalid accessor");
+ ((ComplexAPSInt*)(char*)Data)->Real = R;
+ ((ComplexAPSInt*)(char*)Data)->Imag = I;
+ }
+ void setComplexFloat(const APFloat &R, const APFloat &I) {
+ assert(&R.getSemantics() == &I.getSemantics() &&
+ "Invalid complex float (type mismatch).");
+ assert(isComplexFloat() && "Invalid accessor");
+ ((ComplexAPFloat*)(char*)Data)->Real = R;
+ ((ComplexAPFloat*)(char*)Data)->Imag = I;
+ }
+ void setLValue(Expr *B, const CharUnits &O);
+
+ const APValue &operator=(const APValue &RHS);
+
+private:
+ void MakeUninit();
+ void MakeInt() {
+ assert(isUninit() && "Bad state change");
+ new ((void*)Data) APSInt(1);
+ Kind = Int;
+ }
+ void MakeFloat() {
+ assert(isUninit() && "Bad state change");
+ new ((void*)(char*)Data) APFloat(0.0);
+ Kind = Float;
+ }
+ void MakeVector() {
+ assert(isUninit() && "Bad state change");
+ new ((void*)(char*)Data) Vec();
+ Kind = Vector;
+ }
+ void MakeComplexInt() {
+ assert(isUninit() && "Bad state change");
+ new ((void*)(char*)Data) ComplexAPSInt();
+ Kind = ComplexInt;
+ }
+ void MakeComplexFloat() {
+ assert(isUninit() && "Bad state change");
+ new ((void*)(char*)Data) ComplexAPFloat();
+ Kind = ComplexFloat;
+ }
+ void MakeLValue();
+};
+
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) {
+ V.print(OS);
+ return OS;
+}
+
+} // end namespace clang.
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/AST.h b/contrib/llvm/tools/clang/include/clang/AST/AST.h
new file mode 100644
index 0000000..164c5fb
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/AST.h
@@ -0,0 +1,28 @@
+//===--- 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/Type.h"
+#include "clang/AST/StmtVisitor.h"
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h b/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h
new file mode 100644
index 0000000..0611395
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h
@@ -0,0 +1,92 @@
+//===--- 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
+
+namespace clang {
+ class ASTContext;
+ class CXXRecordDecl;
+ class DeclGroupRef;
+ class TagDecl;
+ class HandleTagDeclDefinition;
+ class SemaConsumer; // layering violation required for safe SemaConsumer
+ class VarDecl;
+
+/// 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*. Note that D can be
+ /// the head of a chain of Decls (e.g. for `int a, b` the chain will have two
+ /// elements). Use Decl::getNextDeclarator() to walk the chain.
+ virtual void HandleTopLevelDecl(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) {}
+
+ /// 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) {}
+
+ /// \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.
+ ///
+ /// \param DefinitionRequired Whether a definition of this vtable is
+ /// required in this translation unit; otherwise, it is only needed if
+ /// it was actually used.
+ virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
+
+ /// PrintStats - If desired, print any statistics.
+ virtual void PrintStats() {}
+
+ // Support isa/cast/dyn_cast
+ static bool classof(const ASTConsumer *) { return true; }
+};
+
+} // end namespace clang.
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h
new file mode 100644
index 0000000..87a12cde
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h
@@ -0,0 +1,1404 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ASTContext interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
+#define LLVM_CLANG_AST_ASTCONTEXT_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/UsuallyTinyPtrVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+
+namespace llvm {
+ struct fltSemantics;
+ class raw_ostream;
+}
+
+namespace clang {
+ class FileManager;
+ class ASTRecordLayout;
+ class BlockExpr;
+ class CharUnits;
+ class Diagnostic;
+ class Expr;
+ class ExternalASTSource;
+ class IdentifierTable;
+ class SelectorTable;
+ class SourceManager;
+ class TargetInfo;
+ // Decls
+ class DeclContext;
+ class CXXMethodDecl;
+ class CXXRecordDecl;
+ class Decl;
+ class FieldDecl;
+ class ObjCIvarDecl;
+ class ObjCIvarRefExpr;
+ class ObjCPropertyDecl;
+ class RecordDecl;
+ class StoredDeclsMap;
+ class TagDecl;
+ class TemplateTypeParmDecl;
+ class TranslationUnitDecl;
+ class TypeDecl;
+ class TypedefDecl;
+ class UsingDecl;
+ class UsingShadowDecl;
+ class UnresolvedSetIterator;
+
+ namespace Builtin { class Context; }
+
+/// ASTContext - This class holds long-lived AST nodes (such as types and
+/// decls) that can be referred to throughout the semantic analysis of a file.
+class ASTContext {
+ std::vector<Type*> Types;
+ llvm::FoldingSet<ExtQuals> ExtQualNodes;
+ llvm::FoldingSet<ComplexType> ComplexTypes;
+ llvm::FoldingSet<PointerType> PointerTypes;
+ llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
+ llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
+ llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
+ llvm::FoldingSet<MemberPointerType> MemberPointerTypes;
+ llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
+ llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
+ std::vector<VariableArrayType*> VariableArrayTypes;
+ llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
+ llvm::FoldingSet<DependentSizedExtVectorType> DependentSizedExtVectorTypes;
+ llvm::FoldingSet<VectorType> VectorTypes;
+ llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
+ llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
+ llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
+ llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
+ llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
+ llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
+ llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
+ llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
+ llvm::FoldingSet<DependentNameType> DependentNameTypes;
+ llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
+ llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
+
+ llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
+ llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
+
+ /// \brief The set of nested name specifiers.
+ ///
+ /// This set is managed by the NestedNameSpecifier class.
+ llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
+ NestedNameSpecifier *GlobalNestedNameSpecifier;
+ friend class NestedNameSpecifier;
+
+ /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts.
+ /// This is lazily created. This is intentionally not serialized.
+ llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts;
+ llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*> ObjCLayouts;
+
+ /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions.
+ llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
+
+ /// \brief Mapping from ObjCContainers to their ObjCImplementations.
+ llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
+
+ /// BuiltinVaListType - built-in va list type.
+ /// This is initially null and set by Sema::LazilyCreateBuiltin when
+ /// a builtin that takes a valist is encountered.
+ QualType BuiltinVaListType;
+
+ /// ObjCIdType - a pseudo built-in typedef type (set by Sema).
+ QualType ObjCIdTypedefType;
+
+ /// ObjCSelType - another pseudo built-in typedef type (set by Sema).
+ QualType ObjCSelTypedefType;
+
+ /// ObjCProtoType - another pseudo built-in typedef type (set by Sema).
+ QualType ObjCProtoType;
+ const RecordType *ProtoStructType;
+
+ /// ObjCClassType - another pseudo built-in typedef type (set by Sema).
+ QualType ObjCClassTypedefType;
+
+ QualType ObjCConstantStringType;
+ RecordDecl *CFConstantStringTypeDecl;
+
+ RecordDecl *NSConstantStringTypeDecl;
+
+ RecordDecl *ObjCFastEnumerationStateTypeDecl;
+
+ /// \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 Type for the Block descriptor for Blocks CodeGen.
+ RecordDecl *BlockDescriptorType;
+
+ /// \brief Type for the Block descriptor for Blocks CodeGen.
+ RecordDecl *BlockDescriptorExtendedType;
+
+ /// \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*, Attr*> DeclAttrs;
+
+ /// \brief Keeps track of the static data member templates from which
+ /// static data members of class template specializations were instantiated.
+ ///
+ /// This data structure stores the mapping from instantiations of static
+ /// data members to the static data member representations within the
+ /// class template from which they were instantiated along with the kind
+ /// of instantiation or specialization (a TemplateSpecializationKind - 1).
+ ///
+ /// 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 *, MemberSpecializationInfo *>
+ InstantiatedFromStaticDataMember;
+
+ /// \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 UsuallyTinyPtrVector<const CXXMethodDecl> CXXMethodVector;
+ llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
+
+ TranslationUnitDecl *TUDecl;
+
+ /// SourceMgr - The associated SourceManager object.
+ SourceManager &SourceMgr;
+
+ /// LangOpts - The language options used to create the AST associated with
+ /// this ASTContext object.
+ LangOptions LangOpts;
+
+ /// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects.
+ bool FreeMemory;
+ llvm::MallocAllocator MallocAlloc;
+ llvm::BumpPtrAllocator BumpAlloc;
+
+ /// \brief Allocator for partial diagnostics.
+ PartialDiagnostic::StorageAllocator DiagAllocator;
+
+public:
+ const TargetInfo &Target;
+ IdentifierTable &Idents;
+ SelectorTable &Selectors;
+ Builtin::Context &BuiltinInfo;
+ DeclarationNameTable DeclarationNames;
+ llvm::OwningPtr<ExternalASTSource> ExternalSource;
+ clang::PrintingPolicy PrintingPolicy;
+
+ // Typedefs which may be provided defining the structure of Objective-C
+ // pseudo-builtins
+ QualType ObjCIdRedefinitionType;
+ QualType ObjCClassRedefinitionType;
+ QualType ObjCSelRedefinitionType;
+
+ SourceManager& getSourceManager() { return SourceMgr; }
+ const SourceManager& getSourceManager() const { return SourceMgr; }
+ void *Allocate(unsigned Size, unsigned Align = 8) {
+ return FreeMemory ? MallocAlloc.Allocate(Size, Align) :
+ BumpAlloc.Allocate(Size, Align);
+ }
+ void Deallocate(void *Ptr) {
+ if (FreeMemory)
+ MallocAlloc.Deallocate(Ptr);
+ }
+
+ PartialDiagnostic::StorageAllocator &getDiagAllocator() {
+ return DiagAllocator;
+ }
+
+ const LangOptions& getLangOptions() const { return LangOpts; }
+
+ FullSourceLoc getFullLoc(SourceLocation Loc) const {
+ return FullSourceLoc(Loc,SourceMgr);
+ }
+
+ /// \brief Retrieve the attributes for the given declaration.
+ Attr*& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
+
+ /// \brief Erase the attributes corresponding to the given declaration.
+ void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(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.
+ MemberSpecializationInfo *getInstantiatedFromStaticDataMember(
+ const VarDecl *Var);
+
+ /// \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);
+
+ /// \brief If the given using decl 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::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;
+
+ /// \brief Note that the given C++ \p Method overrides the given \p
+ /// Overridden method.
+ void addOverriddenMethod(const CXXMethodDecl *Method,
+ const CXXMethodDecl *Overridden);
+
+ TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
+
+
+ // Builtin Types.
+ CanQualType VoidTy;
+ CanQualType BoolTy;
+ CanQualType CharTy;
+ CanQualType WCharTy; // [C++ 3.9.1p5], integer type in C99.
+ 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 FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
+ CanQualType VoidPtrTy, NullPtrTy;
+ CanQualType OverloadTy;
+ CanQualType DependentTy;
+ CanQualType UndeducedAutoTy;
+ CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
+
+ ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
+ IdentifierTable &idents, SelectorTable &sels,
+ Builtin::Context &builtins,
+ bool FreeMemory = true, unsigned size_reserve=0);
+
+ ~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(llvm::OwningPtr<ExternalASTSource> &Source);
+
+ /// \brief Retrieve a pointer to the external AST source associated
+ /// with this AST context, if any.
+ ExternalASTSource *getExternalSource() const { return ExternalSource.get(); }
+
+ void PrintStats() const;
+ const std::vector<Type*>& getTypes() const { return Types; }
+
+ //===--------------------------------------------------------------------===//
+ // Type Constructors
+ //===--------------------------------------------------------------------===//
+
+private:
+ /// getExtQualType - Return a type with extended qualifiers.
+ QualType getExtQualType(const Type *Base, Qualifiers Quals);
+
+ QualType getTypeDeclTypeSlow(const TypeDecl *Decl);
+
+public:
+ /// getAddSpaceQualType - 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);
+
+ /// getObjCGCQualType - Returns the uniqued reference to the type for an
+ /// objc 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);
+
+ /// getRestrictType - Returns the uniqued reference to the type for a
+ /// 'restrict' qualified type. The resulting type has a union of the
+ /// qualifiers from T and 'restrict'.
+ QualType getRestrictType(QualType T) {
+ return T.withFastQualifiers(Qualifiers::Restrict);
+ }
+
+ /// getVolatileType - Returns the uniqued reference to the type for a
+ /// 'volatile' qualified type. The resulting type has a union of the
+ /// qualifiers from T and 'volatile'.
+ QualType getVolatileType(QualType T);
+
+ /// getConstType - Returns the uniqued reference to the type for a
+ /// 'const' qualified type. The resulting type has a union of the
+ /// qualifiers from T and 'const'.
+ ///
+ /// It can be reasonably expected that this will always be
+ /// equivalent to calling T.withConst().
+ QualType getConstType(QualType T) { return T.withConst(); }
+
+ /// getNoReturnType - Add or remove the noreturn attribute to the given type
+ /// which must be a FunctionType or a pointer to an allowable type or a
+ /// BlockPointer.
+ QualType getNoReturnType(QualType T, bool AddNoReturn = true);
+
+ /// getCallConvType - Adds the specified calling convention attribute to
+ /// the given type, which must be a FunctionType or a pointer to an
+ /// allowable type.
+ QualType getCallConvType(QualType T, CallingConv CallConv);
+
+ /// getRegParmType - Sets the specified regparm attribute to
+ /// the given type, which must be a FunctionType or a pointer to an
+ /// allowable type.
+ QualType getRegParmType(QualType T, unsigned RegParm);
+
+ /// getComplexType - Return the uniqued reference to the type for a complex
+ /// number with the specified element type.
+ QualType getComplexType(QualType T);
+ CanQualType getComplexType(CanQualType T) {
+ return CanQualType::CreateUnsafe(getComplexType((QualType) T));
+ }
+
+ /// getPointerType - Return the uniqued reference to the type for a pointer to
+ /// the specified type.
+ QualType getPointerType(QualType T);
+ CanQualType getPointerType(CanQualType T) {
+ return CanQualType::CreateUnsafe(getPointerType((QualType) T));
+ }
+
+ /// getBlockPointerType - Return the uniqued reference to the type for a block
+ /// of the specified type.
+ QualType getBlockPointerType(QualType T);
+
+ /// This gets the struct used to keep track of the descriptor for pointer to
+ /// blocks.
+ QualType getBlockDescriptorType();
+
+ // Set the type for a Block descriptor type.
+ void setBlockDescriptorType(QualType T);
+ /// Get the BlockDescriptorType type, or NULL if it hasn't yet been built.
+ QualType getRawBlockdescriptorType() {
+ if (BlockDescriptorType)
+ return getTagDeclType(BlockDescriptorType);
+ return QualType();
+ }
+
+ /// This gets the struct used to keep track of the extended descriptor for
+ /// pointer to blocks.
+ QualType getBlockDescriptorExtendedType();
+
+ // Set the type for a Block descriptor extended type.
+ void setBlockDescriptorExtendedType(QualType T);
+ /// Get the BlockDescriptorExtendedType type, or NULL if it hasn't yet been
+ /// built.
+ QualType getRawBlockdescriptorExtendedType() {
+ if (BlockDescriptorExtendedType)
+ return getTagDeclType(BlockDescriptorExtendedType);
+ return QualType();
+ }
+
+ /// This gets the struct used to keep track of pointer to blocks, complete
+ /// with captured variables.
+ QualType getBlockParmType(bool BlockHasCopyDispose,
+ llvm::SmallVectorImpl<const Expr *> &Layout);
+
+ /// This builds the struct used for __block variables.
+ QualType BuildByRefType(const char *DeclName, QualType Ty);
+
+ /// Returns true iff we need copy/dispose helpers for the given type.
+ bool BlockRequiresCopying(QualType Ty);
+
+ /// getLValueReferenceType - Return the uniqued reference to the type for an
+ /// lvalue reference to the specified type.
+ QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true);
+
+ /// getRValueReferenceType - Return the uniqued reference to the type for an
+ /// rvalue reference to the specified type.
+ QualType getRValueReferenceType(QualType T);
+
+ /// getMemberPointerType - Return the uniqued reference to the type for a
+ /// member pointer to the specified type in the specified class. The class
+ /// is a Type because it could be a dependent name.
+ QualType getMemberPointerType(QualType T, const Type *Cls);
+
+ /// getVariableArrayType - Returns 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 EltTypeQuals,
+ SourceRange Brackets);
+
+ /// getDependentSizedArrayType - Returns 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 EltTypeQuals,
+ SourceRange Brackets);
+
+ /// getIncompleteArrayType - Returns a unique reference to the type for a
+ /// incomplete array of the specified element type.
+ QualType getIncompleteArrayType(QualType EltTy,
+ ArrayType::ArraySizeModifier ASM,
+ unsigned EltTypeQuals);
+
+ /// getConstantArrayType - 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 EltTypeQuals);
+
+ /// getVectorType - Return the unique reference to a vector type of
+ /// the specified element type and size. VectorType must be a built-in type.
+ QualType getVectorType(QualType VectorType, unsigned NumElts,
+ bool AltiVec, bool IsPixel);
+
+ /// getExtVectorType - Return the unique reference to an extended vector type
+ /// of the specified element type and size. VectorType must be a built-in
+ /// type.
+ QualType getExtVectorType(QualType VectorType, unsigned NumElts);
+
+ /// getDependentSizedExtVectorType - Returns 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);
+
+ /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
+ ///
+ QualType getFunctionNoProtoType(QualType ResultTy,
+ const FunctionType::ExtInfo &Info);
+
+ QualType getFunctionNoProtoType(QualType ResultTy) {
+ return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
+ }
+
+ /// getFunctionType - Return a normal function type with a typed argument
+ /// list. isVariadic indicates whether the argument list includes '...'.
+ QualType getFunctionType(QualType ResultTy, const QualType *ArgArray,
+ unsigned NumArgs, bool isVariadic,
+ unsigned TypeQuals, bool hasExceptionSpec,
+ bool hasAnyExceptionSpec,
+ unsigned NumExs, const QualType *ExArray,
+ const FunctionType::ExtInfo &Info);
+
+ /// getTypeDeclType - Return the unique reference to the type for
+ /// the specified type declaration.
+ QualType getTypeDeclType(const TypeDecl *Decl,
+ const TypeDecl *PrevDecl = 0) {
+ 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);
+ }
+
+ /// getTypedefType - Return the unique reference to the type for the
+ /// specified typename decl.
+ QualType getTypedefType(const TypedefDecl *Decl);
+
+ QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST);
+
+ QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
+ QualType Replacement);
+
+ QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
+ bool ParameterPack,
+ IdentifierInfo *Name = 0);
+
+ QualType getTemplateSpecializationType(TemplateName T,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
+ QualType Canon = QualType(),
+ bool IsCurrentInstantiation = false);
+
+ QualType getTemplateSpecializationType(TemplateName T,
+ const TemplateArgumentListInfo &Args,
+ QualType Canon = QualType(),
+ bool IsCurrentInstantiation = false);
+
+ TypeSourceInfo *
+ getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
+ const TemplateArgumentListInfo &Args,
+ QualType Canon = QualType());
+
+ QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ QualType NamedType);
+ QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ QualType Canon = QualType());
+ QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const TemplateSpecializationType *TemplateId,
+ QualType Canon = QualType());
+
+ QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
+
+ QualType getObjCObjectType(QualType Base,
+ ObjCProtocolDecl * const *Protocols,
+ unsigned NumProtocols);
+
+ /// getObjCObjectPointerType - Return a ObjCObjectPointerType type
+ /// for the given ObjCObjectType.
+ QualType getObjCObjectPointerType(QualType OIT);
+
+ /// getTypeOfType - GCC extension.
+ QualType getTypeOfExprType(Expr *e);
+ QualType getTypeOfType(QualType t);
+
+ /// getDecltypeType - C++0x decltype.
+ QualType getDecltypeType(Expr *e);
+
+ /// getTagDeclType - Return the unique reference to the type for the
+ /// specified TagDecl (struct/union/class/enum) decl.
+ QualType getTagDeclType(const TagDecl *Decl);
+
+ /// getSizeType - 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;
+
+ /// getWCharType - 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 getWCharType() const { return WCharTy; }
+
+ /// getSignedWCharType - Return the type of "signed wchar_t".
+ /// Used when in C++, as a GCC extension.
+ QualType getSignedWCharType() const;
+
+ /// getUnsignedWCharType - Return the type of "unsigned wchar_t".
+ /// Used when in C++, as a GCC extension.
+ QualType getUnsignedWCharType() const;
+
+ /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
+ /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
+ QualType getPointerDiffType() const;
+
+ // getCFConstantStringType - Return the C structure type used to represent
+ // constant CFStrings.
+ QualType getCFConstantStringType();
+
+ // getNSConstantStringType - Return the C structure type used to represent
+ // constant NSStrings.
+ QualType getNSConstantStringType();
+ /// Get the structure type used to representation NSStrings, or NULL
+ /// if it hasn't yet been built.
+ QualType getRawNSConstantStringType() {
+ if (NSConstantStringTypeDecl)
+ return getTagDeclType(NSConstantStringTypeDecl);
+ return QualType();
+ }
+ void setNSConstantStringType(QualType T);
+
+
+ /// Get the structure type used to representation CFStrings, or NULL
+ /// if it hasn't yet been built.
+ QualType getRawCFConstantStringType() {
+ 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;
+ }
+
+ //// This gets the struct used to keep track of fast enumerations.
+ QualType getObjCFastEnumerationStateType();
+
+ /// Get the ObjCFastEnumerationState type, or NULL if it hasn't yet
+ /// been built.
+ QualType getRawObjCFastEnumerationStateType() {
+ if (ObjCFastEnumerationStateTypeDecl)
+ return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
+ return QualType();
+ }
+
+ void setObjCFastEnumerationStateType(QualType T);
+
+ /// \brief Set the type for the C FILE type.
+ void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
+
+ /// \brief Retrieve the C FILE type.
+ QualType getFILEType() {
+ 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() {
+ 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() {
+ if (sigjmp_bufDecl)
+ return getTypeDeclType(sigjmp_bufDecl);
+ return QualType();
+ }
+
+ /// getObjCEncodingForType - Emit the ObjC type encoding for the
+ /// given type into \arg S. If \arg NameFields is specified then
+ /// record field names are also encoded.
+ void getObjCEncodingForType(QualType t, std::string &S,
+ const FieldDecl *Field=0);
+
+ void getLegacyIntegralTypeEncoding(QualType &t) const;
+
+ // Put the string version of type qualifiers into S.
+ void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
+ std::string &S) const;
+
+ /// getObjCEncodingForMethodDecl - Return the encoded type for this method
+ /// declaration.
+ void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S);
+
+ /// getObjCEncodingForBlockDecl - Return the encoded type for this block
+ /// declaration.
+ void getObjCEncodingForBlock(const BlockExpr *Expr, std::string& S);
+
+ /// 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);
+
+ bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
+ ObjCProtocolDecl *rProto);
+
+ /// getObjCEncodingTypeSize returns size of type for objective-c encoding
+ /// purpose in characters.
+ CharUnits getObjCEncodingTypeSize(QualType t);
+
+ /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by
+ /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct.
+ QualType getObjCIdType() const { return ObjCIdTypedefType; }
+ void setObjCIdType(QualType T);
+
+ void setObjCSelType(QualType T);
+ QualType getObjCSelType() const { return ObjCSelTypedefType; }
+
+ void setObjCProtoType(QualType QT);
+ QualType getObjCProtoType() const { return ObjCProtoType; }
+
+ /// This setter/getter repreents the ObjC 'Class' type. It is setup lazily, by
+ /// Sema. 'Class' is always a (typedef for a) pointer type, a pointer to a
+ /// struct.
+ QualType getObjCClassType() const { return ObjCClassTypedefType; }
+ void setObjCClassType(QualType T);
+
+ void setBuiltinVaListType(QualType T);
+ QualType getBuiltinVaListType() const { return BuiltinVaListType; }
+
+ /// getCVRQualifiedType - Returns a type with additional const,
+ /// volatile, or restrict qualifiers.
+ QualType getCVRQualifiedType(QualType T, unsigned CVR) {
+ return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
+ }
+
+ /// getQualifiedType - Returns a type with additional qualifiers.
+ QualType getQualifiedType(QualType T, Qualifiers Qs) {
+ if (!Qs.hasNonFastQualifiers())
+ return T.withFastQualifiers(Qs.getFastQualifiers());
+ QualifierCollector Qc(Qs);
+ const Type *Ptr = Qc.strip(T);
+ return getExtQualType(Ptr, Qc);
+ }
+
+ /// getQualifiedType - Returns a type with additional qualifiers.
+ QualType getQualifiedType(const Type *T, Qualifiers Qs) {
+ if (!Qs.hasNonFastQualifiers())
+ return QualType(T, Qs.getFastQualifiers());
+ return getExtQualType(T, Qs);
+ }
+
+ DeclarationName getNameForTemplate(TemplateName Name);
+
+ TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End);
+
+ TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
+ bool TemplateKeyword,
+ TemplateDecl *Template);
+
+ TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name);
+ TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
+ OverloadedOperatorKind Operator);
+
+ enum GetBuiltinTypeError {
+ GE_None, //< No error
+ GE_Missing_stdio, //< Missing a type from <stdio.h>
+ GE_Missing_setjmp //< Missing a type from <setjmp.h>
+ };
+
+ /// GetBuiltinType - Return the type for the specified builtin.
+ QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error);
+
+private:
+ CanQualType getFromTargetType(unsigned Type) const;
+
+ //===--------------------------------------------------------------------===//
+ // Type Predicates.
+ //===--------------------------------------------------------------------===//
+
+public:
+ /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's
+ /// garbage collection attribute.
+ ///
+ Qualifiers::GC getObjCGCAttrKind(const QualType &Ty) const;
+
+ /// isObjCNSObjectType - Return true if this is an NSObject object with
+ /// its NSObject attribute set.
+ bool isObjCNSObjectType(QualType Ty) const;
+
+ //===--------------------------------------------------------------------===//
+ // Type Sizing and Analysis
+ //===--------------------------------------------------------------------===//
+
+ /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
+ /// scalar floating point type.
+ const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
+
+ /// getTypeInfo - Get the size and alignment of the specified complete type in
+ /// bits.
+ std::pair<uint64_t, unsigned> getTypeInfo(const Type *T);
+ std::pair<uint64_t, unsigned> getTypeInfo(QualType T) {
+ return getTypeInfo(T.getTypePtr());
+ }
+
+ /// getTypeSize - Return the size of the specified type, in bits. This method
+ /// does not work on incomplete types.
+ uint64_t getTypeSize(QualType T) {
+ return getTypeInfo(T).first;
+ }
+ uint64_t getTypeSize(const Type *T) {
+ return getTypeInfo(T).first;
+ }
+
+ /// getCharWidth - Return the size of the character type, in bits
+ uint64_t getCharWidth() {
+ return getTypeSize(CharTy);
+ }
+
+ /// getTypeSizeInChars - Return the size of the specified type, in characters.
+ /// This method does not work on incomplete types.
+ CharUnits getTypeSizeInChars(QualType T);
+ CharUnits getTypeSizeInChars(const Type *T);
+
+ /// getTypeAlign - Return the ABI-specified alignment of a type, in bits.
+ /// This method does not work on incomplete types.
+ unsigned getTypeAlign(QualType T) {
+ return getTypeInfo(T).second;
+ }
+ unsigned getTypeAlign(const Type *T) {
+ return getTypeInfo(T).second;
+ }
+
+ /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
+ /// characters. This method does not work on incomplete types.
+ CharUnits getTypeAlignInChars(QualType T);
+ CharUnits getTypeAlignInChars(const Type *T);
+
+ std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T);
+ std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T);
+
+ /// getPreferredTypeAlign - Return the "preferred" alignment of the specified
+ /// type 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);
+
+ /// getDeclAlign - Return a conservative estimate of the alignment of
+ /// the specified decl. Note that bitfields do not have a valid alignment, so
+ /// this method will assert on them.
+ /// If @p RefAsPointee, references are treated like their underlying type
+ /// (for alignof), else they're treated like pointers (for CodeGen).
+ CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false);
+
+ /// getASTRecordLayout - Get or compute information about the layout of the
+ /// specified record (struct/union/class), which indicates its size and field
+ /// position information.
+ const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D);
+
+ /// getASTObjCInterfaceLayout - Get or compute information about the
+ /// layout of the specified Objective-C interface.
+ const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D);
+
+ void DumpRecordLayout(const RecordDecl *RD, llvm::raw_ostream &OS);
+
+ /// getASTObjCImplementationLayout - 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);
+
+ /// getKeyFunction - Get the key function for the given record decl.
+ /// 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.
+ const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
+
+ void CollectObjCIvars(const ObjCInterfaceDecl *OI,
+ llvm::SmallVectorImpl<FieldDecl*> &Fields);
+
+ void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
+ llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+ void CollectNonClassIvars(const ObjCInterfaceDecl *OI,
+ llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+ unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI);
+ void CollectInheritedProtocols(const Decl *CDecl,
+ llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
+
+ //===--------------------------------------------------------------------===//
+ // Type Operators
+ //===--------------------------------------------------------------------===//
+
+ /// getCanonicalType - Return the canonical (structural) type corresponding to
+ /// the specified potentially non-canonical type. 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 Type *getCanonicalType(const Type *T) {
+ return T->getCanonicalTypeInternal().getTypePtr();
+ }
+
+ /// getCanonicalParamType - 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);
+
+ /// \brief Determine whether the given types are equivalent.
+ bool hasSameType(QualType T1, QualType T2) {
+ return getCanonicalType(T1) == getCanonicalType(T2);
+ }
+
+ /// \brief Returns this type as a completely-unqualified array type,
+ /// capturing the qualifiers in 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) {
+ CanQualType CT1 = getCanonicalType(T1);
+ CanQualType CT2 = getCanonicalType(T2);
+
+ Qualifiers Quals;
+ QualType UnqualT1 = getUnqualifiedArrayType(CT1, Quals);
+ QualType UnqualT2 = getUnqualifiedArrayType(CT2, Quals);
+ return UnqualT1 == UnqualT2;
+ }
+
+ /// \brief Retrieves the "canonical" declaration of
+
+ /// \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);
+
+ /// \brief Retrieves the canonical representation of the given
+ /// calling convention.
+ CallingConv getCanonicalCallConv(CallingConv CC) {
+ if (CC == CC_C)
+ return CC_Default;
+ return CC;
+ }
+
+ /// \brief Determines whether two calling conventions name the same
+ /// calling convention.
+ bool isSameCallConv(CallingConv lcc, CallingConv rcc) {
+ return (getCanonicalCallConv(lcc) == getCanonicalCallConv(rcc));
+ }
+
+ /// \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);
+
+ /// \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);
+
+ /// 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 ConstantArrayType *getAsConstantArrayType(QualType T) {
+ return dyn_cast_or_null<ConstantArrayType>(getAsArrayType(T));
+ }
+ const VariableArrayType *getAsVariableArrayType(QualType T) {
+ return dyn_cast_or_null<VariableArrayType>(getAsArrayType(T));
+ }
+ const IncompleteArrayType *getAsIncompleteArrayType(QualType T) {
+ return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T));
+ }
+ const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T) {
+ return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
+ }
+
+ /// getBaseElementType - Returns the innermost element type of an array type.
+ /// For example, will return "int" for int[m][n]
+ QualType getBaseElementType(const ArrayType *VAT);
+
+ /// getBaseElementType - Returns the innermost element type of a type
+ /// (which needn't actually be an array type).
+ QualType getBaseElementType(QualType QT);
+
+ /// getConstantArrayElementCount - Returns number of constant array elements.
+ uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
+
+ /// getArrayDecayedType - 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 "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);
+
+ /// getPromotedIntegerType - Returns the type that Promotable will
+ /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable
+ /// integer type.
+ QualType getPromotedIntegerType(QualType PromotableType);
+
+ /// \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);
+
+ /// getIntegerTypeOrder - Returns the highest ranked integer type:
+ /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If
+ /// LHS < RHS, return -1.
+ int getIntegerTypeOrder(QualType LHS, QualType RHS);
+
+ /// getFloatingTypeOrder - Compare the rank of the two specified floating
+ /// point types, ignoring the domain of the type (i.e. 'double' ==
+ /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If
+ /// LHS < RHS, return -1.
+ int getFloatingTypeOrder(QualType LHS, QualType RHS);
+
+ /// getFloatingTypeOfSizeWithinDomain - Returns a real floating
+ /// point or a complex type (based on typeDomain/typeSize).
+ /// 'typeDomain' is a real floating point or complex type.
+ /// 'typeSize' is a real floating point or complex type.
+ QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
+ QualType typeDomain) const;
+
+private:
+ // Helper for integer ordering
+ unsigned getIntegerRank(Type* T);
+
+public:
+
+ //===--------------------------------------------------------------------===//
+ // Type Compatibility Predicates
+ //===--------------------------------------------------------------------===//
+
+ /// Compatibility predicates used to check assignment expressions.
+ bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
+
+ bool typesAreBlockPointerCompatible(QualType, QualType);
+
+ bool isObjCIdType(QualType T) const {
+ return T == ObjCIdTypedefType;
+ }
+ bool isObjCClassType(QualType T) const {
+ return T == ObjCClassTypedefType;
+ }
+ bool isObjCSelType(QualType T) const {
+ return T == ObjCSelTypedefType;
+ }
+ bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS);
+ bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
+ bool ForCompare);
+
+ // 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 areComparableObjCPointerTypes(QualType LHS, QualType RHS);
+ QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
+ const ObjCObjectPointerType *RHSOPT);
+
+ // Functions for calculating composite types
+ QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false);
+ QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false);
+
+ QualType mergeObjCGCQualifiers(QualType, QualType);
+
+ /// UsualArithmeticConversionsType - handles the various conversions
+ /// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9)
+ /// and returns the result type of that conversion.
+ QualType UsualArithmeticConversionsType(QualType lhs, QualType rhs);
+
+ //===--------------------------------------------------------------------===//
+ // 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);
+
+ // 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);
+
+ //===--------------------------------------------------------------------===//
+ // Type Iterators.
+ //===--------------------------------------------------------------------===//
+
+ typedef std::vector<Type*>::iterator type_iterator;
+ typedef std::vector<Type*>::const_iterator const_type_iterator;
+
+ type_iterator types_begin() { return Types.begin(); }
+ type_iterator types_end() { return Types.end(); }
+ const_type_iterator types_begin() const { return Types.begin(); }
+ const_type_iterator types_end() const { return Types.end(); }
+
+ //===--------------------------------------------------------------------===//
+ // Integer Values
+ //===--------------------------------------------------------------------===//
+
+ /// MakeIntValue - Make an APSInt of the appropriate width and
+ /// signedness for the given \arg Value and integer \arg Type.
+ llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) {
+ llvm::APSInt Res(getIntWidth(Type), !Type->isSignedIntegerType());
+ Res = Value;
+ return Res;
+ }
+
+ /// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists.
+ ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
+ /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
+ ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
+
+ /// \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 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);
+
+ /// \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());
+
+ /// \brief Add a deallocation callback that will be invoked when the
+ /// ASTContext is destroyed.
+ ///
+ /// \brief Callback A callback function that will be invoked on destruction.
+ ///
+ /// \brief Data Pointer data that will be provided to the callback function
+ /// when it is called.
+ void AddDeallocation(void (*Callback)(void*), void *Data);
+
+private:
+ ASTContext(const ASTContext&); // DO NOT IMPLEMENT
+ void operator=(const ASTContext&); // DO NOT IMPLEMENT
+
+ void InitBuiltinTypes();
+ void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
+
+ // Return the ObjC 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);
+
+ const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
+ const ObjCImplementationDecl *Impl);
+
+private:
+ /// \brief A set of deallocations that should be performed when the
+ /// ASTContext is destroyed.
+ llvm::SmallVector<std::pair<void (*)(void*), void *>, 16> 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();
+};
+
+/// @brief Utility function for constructing a nullary selector.
+static inline Selector GetNullarySelector(const char* 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(const char* 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.
+// The throw specifications are mandated by the standard.
+/// @brief Placement new for using the ASTContext's allocator.
+///
+/// This placement form of operator new uses the ASTContext's allocator for
+/// obtaining memory. It is a non-throwing new, which means that it returns
+/// null on error. (If that is what the allocator does. The current does, so if
+/// this ever changes, this operator will have to be changed, too.)
+/// 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
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @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, clang::ASTContext &C,
+ size_t Alignment) throw () {
+ 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, clang::ASTContext &C, size_t)
+ throw () {
+ C.Deallocate(Ptr);
+}
+
+/// This placement form of operator new[] uses the ASTContext's allocator for
+/// obtaining memory. It is a non-throwing new[], which means that it returns
+/// null on error.
+/// 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
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @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, clang::ASTContext& C,
+ size_t Alignment = 8) throw () {
+ 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, clang::ASTContext &C, size_t)
+ throw () {
+ C.Deallocate(Ptr);
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h b/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h
new file mode 100644
index 0000000..7cbf3a5
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h
@@ -0,0 +1,47 @@
+//===--- 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_DIAGNOSTICAST_H
+#define LLVM_CLANG_DIAGNOSTICAST_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+ namespace diag {
+ enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
+#define ASTSTART
+#include "clang/Basic/DiagnosticASTKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_AST_DIAGNOSTICS
+ };
+ } // end namespace diag
+
+ /// \brief Diagnostic 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 Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext
+ /// pointer.
+ void FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind,
+ intptr_t Val,
+ const char *Modifier,
+ unsigned ModLen,
+ const char *Argument,
+ unsigned ArgLen,
+ const Diagnostic::ArgumentValue *PrevArgs,
+ unsigned NumPrevArgs,
+ llvm::SmallVectorImpl<char> &Output,
+ void *Cookie);
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h b/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h
new file mode 100644
index 0000000..7975c43
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h
@@ -0,0 +1,240 @@
+//===--- 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/Type.h"
+#include "clang/AST/DeclarationName.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 Diagnostic;
+ 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 The diagnostics object that we should use to emit diagnostics.
+ Diagnostic &Diags;
+
+ /// \brief Mapping from the already-imported types in the "from" context
+ /// to the corresponding types in the "to" context.
+ llvm::DenseMap<Type *, 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<unsigned, FileID> ImportedFileIDs;
+
+ /// \brief Imported, anonymous tag declarations that are missing their
+ /// corresponding typedefs.
+ llvm::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:
+ ASTImporter(Diagnostic &Diags,
+ ASTContext &ToContext, FileManager &ToFileManager,
+ ASTContext &FromContext, FileManager &FromFileManager);
+
+ virtual ~ASTImporter();
+
+ /// \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 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 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(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 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 Retrieve the diagnostic formatter.
+ Diagnostic &getDiags() const { return Diags; }
+
+ /// \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 Note that we have imported the "from" declaration by mapping it
+ /// to the (potentially-newly-created) "to" declaration.
+ ///
+ /// \returns \p To
+ Decl *Imported(Decl *From, Decl *To);
+
+ /// \brief Determine whether the given types are structurally
+ /// equivalent.
+ bool IsStructurallyEquivalent(QualType From, QualType To);
+ };
+}
+
+#endif // LLVM_CLANG_AST_ASTIMPORTER_H
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h b/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h
new file mode 100644
index 0000000..217dfad
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h
@@ -0,0 +1,397 @@
+//===- 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_VECTOR
+#define LLVM_CLANG_AST_VECTOR
+
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <algorithm>
+#include <memory>
+#include <cstring>
+
+#ifdef _MSC_VER
+namespace std {
+#if _MSC_VER <= 1310
+ // Work around flawed VC++ implementation of std::uninitialized_copy. Define
+ // additional overloads so that elements with pointer types are recognized as
+ // scalars and not objects, causing bizarre type conversion errors.
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+#else
+ // FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
+ // is that the above hack won't work if it wasn't fixed.
+#endif
+}
+#endif
+
+namespace clang {
+
+template<typename T>
+class ASTVector {
+ T *Begin, *End, *Capacity;
+
+ void setEnd(T *P) { this->End = P; }
+
+public:
+ // Default ctor - Initialize to empty.
+ explicit ASTVector(ASTContext &C, unsigned N = 0)
+ : Begin(NULL), End(NULL), Capacity(NULL) {
+ reserve(C, N);
+ }
+
+ ~ASTVector() {
+ if (llvm::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 (llvm::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, ASTContext &C) {
+ if (End < Capacity) {
+ Retry:
+ new (End) T(Elt);
+ ++End;
+ return;
+ }
+ grow(C);
+ goto Retry;
+ }
+
+ void reserve(ASTContext &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; }
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ template<typename in_iter>
+ void append(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(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(ASTContext &C, iterator I, const T &Elt) {
+ if (I == this->end()) { // Important special case for empty vector.
+ push_back(Elt);
+ return this->end()-1;
+ }
+
+ if (this->EndX < this->CapacityX) {
+ 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(ASTContext &C, iterator I, size_type NumToInsert,
+ const T &Elt) {
+ if (I == this->end()) { // Important special case for empty vector.
+ append(C, NumToInsert, Elt);
+ return this->end()-1;
+ }
+
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
+ // 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(ASTContext &C, iterator I, ItTy From, ItTy To) {
+ if (I == this->end()) { // Important special case for empty vector.
+ append(C, From, To);
+ return this->end()-1;
+ }
+
+ size_t NumToInsert = std::distance(From, To);
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
+ // 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(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(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:
+ iterator capacity_ptr() { return (iterator)this->Capacity; }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void ASTVector<T>::grow(ASTContext &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 ASTContext.
+ T *NewElts = new (C) T[NewCapacity];
+
+ // Copy the elements over.
+ if (llvm::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));
+ }
+
+ C.Deallocate(Begin);
+ Begin = NewElts;
+ End = NewElts+CurSize;
+ Capacity = Begin+NewCapacity;
+}
+
+} // end: clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/Attr.h b/contrib/llvm/tools/clang/include/clang/AST/Attr.h
new file mode 100644
index 0000000..3240e50
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/Attr.h
@@ -0,0 +1,614 @@
+//===--- Attr.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 Attr interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ATTR_H
+#define LLVM_CLANG_AST_ATTR_H
+
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <cstring>
+#include <algorithm>
+using llvm::dyn_cast;
+
+namespace clang {
+ class ASTContext;
+ class IdentifierInfo;
+ class ObjCInterfaceDecl;
+}
+
+// Defined in ASTContext.h
+void *operator new(size_t Bytes, clang::ASTContext &C,
+ size_t Alignment = 16) throw ();
+
+// 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, clang::ASTContext &C, size_t)
+ throw ();
+
+namespace clang {
+
+/// Attr - This represents one attribute.
+class Attr {
+public:
+ enum Kind {
+ Alias,
+ Aligned,
+ AlignMac68k,
+ AlwaysInline,
+ AnalyzerNoReturn, // Clang-specific.
+ Annotate,
+ AsmLabel, // Represent GCC asm label extension.
+ BaseCheck,
+ Blocks,
+ CDecl,
+ Cleanup,
+ Const,
+ Constructor,
+ Deprecated,
+ Destructor,
+ FastCall,
+ Final,
+ Format,
+ FormatArg,
+ GNUInline,
+ Hiding,
+ IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
+ IBOutletCollectionKind, // Clang-specific.
+ IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
+ Malloc,
+ MaxFieldAlignment,
+ NoDebug,
+ NoInline,
+ NonNull,
+ NoReturn,
+ NoThrow,
+ ObjCException,
+ ObjCNSObject,
+ Override,
+ CFReturnsRetained, // Clang/Checker-specific.
+ CFReturnsNotRetained, // Clang/Checker-specific.
+ NSReturnsRetained, // Clang/Checker-specific.
+ NSReturnsNotRetained, // Clang/Checker-specific.
+ Overloadable, // Clang-specific
+ Packed,
+ Pure,
+ Regparm,
+ ReqdWorkGroupSize, // OpenCL-specific
+ Section,
+ Sentinel,
+ StdCall,
+ ThisCall,
+ TransparentUnion,
+ Unavailable,
+ Unused,
+ Used,
+ Visibility,
+ WarnUnusedResult,
+ Weak,
+ WeakImport,
+ WeakRef,
+
+ FIRST_TARGET_ATTRIBUTE,
+ DLLExport,
+ DLLImport,
+ MSP430Interrupt,
+ X86ForceAlignArgPointer
+ };
+
+private:
+ Attr *Next;
+ Kind AttrKind;
+ bool Inherited : 1;
+
+protected:
+ void* operator new(size_t bytes) throw() {
+ assert(0 && "Attrs cannot be allocated with regular 'new'.");
+ return 0;
+ }
+ void operator delete(void* data) throw() {
+ assert(0 && "Attrs cannot be released with regular 'delete'.");
+ }
+
+protected:
+ Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
+ virtual ~Attr() {
+ assert(Next == 0 && "Destroy didn't work");
+ }
+public:
+ virtual void Destroy(ASTContext &C);
+
+ /// \brief Whether this attribute should be merged to new
+ /// declarations.
+ virtual bool isMerged() const { return true; }
+
+ Kind getKind() const { return AttrKind; }
+
+ Attr *getNext() { return Next; }
+ const Attr *getNext() const { return Next; }
+ void setNext(Attr *next) { Next = next; }
+
+ template<typename T> const T *getNext() const {
+ for (const Attr *attr = getNext(); attr; attr = attr->getNext())
+ if (const T *V = dyn_cast<T>(attr))
+ return V;
+ return 0;
+ }
+
+ bool isInherited() const { return Inherited; }
+ void setInherited(bool value) { Inherited = value; }
+
+ void addAttr(Attr *attr) {
+ assert((attr != 0) && "addAttr(): attr is null");
+
+ // FIXME: This doesn't preserve the order in any way.
+ attr->Next = Next;
+ Next = attr;
+ }
+
+ // Clone this attribute.
+ virtual Attr* clone(ASTContext &C) const = 0;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *) { return true; }
+};
+
+class AttrWithString : public Attr {
+private:
+ const char *Str;
+ unsigned StrLen;
+protected:
+ AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s);
+ llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
+ void ReplaceString(ASTContext &C, llvm::StringRef newS);
+public:
+ virtual void Destroy(ASTContext &C);
+};
+
+#define DEF_SIMPLE_ATTR(ATTR) \
+class ATTR##Attr : public Attr { \
+public: \
+ ATTR##Attr() : Attr(ATTR) {} \
+ virtual Attr *clone(ASTContext &C) const; \
+ static bool classof(const Attr *A) { return A->getKind() == ATTR; } \
+ static bool classof(const ATTR##Attr *A) { return true; } \
+}
+
+DEF_SIMPLE_ATTR(Packed);
+
+/// \brief Attribute for specifying a maximum field alignment; this is only
+/// valid on record decls.
+class MaxFieldAlignmentAttr : public Attr {
+ unsigned Alignment;
+
+public:
+ MaxFieldAlignmentAttr(unsigned alignment)
+ : Attr(MaxFieldAlignment), Alignment(alignment) {}
+
+ /// getAlignment - The specified alignment in bits.
+ unsigned getAlignment() const { return Alignment; }
+
+ virtual Attr* clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == MaxFieldAlignment;
+ }
+ static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(AlignMac68k);
+
+class AlignedAttr : public Attr {
+ unsigned Alignment;
+public:
+ AlignedAttr(unsigned alignment)
+ : Attr(Aligned), Alignment(alignment) {}
+
+ /// getAlignment - The specified alignment in bits.
+ unsigned getAlignment() const { return Alignment; }
+
+ /// getMaxAlignment - Get the maximum alignment of attributes on this list.
+ unsigned getMaxAlignment() const {
+ const AlignedAttr *Next = getNext<AlignedAttr>();
+ if (Next)
+ return std::max(Next->getMaxAlignment(), Alignment);
+ else
+ return Alignment;
+ }
+
+ virtual Attr* clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == Aligned;
+ }
+ static bool classof(const AlignedAttr *A) { return true; }
+};
+
+class AnnotateAttr : public AttrWithString {
+public:
+ AnnotateAttr(ASTContext &C, llvm::StringRef ann)
+ : AttrWithString(Annotate, C, ann) {}
+
+ llvm::StringRef getAnnotation() const { return getString(); }
+
+ virtual Attr* clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == Annotate;
+ }
+ static bool classof(const AnnotateAttr *A) { return true; }
+};
+
+class AsmLabelAttr : public AttrWithString {
+public:
+ AsmLabelAttr(ASTContext &C, llvm::StringRef L)
+ : AttrWithString(AsmLabel, C, L) {}
+
+ llvm::StringRef getLabel() const { return getString(); }
+
+ virtual Attr* clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == AsmLabel;
+ }
+ static bool classof(const AsmLabelAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(AlwaysInline);
+
+class AliasAttr : public AttrWithString {
+public:
+ AliasAttr(ASTContext &C, llvm::StringRef aliasee)
+ : AttrWithString(Alias, C, aliasee) {}
+
+ llvm::StringRef getAliasee() const { return getString(); }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Alias; }
+ static bool classof(const AliasAttr *A) { return true; }
+};
+
+class ConstructorAttr : public Attr {
+ int priority;
+public:
+ ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
+
+ int getPriority() const { return priority; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Constructor; }
+ static bool classof(const ConstructorAttr *A) { return true; }
+};
+
+class DestructorAttr : public Attr {
+ int priority;
+public:
+ DestructorAttr(int p) : Attr(Destructor), priority(p) {}
+
+ int getPriority() const { return priority; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Destructor; }
+ static bool classof(const DestructorAttr *A) { return true; }
+};
+
+class IBOutletAttr : public Attr {
+public:
+ IBOutletAttr() : Attr(IBOutletKind) {}
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == IBOutletKind;
+ }
+ static bool classof(const IBOutletAttr *A) { return true; }
+};
+
+class IBOutletCollectionAttr : public Attr {
+ const ObjCInterfaceDecl *D;
+public:
+ IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
+ : Attr(IBOutletCollectionKind), D(d) {}
+
+ const ObjCInterfaceDecl *getClass() const { return D; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == IBOutletCollectionKind;
+ }
+ static bool classof(const IBOutletCollectionAttr *A) { return true; }
+};
+
+class IBActionAttr : public Attr {
+public:
+ IBActionAttr() : Attr(IBActionKind) {}
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == IBActionKind;
+ }
+ static bool classof(const IBActionAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(AnalyzerNoReturn);
+DEF_SIMPLE_ATTR(Deprecated);
+DEF_SIMPLE_ATTR(Final);
+DEF_SIMPLE_ATTR(GNUInline);
+DEF_SIMPLE_ATTR(Malloc);
+DEF_SIMPLE_ATTR(NoReturn);
+
+class SectionAttr : public AttrWithString {
+public:
+ SectionAttr(ASTContext &C, llvm::StringRef N)
+ : AttrWithString(Section, C, N) {}
+
+ llvm::StringRef getName() const { return getString(); }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == Section;
+ }
+ static bool classof(const SectionAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(Unavailable);
+DEF_SIMPLE_ATTR(Unused);
+DEF_SIMPLE_ATTR(Used);
+DEF_SIMPLE_ATTR(Weak);
+DEF_SIMPLE_ATTR(WeakImport);
+DEF_SIMPLE_ATTR(WeakRef);
+DEF_SIMPLE_ATTR(NoThrow);
+DEF_SIMPLE_ATTR(Const);
+DEF_SIMPLE_ATTR(Pure);
+
+class NonNullAttr : public Attr {
+ unsigned* ArgNums;
+ unsigned Size;
+public:
+ NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
+
+ virtual void Destroy(ASTContext &C);
+
+ typedef const unsigned *iterator;
+ iterator begin() const { return ArgNums; }
+ iterator end() const { return ArgNums + Size; }
+ unsigned size() const { return Size; }
+
+ bool isNonNull(unsigned arg) const {
+ return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
+ }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ static bool classof(const Attr *A) { return A->getKind() == NonNull; }
+ static bool classof(const NonNullAttr *A) { return true; }
+};
+
+class FormatAttr : public AttrWithString {
+ int formatIdx, firstArg;
+public:
+ FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
+ : AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {}
+
+ llvm::StringRef getType() const { return getString(); }
+ void setType(ASTContext &C, llvm::StringRef type);
+ int getFormatIdx() const { return formatIdx; }
+ int getFirstArg() const { return firstArg; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Format; }
+ static bool classof(const FormatAttr *A) { return true; }
+};
+
+class FormatArgAttr : public Attr {
+ int formatIdx;
+public:
+ FormatArgAttr(int idx) : Attr(FormatArg), formatIdx(idx) {}
+ int getFormatIdx() const { return formatIdx; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == FormatArg; }
+ static bool classof(const FormatArgAttr *A) { return true; }
+};
+
+class SentinelAttr : public Attr {
+ int sentinel, NullPos;
+public:
+ SentinelAttr(int sentinel_val, int nullPos) : Attr(Sentinel),
+ sentinel(sentinel_val), NullPos(nullPos) {}
+ int getSentinel() const { return sentinel; }
+ int getNullPos() const { return NullPos; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Sentinel; }
+ static bool classof(const SentinelAttr *A) { return true; }
+};
+
+class VisibilityAttr : public Attr {
+public:
+ /// @brief An enumeration for the kinds of visibility of symbols.
+ enum VisibilityTypes {
+ DefaultVisibility = 0,
+ HiddenVisibility,
+ ProtectedVisibility
+ };
+private:
+ VisibilityTypes VisibilityType;
+public:
+ VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
+ VisibilityType(v) {}
+
+ VisibilityTypes getVisibility() const { return VisibilityType; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Visibility; }
+ static bool classof(const VisibilityAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(FastCall);
+DEF_SIMPLE_ATTR(StdCall);
+DEF_SIMPLE_ATTR(ThisCall);
+DEF_SIMPLE_ATTR(CDecl);
+DEF_SIMPLE_ATTR(TransparentUnion);
+DEF_SIMPLE_ATTR(ObjCNSObject);
+DEF_SIMPLE_ATTR(ObjCException);
+
+class OverloadableAttr : public Attr {
+public:
+ OverloadableAttr() : Attr(Overloadable) { }
+
+ virtual bool isMerged() const { return false; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
+ static bool classof(const OverloadableAttr *) { return true; }
+};
+
+class BlocksAttr : public Attr {
+public:
+ enum BlocksAttrTypes {
+ ByRef = 0
+ };
+private:
+ BlocksAttrTypes BlocksAttrType;
+public:
+ BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}
+
+ BlocksAttrTypes getType() const { return BlocksAttrType; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Blocks; }
+ static bool classof(const BlocksAttr *A) { return true; }
+};
+
+class FunctionDecl;
+
+class CleanupAttr : public Attr {
+ FunctionDecl *FD;
+
+public:
+ CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}
+
+ const FunctionDecl *getFunctionDecl() const { return FD; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
+ static bool classof(const CleanupAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(NoDebug);
+DEF_SIMPLE_ATTR(WarnUnusedResult);
+DEF_SIMPLE_ATTR(NoInline);
+
+class RegparmAttr : public Attr {
+ unsigned NumParams;
+
+public:
+ RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}
+
+ unsigned getNumParams() const { return NumParams; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Regparm; }
+ static bool classof(const RegparmAttr *A) { return true; }
+};
+
+class ReqdWorkGroupSizeAttr : public Attr {
+ unsigned X, Y, Z;
+public:
+ ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
+ : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
+
+ unsigned getXDim() const { return X; }
+ unsigned getYDim() const { return Y; }
+ unsigned getZDim() const { return Z; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == ReqdWorkGroupSize;
+ }
+ static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
+};
+
+// Checker-specific attributes.
+DEF_SIMPLE_ATTR(CFReturnsNotRetained);
+DEF_SIMPLE_ATTR(CFReturnsRetained);
+DEF_SIMPLE_ATTR(NSReturnsNotRetained);
+DEF_SIMPLE_ATTR(NSReturnsRetained);
+
+// C++0x member checking attributes.
+DEF_SIMPLE_ATTR(BaseCheck);
+DEF_SIMPLE_ATTR(Hiding);
+DEF_SIMPLE_ATTR(Override);
+
+// Target-specific attributes
+DEF_SIMPLE_ATTR(DLLImport);
+DEF_SIMPLE_ATTR(DLLExport);
+
+class MSP430InterruptAttr : public Attr {
+ unsigned Number;
+
+public:
+ MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {}
+
+ unsigned getNumber() const { return Number; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; }
+ static bool classof(const MSP430InterruptAttr *A) { return true; }
+};
+
+DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
+
+#undef DEF_SIMPLE_ATTR
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/AST/CMakeLists.txt
new file mode 100644
index 0000000..c24ea06
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_TARGET_DEFINITIONS StmtNodes.td)
+tablegen(StmtNodes.inc
+ -gen-clang-stmt-nodes)
+add_custom_target(ClangStmtNodes
+ DEPENDS StmtNodes.inc)
diff --git a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h
new file mode 100644
index 0000000..5a84e40
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h
@@ -0,0 +1,365 @@
+//===------ 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/DeclarationName.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeOrdering.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include <list>
+#include <map>
+#include <cassert>
+
+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 llvm::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() {
+ llvm::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 hierachy:
+///
+/// @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.
+ std::map<QualType, std::pair<bool, unsigned>, QualTypeOrdering>
+ 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.
+ NamedDecl **DeclsFound;
+ unsigned NumDeclsFound;
+
+ friend class CXXRecordDecl;
+
+ void ComputeDeclsFound();
+
+ bool lookupInBases(ASTContext &Context,
+ const CXXRecordDecl *Record,
+ CXXRecordDecl::BaseMatchesCallback *BaseMatches,
+ void *UserData);
+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(0), DeclsFound(0),
+ NumDeclsFound(0) { }
+
+ ~CXXBasePaths() { delete [] DeclsFound; }
+
+ 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(); }
+
+ decl_iterator found_decls_begin();
+ decl_iterator found_decls_end();
+
+ /// \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(0), Subobject(0), InVirtualSubobject(0) { }
+
+ 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 {
+ llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> >
+ Overrides;
+
+public:
+ // Iterate over the set of subobjects that have overriding methods.
+ typedef llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> >
+ ::iterator iterator;
+ typedef llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> >
+ ::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 llvm::SmallVector<UniqueVirtualMethod, 4>::iterator
+ overriding_iterator;
+ typedef llvm::SmallVector<UniqueVirtualMethod, 4>::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 contaings 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 overriden 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 virtua 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::DenseMap<const CXXMethodDecl *, OverridingMethods> { };
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h b/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h
new file mode 100644
index 0000000..4afb81d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h
@@ -0,0 +1,742 @@
+//===-- 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_CANONICAL_TYPE_H
+#define LLVM_CLANG_AST_CANONICAL_TYPE_H
+
+#include "clang/AST/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/type_traits.h"
+#include <iterator>
+
+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 llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
+
+ /// \brief Retrieve the underlying type pointer, which refers to a
+ /// canonical type.
+ T *getTypePtr() const { return cast_or_null<T>(Stored.getTypePtr()); }
+
+ /// \brief Implicit conversion to a qualified type.
+ operator QualType() const { return Stored; }
+
+ /// \brief Implicit conversion to bool.
+ operator bool() const { return !isNull(); }
+
+ bool isNull() const {
+ return Stored.isNull();
+ }
+
+ /// \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;
+
+ /// \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
+ 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.getTypePtr(); }
+
+ /// \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, isPODType)
+ 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, 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, 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, hasPointerRepresentation)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
+ 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, isConstantSizeType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
+
+ /// \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<const ::clang::CanQual<T> > {
+ typedef T* SimpleType;
+ static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
+ return Val.getTypePtr();
+ }
+};
+template<typename T>
+struct simplify_type< ::clang::CanQual<T> >
+: public simplify_type<const ::clang::CanQual<T> > {};
+
+// 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>
+class CanTypeIterator {
+ InputIterator Iter;
+
+public:
+ typedef CanQualType value_type;
+ typedef value_type reference;
+ typedef CanProxy<Type> pointer;
+ typedef typename std::iterator_traits<InputIterator>::difference_type
+ difference_type;
+ typedef typename std::iterator_traits<InputIterator>::iterator_category
+ iterator_category;
+
+ CanTypeIterator() : Iter() { }
+ explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
+
+ // Input iterator
+ reference operator*() const {
+ return CanQualType::CreateUnsafe(*Iter);
+ }
+
+ pointer operator->() const;
+
+ CanTypeIterator &operator++() {
+ ++Iter;
+ return *this;
+ }
+
+ CanTypeIterator operator++(int) {
+ CanTypeIterator Tmp(*this);
+ ++Iter;
+ return Tmp;
+ }
+
+ friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
+ return X.Iter == Y.Iter;
+ }
+ friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
+ return X.Iter != Y.Iter;
+ }
+
+ // Bidirectional iterator
+ CanTypeIterator &operator--() {
+ --Iter;
+ return *this;
+ }
+
+ CanTypeIterator operator--(int) {
+ CanTypeIterator Tmp(*this);
+ --Iter;
+ return Tmp;
+ }
+
+ // Random access iterator
+ reference operator[](difference_type n) const {
+ return CanQualType::CreateUnsafe(Iter[n]);
+ }
+
+ CanTypeIterator &operator+=(difference_type n) {
+ Iter += n;
+ return *this;
+ }
+
+ CanTypeIterator &operator-=(difference_type n) {
+ Iter -= n;
+ return *this;
+ }
+
+ friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
+ X += n;
+ return X;
+ }
+
+ friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
+ X += n;
+ return X;
+ }
+
+ friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
+ X -= n;
+ return X;
+ }
+
+ friend difference_type operator-(const CanTypeIterator &X,
+ const CanTypeIterator &Y) {
+ return X - Y;
+ }
+};
+
+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)
+};
+
+template<>
+struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
+ getSizeModifier)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
+};
+
+template<>
+struct CanProxyAdaptor<ConstantArrayType>
+ : public CanProxyBase<ConstantArrayType> {
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
+ getSizeModifier)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
+};
+
+template<>
+struct CanProxyAdaptor<IncompleteArrayType>
+ : public CanProxyBase<IncompleteArrayType> {
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
+ getSizeModifier)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
+};
+
+template<>
+struct CanProxyAdaptor<VariableArrayType>
+ : public CanProxyBase<VariableArrayType> {
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
+ getSizeModifier)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
+};
+
+template<>
+struct CanProxyAdaptor<DependentSizedArrayType>
+ : public CanProxyBase<DependentSizedArrayType> {
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
+};
+
+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(getResultType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionNoProtoType>
+ : public CanProxyBase<FunctionNoProtoType> {
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionProtoType>
+ : public CanProxyBase<FunctionProtoType> {
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
+ CanQualType getArgType(unsigned i) const {
+ return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
+ }
+
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
+
+ typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
+ arg_type_iterator;
+
+ arg_type_iterator arg_type_begin() const {
+ return arg_type_iterator(this->getTypePtr()->arg_type_begin());
+ }
+
+ arg_type_iterator arg_type_end() const {
+ return arg_type_iterator(this->getTypePtr()->arg_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<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)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace)
+};
+
+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(IdentifierInfo *, getName)
+};
+
+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.setFromOpaqueValue(Ptr);
+ assert((!Result || 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 {
+ if (Stored.isNull())
+ return CanProxy<U>();
+
+ if (isa<U>(Stored.getTypePtr()))
+ return CanQual<U>::CreateUnsafe(Stored);
+
+ return CanProxy<U>();
+}
+
+template<typename T>
+CanProxy<T> CanQual<T>::operator->() const {
+ return CanProxy<T>(*this);
+}
+
+template<typename InputIterator>
+typename CanTypeIterator<InputIterator>::pointer
+CanTypeIterator<InputIterator>::operator->() const {
+ return CanProxy<Type>(*this);
+}
+
+}
+
+
+#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
diff --git a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h
new file mode 100644
index 0000000..0bb4b76
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h
@@ -0,0 +1,149 @@
+//===--- 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/System/DataTypes.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.
+ ///
+ /// It should be noted that characters and bytes are distinct concepts. Bytes
+ /// refer to addressable units of data storage on the target machine, and
+ /// characters are members of a set of elements used for the organization,
+ /// control, or representation of data. According to C99, bytes are allowed
+ /// to exceed characters in size, although currently, clang only supports
+ /// architectures where the two are the same size.
+ ///
+ /// For portability, never assume that a target character is 8 bits wide. Use
+ /// CharUnit values whereever 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-= (const CharUnits &Other) {
+ Quantity -= Other.Quantity;
+ return *this;
+ }
+
+ // 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; }
+
+ // 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);
+ }
+
+ // Conversions.
+
+ /// getQuantity - Get the raw integer representation of this quantity.
+ QuantityType getQuantity() const { return Quantity; }
+
+
+ }; // class CharUnit
+} // namespace clang
+
+inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
+ const clang::CharUnits &CU) {
+ return CU * Scale;
+}
+
+#endif // LLVM_CLANG_AST_CHARUNITS_H
diff --git a/contrib/llvm/tools/clang/include/clang/AST/Decl.h b/contrib/llvm/tools/clang/include/clang/AST/Decl.h
new file mode 100644
index 0000000..7d5b66e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/Decl.h
@@ -0,0 +1,2196 @@
+//===--- 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/Redeclarable.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/Linkage.h"
+
+namespace clang {
+class CXXTemporary;
+class Expr;
+class FunctionTemplateDecl;
+class Stmt;
+class CompoundStmt;
+class StringLiteral;
+class TemplateArgumentList;
+class MemberSpecializationInfo;
+class FunctionTemplateSpecializationInfo;
+class DependentFunctionTemplateSpecializationInfo;
+class TypeLoc;
+class UnresolvedSetImpl;
+
+/// \brief A container of type source information.
+///
+/// A client can read the relevant info using TypeLoc wrappers, e.g:
+/// @code
+/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
+/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL))
+/// PL->getStarLoc().print(OS, SrcMgr);
+/// @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
+};
+
+/// TranslationUnitDecl - The top declaration context.
+class TranslationUnitDecl : public Decl, public DeclContext {
+ ASTContext &Ctx;
+
+ /// The (most recently entered) anonymous namespace for this
+ /// translation unit, if one has been created.
+ NamespaceDecl *AnonymousNamespace;
+
+ explicit TranslationUnitDecl(ASTContext &ctx)
+ : Decl(TranslationUnit, 0, SourceLocation()),
+ DeclContext(TranslationUnit),
+ Ctx(ctx), AnonymousNamespace(0) {}
+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 classof(const TranslationUnitDecl *D) { return true; }
+ 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));
+ }
+};
+
+/// NamedDecl - This represents a decl with a name. Many decls have names such
+/// as ObjCMethodDecl, but not @class, etc.
+class NamedDecl : public Decl {
+ /// 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;
+
+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.
+ llvm::StringRef getName() const {
+ assert(Name.isIdentifier() && "Name is not a simple identifier");
+ return getIdentifier() ? getIdentifier()->getName() : "";
+ }
+
+ /// getNameAsCString - Get the name of identifier for this declaration as a
+ /// C string (const char*). This requires that the declaration have a name
+ /// and that it be a simple identifier.
+ //
+ // FIXME: Deprecated, move clients to getName().
+ const char *getNameAsCString() const {
+ assert(Name.isIdentifier() && "Name is not a simple identifier");
+ return getIdentifier() ? getIdentifier()->getNameStart() : "";
+ }
+
+ /// 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(llvm::raw_ostream &os) const { return Name.printName(os); }
+
+ /// 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; }
+
+ /// getQualifiedNameAsString - 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 getNameAsString().
+ /// Creating this name is expensive, so it should be called only when
+ /// performance doesn't matter.
+ std::string getQualifiedNameAsString() const;
+ std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const;
+
+ /// getNameForDiagnostic - Appends a human-readable name for this
+ /// declaration into the given string.
+ ///
+ /// This is the method invoked by Sema when displaying a NamedDecl
+ /// in a diagnostic. It does not necessarily produce the same
+ /// result as getNameAsString(); for example, class template
+ /// specializations are printed with their template arguments.
+ ///
+ /// TODO: use an API that doesn't require so many temporary strings
+ virtual void getNameForDiagnostic(std::string &S,
+ const PrintingPolicy &Policy,
+ bool Qualified) const {
+ if (Qualified)
+ S += getQualifiedNameAsString(Policy);
+ else
+ S += getNameAsString();
+ }
+
+ /// declarationReplaces - 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.
+ bool declarationReplaces(NamedDecl *OldD) const;
+
+ /// \brief Determine whether this declaration has linkage.
+ bool hasLinkage() const;
+
+ /// \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.
+ // FIXME: support C++0x scoped enumerations.
+ if (isa<EnumDecl>(DC))
+ DC = DC->getParent();
+
+ return DC->isRecord();
+ }
+
+ /// \brief Given that this declaration is a C++ class member,
+ /// determine whether it's an instance member of its class.
+ bool isCXXInstanceMember() const;
+
+ /// \brief Determine what kind of linkage this entity has.
+ Linkage getLinkage() const;
+
+ /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
+ /// the underlying named decl.
+ NamedDecl *getUnderlyingDecl();
+ const NamedDecl *getUnderlyingDecl() const {
+ return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const NamedDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= NamedFirst && K <= NamedLast; }
+};
+
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const NamedDecl *ND) {
+ ND->getDeclName().printName(OS);
+ return OS;
+}
+
+/// NamespaceDecl - Represent a C++ namespace.
+class NamespaceDecl : public NamedDecl, public DeclContext {
+ SourceLocation LBracLoc, RBracLoc;
+
+ // For extended namespace definitions:
+ //
+ // namespace A { int x; }
+ // namespace A { int y; }
+ //
+ // there will be one NamespaceDecl for each declaration.
+ // NextNamespace points to the next extended declaration.
+ // OrigNamespace points to the original namespace declaration.
+ // OrigNamespace of the first namespace decl points to itself.
+ NamespaceDecl *NextNamespace;
+
+ /// \brief A pointer to either the original namespace definition for
+ /// this namespace (if the boolean value is false) or the anonymous
+ /// namespace that lives just inside this namespace (if the boolean
+ /// value is true).
+ ///
+ /// We can combine these two notions because the anonymous namespace
+ /// must only be stored in one of the namespace declarations (so all
+ /// of the namespace declarations can find it). We therefore choose
+ /// the original namespace declaration, since all of the namespace
+ /// declarations have a link directly to it; the original namespace
+ /// declaration itself only needs to know that it is the original
+ /// namespace declaration (which the boolean indicates).
+ llvm::PointerIntPair<NamespaceDecl *, 1, bool> OrigOrAnonNamespace;
+
+ NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
+ : NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace),
+ NextNamespace(0), OrigOrAnonNamespace(0, true) { }
+
+public:
+ static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id);
+
+ virtual void Destroy(ASTContext& C);
+
+ // \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 Return the next extended namespace declaration or null if this
+ /// is none.
+ NamespaceDecl *getNextNamespace() { return NextNamespace; }
+ const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
+
+ /// \brief Set the next extended namespace declaration.
+ void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
+
+ /// \brief Get the original (first) namespace declaration.
+ NamespaceDecl *getOriginalNamespace() const {
+ if (OrigOrAnonNamespace.getInt())
+ return const_cast<NamespaceDecl *>(this);
+
+ return OrigOrAnonNamespace.getPointer();
+ }
+
+ /// \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 {
+ return getOriginalNamespace() == this;
+ }
+
+ /// \brief Set the original (first) namespace declaration.
+ void setOriginalNamespace(NamespaceDecl *ND) {
+ if (ND != this) {
+ OrigOrAnonNamespace.setPointer(ND);
+ OrigOrAnonNamespace.setInt(false);
+ }
+ }
+
+ NamespaceDecl *getAnonymousNamespace() const {
+ return getOriginalNamespace()->OrigOrAnonNamespace.getPointer();
+ }
+
+ void setAnonymousNamespace(NamespaceDecl *D) {
+ assert(!D || D->isAnonymousNamespace());
+ assert(!D || D->getParent() == this);
+ getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D);
+ }
+
+ virtual NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); }
+ const NamespaceDecl *getCanonicalDecl() const {
+ return getOriginalNamespace();
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getLocation(), RBracLoc);
+ }
+
+ SourceLocation getLBracLoc() const { return LBracLoc; }
+ SourceLocation getRBracLoc() const { return RBracLoc; }
+ void setLBracLoc(SourceLocation LBrace) { LBracLoc = LBrace; }
+ void setRBracLoc(SourceLocation RBrace) { RBracLoc = RBrace; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const NamespaceDecl *D) { return true; }
+ 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));
+ }
+};
+
+/// 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 {
+ 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; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ValueDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= ValueFirst && K <= ValueLast; }
+};
+
+/// \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 {
+ TypeSourceInfo *TInfo;
+ NestedNameSpecifier *NNS;
+ SourceRange NNSRange;
+ };
+
+ llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
+
+ 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)
+ : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo) {}
+
+public:
+ virtual ~DeclaratorDecl();
+ virtual void Destroy(ASTContext &C);
+
+ TypeSourceInfo *getTypeSourceInfo() const {
+ return hasExtInfo()
+ ? DeclInfo.get<ExtInfo*>()->TInfo
+ : DeclInfo.get<TypeSourceInfo*>();
+ }
+ void setTypeSourceInfo(TypeSourceInfo *TI) {
+ if (hasExtInfo())
+ DeclInfo.get<ExtInfo*>()->TInfo = TI;
+ else
+ DeclInfo = TI;
+ }
+
+ NestedNameSpecifier *getQualifier() const {
+ return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNS : 0;
+ }
+ SourceRange getQualifierRange() const {
+ return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNSRange : SourceRange();
+ }
+ void setQualifierInfo(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange);
+
+ SourceLocation getTypeSpecStartLoc() const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const DeclaratorDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= DeclaratorFirst && K <= DeclaratorLast;
+ }
+};
+
+/// \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. Only valid if CheckedICE is true.
+ bool IsICE : 1;
+
+ Stmt *Value;
+ APValue Evaluated;
+};
+
+// \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++0x [temp.explicit]).
+ TSK_ExplicitInstantiationDeclaration,
+ /// This template specialization was instantiated from a template
+ /// due to an explicit instantiation definition request
+ /// (C++ [temp.explicit]).
+ TSK_ExplicitInstantiationDefinition
+};
+
+/// VarDecl - An instance of this class is created to represent a variable
+/// declaration or definition.
+class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
+public:
+ enum StorageClass {
+ None, Auto, Register, Extern, Static, PrivateExtern
+ };
+
+ /// getStorageClassSpecifierString - Return the string used to
+ /// specify the storage class \arg SC.
+ ///
+ /// It is illegal to call this function with SC == None.
+ static const char *getStorageClassSpecifierString(StorageClass SC);
+
+protected:
+ /// \brief Placeholder type used in Init to denote an unparsed C++ default
+ /// argument.
+ struct UnparsedDefaultArgument;
+
+ /// \brief Placeholder type used in Init to denote an uninstantiated C++
+ /// default argument.
+ struct UninstantiatedDefaultArgument;
+
+ typedef llvm::PointerUnion4<Stmt *, EvaluatedStmt *,
+ UnparsedDefaultArgument *,
+ UninstantiatedDefaultArgument *> InitType;
+
+ /// \brief The initializer for this variable or, for a ParmVarDecl, the
+ /// C++ default argument.
+ mutable InitType Init;
+
+private:
+ // FIXME: This can be packed into the bitfields in Decl.
+ unsigned SClass : 3;
+ unsigned SClassAsWritten : 3;
+ bool ThreadSpecified : 1;
+ bool HasCXXDirectInit : 1;
+
+ /// DeclaredInCondition - Whether this variable was declared in a
+ /// condition, e.g., if (int x = foo()) { ... }.
+ bool DeclaredInCondition : 1;
+
+ /// \brief Whether this variable is the exception variable in a C++ catch
+ /// or an Objective-C @catch statement.
+ bool ExceptionVar : 1;
+
+ /// \brief Whether this local variable could be allocated in the return
+ /// slot of its function, enabling the named return value optimization (NRVO).
+ bool NRVOVariable : 1;
+
+ friend class StmtIteratorBase;
+protected:
+ VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ QualType T, TypeSourceInfo *TInfo, StorageClass SC,
+ StorageClass SCAsWritten)
+ : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
+ ThreadSpecified(false), HasCXXDirectInit(false),
+ DeclaredInCondition(false), ExceptionVar(false), NRVOVariable(false) {
+ SClass = SC;
+ SClassAsWritten = SCAsWritten;
+ }
+
+ typedef Redeclarable<VarDecl> redeclarable_base;
+ virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
+public:
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ redecl_iterator redecls_begin() const {
+ return redeclarable_base::redecls_begin();
+ }
+ redecl_iterator redecls_end() const {
+ return redeclarable_base::redecls_end();
+ }
+
+ static VarDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ QualType T, TypeSourceInfo *TInfo, StorageClass S,
+ StorageClass SCAsWritten);
+
+ virtual void Destroy(ASTContext& C);
+ virtual ~VarDecl();
+
+ virtual SourceRange getSourceRange() const;
+
+ StorageClass getStorageClass() const { return (StorageClass)SClass; }
+ StorageClass getStorageClassAsWritten() const {
+ return (StorageClass) SClassAsWritten;
+ }
+ void setStorageClass(StorageClass SC) { SClass = SC; }
+ void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+
+ void setThreadSpecified(bool T) { ThreadSpecified = T; }
+ bool isThreadSpecified() const {
+ return ThreadSpecified;
+ }
+
+ /// hasLocalStorage - Returns true if a variable with function scope
+ /// is a non-static local variable.
+ bool hasLocalStorage() const {
+ if (getStorageClass() == None)
+ return !isFileVarDecl();
+
+ // Return true for: Auto, Register.
+ // Return false for: Extern, Static, PrivateExtern.
+
+ return getStorageClass() <= Register;
+ }
+
+ /// isStaticLocal - Returns true if a variable with function scope is a
+ /// static local variable.
+ bool isStaticLocal() const {
+ return getStorageClass() == Static && !isFileVarDecl();
+ }
+
+ /// hasExternStorage - Returns true if a variable has extern or
+ /// __private_extern__ storage.
+ bool hasExternalStorage() const {
+ return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
+ }
+
+ /// hasGlobalStorage - Returns true for all variables that do not
+ /// have local storage. This includs all global variables as well
+ /// as static variables declared within a function.
+ bool hasGlobalStorage() const { return !hasLocalStorage(); }
+
+ /// \brief Determines whether this variable is a variable with
+ /// external, C linkage.
+ bool isExternC() const;
+
+ /// isBlockVarDecl - Returns true for local variable declarations. 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 isBlockVarDecl() const {
+ if (getKind() != Decl::Var)
+ return false;
+ if (const DeclContext *DC = getDeclContext())
+ return DC->getLookupContext()->isFunctionOrMethod();
+ return false;
+ }
+
+ /// isFunctionOrMethodVarDecl - Similar to isBlockVarDecl, but excludes
+ /// variables declared in blocks.
+ bool isFunctionOrMethodVarDecl() const {
+ if (getKind() != Decl::Var)
+ return false;
+ if (const DeclContext *DC = getDeclContext())
+ return DC->getLookupContext()->isFunctionOrMethod() &&
+ DC->getLookupContext()->getDeclKind() != Decl::Block;
+ return false;
+ }
+
+ /// \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 getDeclContext()->isRecord();
+ }
+
+ virtual VarDecl *getCanonicalDecl();
+ 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() const;
+
+ /// \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 Determine whether this is a tentative definition of a
+ /// variable in C.
+ bool isTentativeDefinitionNow() const;
+
+ /// \brief Get the real (not just tentative) definition for this declaration.
+ VarDecl *getDefinition();
+ 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.
+ virtual bool isOutOfLine() const;
+
+ /// \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 {
+ if (getKind() != Decl::Var)
+ return false;
+ if (const DeclContext *Ctx = getDeclContext()) {
+ Ctx = Ctx->getLookupContext();
+ if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
+ 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 {
+ return !Init.isNull();
+ }
+ const Expr *getInit() const {
+ if (Init.isNull())
+ return 0;
+
+ const Stmt *S = Init.dyn_cast<Stmt *>();
+ if (!S) {
+ if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+ S = ES->Value;
+ }
+ return (const Expr*) S;
+ }
+ Expr *getInit() {
+ if (Init.isNull())
+ return 0;
+
+ Stmt *S = Init.dyn_cast<Stmt *>();
+ if (!S) {
+ if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+ S = ES->Value;
+ }
+
+ return (Expr*) S;
+ }
+
+ /// \brief Retrieve the address of the initializer expression.
+ Stmt **getInitAddress() {
+ if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+ return &ES->Value;
+
+ // This union hack tip-toes around strict-aliasing rules.
+ union {
+ InitType *InitPtr;
+ Stmt **StmtPtr;
+ };
+
+ InitPtr = &Init;
+ return StmtPtr;
+ }
+
+ void setInit(Expr *I);
+
+ EvaluatedStmt *EnsureEvaluatedStmt() const {
+ EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
+ if (!Eval) {
+ Stmt *S = Init.get<Stmt *>();
+ Eval = new (getASTContext()) EvaluatedStmt;
+ Eval->Value = S;
+ Init = Eval;
+ }
+ return Eval;
+ }
+
+ /// \brief Check whether we are in the process of checking whether the
+ /// initializer can be evaluated.
+ bool isEvaluatingValue() const {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ return Eval->IsEvaluating;
+
+ return false;
+ }
+
+ /// \brief Note that we now are checking whether the initializer can be
+ /// evaluated.
+ void setEvaluatingValue() const {
+ EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+ Eval->IsEvaluating = true;
+ }
+
+ /// \brief Note that constant evaluation has computed the given
+ /// value for this variable's initializer.
+ void setEvaluatedValue(const APValue &Value) const {
+ EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+ Eval->IsEvaluating = false;
+ Eval->WasEvaluated = true;
+ Eval->Evaluated = Value;
+ }
+
+ /// \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 {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ if (Eval->WasEvaluated)
+ return &Eval->Evaluated;
+
+ return 0;
+ }
+
+ /// \brief Determines whether it is already known whether the
+ /// initializer is an integral constant expression or not.
+ bool isInitKnownICE() const {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ return Eval->CheckedICE;
+
+ return false;
+ }
+
+ /// \brief Determines whether the initializer is an integral
+ /// constant expression.
+ ///
+ /// \pre isInitKnownICE()
+ bool isInitICE() const {
+ assert(isInitKnownICE() &&
+ "Check whether we already know that the initializer is an ICE");
+ return Init.get<EvaluatedStmt *>()->IsICE;
+ }
+
+ /// \brief Check whether we are in the process of checking the initializer
+ /// is an integral constant expression.
+ bool isCheckingICE() const {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ return Eval->CheckingICE;
+
+ return false;
+ }
+
+ /// \brief Note that we now are checking whether the initializer is an
+ /// integral constant expression.
+ void setCheckingICE() const {
+ EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+ Eval->CheckingICE = true;
+ }
+
+ /// \brief Note that we now know whether the initializer is an
+ /// integral constant expression.
+ void setInitKnownICE(bool IsICE) const {
+ EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+ Eval->CheckingICE = false;
+ Eval->CheckedICE = true;
+ Eval->IsICE = IsICE;
+ }
+
+ void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
+
+ /// hasCXXDirectInitializer - If true, the initializer was a 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. Clients can distinguish between "int x(1);" and "int x=1;"
+ /// by checking hasCXXDirectInitializer.
+ ///
+ bool hasCXXDirectInitializer() const {
+ return HasCXXDirectInit;
+ }
+
+ /// isDeclaredInCondition - Whether this variable was declared as
+ /// part of a condition in an if/switch/while statement, e.g.,
+ /// @code
+ /// if (int x = foo()) { ... }
+ /// @endcode
+ bool isDeclaredInCondition() const {
+ return DeclaredInCondition;
+ }
+ void setDeclaredInCondition(bool InCondition) {
+ DeclaredInCondition = InCondition;
+ }
+
+ /// \brief Determine whether this variable is the exception variable in a
+ /// C++ catch statememt or an Objective-C @catch statement.
+ bool isExceptionVariable() const {
+ return ExceptionVar;
+ }
+ void setExceptionVariable(bool EV) { 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 NRVOVariable; }
+ void setNRVOVariable(bool NRVO) { NRVOVariable = NRVO; }
+
+ /// \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 a static data member, determine what kind of
+ /// template specialization or instantiation this is.
+ TemplateSpecializationKind getTemplateSpecializationKind() 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());
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const VarDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= VarFirst && K <= VarLast; }
+};
+
+class ImplicitParamDecl : public VarDecl {
+protected:
+ ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, QualType Tw)
+ : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None, VarDecl::None) {}
+public:
+ static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ QualType T);
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const ImplicitParamDecl *D) { return true; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == ImplicitParam; }
+};
+
+/// ParmVarDecl - Represent a parameter to a function.
+class ParmVarDecl : public VarDecl {
+ // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
+ /// FIXME: Also can be paced into the bitfields in Decl.
+ /// in, inout, etc.
+ unsigned objcDeclQualifier : 6;
+ bool HasInheritedDefaultArg : 1;
+
+protected:
+ ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+ StorageClass S, StorageClass SCAsWritten, Expr *DefArg)
+ : VarDecl(DK, DC, L, Id, T, TInfo, S, SCAsWritten),
+ objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) {
+ setDefaultArg(DefArg);
+ }
+
+public:
+ static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,IdentifierInfo *Id,
+ QualType T, TypeSourceInfo *TInfo,
+ StorageClass S, StorageClass SCAsWritten,
+ Expr *DefArg);
+
+ ObjCDeclQualifier getObjCDeclQualifier() const {
+ return ObjCDeclQualifier(objcDeclQualifier);
+ }
+ void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
+ objcDeclQualifier = QTVal;
+ }
+
+ Expr *getDefaultArg();
+ const Expr *getDefaultArg() const {
+ return const_cast<ParmVarDecl *>(this)->getDefaultArg();
+ }
+
+ void setDefaultArg(Expr *defarg) {
+ Init = reinterpret_cast<Stmt *>(defarg);
+ }
+
+ unsigned getNumDefaultArgTemporaries() const;
+ CXXTemporary *getDefaultArgTemporary(unsigned i);
+ const CXXTemporary *getDefaultArgTemporary(unsigned i) const {
+ return const_cast<ParmVarDecl *>(this)->getDefaultArgTemporary(i);
+ }
+
+ /// \brief Retrieve the source range that covers the entire default
+ /// argument.
+ SourceRange getDefaultArgRange() const;
+ void setUninstantiatedDefaultArg(Expr *arg) {
+ Init = reinterpret_cast<UninstantiatedDefaultArgument *>(arg);
+ }
+ Expr *getUninstantiatedDefaultArg() {
+ return (Expr *)Init.get<UninstantiatedDefaultArgument *>();
+ }
+ const Expr *getUninstantiatedDefaultArg() const {
+ return (const Expr *)Init.get<UninstantiatedDefaultArgument *>();
+ }
+
+ /// hasDefaultArg - Determines whether this parameter has a default argument,
+ /// either parsed or not.
+ bool hasDefaultArg() const {
+ return getInit() || hasUnparsedDefaultArg() ||
+ hasUninstantiatedDefaultArg();
+ }
+
+ /// 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 Init.is<UnparsedDefaultArgument*>();
+ }
+
+ bool hasUninstantiatedDefaultArg() const {
+ return Init.is<UninstantiatedDefaultArgument*>();
+ }
+
+ /// 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() {
+ Init = (UnparsedDefaultArgument *)0;
+ }
+
+ bool hasInheritedDefaultArg() const {
+ return HasInheritedDefaultArg;
+ }
+
+ void setHasInheritedDefaultArg(bool I = true) {
+ HasInheritedDefaultArg = I;
+ }
+
+ QualType getOriginalType() const {
+ if (getTypeSourceInfo())
+ return getTypeSourceInfo()->getType();
+ return getType();
+ }
+
+ /// 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 classof(const ParmVarDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ParmVar; }
+};
+
+/// 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
+/// getPreviousDeclaration() chain.
+class FunctionDecl : public DeclaratorDecl, public DeclContext,
+ public Redeclarable<FunctionDecl> {
+public:
+ enum StorageClass {
+ None, Extern, Static, PrivateExtern
+ };
+
+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;
+
+ LazyDeclStmtPtr Body;
+
+ // FIXME: This can be packed into the bitfields in Decl.
+ // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
+ unsigned SClass : 2;
+ unsigned SClassAsWritten : 2;
+ bool IsInline : 1;
+ bool IsVirtualAsWritten : 1;
+ bool IsPure : 1;
+ bool HasInheritedPrototype : 1;
+ bool HasWrittenPrototype : 1;
+ bool IsDeleted : 1;
+ bool IsTrivial : 1; // sunk from CXXMethodDecl
+ bool IsCopyAssignment : 1; // sunk from CXXMethodDecl
+ bool HasImplicitReturnZero : 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;
+
+protected:
+ FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ StorageClass S, StorageClass SCAsWritten, bool isInline)
+ : DeclaratorDecl(DK, DC, L, N, T, TInfo),
+ DeclContext(DK),
+ ParamInfo(0), Body(),
+ SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInline),
+ IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
+ HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
+ IsCopyAssignment(false),
+ HasImplicitReturnZero(false),
+ EndRangeLoc(L), TemplateOrSpecialization() {}
+
+ virtual ~FunctionDecl() {}
+ virtual void Destroy(ASTContext& C);
+
+ typedef Redeclarable<FunctionDecl> redeclarable_base;
+ virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
+public:
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ redecl_iterator redecls_begin() const {
+ return redeclarable_base::redecls_begin();
+ }
+ redecl_iterator redecls_end() const {
+ return redeclarable_base::redecls_end();
+ }
+
+ static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName N, QualType T,
+ TypeSourceInfo *TInfo,
+ StorageClass S = None,
+ StorageClass SCAsWritten = None,
+ bool isInline = false,
+ bool hasWrittenPrototype = true);
+
+ virtual void getNameForDiagnostic(std::string &S,
+ const PrintingPolicy &Policy,
+ bool Qualified) const;
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getLocation(), EndRangeLoc);
+ }
+ void setLocEnd(SourceLocation E) {
+ EndRangeLoc = E;
+ }
+
+ /// 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).
+ Stmt *getBody(const FunctionDecl *&Definition) const;
+
+ virtual Stmt *getBody() const {
+ 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 getBody.
+ /// FIXME: Should return true if function is deleted or defaulted. However,
+ /// CodeGenModule.cpp uses it, and I don't know if this would break it.
+ bool isThisDeclarationADefinition() const { return Body; }
+
+ 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) { IsPure = P; }
+
+ /// 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; }
+
+ bool isCopyAssignment() const { return IsCopyAssignment; }
+ void setCopyAssignment(bool CA) { IsCopyAssignment = CA; }
+
+ /// 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; }
+ void setHasWrittenPrototype(bool P) { HasWrittenPrototype = P; }
+
+ /// \brief Whether this function inherited its prototype from a
+ /// previous declaration.
+ bool hasInheritedPrototype() const { return HasInheritedPrototype; }
+ void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; }
+
+ /// \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
+ bool isDeleted() const { return IsDeleted; }
+ void setDeleted(bool D = true) { IsDeleted = D; }
+
+ /// \brief Determines whether this is a function "main", which is
+ /// the entry point into an executable program.
+ bool isMain() const;
+
+ /// \brief Determines whether this function is a function with
+ /// external, C linkage.
+ bool isExternC() const;
+
+ /// \brief Determines whether this is a global function.
+ bool isGlobal() const;
+
+ void setPreviousDeclaration(FunctionDecl * PrevDecl);
+
+ virtual const FunctionDecl *getCanonicalDecl() const;
+ virtual FunctionDecl *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;
+
+ param_iterator param_begin() { return ParamInfo; }
+ param_iterator param_end() { return ParamInfo+param_size(); }
+
+ param_const_iterator param_begin() const { return ParamInfo; }
+ param_const_iterator param_end() const { return ParamInfo+param_size(); }
+
+ /// 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(ParmVarDecl **NewParamInfo, unsigned NumParams);
+
+ /// 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 getResultType() const {
+ return getType()->getAs<FunctionType>()->getResultType();
+ }
+ StorageClass getStorageClass() const { return StorageClass(SClass); }
+ void setStorageClass(StorageClass SC) { SClass = SC; }
+
+ StorageClass getStorageClassAsWritten() const {
+ return StorageClass(SClassAsWritten);
+ }
+ void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+
+ /// \brief Determine whether the "inline" keyword was specified for this
+ /// function.
+ bool isInlineSpecified() const { return IsInline; }
+
+ /// Set whether the "inline" keyword was specified for this function.
+ void setInlineSpecified(bool I) { IsInline = I; }
+
+ /// \brief Determine whether this function should be inlined, because it is
+ /// either marked "inline" or is a member function of a C++ class that
+ /// was defined in the class body.
+ bool isInlined() const;
+
+ bool isInlineDefinitionExternallyVisible() 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 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);
+
+ /// \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 {
+ return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl*>();
+ }
+
+ void setDescribedFunctionTemplate(FunctionTemplateDecl *Template) {
+ TemplateOrSpecialization = Template;
+ }
+
+ /// \brief Determine whether this function is a function template
+ /// specialization.
+ bool isFunctionTemplateSpecialization() const {
+ return getPrimaryTemplate() != 0;
+ }
+
+ /// \brief If this function is actually a function template specialization,
+ /// retrieve information about this function template specialization.
+ /// Otherwise, returns NULL.
+ FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const {
+ return TemplateOrSpecialization.
+ dyn_cast<FunctionTemplateSpecializationInfo*>();
+ }
+
+ /// \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 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 TemplateArgumentListInfo*
+ getTemplateSpecializationArgsAsWritten() const;
+
+ /// \brief Specify that this function declaration is actually a function
+ /// template specialization.
+ ///
+ /// \param Context the AST context in which this function resides.
+ ///
+ /// \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.
+ void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos,
+ TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten = 0);
+
+ /// \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 {
+ return TemplateOrSpecialization.
+ dyn_cast<DependentFunctionTemplateSpecializationInfo*>();
+ }
+
+ /// \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; otherwie, 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.
+ virtual bool isOutOfLine() const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const FunctionDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= FunctionFirst && K <= FunctionLast;
+ }
+ 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));
+ }
+};
+
+
+/// FieldDecl - An instance of this class is created by Sema::ActOnField to
+/// represent a member of a struct/union/class.
+class FieldDecl : public DeclaratorDecl {
+ // FIXME: This can be packed into the bitfields in Decl.
+ bool Mutable : 1;
+ Expr *BitWidth;
+protected:
+ FieldDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+ Expr *BW, bool Mutable)
+ : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Mutable(Mutable), BitWidth(BW) {
+ }
+
+public:
+ static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo, Expr *BW, bool Mutable);
+
+ /// isMutable - Determines whether this field is mutable (C++ only).
+ bool isMutable() const { return Mutable; }
+
+ /// \brief Set whether this field is mutable (C++ only).
+ void setMutable(bool M) { Mutable = M; }
+
+ /// isBitfield - Determines whether this field is a bitfield.
+ bool isBitField() const { return BitWidth != NULL; }
+
+ /// @brief Determines whether this is an unnamed bitfield.
+ bool isUnnamedBitfield() const { return BitWidth != NULL && !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 BitWidth; }
+ void setBitWidth(Expr *BW) { BitWidth = BW; }
+
+ /// 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());
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const FieldDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= FieldFirst && K <= FieldLast; }
+};
+
+/// 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 {
+ 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) {}
+
+ virtual ~EnumConstantDecl() {}
+public:
+
+ static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ QualType T, Expr *E,
+ const llvm::APSInt &V);
+
+ virtual void Destroy(ASTContext& C);
+
+ 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; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const EnumConstantDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == EnumConstant; }
+
+ friend class StmtIteratorBase;
+};
+
+
+/// TypeDecl - Represents a declaration of a type.
+///
+class TypeDecl : public NamedDecl {
+ /// 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 Type *TypeForDecl;
+ friend class ASTContext;
+ friend class DeclContext;
+ friend class TagDecl;
+ friend class TemplateTypeParmDecl;
+ friend class TagType;
+
+protected:
+ TypeDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id)
+ : NamedDecl(DK, DC, L, Id), TypeForDecl(0) {}
+
+public:
+ // Low-level accessor
+ Type *getTypeForDecl() const { return TypeForDecl; }
+ void setTypeForDecl(Type *TD) { TypeForDecl = TD; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const TypeDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= TypeFirst && K <= TypeLast; }
+};
+
+
+class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
+ /// UnderlyingType - This is the type the typedef is set to.
+ TypeSourceInfo *TInfo;
+
+ TypedefDecl(DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
+
+ virtual ~TypedefDecl();
+
+protected:
+ typedef Redeclarable<TypedefDecl> redeclarable_base;
+ virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
+public:
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ redecl_iterator redecls_begin() const {
+ return redeclarable_base::redecls_begin();
+ }
+ redecl_iterator redecls_end() const {
+ return redeclarable_base::redecls_end();
+ }
+
+ static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ TypeSourceInfo *TInfo);
+
+ TypeSourceInfo *getTypeSourceInfo() const {
+ return TInfo;
+ }
+
+ /// Retrieves the canonical declaration of this typedef.
+ TypedefDecl *getCanonicalDecl() {
+ return getFirstDeclaration();
+ }
+ const TypedefDecl *getCanonicalDecl() const {
+ return getFirstDeclaration();
+ }
+
+ QualType getUnderlyingType() const {
+ return TInfo->getType();
+ }
+ void setTypeSourceInfo(TypeSourceInfo *newType) {
+ TInfo = newType;
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const TypedefDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Typedef; }
+};
+
+class TypedefDecl;
+
+/// 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 : 2;
+
+ /// IsDefinition - True if this is a definition ("struct foo {};"), false if
+ /// it is a declaration ("struct foo;").
+ bool IsDefinition : 1;
+
+ /// 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;
+
+protected:
+ // These are used by (and only defined for) EnumDecl.
+ unsigned NumPositiveBits : 8;
+ unsigned NumNegativeBits : 8;
+
+private:
+ SourceLocation TagKeywordLoc;
+ SourceLocation RBraceLoc;
+
+ // A struct representing syntactic qualifier info,
+ // to be used for the (uncommon) case of out-of-line declarations.
+ struct ExtInfo {
+ NestedNameSpecifier *NNS;
+ SourceRange NNSRange;
+ };
+
+ /// TypedefDeclOrQualifier - 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, it points to the TypedefDecl (used for mangling);
+ /// otherwise, it is a null (TypedefDecl) pointer.
+ llvm::PointerUnion<TypedefDecl*, ExtInfo*> TypedefDeclOrQualifier;
+
+ bool hasExtInfo() const { return TypedefDeclOrQualifier.is<ExtInfo*>(); }
+ ExtInfo *getExtInfo() { return TypedefDeclOrQualifier.get<ExtInfo*>(); }
+ const ExtInfo *getExtInfo() const {
+ return TypedefDeclOrQualifier.get<ExtInfo*>();
+ }
+
+protected:
+ TagDecl(Kind DK, TagKind TK, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ TagDecl *PrevDecl, SourceLocation TKL = SourceLocation())
+ : TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL),
+ TypedefDeclOrQualifier((TypedefDecl*) 0) {
+ assert((DK != Enum || TK == TTK_Enum) &&
+ "EnumDecl not matched with TTK_Enum");
+ TagDeclKind = TK;
+ IsDefinition = false;
+ IsEmbeddedInDeclarator = false;
+ setPreviousDeclaration(PrevDecl);
+ }
+
+ typedef Redeclarable<TagDecl> redeclarable_base;
+ virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
+public:
+ void Destroy(ASTContext &C);
+
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ redecl_iterator redecls_begin() const {
+ return redeclarable_base::redecls_begin();
+ }
+ redecl_iterator redecls_end() const {
+ return redeclarable_base::redecls_end();
+ }
+
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+ void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+
+ SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
+ void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
+
+ virtual SourceRange getSourceRange() const;
+
+ virtual TagDecl* getCanonicalDecl();
+ const TagDecl* getCanonicalDecl() const {
+ return const_cast<TagDecl*>(this)->getCanonicalDecl();
+ }
+
+ /// isDefinition - Return true if this decl has its body specified.
+ bool isDefinition() const {
+ return IsDefinition;
+ }
+
+ bool isEmbeddedInDeclarator() const {
+ return IsEmbeddedInDeclarator;
+ }
+ void setEmbeddedInDeclarator(bool isInDeclarator) {
+ IsEmbeddedInDeclarator = isInDeclarator;
+ }
+
+ /// \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();
+
+ /// @brief Completes the definition of this tag declaration.
+ void completeDefinition();
+
+ /// getDefinition - Returns the TagDecl that actually defines this
+ /// struct/union/class/enum. When determining whether or not a
+ /// struct/union/class/enum is completely defined, 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 setDefinition(bool V) { IsDefinition = V; }
+
+ const char *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 isClass() const { return getTagKind() == TTK_Class; }
+ bool isUnion() const { return getTagKind() == TTK_Union; }
+ bool isEnum() const { return getTagKind() == TTK_Enum; }
+
+ TypedefDecl *getTypedefForAnonDecl() const {
+ return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
+ }
+
+ void setTypedefForAnonDecl(TypedefDecl *TDD);
+
+ NestedNameSpecifier *getQualifier() const {
+ return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0;
+ }
+ SourceRange getQualifierRange() const {
+ return hasExtInfo()
+ ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNSRange
+ : SourceRange();
+ }
+ void setQualifierInfo(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange);
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const TagDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= TagFirst && K <= TagLast; }
+
+ 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));
+ }
+};
+
+/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
+/// enums.
+class EnumDecl : public TagDecl {
+ /// 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.
+ QualType 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 the enumeration was instantiated from an enumeration
+ /// within a class or function template, this pointer refers to the
+ /// enumeration declared within the template.
+ EnumDecl *InstantiatedFrom;
+
+ // The number of positive and negative bits required by the
+ // enumerators are stored in the SubclassBits field.
+ enum {
+ NumBitsWidth = 8,
+ NumBitsMask = (1 << NumBitsWidth) - 1
+ };
+
+ EnumDecl(DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
+ : TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
+ IntegerType = QualType();
+ }
+public:
+ EnumDecl *getCanonicalDecl() {
+ return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+ }
+ const EnumDecl *getCanonicalDecl() const {
+ return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+ }
+
+ static EnumDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ SourceLocation TKL, EnumDecl *PrevDecl);
+
+ virtual void Destroy(ASTContext& C);
+
+ /// 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;
+
+ enumerator_iterator enumerator_begin() const {
+ return enumerator_iterator(this->decls_begin());
+ }
+
+ enumerator_iterator enumerator_end() const {
+ return enumerator_iterator(this->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.
+ QualType getIntegerType() const { return IntegerType; }
+
+ /// \brief Set the underlying integer type.
+ void setIntegerType(QualType T) { IntegerType = T; }
+
+ /// \brief Returns the width in bits requred 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 requred 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 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 {
+ return InstantiatedFrom;
+ }
+
+ void setInstantiationOfMemberEnum(EnumDecl *IF) { InstantiatedFrom = IF; }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const EnumDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Enum; }
+};
+
+
+/// 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 object.
+ bool HasObjectMember : 1;
+
+protected:
+ RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ RecordDecl *PrevDecl, SourceLocation TKL);
+ virtual ~RecordDecl();
+
+public:
+ static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ SourceLocation TKL = SourceLocation(),
+ RecordDecl* PrevDecl = 0);
+
+ virtual void Destroy(ASTContext& C);
+
+ 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;
+ }
+
+ ValueDecl *getAnonymousStructOrUnionObject();
+ const ValueDecl *getAnonymousStructOrUnionObject() const {
+ return const_cast<RecordDecl*>(this)->getAnonymousStructOrUnionObject();
+ }
+
+ bool hasObjectMember() const { return HasObjectMember; }
+ void setHasObjectMember (bool val) { HasObjectMember = 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;
+
+ /// 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
+ /// 'isDefinition'. 'isDefinition' indicates whether or not a specific
+ /// RecordDecl is defining declaration, 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;
+
+ field_iterator field_begin() const {
+ return field_iterator(decls_begin());
+ }
+ field_iterator field_end() const {
+ return field_iterator(decls_end());
+ }
+
+ // 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.
+ void completeDefinition();
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const RecordDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= RecordFirst && K <= RecordLast;
+ }
+};
+
+class FileScopeAsmDecl : public Decl {
+ StringLiteral *AsmString;
+ FileScopeAsmDecl(DeclContext *DC, SourceLocation L, StringLiteral *asmstring)
+ : Decl(FileScopeAsm, DC, L), AsmString(asmstring) {}
+public:
+ static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, StringLiteral *Str);
+
+ 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 classof(const FileScopeAsmDecl *D) { return true; }
+ 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 {
+ // FIXME: This can be packed into the bitfields in Decl.
+ bool IsVariadic : 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;
+
+protected:
+ BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
+ : Decl(Block, DC, CaretLoc), DeclContext(Block),
+ IsVariadic(false), ParamInfo(0), NumParams(0), Body(0) {}
+
+ virtual ~BlockDecl();
+ virtual void Destroy(ASTContext& C);
+
+public:
+ static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
+
+ 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 { return (Stmt*) Body; }
+ void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
+
+ // Iterator access to formal parameters.
+ unsigned param_size() const { return getNumParams(); }
+ typedef ParmVarDecl **param_iterator;
+ typedef ParmVarDecl * const *param_const_iterator;
+
+ bool param_empty() const { return NumParams == 0; }
+ param_iterator param_begin() { return ParamInfo; }
+ param_iterator param_end() { return ParamInfo+param_size(); }
+
+ param_const_iterator param_begin() const { return ParamInfo; }
+ param_const_iterator param_end() const { return ParamInfo+param_size(); }
+
+ 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(ParmVarDecl **NewParamInfo, unsigned NumParams);
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const BlockDecl *D) { return true; }
+ 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));
+ }
+};
+
+/// Insertion operator for diagnostics. This allows sending NamedDecl's
+/// into a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ NamedDecl* ND) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND), Diagnostic::ak_nameddecl);
+ return DB;
+}
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h b/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h
new file mode 100644
index 0000000..7ecd8f8
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h
@@ -0,0 +1,72 @@
+//===--- 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"
+
+namespace clang {
+
+class NamedDecl;
+
+/// A POD class for pairing a NamedDecl* with an access specifier.
+/// Can be put into unions.
+class DeclAccessPair {
+ NamedDecl *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 (NamedDecl*) (~Mask & (uintptr_t) Ptr);
+ }
+ AccessSpecifier getAccess() const {
+ return AccessSpecifier(Mask & (uintptr_t) Ptr);
+ }
+
+ void setDecl(NamedDecl *D) {
+ set(D, getAccess());
+ }
+ void setAccess(AccessSpecifier AS) {
+ set(getDecl(), AS);
+ }
+ void set(NamedDecl *D, AccessSpecifier AS) {
+ Ptr = reinterpret_cast<NamedDecl*>(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/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h
new file mode 100644
index 0000000..c15aeef
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h
@@ -0,0 +1,1211 @@
+//===-- 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/Attr.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+class DeclContext;
+class TranslationUnitDecl;
+class NamespaceDecl;
+class UsingDirectiveDecl;
+class NamedDecl;
+class FunctionDecl;
+class CXXRecordDecl;
+class EnumDecl;
+class ObjCMethodDecl;
+class ObjCContainerDecl;
+class ObjCInterfaceDecl;
+class ObjCCategoryDecl;
+class ObjCProtocolDecl;
+class ObjCImplementationDecl;
+class ObjCCategoryImplDecl;
+class ObjCImplDecl;
+class LinkageSpecDecl;
+class BlockDecl;
+class DeclarationName;
+class CompoundStmt;
+class StoredDeclsMap;
+class DependentDiagnostic;
+}
+
+namespace llvm {
+// DeclContext* is only 4-byte aligned on 32-bit systems.
+template<>
+ class PointerLikeTypeTraits<clang::DeclContext*> {
+ typedef clang::DeclContext* PT;
+public:
+ static inline void *getAsVoidPointer(PT P) { return P; }
+ static inline PT getFromVoidPointer(void *P) {
+ return static_cast<PT>(P);
+ }
+ enum { NumLowBitsAvailable = 2 };
+};
+}
+
+namespace clang {
+
+/// Decl - This represents one declaration (or definition), e.g. a variable,
+/// typedef, function, struct, etc.
+///
+class Decl {
+public:
+ /// \brief Lists the kind of concrete classes of Decl.
+ enum Kind {
+#define DECL(Derived, Base) Derived,
+#define DECL_RANGE(CommonBase, Start, End) \
+ CommonBase##First = Start, CommonBase##Last = End,
+#define LAST_DECL_RANGE(CommonBase, Start, End) \
+ CommonBase##First = Start, CommonBase##Last = End
+#include "clang/AST/DeclNodes.def"
+ };
+
+ /// \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 16 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
+ };
+
+ /// ObjCDeclQualifier - Qualifier used on types in method declarations
+ /// for remote messaging. They are meant for the arguments though and
+ /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
+ 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
+ };
+
+private:
+ /// NextDeclInContext - The next declaration within the same lexical
+ /// DeclContext. These pointers form the linked list that is
+ /// traversed via DeclContext's decls_begin()/decls_end().
+ Decl *NextDeclInContext;
+
+ 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 that this decl.
+ SourceLocation Loc;
+
+ /// DeclKind - This indicates which class this is.
+ Kind DeclKind : 8;
+
+ /// InvalidDecl - This indicates a semantic error occurred.
+ unsigned int InvalidDecl : 1;
+
+ /// HasAttrs - This indicates whether the decl has attributes or not.
+ unsigned int HasAttrs : 1;
+
+ /// Implicit - Whether this declaration was implicitly generated by
+ /// the implementation rather than explicitly written by the user.
+ bool Implicit : 1;
+
+ /// \brief Whether this declaration was "used", meaning that a definition is
+ /// required.
+ bool Used : 1;
+
+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;
+
+ // PCHLevel - the "level" of precompiled header/AST file from which this
+ // declaration was built.
+ unsigned PCHLevel : 2;
+
+ /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
+ unsigned IdentifierNamespace : 16;
+
+private:
+#ifndef NDEBUG
+ void CheckAccessDeclContext() const;
+#else
+ void CheckAccessDeclContext() const { }
+#endif
+
+protected:
+
+ Decl(Kind DK, DeclContext *DC, SourceLocation L)
+ : NextDeclInContext(0), DeclCtx(DC),
+ Loc(L), DeclKind(DK), InvalidDecl(0),
+ HasAttrs(false), Implicit(false), Used(false),
+ Access(AS_none), PCHLevel(0),
+ IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
+ if (Decl::CollectingStats()) addDeclKind(DK);
+ }
+
+ virtual ~Decl();
+
+public:
+
+ /// \brief Source range that this declaration covers.
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getLocation(), getLocation());
+ }
+ SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
+ SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
+ Kind getKind() const { return DeclKind; }
+ const char *getDeclKindName() const;
+
+ Decl *getNextDeclInContext() { return NextDeclInContext; }
+ const Decl *getNextDeclInContext() const { return NextDeclInContext; }
+
+ DeclContext *getDeclContext() {
+ if (isInSemaDC())
+ return getSemanticDC();
+ return getMultipleDC()->SemanticDC;
+ }
+ const DeclContext *getDeclContext() const {
+ return const_cast<Decl*>(this)->getDeclContext();
+ }
+
+ TranslationUnitDecl *getTranslationUnitDecl();
+ const TranslationUnitDecl *getTranslationUnitDecl() const {
+ return const_cast<Decl*>(this)->getTranslationUnitDecl();
+ }
+
+ bool isInAnonymousNamespace() const;
+
+ ASTContext &getASTContext() const;
+
+ void setAccess(AccessSpecifier AS) {
+ Access = AS;
+ CheckAccessDeclContext();
+ }
+
+ AccessSpecifier getAccess() const {
+ CheckAccessDeclContext();
+ return AccessSpecifier(Access);
+ }
+
+ bool hasAttrs() const { return HasAttrs; }
+ void addAttr(Attr *attr);
+ const Attr *getAttrs() const {
+ if (!HasAttrs) return 0; // common case, no attributes.
+ return getAttrsImpl(); // Uncommon case, out of line hash lookup.
+ }
+ void swapAttrs(Decl *D);
+ void invalidateAttrs();
+
+ template<typename T> const T *getAttr() const {
+ for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
+ if (const T *V = dyn_cast<T>(attr))
+ return V;
+ return 0;
+ }
+
+ template<typename T> bool hasAttr() const {
+ return getAttr<T>() != 0;
+ }
+
+ /// 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.
+ bool isUsed() const;
+
+ void setUsed(bool U = true) { Used = U; }
+
+ /// \brief Retrieve the level of precompiled header from which this
+ /// declaration was generated.
+ ///
+ /// The PCH level of a declaration describes where the declaration originated
+ /// from. A PCH level of 0 indicates that the declaration was not from a
+ /// precompiled header. A PCH level of 1 indicates that the declaration was
+ /// from a top-level precompiled header; 2 indicates that the declaration
+ /// comes from a precompiled header on which the top-level precompiled header
+ /// depends, and so on.
+ unsigned getPCHLevel() const { return PCHLevel; }
+
+ /// \brief The maximum PCH level that any declaration may have.
+ static const unsigned MaxPCHLevel = 3;
+
+ /// \brief Set the PCH level of this declaration.
+ void setPCHLevel(unsigned Level) {
+ assert(Level < MaxPCHLevel && "PCH level exceeds the maximum");
+ PCHLevel = Level;
+ }
+
+ 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();
+ }
+
+ virtual bool isOutOfLine() const {
+ return getLexicalDeclContext() != getDeclContext();
+ }
+
+ /// 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;
+
+ /// \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 *getNextRedeclaration() { 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 Decl* reference;
+ typedef Decl* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ redecl_iterator() : Current(0) { }
+ explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
+
+ reference operator*() const { return Current; }
+ pointer 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->getNextRedeclaration();
+ assert(Next && "Should return next redeclaration or itself, never null!");
+ Current = (Next != Starter ? Next : 0);
+ 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;
+ }
+ };
+
+ /// \brief Returns iterator for all the redeclarations of the same decl.
+ /// It will iterate at least once (when this decl is the only one).
+ redecl_iterator redecls_begin() const {
+ return redecl_iterator(const_cast<Decl*>(this));
+ }
+ redecl_iterator redecls_end() const { return redecl_iterator(); }
+
+ /// getBody - If this Decl represents a declaration for a body of code,
+ /// such as a function or method definition, this method returns the
+ /// top-level Stmt* of that body. Otherwise this method returns null.
+ virtual Stmt* getBody() const { return 0; }
+
+ /// getCompoundBody - Returns getBody(), dyn_casted to a CompoundStmt.
+ CompoundStmt* getCompoundBody() const;
+
+ /// 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 addDeclKind(Kind k);
+ static bool CollectingStats(bool Enable = false);
+ 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 function or function template.
+ bool isFunctionOrFunctionTemplate() const;
+
+ /// \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 PreviouslyDeclared) {
+ unsigned OldNS = IdentifierNamespace;
+ assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
+ IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+ "namespace includes neither ordinary nor tag");
+ assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
+ IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+ "namespace includes other than ordinary or tag");
+
+ IdentifierNamespace = 0;
+ if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
+ IdentifierNamespace |= IDNS_TagFriend;
+ if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag | IDNS_Type;
+ }
+
+ if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) {
+ IdentifierNamespace |= IDNS_OrdinaryFriend;
+ if (PreviouslyDeclared) 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;
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *) { return true; }
+ static bool classofKind(Kind K) { return true; }
+ static DeclContext *castToDeclContext(const Decl *);
+ static Decl *castFromDeclContext(const DeclContext *);
+
+ /// Destroy - Call destructors and release memory.
+ virtual void Destroy(ASTContext& C);
+
+ void print(llvm::raw_ostream &Out, unsigned Indentation = 0) const;
+ void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
+ unsigned Indentation = 0) const;
+ static void printGroup(Decl** Begin, unsigned NumDecls,
+ llvm::raw_ostream &Out, const PrintingPolicy &Policy,
+ unsigned Indentation = 0);
+ void dump() const;
+
+private:
+ const Attr *getAttrsImpl() const;
+
+};
+
+/// 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) {}
+
+ virtual void print(llvm::raw_ostream &OS) const;
+};
+
+
+/// 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.
+ Decl::Kind 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 Pointer to the data structure used to lookup declarations
+ /// within this context (or a DependentStoredDeclsMap if this is a
+ /// dependent context).
+ mutable StoredDeclsMap *LookupPtr;
+
+ /// 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;
+
+protected:
+ DeclContext(Decl::Kind K)
+ : DeclKind(K), ExternalLexicalStorage(false),
+ ExternalVisibleStorage(false), LookupPtr(0), FirstDecl(0),
+ LastDecl(0) { }
+
+ void DestroyDecls(ASTContext &C);
+
+public:
+ ~DeclContext();
+
+ Decl::Kind getDeclKind() const {
+ return 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 isFunctionOrMethod() const {
+ switch (DeclKind) {
+ case Decl::Block:
+ case Decl::ObjCMethod:
+ return true;
+ default:
+ return DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast;
+ }
+ }
+
+ bool isFileContext() const {
+ return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
+ }
+
+ bool isTranslationUnit() const {
+ return DeclKind == Decl::TranslationUnit;
+ }
+
+ bool isRecord() const {
+ return DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast;
+ }
+
+ bool isNamespace() const {
+ return DeclKind == Decl::Namespace;
+ }
+
+ /// \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), C++ linkage specifications, and C++0x
+ /// inline namespaces.
+ bool isTransparentContext() const;
+
+ /// \brief Determine whether this declaration context is equivalent
+ /// to the declaration context DC.
+ bool Equals(DeclContext *DC) {
+ return DC && this->getPrimaryContext() == DC->getPrimaryContext();
+ }
+
+ /// \brief Determine whether this declaration context encloses the
+ /// declaration context DC.
+ bool Encloses(DeclContext *DC);
+
+ /// 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();
+ }
+
+ /// getLookupContext - Retrieve the innermost non-transparent
+ /// context of this context, which corresponds to the innermost
+ /// location from which name lookup can find the entities in this
+ /// context.
+ DeclContext *getLookupContext();
+ const DeclContext *getLookupContext() const {
+ return const_cast<DeclContext *>(this)->getLookupContext();
+ }
+
+ /// \brief Retrieve the nearest enclosing namespace context.
+ DeclContext *getEnclosingNamespaceContext();
+ const DeclContext *getEnclosingNamespaceContext() const {
+ return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
+ }
+
+ /// getNextContext - If this is a DeclContext that may have other
+ /// DeclContexts that are semantically connected but syntactically
+ /// different, such as C++ namespaces, this routine retrieves the
+ /// next DeclContext in the link. Iteration through the chain of
+ /// DeclContexts should begin at the primary DeclContext and
+ /// continue until this function returns NULL. For example, given:
+ /// @code
+ /// namespace N {
+ /// int x;
+ /// }
+ /// namespace N {
+ /// int y;
+ /// }
+ /// @endcode
+ /// The first occurrence of namespace N will be the primary
+ /// DeclContext. Its getNextContext will return the second
+ /// occurrence of namespace N.
+ DeclContext *getNextContext();
+
+ /// 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 Decl* reference;
+ typedef Decl* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ decl_iterator() : Current(0) { }
+ explicit decl_iterator(Decl *C) : Current(C) { }
+
+ reference operator*() const { return Current; }
+ pointer 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;
+ }
+ };
+
+ /// decls_begin/decls_end - Iterate over the declarations stored in
+ /// this context.
+ decl_iterator decls_begin() const;
+ decl_iterator decls_end() const;
+ bool decls_empty() const;
+
+ /// 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;
+ typedef SpecificDecl* reference;
+ typedef SpecificDecl* 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();
+ }
+
+ reference operator*() const { return cast<SpecificDecl>(*Current); }
+ pointer operator->() const { return cast<SpecificDecl>(*Current); }
+
+ 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;
+ typedef SpecificDecl* reference;
+ typedef SpecificDecl* pointer;
+ typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
+ difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ filtered_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 filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
+ SkipToNextDecl();
+ }
+
+ reference operator*() const { return cast<SpecificDecl>(*Current); }
+ pointer 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 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);
+
+ /// lookup_iterator - An iterator that provides access to the results
+ /// of looking up a name within this context.
+ typedef NamedDecl **lookup_iterator;
+
+ /// lookup_const_iterator - An iterator that provides non-mutable
+ /// access to the results of lookup up a name within this context.
+ typedef NamedDecl * const * lookup_const_iterator;
+
+ typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
+ typedef std::pair<lookup_const_iterator, lookup_const_iterator>
+ lookup_const_result;
+
+ /// 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);
+ lookup_const_result lookup(DeclarationName Name) const;
+
+ /// @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.
+ ///
+ /// @param Recoverable true if it's okay to not add this decl to
+ /// the lookup tables because it can be easily recovered by walking
+ /// the declaration chains.
+ void makeDeclVisibleInContext(NamedDecl *D, bool Recoverable = true);
+
+ /// udir_iterator - Iterates through the using-directives stored
+ /// within this context.
+ typedef UsingDirectiveDecl * const * udir_iterator;
+
+ typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
+
+ udir_iterator_range getUsingDirectives() const;
+
+ udir_iterator using_directives_begin() const {
+ return getUsingDirectives().first;
+ }
+
+ udir_iterator using_directives_end() const {
+ return getUsingDirectives().second;
+ }
+
+ // These are all defined in DependentDiagnostic.h.
+ class ddiag_iterator;
+ inline ddiag_iterator ddiag_begin() const;
+ inline ddiag_iterator ddiag_end() const;
+
+ // Low-level accessors
+
+ /// \brief Retrieve the internal representation of the lookup structure.
+ StoredDeclsMap* getLookupPtr() const { return LookupPtr; }
+
+ /// \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;
+ }
+
+ static bool classof(const Decl *D);
+ static bool classof(const DeclContext *D) { return true; }
+#define DECL_CONTEXT(Name) \
+ static bool classof(const Name##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.def"
+
+ void dumpDeclContext() const;
+
+private:
+ void LoadLexicalDeclsFromExternalStorage() const;
+ void LoadVisibleDeclsFromExternalStorage() const;
+
+ friend class DependentDiagnostic;
+ StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
+
+ void buildLookup(DeclContext *DCtx);
+ void makeDeclVisibleInContextImpl(NamedDecl *D);
+};
+
+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 = ::llvm::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<class ToTy>
+struct isa_impl_wrap<ToTy,
+ const ::clang::DeclContext,const ::clang::DeclContext> {
+ static bool doit(const ::clang::DeclContext &Val) {
+ return ToTy::classofKind(Val.getDeclKind());
+ }
+};
+template<class ToTy>
+struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
+ : public isa_impl_wrap<ToTy,
+ const ::clang::DeclContext,const ::clang::DeclContext> {};
+
+/// 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/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h
new file mode 100644
index 0000000..c19c200
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h
@@ -0,0 +1,2111 @@
+//===-- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the C++ Decl subclasses, other than those for
+// templates (in DeclTemplate.h) and friends (in DeclFriend.h).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLCXX_H
+#define LLVM_CLANG_AST_DECLCXX_H
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.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 FriendDecl;
+
+/// \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 {
+ /// Implement simplify_type for AnyFunctionDecl, so that we can dyn_cast from
+ /// AnyFunctionDecl to any function or function template declaration.
+ template<> struct simplify_type<const ::clang::AnyFunctionDecl> {
+ typedef ::clang::NamedDecl* SimpleType;
+ static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) {
+ return Val;
+ }
+ };
+ template<> struct simplify_type< ::clang::AnyFunctionDecl>
+ : public simplify_type<const ::clang::AnyFunctionDecl> {};
+
+ // 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 {
+
+/// CXXBaseSpecifier - 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 {
+ /// Range - The source code range that covers the full base
+ /// specifier, including the "virtual" (if present) and access
+ /// specifier (if present).
+ // FIXME: Move over to a TypeLoc!
+ SourceRange Range;
+
+ /// Virtual - Whether this is a virtual base class or not.
+ bool Virtual : 1;
+
+ /// BaseOfClass - 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;
+
+ /// Access - Access specifier as written in the source code (which
+ /// 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;
+
+ /// BaseType - The type of the base class. This will be a class or
+ /// struct (or a typedef of such).
+ QualType BaseType;
+
+public:
+ CXXBaseSpecifier() { }
+
+ CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, QualType T)
+ : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseType(T) { }
+
+ /// getSourceRange - Retrieves the source range that contains the
+ /// entire base specifier.
+ SourceRange getSourceRange() const { return Range; }
+
+ /// isVirtual - Determines whether the base class is a virtual base
+ /// class (or not).
+ bool isVirtual() const { return Virtual; }
+
+ /// \brief Determine whether this base class if a base of a class declared
+ /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
+ bool isBaseOfClass() const { return BaseOfClass; }
+
+ /// getAccessSpecifier - 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;
+ }
+
+ /// getAccessSpecifierAsWritten - 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;
+ }
+
+ /// getType - Retrieves the type of the base class. This type will
+ /// always be an unqualified class type.
+ QualType getType() const { return BaseType; }
+};
+
+/// CXXRecordDecl - Represents a C++ struct/union/class.
+/// FIXME: This class will disappear once we've properly taught RecordDecl
+/// to deal with C++-specific things.
+class CXXRecordDecl : public RecordDecl {
+
+ friend void TagDecl::startDefinition();
+
+ struct DefinitionData {
+ DefinitionData(CXXRecordDecl *D);
+
+ /// UserDeclaredConstructor - True when this class has a
+ /// user-declared constructor.
+ bool UserDeclaredConstructor : 1;
+
+ /// UserDeclaredCopyConstructor - True when this class has a
+ /// user-declared copy constructor.
+ bool UserDeclaredCopyConstructor : 1;
+
+ /// UserDeclaredCopyAssignment - True when this class has a
+ /// user-declared copy assignment operator.
+ bool UserDeclaredCopyAssignment : 1;
+
+ /// UserDeclaredDestructor - True when this class has a
+ /// user-declared destructor.
+ bool UserDeclaredDestructor : 1;
+
+ /// Aggregate - True when this class is an aggregate.
+ bool Aggregate : 1;
+
+ /// PlainOldData - True when this class is a POD-type.
+ bool PlainOldData : 1;
+
+ /// Empty - 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;
+
+ /// Polymorphic - True when this class is polymorphic, i.e. has at
+ /// least one virtual member or derives from a polymorphic class.
+ bool Polymorphic : 1;
+
+ /// Abstract - 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;
+
+ /// HasTrivialConstructor - True when this class has a trivial constructor.
+ ///
+ /// C++ [class.ctor]p5. A constructor is trivial if it is an
+ /// implicitly-declared default constructor and if:
+ /// * its class has no virtual functions and no virtual base classes, and
+ /// * all the direct base classes of its class have trivial constructors, and
+ /// * for all the nonstatic data members of its class that are of class type
+ /// (or array thereof), each such class has a trivial constructor.
+ bool HasTrivialConstructor : 1;
+
+ /// HasTrivialCopyConstructor - True when this class has a trivial copy
+ /// constructor.
+ ///
+ /// C++ [class.copy]p6. A copy constructor for class X is trivial
+ /// if it is implicitly declared and if
+ /// * class X has no virtual functions and no virtual base classes, and
+ /// * each direct base class of X has a trivial copy constructor, and
+ /// * for all the nonstatic data members of X that are of class type (or
+ /// array thereof), each such class type has a trivial copy constructor;
+ /// otherwise the copy constructor is non-trivial.
+ bool HasTrivialCopyConstructor : 1;
+
+ /// HasTrivialCopyAssignment - True when this class has a trivial copy
+ /// assignment operator.
+ ///
+ /// C++ [class.copy]p11. A copy assignment operator for class X is
+ /// trivial if it is implicitly declared and if
+ /// * class X has no virtual functions and no virtual base classes, and
+ /// * each direct base class of X has a trivial copy assignment operator, and
+ /// * for all the nonstatic data members of X that are of class type (or
+ /// array thereof), each such class type has a trivial copy assignment
+ /// operator;
+ /// otherwise the copy assignment operator is non-trivial.
+ bool HasTrivialCopyAssignment : 1;
+
+ /// HasTrivialDestructor - True when this class has a trivial destructor.
+ ///
+ /// C++ [class.dtor]p3. A destructor is trivial if it is an
+ /// implicitly-declared destructor and if:
+ /// * all of the direct base classes of its class have trivial destructors
+ /// and
+ /// * for all of the non-static data members of its class that are of class
+ /// type (or array thereof), each such class has a trivial destructor.
+ bool HasTrivialDestructor : 1;
+
+ /// ComputedVisibleConversions - True when visible conversion functions are
+ /// already computed and are available.
+ bool ComputedVisibleConversions : 1;
+
+ /// Bases - Base classes of this class.
+ /// FIXME: This is wasted space for a union.
+ CXXBaseSpecifier *Bases;
+
+ /// NumBases - The number of base class specifiers in Bases.
+ unsigned NumBases;
+
+ /// VBases - direct and indirect virtual base classes of this class.
+ CXXBaseSpecifier *VBases;
+
+ /// NumVBases - The number of virtual base class specifiers in VBases.
+ unsigned NumVBases;
+
+ /// Conversions - Overload set containing the conversion functions
+ /// of this C++ class (but not its inherited conversion
+ /// functions). Each of the entries in this overload set is a
+ /// CXXConversionDecl.
+ UnresolvedSet<4> Conversions;
+
+ /// VisibleConversions - Overload set containing 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.
+ UnresolvedSet<4> VisibleConversions;
+
+ /// Definition - The declaration which defines this record.
+ CXXRecordDecl *Definition;
+
+ /// FirstFriend - The first friend declaration in this class, or
+ /// null if there aren't any. This is actually currently stored
+ /// in reverse order.
+ FriendDecl *FirstFriend;
+
+ } *DefinitionData;
+
+ struct DefinitionData &data() {
+ assert(DefinitionData && "queried property of class with no definition");
+ return *DefinitionData;
+ }
+
+ const struct DefinitionData &data() const {
+ assert(DefinitionData && "queried property of class with no definition");
+ return *DefinitionData;
+ }
+
+ /// \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;
+
+#ifndef NDEBUG
+ void CheckConversionFunction(NamedDecl *D);
+#endif
+
+protected:
+ CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ CXXRecordDecl *PrevDecl,
+ SourceLocation TKL = SourceLocation());
+
+ ~CXXRecordDecl();
+
+public:
+ /// base_class_iterator - Iterator that traverses the base classes
+ /// of a class.
+ typedef CXXBaseSpecifier* base_class_iterator;
+
+ /// base_class_const_iterator - Iterator that traverses the base
+ /// classes of a class.
+ typedef const CXXBaseSpecifier* base_class_const_iterator;
+
+ /// reverse_base_class_iterator = Iterator that traverses the base classes
+ /// of a class in reverse order.
+ typedef std::reverse_iterator<base_class_iterator>
+ reverse_base_class_iterator;
+
+ /// reverse_base_class_iterator = Iterator that traverses the base classes
+ /// of a class in reverse order.
+ typedef std::reverse_iterator<base_class_const_iterator>
+ reverse_base_class_const_iterator;
+
+ virtual CXXRecordDecl *getCanonicalDecl() {
+ return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+ }
+ virtual const CXXRecordDecl *getCanonicalDecl() const {
+ return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+ }
+
+ CXXRecordDecl *getDefinition() const {
+ if (!DefinitionData) return 0;
+ return data().Definition;
+ }
+
+ bool hasDefinition() const { return DefinitionData != 0; }
+
+ static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ SourceLocation TKL = SourceLocation(),
+ CXXRecordDecl* PrevDecl=0,
+ bool DelayTypeCreation = false);
+
+ virtual void Destroy(ASTContext& C);
+
+ bool isDynamicClass() const {
+ return data().Polymorphic || data().NumVBases != 0;
+ }
+
+ /// setBases - Sets the base classes of this struct or class.
+ void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
+
+ /// getNumBases - Retrieves the number of base classes of this
+ /// class.
+ unsigned getNumBases() const { return data().NumBases; }
+
+ base_class_iterator bases_begin() { return data().Bases; }
+ base_class_const_iterator bases_begin() const { return data().Bases; }
+ base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
+ base_class_const_iterator bases_end() const {
+ return bases_begin() + data().NumBases;
+ }
+ reverse_base_class_iterator bases_rbegin() {
+ return reverse_base_class_iterator(bases_end());
+ }
+ reverse_base_class_const_iterator bases_rbegin() const {
+ return reverse_base_class_const_iterator(bases_end());
+ }
+ reverse_base_class_iterator bases_rend() {
+ return reverse_base_class_iterator(bases_begin());
+ }
+ reverse_base_class_const_iterator bases_rend() const {
+ return reverse_base_class_const_iterator(bases_begin());
+ }
+
+ /// getNumVBases - Retrieves the number of virtual base classes of this
+ /// class.
+ unsigned getNumVBases() const { return data().NumVBases; }
+
+ base_class_iterator vbases_begin() { return data().VBases; }
+ base_class_const_iterator vbases_begin() const { return data().VBases; }
+ base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
+ base_class_const_iterator vbases_end() const {
+ return vbases_begin() + data().NumVBases;
+ }
+ reverse_base_class_iterator vbases_rbegin() {
+ return reverse_base_class_iterator(vbases_end());
+ }
+ reverse_base_class_const_iterator vbases_rbegin() const {
+ return reverse_base_class_const_iterator(vbases_end());
+ }
+ reverse_base_class_iterator vbases_rend() {
+ return reverse_base_class_iterator(vbases_begin());
+ }
+ reverse_base_class_const_iterator vbases_rend() const {
+ return reverse_base_class_const_iterator(vbases_begin());
+ }
+
+ /// \brief Determine whether this class has any dependent base classes.
+ 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;
+
+ /// method_begin - Method begin iterator. Iterates in the order the methods
+ /// were declared.
+ method_iterator method_begin() const {
+ return method_iterator(decls_begin());
+ }
+ /// method_end - Method end iterator.
+ method_iterator method_end() const {
+ return method_iterator(decls_end());
+ }
+
+ /// Iterator access to constructor members.
+ typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
+
+ 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;
+ 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 != 0;
+ }
+
+ /// hasConstCopyConstructor - Determines whether this class has a
+ /// copy constructor that accepts a const-qualified argument.
+ bool hasConstCopyConstructor(ASTContext &Context) const;
+
+ /// getCopyConstructor - Returns the copy constructor for this class
+ CXXConstructorDecl *getCopyConstructor(ASTContext &Context,
+ unsigned TypeQuals) const;
+
+ /// hasConstCopyAssignment - Determines whether this class has a
+ /// copy assignment operator that accepts a const-qualified argument.
+ /// It returns its decl in MD if found.
+ bool hasConstCopyAssignment(ASTContext &Context,
+ const CXXMethodDecl *&MD) const;
+
+ /// addedConstructor - Notify the class that another constructor has
+ /// been added. This routine helps maintain information about the
+ /// class based on which constructors have been added.
+ void addedConstructor(ASTContext &Context, CXXConstructorDecl *ConDecl);
+
+ /// hasUserDeclaredConstructor - Whether this class has any
+ /// user-declared constructors. When true, a default constructor
+ /// will not be implicitly declared.
+ bool hasUserDeclaredConstructor() const {
+ return data().UserDeclaredConstructor;
+ }
+
+ /// hasUserDeclaredCopyConstructor - Whether this class has a
+ /// user-declared copy constructor. When false, a copy constructor
+ /// will be implicitly declared.
+ bool hasUserDeclaredCopyConstructor() const {
+ return data().UserDeclaredCopyConstructor;
+ }
+
+ /// addedAssignmentOperator - Notify the class that another assignment
+ /// operator has been added. This routine helps maintain information about the
+ /// class based on which operators have been added.
+ void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl);
+
+ /// hasUserDeclaredCopyAssignment - 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().UserDeclaredCopyAssignment;
+ }
+
+ /// hasUserDeclaredDestructor - Whether this class has a
+ /// user-declared destructor. When false, a destructor will be
+ /// implicitly declared.
+ bool hasUserDeclaredDestructor() const {
+ return data().UserDeclaredDestructor;
+ }
+
+ /// setUserDeclaredDestructor - Set whether this class has a
+ /// user-declared destructor. If not set by the time the class is
+ /// fully defined, a destructor will be implicitly declared.
+ void setUserDeclaredDestructor(bool UCD) {
+ data().UserDeclaredDestructor = UCD;
+ }
+
+ /// getConversions - Retrieve the overload set containing all of the
+ /// conversion functions in this class.
+ UnresolvedSetImpl *getConversionFunctions() {
+ return &data().Conversions;
+ }
+ const UnresolvedSetImpl *getConversionFunctions() const {
+ return &data().Conversions;
+ }
+
+ typedef UnresolvedSetImpl::iterator conversion_iterator;
+ conversion_iterator conversion_begin() const {
+ return getConversionFunctions()->begin();
+ }
+ conversion_iterator conversion_end() const {
+ return getConversionFunctions()->end();
+ }
+
+ /// Replaces a conversion function with a new declaration.
+ ///
+ /// Returns true if the old conversion was found.
+ bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
+ return getConversionFunctions()->replace(Old, New);
+ }
+
+ /// 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);
+
+ /// getVisibleConversionFunctions - get all conversion functions visible
+ /// in current class; including conversion function templates.
+ const UnresolvedSetImpl *getVisibleConversionFunctions();
+
+ /// addConversionFunction - Registers a conversion function which
+ /// this class declares directly.
+ void addConversionFunction(NamedDecl *Decl) {
+#ifndef NDEBUG
+ CheckConversionFunction(Decl);
+#endif
+
+ // We intentionally don't use the decl's access here because it
+ // hasn't been set yet. That's really just a misdesign in Sema.
+ data().Conversions.addDecl(Decl);
+ }
+
+ /// isAggregate - 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; }
+
+ /// setAggregate - Set whether this class is an aggregate (C++
+ /// [dcl.init.aggr]).
+ void setAggregate(bool Agg) { data().Aggregate = Agg; }
+
+ /// setMethodAsVirtual - Make input method virtual and set the necesssary
+ /// special function bits and other bits accordingly.
+ void setMethodAsVirtual(FunctionDecl *Method);
+
+ /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
+ /// that 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.
+ bool isPOD() const { return data().PlainOldData; }
+
+ /// setPOD - Set whether this class is a POD-type (C++ [class]p4).
+ void setPOD(bool POD) { data().PlainOldData = POD; }
+
+ /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
+ /// means it has a virtual function, virtual base, data member (other than
+ /// 0-width bit-field) or inherits from a non-empty class. Does NOT include
+ /// a check for union-ness.
+ bool isEmpty() const { return data().Empty; }
+
+ /// Set whether this class is empty (C++0x [meta.unary.prop])
+ void setEmpty(bool Emp) { data().Empty = Emp; }
+
+ /// isPolymorphic - 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; }
+
+ /// setPolymorphic - Set whether this class is polymorphic (C++
+ /// [class.virtual]).
+ void setPolymorphic(bool Poly) { data().Polymorphic = Poly; }
+
+ /// isAbstract - Whether this class is abstract (C++ [class.abstract]),
+ /// which means that the class contains or inherits a pure virtual function.
+ bool isAbstract() const { return data().Abstract; }
+
+ /// setAbstract - Set whether this class is abstract (C++ [class.abstract])
+ void setAbstract(bool Abs) { data().Abstract = Abs; }
+
+ // hasTrivialConstructor - Whether this class has a trivial constructor
+ // (C++ [class.ctor]p5)
+ bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
+
+ // setHasTrivialConstructor - Set whether this class has a trivial constructor
+ // (C++ [class.ctor]p5)
+ void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
+
+ // hasTrivialCopyConstructor - Whether this class has a trivial copy
+ // constructor (C++ [class.copy]p6)
+ bool hasTrivialCopyConstructor() const {
+ return data().HasTrivialCopyConstructor;
+ }
+
+ // setHasTrivialCopyConstructor - Set whether this class has a trivial
+ // copy constructor (C++ [class.copy]p6)
+ void setHasTrivialCopyConstructor(bool TC) {
+ data().HasTrivialCopyConstructor = TC;
+ }
+
+ // hasTrivialCopyAssignment - Whether this class has a trivial copy
+ // assignment operator (C++ [class.copy]p11)
+ bool hasTrivialCopyAssignment() const {
+ return data().HasTrivialCopyAssignment;
+ }
+
+ // setHasTrivialCopyAssignment - Set whether this class has a
+ // trivial copy assignment operator (C++ [class.copy]p11)
+ void setHasTrivialCopyAssignment(bool TC) {
+ data().HasTrivialCopyAssignment = TC;
+ }
+
+ // hasTrivialDestructor - Whether this class has a trivial destructor
+ // (C++ [class.dtor]p3)
+ bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
+
+ // setHasTrivialDestructor - Set whether this class has a trivial destructor
+ // (C++ [class.dtor]p3)
+ void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
+
+ /// \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 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 {
+ return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl*>();
+ }
+
+ void setDescribedClassTemplate(ClassTemplateDecl *Template) {
+ TemplateOrInstantiation = 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);
+
+ /// getDefaultConstructor - Returns the default constructor for this class
+ CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
+
+ /// getDestructor - Returns the destructor decl for this class.
+ CXXDestructorDecl *getDestructor(ASTContext &Context) const;
+
+ /// isLocalClass - 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());
+ }
+
+ /// \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(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 Base, false otherwise.
+ ///
+ /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
+ /// tangling input and output in \p Paths
+ bool isDerivedFrom(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(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 Base the definition of the base class
+ ///
+ /// \returns true if this base matched the search criteria
+ typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition,
+ void *UserData);
+
+ /// \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 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, void *UserData,
+ 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.
+ ///
+ /// \param UserData a single pointer to user-specified data, provided to
+ /// lookupInBases().
+ ///
+ /// \returns true if this base matched the search criteria, false otherwise.
+ typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path,
+ void *UserData);
+
+ /// \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 UserData user data pointer that will be provided to \p BaseMatches.
+ ///
+ /// \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, void *UserData,
+ 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 user data pointer should refer to the canonical CXXRecordDecl of the
+ /// base class that we are searching for.
+ static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *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 user data pointer should
+ /// refer to the canonical CXXRecordDecl of the base class that we
+ /// are searching for.
+ static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *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. The user data pointer
+ /// is an opaque \c DeclarationName pointer.
+ static bool FindTagMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *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. The user data pointer
+ /// is an opaque \c DeclarationName pointer.
+ static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *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 membes of
+ /// the given name within a C++ class hierarchy that can occur within
+ /// nested-name-specifiers.
+ static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path,
+ void *UserData);
+
+ /// \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;
+
+ /// viewInheritance - Renders and displays an inheritance diagram
+ /// for this C++ class and all of its base classes (transitively) using
+ /// GraphViz.
+ void viewInheritance(ASTContext& Context) const;
+
+ /// MergeAccess - 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);
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == CXXRecord ||
+ K == ClassTemplateSpecialization ||
+ K == ClassTemplatePartialSpecialization;
+ }
+ static bool classof(const CXXRecordDecl *D) { return true; }
+ static bool classof(const ClassTemplateSpecializationDecl *D) {
+ return true;
+ }
+};
+
+/// CXXMethodDecl - Represents a static or instance method of a
+/// struct/union/class.
+class CXXMethodDecl : public FunctionDecl {
+protected:
+ CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ bool isStatic, StorageClass SCAsWritten, bool isInline)
+ : FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None),
+ SCAsWritten, isInline) {}
+
+public:
+ static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation L, DeclarationName N,
+ QualType T, TypeSourceInfo *TInfo,
+ bool isStatic = false,
+ StorageClass SCAsWritten = FunctionDecl::None,
+ bool isInline = false);
+
+ bool isStatic() const { return getStorageClass() == Static; }
+ bool isInstance() const { return !isStatic(); }
+
+ bool isVirtual() const {
+ CXXMethodDecl *CD =
+ cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
+
+ if (CD->isVirtualAsWritten())
+ 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;
+
+ const CXXMethodDecl *getCanonicalDecl() const {
+ return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
+ }
+ CXXMethodDecl *getCanonicalDecl() {
+ return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
+ }
+
+ ///
+ void addOverriddenMethod(const CXXMethodDecl *MD);
+
+ typedef const CXXMethodDecl ** method_iterator;
+
+ method_iterator begin_overridden_methods() const;
+ method_iterator end_overridden_methods() const;
+
+ /// getParent - 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());
+ }
+
+ /// 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()));
+ }
+
+ /// getThisType - Returns the type of 'this' pointer.
+ /// Should only be called for instance methods.
+ QualType getThisType(ASTContext &C) const;
+
+ unsigned getTypeQualifiers() const {
+ return getType()->getAs<FunctionProtoType>()->getTypeQuals();
+ }
+
+ bool hasInlineBody() const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const CXXMethodDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= CXXMethod && K <= CXXConversion;
+ }
+};
+
+/// CXXBaseOrMemberInitializer - Represents a C++ base or member
+/// initializer, which 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 CXXBaseOrMemberInitializer {
+ /// \brief Either the base class name (stored as a TypeSourceInfo*) or the
+ /// field being initialized.
+ llvm::PointerUnion<TypeSourceInfo *, FieldDecl *> BaseOrMember;
+
+ /// \brief The source location for the field name.
+ SourceLocation MemberLocation;
+
+ /// \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 Stores either the constructor to call to initialize this base or
+ /// member (a CXXConstructorDecl pointer), or stores the anonymous union of
+ /// which the initialized value is a member.
+ ///
+ /// When the value is a FieldDecl pointer, 'BaseOrMember' is class's
+ /// anonymous union data member, this field holds the FieldDecl for the
+ /// member of the anonymous union being initialized.
+ /// @code
+ /// struct X {
+ /// X() : au_i1(123) {}
+ /// union {
+ /// int au_i1;
+ /// float au_f1;
+ /// };
+ /// };
+ /// @endcode
+ /// In above example, BaseOrMember holds the field decl. for anonymous union
+ /// and AnonUnionMember holds field decl for au_i1.
+ FieldDecl *AnonUnionMember;
+
+ /// LParenLoc - Location of the left paren of the ctor-initializer.
+ SourceLocation LParenLoc;
+
+ /// RParenLoc - Location of the right paren of the ctor-initializer.
+ SourceLocation RParenLoc;
+
+ /// IsVirtual - If the initializer is a base initializer, this keeps track
+ /// of whether the base is virtual or not.
+ bool IsVirtual : 1;
+
+ /// IsWritten - Whether or not the initializer is explicitly written
+ /// in the sources.
+ bool IsWritten : 1;
+ /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
+ /// number keeps track of the textual order of this initializer in the
+ /// original sources, counting from 0; otherwise, if IsWritten is false,
+ /// it stores the number of array index variables stored after this
+ /// object in memory.
+ unsigned SourceOrderOrNumArrayIndices : 14;
+
+ CXXBaseOrMemberInitializer(ASTContext &Context,
+ FieldDecl *Member, SourceLocation MemberLoc,
+ SourceLocation L,
+ Expr *Init,
+ SourceLocation R,
+ VarDecl **Indices,
+ unsigned NumIndices);
+
+public:
+ /// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
+ explicit
+ CXXBaseOrMemberInitializer(ASTContext &Context,
+ TypeSourceInfo *TInfo, bool IsVirtual,
+ SourceLocation L,
+ Expr *Init,
+ SourceLocation R);
+
+ /// CXXBaseOrMemberInitializer - Creates a new member initializer.
+ explicit
+ CXXBaseOrMemberInitializer(ASTContext &Context,
+ FieldDecl *Member, SourceLocation MemberLoc,
+ SourceLocation L,
+ Expr *Init,
+ SourceLocation R);
+
+ /// \brief Creates a new member initializer that optionally contains
+ /// array indices used to describe an elementwise initialization.
+ static CXXBaseOrMemberInitializer *Create(ASTContext &Context,
+ FieldDecl *Member,
+ SourceLocation MemberLoc,
+ SourceLocation L,
+ Expr *Init,
+ SourceLocation R,
+ VarDecl **Indices,
+ unsigned NumIndices);
+
+ /// \brief Destroy the base or member initializer.
+ void Destroy(ASTContext &Context);
+
+ /// isBaseInitializer - Returns true when this initializer is
+ /// initializing a base class.
+ bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
+
+ /// isMemberInitializer - Returns true when this initializer is
+ /// initializing a non-static data member.
+ bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); }
+
+ /// 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;
+ Type *getBaseClass();
+
+ /// 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 initializer.
+ TypeSourceInfo *getBaseClassInfo() const {
+ return BaseOrMember.dyn_cast<TypeSourceInfo *>();
+ }
+
+ /// getMember - If this is a member initializer, returns the
+ /// declaration of the non-static data member being
+ /// initialized. Otherwise, returns NULL.
+ FieldDecl *getMember() {
+ if (isMemberInitializer())
+ return BaseOrMember.get<FieldDecl*>();
+ else
+ return 0;
+ }
+
+ SourceLocation getMemberLocation() const {
+ return MemberLocation;
+ }
+
+ void setMember(FieldDecl *Member) {
+ assert(isMemberInitializer());
+ BaseOrMember = Member;
+ }
+
+ /// \brief Determine the source location of the initializer.
+ SourceLocation getSourceLocation() const;
+
+ /// \brief Determine the source range covering the entire initializer.
+ SourceRange getSourceRange() const;
+
+ /// isWritten - Returns true if 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 method can only
+ /// be called once for each initializer; it cannot be called on an
+ /// initializer having a positive number of (implicit) array indices.
+ 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);
+ }
+
+ FieldDecl *getAnonUnionMember() const {
+ return AnonUnionMember;
+ }
+ void setAnonUnionMember(FieldDecl *anonMember) {
+ AnonUnionMember = anonMember;
+ }
+
+
+ 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 reinterpret_cast<VarDecl **>(this + 1)[I];
+ }
+ const VarDecl *getArrayIndex(unsigned I) const {
+ assert(I < getNumArrayIndices() && "Out of bounds member array index");
+ return reinterpret_cast<const VarDecl * const *>(this + 1)[I];
+ }
+ void setArrayIndex(unsigned I, VarDecl *Index) {
+ assert(I < getNumArrayIndices() && "Out of bounds member array index");
+ reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
+ }
+
+ Expr *getInit() { return static_cast<Expr *>(Init); }
+};
+
+/// CXXConstructorDecl - 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 {
+ /// IsExplicitSpecified - Whether this constructor declaration has the
+ /// 'explicit' keyword specified.
+ bool IsExplicitSpecified : 1;
+
+ /// ImplicitlyDefined - Whether this constructor was implicitly
+ /// defined by the compiler. When false, the constructor was defined
+ /// by the user. In C++03, this flag will have the same value as
+ /// Implicit. In C++0x, however, a constructor that is
+ /// explicitly defaulted (i.e., defined with " = default") will have
+ /// @c !Implicit && ImplicitlyDefined.
+ bool ImplicitlyDefined : 1;
+
+ /// Support for base and member initializers.
+ /// BaseOrMemberInitializers - The arguments used to initialize the base
+ /// or member.
+ CXXBaseOrMemberInitializer **BaseOrMemberInitializers;
+ unsigned NumBaseOrMemberInitializers;
+
+ CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ bool isExplicitSpecified, bool isInline,
+ bool isImplicitlyDeclared)
+ : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false,
+ FunctionDecl::None, isInline),
+ IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
+ BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
+ setImplicit(isImplicitlyDeclared);
+ }
+ virtual void Destroy(ASTContext& C);
+
+public:
+ static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
+ static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation L, DeclarationName N,
+ QualType T, TypeSourceInfo *TInfo,
+ bool isExplicit,
+ bool isInline, bool isImplicitlyDeclared);
+
+ /// isExplicitSpecified - Whether this constructor declaration has the
+ /// 'explicit' keyword specified.
+ bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
+ /// isExplicit - Whether this constructor was marked "explicit" or not.
+ bool isExplicit() const {
+ return cast<CXXConstructorDecl>(getFirstDeclaration())
+ ->isExplicitSpecified();
+ }
+
+ /// isImplicitlyDefined - Whether this constructor was implicitly
+ /// defined. If false, then this constructor was defined by the
+ /// user. This operation can only be invoked if the constructor has
+ /// already been defined.
+ bool isImplicitlyDefined() const {
+ assert(isThisDeclarationADefinition() &&
+ "Can only get the implicit-definition flag once the "
+ "constructor has been defined");
+ return ImplicitlyDefined;
+ }
+
+ /// setImplicitlyDefined - Set whether this constructor was
+ /// implicitly defined or not.
+ void setImplicitlyDefined(bool ID) {
+ assert(isThisDeclarationADefinition() &&
+ "Can only set the implicit-definition flag once the constructor "
+ "has been defined");
+ ImplicitlyDefined = ID;
+ }
+
+ /// init_iterator - Iterates through the member/base initializer list.
+ typedef CXXBaseOrMemberInitializer **init_iterator;
+
+ /// init_const_iterator - Iterates through the memberbase initializer list.
+ typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
+
+ /// init_begin() - Retrieve an iterator to the first initializer.
+ init_iterator init_begin() { return BaseOrMemberInitializers; }
+ /// begin() - Retrieve an iterator to the first initializer.
+ init_const_iterator init_begin() const { return BaseOrMemberInitializers; }
+
+ /// init_end() - Retrieve an iterator past the last initializer.
+ init_iterator init_end() {
+ return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+ }
+ /// end() - Retrieve an iterator past the last initializer.
+ init_const_iterator init_end() const {
+ return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+ }
+
+ /// getNumArgs - Determine the number of arguments used to
+ /// initialize the member or base.
+ unsigned getNumBaseOrMemberInitializers() const {
+ return NumBaseOrMemberInitializers;
+ }
+
+ void setNumBaseOrMemberInitializers(unsigned numBaseOrMemberInitializers) {
+ NumBaseOrMemberInitializers = numBaseOrMemberInitializers;
+ }
+
+ void setBaseOrMemberInitializers(CXXBaseOrMemberInitializer ** initializers) {
+ BaseOrMemberInitializers = initializers;
+ }
+ /// isDefaultConstructor - 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;
+
+ /// isCopyConstructor - 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
+ /// QualType::Const for the following copy constructor:
+ ///
+ /// @code
+ /// class X {
+ /// public:
+ /// X(const X&);
+ /// };
+ /// @endcode
+ bool isCopyConstructor(unsigned &TypeQuals) const;
+
+ /// isCopyConstructor - 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);
+ }
+
+ /// isConvertingConstructor - 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
+ /// looks like a copy constructor. Such constructors are never used to copy
+ /// an object.
+ bool isCopyConstructorLikeSpecialization() const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const CXXConstructorDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXConstructor; }
+};
+
+/// CXXDestructorDecl - Represents a C++ destructor within a
+/// class. For example:
+///
+/// @code
+/// class X {
+/// public:
+/// ~X(); // represented by a CXXDestructorDecl.
+/// };
+/// @endcode
+class CXXDestructorDecl : public CXXMethodDecl {
+ /// ImplicitlyDefined - Whether this destructor was implicitly
+ /// defined by the compiler. When false, the destructor was defined
+ /// by the user. In C++03, this flag will have the same value as
+ /// Implicit. In C++0x, however, a destructor that is
+ /// explicitly defaulted (i.e., defined with " = default") will have
+ /// @c !Implicit && ImplicitlyDefined.
+ bool ImplicitlyDefined : 1;
+
+ FunctionDecl *OperatorDelete;
+
+ CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
+ DeclarationName N, QualType T,
+ bool isInline, bool isImplicitlyDeclared)
+ : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false,
+ FunctionDecl::None, isInline),
+ ImplicitlyDefined(false), OperatorDelete(0) {
+ setImplicit(isImplicitlyDeclared);
+ }
+
+public:
+ static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
+ static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation L, DeclarationName N,
+ QualType T, bool isInline,
+ bool isImplicitlyDeclared);
+
+ /// isImplicitlyDefined - Whether this destructor was implicitly
+ /// defined. If false, then this destructor was defined by the
+ /// user. This operation can only be invoked if the destructor has
+ /// already been defined.
+ bool isImplicitlyDefined() const {
+ assert(isThisDeclarationADefinition() &&
+ "Can only get the implicit-definition flag once the destructor has been defined");
+ return ImplicitlyDefined;
+ }
+
+ /// setImplicitlyDefined - Set whether this destructor was
+ /// implicitly defined or not.
+ void setImplicitlyDefined(bool ID) {
+ assert(isThisDeclarationADefinition() &&
+ "Can only set the implicit-definition flag once the destructor has been defined");
+ ImplicitlyDefined = ID;
+ }
+
+ void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
+ const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const CXXDestructorDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXDestructor; }
+};
+
+/// CXXConversionDecl - Represents a C++ conversion function within a
+/// class. For example:
+///
+/// @code
+/// class X {
+/// public:
+/// operator bool();
+/// };
+/// @endcode
+class CXXConversionDecl : public CXXMethodDecl {
+ /// IsExplicitSpecified - Whether this conversion function declaration is
+ /// marked "explicit", meaning that it can only be applied when the user
+ /// explicitly wrote a cast. This is a C++0x feature.
+ bool IsExplicitSpecified : 1;
+
+ CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ bool isInline, bool isExplicitSpecified)
+ : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false,
+ FunctionDecl::None, isInline),
+ IsExplicitSpecified(isExplicitSpecified) { }
+
+public:
+ static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
+ static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation L, DeclarationName N,
+ QualType T, TypeSourceInfo *TInfo,
+ bool isInline, bool isExplicit);
+
+ /// IsExplicitSpecified - Whether this conversion function declaration is
+ /// marked "explicit", meaning that it can only be applied when the user
+ /// explicitly wrote a cast. This is a C++0x feature.
+ bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
+ /// isExplicit - Whether this is an explicit conversion operator
+ /// (C++0x only). Explicit conversion operators are only considered
+ /// when the user has explicitly written a cast.
+ bool isExplicit() const {
+ return cast<CXXConversionDecl>(getFirstDeclaration())
+ ->isExplicitSpecified();
+ }
+
+ /// getConversionType - Returns the type that this conversion
+ /// function is converting to.
+ QualType getConversionType() const {
+ return getType()->getAs<FunctionType>()->getResultType();
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const CXXConversionDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXConversion; }
+};
+
+/// LinkageSpecDecl - This represents a linkage specification. For example:
+/// extern "C" void foo();
+///
+class LinkageSpecDecl : public Decl, public DeclContext {
+public:
+ /// LanguageIDs - Used to represent 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:
+ /// Language - The language for this linkage specification.
+ LanguageIDs Language;
+
+ /// HadBraces - Whether this linkage specification had curly braces or not.
+ bool HadBraces : 1;
+
+ LinkageSpecDecl(DeclContext *DC, SourceLocation L, LanguageIDs lang,
+ bool Braces)
+ : Decl(LinkageSpec, DC, L),
+ DeclContext(LinkageSpec), Language(lang), HadBraces(Braces) { }
+
+public:
+ static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, LanguageIDs Lang,
+ bool Braces);
+
+ /// \brief Return the language specified by this linkage specification.
+ LanguageIDs getLanguage() const { return 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 { return HadBraces; }
+
+ /// \brief Set whether this linkage specification has braces in its
+ /// syntactic form.
+ void setHasBraces(bool B) { HadBraces = B; }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const LinkageSpecDecl *D) { return true; }
+ 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));
+ }
+};
+
+/// UsingDirectiveDecl - Represents C++ using-directive. For example:
+///
+/// using namespace std;
+///
+// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide
+// artificial name, for all using-directives in order to store
+// them in DeclContext effectively.
+class UsingDirectiveDecl : public NamedDecl {
+
+ /// SourceLocation - Location of 'namespace' token.
+ SourceLocation NamespaceLoc;
+
+ /// \brief The source range that covers the nested-name-specifier
+ /// preceding the namespace name.
+ SourceRange QualifierRange;
+
+ /// \brief The nested-name-specifier that precedes the namespace
+ /// name, if any.
+ NestedNameSpecifier *Qualifier;
+
+ /// IdentLoc - Location of nominated namespace-name identifier.
+ // FIXME: We don't store location of scope specifier.
+ SourceLocation IdentLoc;
+
+ /// NominatedNamespace - Namespace nominated by using-directive.
+ NamedDecl *NominatedNamespace;
+
+ /// Enclosing context containing both using-directive and nominated
+ /// namespace.
+ DeclContext *CommonAncestor;
+
+ /// getUsingDirectiveName - 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 L,
+ SourceLocation NamespcLoc,
+ SourceRange QualifierRange,
+ NestedNameSpecifier *Qualifier,
+ SourceLocation IdentLoc,
+ NamedDecl *Nominated,
+ DeclContext *CommonAncestor)
+ : NamedDecl(Decl::UsingDirective, DC, L, getName()),
+ NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
+ Qualifier(Qualifier), IdentLoc(IdentLoc),
+ NominatedNamespace(Nominated),
+ CommonAncestor(CommonAncestor) {
+ }
+
+public:
+ /// \brief Retrieve the source range of the nested-name-specifier
+ /// that qualifies the namespace name.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Set the source range of the nested-name-specifier that
+ /// qualifies the namespace name.
+ void setQualifierRange(SourceRange R) { QualifierRange = R; }
+
+ /// \brief Retrieve the nested-name-specifier that qualifies the
+ /// name of the namespace.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Set the nested-name-specifier that qualifes the name of the
+ /// namespace.
+ void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+
+ NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
+ const NamedDecl *getNominatedNamespaceAsWritten() const {
+ return NominatedNamespace;
+ }
+
+ /// getNominatedNamespace - Returns namespace nominated by using-directive.
+ NamespaceDecl *getNominatedNamespace();
+
+ const NamespaceDecl *getNominatedNamespace() const {
+ return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
+ }
+
+ /// setNominatedNamespace - Set the namespace nominataed by the
+ /// using-directive.
+ void setNominatedNamespace(NamedDecl* NS);
+
+ /// \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 Set the common ancestor context of this using-directive and its
+ /// nominated namespace.
+ void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; }
+
+ // FIXME: Could omit 'Key' in name.
+ /// getNamespaceKeyLocation - Returns location of namespace keyword.
+ SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
+
+ /// setNamespaceKeyLocation - Set the the location of the namespacekeyword.
+ void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; }
+
+ /// getIdentLocation - Returns location of identifier.
+ SourceLocation getIdentLocation() const { return IdentLoc; }
+
+ /// setIdentLocation - set the location of the identifier.
+ void setIdentLocation(SourceLocation L) { IdentLoc = L; }
+
+ static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ SourceLocation NamespaceLoc,
+ SourceRange QualifierRange,
+ NestedNameSpecifier *Qualifier,
+ SourceLocation IdentLoc,
+ NamedDecl *Nominated,
+ DeclContext *CommonAncestor);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const UsingDirectiveDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UsingDirective; }
+
+ // Friend for getUsingDirectiveName.
+ friend class DeclContext;
+};
+
+/// NamespaceAliasDecl - Represents a C++ namespace alias. For example:
+///
+/// @code
+/// namespace Foo = Bar;
+/// @endcode
+class NamespaceAliasDecl : public NamedDecl {
+ SourceLocation AliasLoc;
+
+ /// \brief The source range that covers the nested-name-specifier
+ /// preceding the namespace name.
+ SourceRange QualifierRange;
+
+ /// \brief The nested-name-specifier that precedes the namespace
+ /// name, if any.
+ NestedNameSpecifier *Qualifier;
+
+ /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
+ SourceLocation IdentLoc;
+
+ /// Namespace - The Decl that this alias points to. Can either be a
+ /// NamespaceDecl or a NamespaceAliasDecl.
+ NamedDecl *Namespace;
+
+ NamespaceAliasDecl(DeclContext *DC, SourceLocation L,
+ SourceLocation AliasLoc, IdentifierInfo *Alias,
+ SourceRange QualifierRange,
+ NestedNameSpecifier *Qualifier,
+ SourceLocation IdentLoc, NamedDecl *Namespace)
+ : NamedDecl(Decl::NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
+ QualifierRange(QualifierRange), Qualifier(Qualifier),
+ IdentLoc(IdentLoc), Namespace(Namespace) { }
+
+public:
+ /// \brief Retrieve the source range of the nested-name-specifier
+ /// that qualifiers the namespace name.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Set the source range of the nested-name-specifier that qualifies
+ /// the namespace name.
+ void setQualifierRange(SourceRange R) { QualifierRange = R; }
+
+ /// \brief Retrieve the nested-name-specifier that qualifies the
+ /// name of the namespace.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Set the nested-name-specifier that qualifies the name of the
+ /// namespace.
+ void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+
+ /// \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 AliasLoc; }
+
+ /// Set the location o;f the alias name, e.e., 'foo' in
+ /// "namespace foo = ns::bar;".
+ void setAliasLoc(SourceLocation L) { AliasLoc = L; }
+
+ /// Returns the location of the 'namespace' keyword.
+ SourceLocation getNamespaceLoc() const { return getLocation(); }
+
+ /// Returns the location of the identifier in the named namespace.
+ SourceLocation getTargetNameLoc() const { return IdentLoc; }
+
+ /// Set the location of the identifier in the named namespace.
+ void setTargetNameLoc(SourceLocation L) { IdentLoc = L; }
+
+ /// \brief Retrieve the namespace that this alias refers to, which
+ /// may either be a NamespaceDecl or a NamespaceAliasDecl.
+ NamedDecl *getAliasedNamespace() const { return Namespace; }
+
+ /// \brief Set the namespace or namespace alias pointed to by this
+ /// alias decl.
+ void setAliasedNamespace(NamedDecl *ND) {
+ assert((isa<NamespaceAliasDecl>(ND) || isa<NamespaceDecl>(ND)) &&
+ "expecting namespace or namespace alias decl");
+ Namespace = ND;
+ }
+
+ static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, SourceLocation AliasLoc,
+ IdentifierInfo *Alias,
+ SourceRange QualifierRange,
+ NestedNameSpecifier *Qualifier,
+ SourceLocation IdentLoc,
+ NamedDecl *Namespace);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const NamespaceAliasDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::NamespaceAlias; }
+};
+
+/// UsingShadowDecl - Represents a shadow declaration introduced into
+/// a scope by a (resolved) using declaration. For example,
+///
+/// namespace A {
+/// void foo();
+/// }
+/// namespace B {
+/// using A::foo(); // <- a UsingDecl
+/// // Also creates a UsingShadowDecl for A::foo in B
+/// }
+///
+class UsingShadowDecl : public NamedDecl {
+ /// The referenced declaration.
+ NamedDecl *Underlying;
+
+ /// The using declaration which introduced this decl.
+ UsingDecl *Using;
+
+ UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
+ NamedDecl *Target)
+ : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
+ Underlying(Target), Using(Using) {
+ IdentifierNamespace = Target->getIdentifierNamespace();
+ setImplicit();
+ }
+
+public:
+ static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation Loc, UsingDecl *Using,
+ NamedDecl *Target) {
+ return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+ }
+
+ /// \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) { Underlying = ND; }
+
+ /// \brief Gets the using declaration to which this declaration is tied.
+ UsingDecl *getUsingDecl() const { return Using; }
+
+ /// \brief Sets the using declaration that introduces this target
+ /// declaration.
+ void setUsingDecl(UsingDecl* UD) { Using = UD; }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const UsingShadowDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
+};
+
+/// UsingDecl - Represents a C++ using-declaration. For example:
+/// using someNameSpace::someIdentifier;
+class UsingDecl : public NamedDecl {
+ /// \brief The source range that covers the nested-name-specifier
+ /// preceding the declaration name.
+ SourceRange NestedNameRange;
+
+ /// \brief The source location of the "using" location itself.
+ SourceLocation UsingLocation;
+
+ /// \brief Target nested name specifier.
+ NestedNameSpecifier* TargetNestedName;
+
+ /// \brief The collection of shadow declarations associated with
+ /// this using declaration. This set can change as a class is
+ /// processed.
+ llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows;
+
+ // \brief Has 'typename' keyword.
+ bool IsTypeName;
+
+ UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
+ SourceLocation UL, NestedNameSpecifier* TargetNNS,
+ DeclarationName Name, bool IsTypeNameArg)
+ : NamedDecl(Decl::Using, DC, L, Name),
+ NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
+ IsTypeName(IsTypeNameArg) {
+ }
+
+public:
+ // FIXME: Should be const?
+ /// \brief Returns the source range that covers the nested-name-specifier
+ /// preceding the namespace name.
+ SourceRange getNestedNameRange() { return NestedNameRange; }
+
+ /// \brief Set the source range of the nested-name-specifier.
+ void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
+
+ // FIXME; Should be const?
+ // FIXME: Naming is inconsistent with other get*Loc functions.
+ /// \brief Returns the source location of the "using" keyword.
+ SourceLocation getUsingLocation() { return UsingLocation; }
+
+ /// \brief Set the source location of the 'using' keyword.
+ void setUsingLocation(SourceLocation L) { UsingLocation = L; }
+
+
+ /// \brief Get the target nested name declaration.
+ NestedNameSpecifier* getTargetNestedNameDecl() {
+ return TargetNestedName;
+ }
+
+ /// \brief Set the target nested name declaration.
+ void setTargetNestedNameDecl(NestedNameSpecifier *NNS) {
+ TargetNestedName = NNS;
+ }
+
+ /// \brief Return true if the using declaration has 'typename'.
+ bool isTypeName() const { return IsTypeName; }
+
+ /// \brief Sets whether the using declaration has 'typename'.
+ void setTypeName(bool TN) { IsTypeName = TN; }
+
+ typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
+ shadow_iterator shadow_begin() const { return Shadows.begin(); }
+ shadow_iterator shadow_end() const { return Shadows.end(); }
+
+ void addShadowDecl(UsingShadowDecl *S) {
+ assert(S->getUsingDecl() == this);
+ if (!Shadows.insert(S)) {
+ assert(false && "declaration already in set");
+ }
+ }
+ void removeShadowDecl(UsingShadowDecl *S) {
+ assert(S->getUsingDecl() == this);
+ if (!Shadows.erase(S)) {
+ assert(false && "declaration not in set");
+ }
+ }
+
+ /// \brief Return the number of shadowed declarations associated with this
+ /// using declaration.
+ unsigned getNumShadowDecls() const {
+ return Shadows.size();
+ }
+
+ static UsingDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
+ NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const UsingDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::Using; }
+};
+
+/// UnresolvedUsingValueDecl - Represents a dependent using
+/// declaration which was not marked with 'typename'. Unlike
+/// non-dependent using declarations, these *only* bring through
+/// non-types; otherwise they would break two-phase lookup.
+///
+/// template <class T> class A : public Base<T> {
+/// using Base<T>::foo;
+/// };
+class UnresolvedUsingValueDecl : public ValueDecl {
+ /// \brief The source range that covers the nested-name-specifier
+ /// preceding the declaration name.
+ SourceRange TargetNestedNameRange;
+
+ /// \brief The source location of the 'using' keyword
+ SourceLocation UsingLocation;
+
+ NestedNameSpecifier *TargetNestedNameSpecifier;
+
+ UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
+ SourceLocation UsingLoc, SourceRange TargetNNR,
+ NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc,
+ DeclarationName TargetName)
+ : ValueDecl(Decl::UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TargetNestedNameSpecifier(TargetNNS)
+ { }
+
+public:
+ /// \brief Returns the source range that covers the nested-name-specifier
+ /// preceding the namespace name.
+ SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
+
+ /// \brief Set the source range coverting the nested-name-specifier preceding
+ /// the namespace name.
+ void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
+
+ /// \brief Get target nested name declaration.
+ NestedNameSpecifier* getTargetNestedNameSpecifier() {
+ return TargetNestedNameSpecifier;
+ }
+
+ /// \brief Set the nested name declaration.
+ void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
+ TargetNestedNameSpecifier = NNS;
+ }
+
+ /// \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; }
+
+ static UnresolvedUsingValueDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, DeclarationName TargetName);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingValue; }
+};
+
+/// UnresolvedUsingTypenameDecl - Represents a dependent using
+/// declaration which was marked with 'typename'.
+///
+/// template <class T> class A : public Base<T> {
+/// using typename Base<T>::foo;
+/// };
+///
+/// The type associated with a unresolved using typename decl is
+/// currently always a typename type.
+class UnresolvedUsingTypenameDecl : public TypeDecl {
+ /// \brief The source range that covers the nested-name-specifier
+ /// preceding the declaration name.
+ SourceRange TargetNestedNameRange;
+
+ /// \brief The source location of the 'using' keyword
+ SourceLocation UsingLocation;
+
+ /// \brief The source location of the 'typename' keyword
+ SourceLocation TypenameLocation;
+
+ NestedNameSpecifier *TargetNestedNameSpecifier;
+
+ UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
+ : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
+ { }
+
+public:
+ /// \brief Returns the source range that covers the nested-name-specifier
+ /// preceding the namespace name.
+ SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
+
+ /// \brief Set the source range coverting the nested-name-specifier preceding
+ /// the namespace name.
+ void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
+
+ /// \brief Get target nested name declaration.
+ NestedNameSpecifier* getTargetNestedNameSpecifier() {
+ return TargetNestedNameSpecifier;
+ }
+
+ /// \brief Set the nested name declaration.
+ void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
+ TargetNestedNameSpecifier = NNS;
+ }
+
+ /// \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 Returns the source location of the 'typename' keyword.
+ SourceLocation getTypenameLoc() const { return TypenameLocation; }
+
+ /// \brief Set the source location of the 'typename' keyword.
+ void setTypenameLoc(SourceLocation L) { TypenameLocation = L; }
+
+ static UnresolvedUsingTypenameDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, DeclarationName TargetName);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingTypename; }
+};
+
+/// StaticAssertDecl - Represents a C++0x static_assert declaration.
+class StaticAssertDecl : public Decl {
+ Expr *AssertExpr;
+ StringLiteral *Message;
+
+ StaticAssertDecl(DeclContext *DC, SourceLocation L,
+ Expr *assertexpr, StringLiteral *message)
+ : Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { }
+
+public:
+ static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, Expr *AssertExpr,
+ StringLiteral *Message);
+
+ Expr *getAssertExpr() { return AssertExpr; }
+ const Expr *getAssertExpr() const { return AssertExpr; }
+
+ StringLiteral *getMessage() { return Message; }
+ const StringLiteral *getMessage() const { return Message; }
+
+ virtual ~StaticAssertDecl();
+ virtual void Destroy(ASTContext& C);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(StaticAssertDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::StaticAssert; }
+};
+
+/// Insertion operator for diagnostics. This allows sending AccessSpecifier's
+/// into a diagnostic with <<.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ AccessSpecifier AS);
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h b/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h
new file mode 100644
index 0000000..9602b67
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h
@@ -0,0 +1,289 @@
+//===-- 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/DeclarationName.h"
+#include "clang/AST/DeclCXX.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include <algorithm>
+
+namespace clang {
+
+class DependentDiagnostic;
+
+/// StoredDeclsList - This is an array of decls optimized a common case of only
+/// containing one entry.
+struct StoredDeclsList {
+ /// The kind of data encoded in this list.
+ enum DataKind {
+ /// \brief The data is a NamedDecl*.
+ DK_Decl = 0,
+ /// \brief The data is a declaration ID (an unsigned value),
+ /// shifted left by 2 bits.
+ DK_DeclID = 1,
+ /// \brief The data is a pointer to a vector (of type VectorTy)
+ /// that contains declarations.
+ DK_Decl_Vector = 2,
+ /// \brief The data is a pointer to a vector (of type VectorTy)
+ /// that contains declaration ID.
+ DK_ID_Vector = 3
+ };
+
+ /// VectorTy - When in vector form, this is what the Data pointer points to.
+ typedef llvm::SmallVector<uintptr_t, 4> VectorTy;
+
+ /// \brief The stored data, which will be either a declaration ID, a
+ /// pointer to a NamedDecl, or a pointer to a vector.
+ uintptr_t Data;
+
+public:
+ StoredDeclsList() : Data(0) {}
+
+ StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
+ if (VectorTy *RHSVec = RHS.getAsVector()) {
+ VectorTy *New = new VectorTy(*RHSVec);
+ Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
+ }
+ }
+
+ ~StoredDeclsList() {
+ // If this is a vector-form, free the vector.
+ if (VectorTy *Vector = getAsVector())
+ delete Vector;
+ }
+
+ StoredDeclsList &operator=(const StoredDeclsList &RHS) {
+ if (VectorTy *Vector = getAsVector())
+ delete Vector;
+ Data = RHS.Data;
+ if (VectorTy *RHSVec = RHS.getAsVector()) {
+ VectorTy *New = new VectorTy(*RHSVec);
+ Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
+ }
+ return *this;
+ }
+
+ bool isNull() const { return (Data & ~0x03) == 0; }
+
+ NamedDecl *getAsDecl() const {
+ if ((Data & 0x03) != DK_Decl)
+ return 0;
+
+ return reinterpret_cast<NamedDecl *>(Data & ~0x03);
+ }
+
+ VectorTy *getAsVector() const {
+ if ((Data & 0x03) != DK_ID_Vector && (Data & 0x03) != DK_Decl_Vector)
+ return 0;
+
+ return reinterpret_cast<VectorTy *>(Data & ~0x03);
+ }
+
+ void setOnlyValue(NamedDecl *ND) {
+ assert(!getAsVector() && "Not inline");
+ Data = reinterpret_cast<uintptr_t>(ND);
+ }
+
+ void setFromDeclIDs(const llvm::SmallVectorImpl<unsigned> &Vec) {
+ if (Vec.size() > 1) {
+ VectorTy *Vector = getAsVector();
+ if (!Vector) {
+ Vector = new VectorTy;
+ Data = reinterpret_cast<uintptr_t>(Vector) | DK_ID_Vector;
+ }
+
+ Vector->resize(Vec.size());
+ std::copy(Vec.begin(), Vec.end(), Vector->begin());
+ return;
+ }
+
+ if (VectorTy *Vector = getAsVector())
+ delete Vector;
+
+ if (Vec.empty())
+ Data = 0;
+ else
+ Data = (Vec[0] << 2) | DK_DeclID;
+ }
+
+ /// \brief Force the stored declarations list to contain actual
+ /// declarations.
+ ///
+ /// This routine will resolve any declaration IDs for declarations
+ /// that may not yet have been loaded from external storage.
+ void materializeDecls(ASTContext &Context);
+
+ bool hasDeclarationIDs() const {
+ DataKind DK = (DataKind)(Data & 0x03);
+ return DK == DK_DeclID || DK == DK_ID_Vector;
+ }
+
+ void remove(NamedDecl *D) {
+ assert(!isNull() && "removing from empty list");
+ if (NamedDecl *Singleton = getAsDecl()) {
+ assert(Singleton == D && "list is different singleton");
+ (void)Singleton;
+ Data = 0;
+ return;
+ }
+
+ VectorTy &Vec = *getAsVector();
+ VectorTy::iterator I = std::find(Vec.begin(), Vec.end(),
+ reinterpret_cast<uintptr_t>(D));
+ assert(I != Vec.end() && "list does not contain decl");
+ Vec.erase(I);
+
+ assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D))
+ == Vec.end() && "list still contains decl");
+ }
+
+ /// getLookupResult - Return an array of all the decls that this list
+ /// represents.
+ DeclContext::lookup_result getLookupResult(ASTContext &Context) {
+ if (isNull())
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
+ DeclContext::lookup_iterator(0));
+
+ if (hasDeclarationIDs())
+ materializeDecls(Context);
+
+ // If we have a single NamedDecl, return it.
+ if (getAsDecl()) {
+ assert(!isNull() && "Empty list isn't allowed");
+
+ // Data is a raw pointer to a NamedDecl*, return it.
+ void *Ptr = &Data;
+ return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1);
+ }
+
+ assert(getAsVector() && "Must have a vector at this point");
+ VectorTy &Vector = *getAsVector();
+
+ // Otherwise, we have a range result.
+ return DeclContext::lookup_result((NamedDecl **)&Vector[0],
+ (NamedDecl **)&Vector[0]+Vector.size());
+ }
+
+ /// HandleRedeclaration - If this is a redeclaration of an existing decl,
+ /// replace the old one with D and return true. Otherwise return false.
+ bool HandleRedeclaration(ASTContext &Context, NamedDecl *D) {
+ if (hasDeclarationIDs())
+ materializeDecls(Context);
+
+ // Most decls only have one entry in their list, special case it.
+ if (NamedDecl *OldD = getAsDecl()) {
+ if (!D->declarationReplaces(OldD))
+ return false;
+ setOnlyValue(D);
+ return true;
+ }
+
+ // Determine if this declaration is actually a redeclaration.
+ VectorTy &Vec = *getAsVector();
+ for (VectorTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
+ OD != ODEnd; ++OD) {
+ NamedDecl *OldD = reinterpret_cast<NamedDecl *>(*OD);
+ if (D->declarationReplaces(OldD)) {
+ *OD = reinterpret_cast<uintptr_t>(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(!hasDeclarationIDs() && "Must materialize before adding decls");
+
+ // If this is the second decl added to the list, convert this to vector
+ // form.
+ if (NamedDecl *OldD = getAsDecl()) {
+ VectorTy *VT = new VectorTy();
+ VT->push_back(reinterpret_cast<uintptr_t>(OldD));
+ Data = reinterpret_cast<uintptr_t>(VT) | DK_Decl_Vector;
+ }
+
+ VectorTy &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(reinterpret_cast<uintptr_t>(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) {
+ VectorTy::iterator I = Vec.begin();
+ if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
+ while (I != Vec.end() &&
+ reinterpret_cast<NamedDecl *>(*I)
+ ->getIdentifierNamespace() == Decl::IDNS_Using)
+ ++I;
+ }
+ Vec.insert(I, reinterpret_cast<uintptr_t>(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 (reinterpret_cast<NamedDecl *>(Vec.back())
+ ->hasTagIdentifierNamespace()) {
+ uintptr_t TagD = Vec.back();
+ Vec.back() = reinterpret_cast<uintptr_t>(D);
+ Vec.push_back(TagD);
+ } else
+ Vec.push_back(reinterpret_cast<uintptr_t>(D));
+ }
+};
+
+class StoredDeclsMap
+ : public llvm::DenseMap<DeclarationName, StoredDeclsList> {
+
+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(0) {}
+
+private:
+ friend class DependentDiagnostic;
+ friend class DeclContext; // iterates over diagnostics
+
+ DependentDiagnostic *FirstDiagnostic;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h
new file mode 100644
index 0000000..a20625d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h
@@ -0,0 +1,159 @@
+//===-- 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"
+
+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 : public Decl {
+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.
+ FriendDecl *NextFriend;
+
+ // Location of the 'friend' specifier.
+ SourceLocation FriendLoc;
+
+ friend class CXXRecordDecl::friend_iterator;
+ friend class CXXRecordDecl;
+
+ FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
+ SourceLocation FriendL)
+ : Decl(Decl::Friend, DC, L),
+ Friend(Friend),
+ NextFriend(0),
+ FriendLoc(FriendL) {
+ }
+
+public:
+ static FriendDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, FriendUnion Friend_,
+ SourceLocation FriendL);
+
+ /// If this friend declaration names an (untemplated but
+ /// possibly dependent) type, return the type; otherwise
+ /// return null. This is used only for C++0x's unelaborated
+ /// friend type declarations.
+ TypeSourceInfo *getFriendType() const {
+ return Friend.dyn_cast<TypeSourceInfo*>();
+ }
+
+ /// If this friend declaration doesn't name an unelaborated
+ /// 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;
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const FriendDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::Friend; }
+};
+
+/// 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->NextFriend;
+ 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(data().FirstFriend);
+}
+
+inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
+ return friend_iterator(0);
+}
+
+inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
+ assert(FD->NextFriend == 0 && "friend already has next friend?");
+ FD->NextFriend = data().FirstFriend;
+ data().FirstFriend = FD;
+}
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclGroup.h b/contrib/llvm/tools/clang/include/clang/AST/DeclGroup.h
new file mode 100644
index 0000000..e1fae8f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclGroup.h
@@ -0,0 +1,152 @@
+//===--- 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/System/DataTypes.h"
+#include <cassert>
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class DeclGroup;
+class DeclGroupIterator;
+
+class DeclGroup {
+ // 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);
+ void Destroy(ASTContext& C);
+
+ unsigned size() const { return NumDecls; }
+
+ Decl*& operator[](unsigned i) {
+ assert (i < NumDecls && "Out-of-bounds access.");
+ return *((Decl**) (this+1));
+ }
+
+ Decl* const& operator[](unsigned i) const {
+ assert (i < NumDecls && "Out-of-bounds access.");
+ return *((Decl* const*) (this+1));
+ }
+};
+
+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(0) {}
+
+ 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 == 0; }
+ 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 : 0;
+ return &getDeclGroup()[0];
+ }
+
+ iterator end() {
+ if (isSingleDecl())
+ return D ? &D+1 : 0;
+ DeclGroup &G = getDeclGroup();
+ return &G[0] + G.size();
+ }
+
+ const_iterator begin() const {
+ if (isSingleDecl())
+ return D ? &D : 0;
+ return &getDeclGroup()[0];
+ }
+
+ const_iterator end() const {
+ if (isSingleDecl())
+ return D ? &D+1 : 0;
+ 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/contrib/llvm/tools/clang/include/clang/AST/DeclNodes.def b/contrib/llvm/tools/clang/include/clang/AST/DeclNodes.def
new file mode 100644
index 0000000..5b03ff8
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclNodes.def
@@ -0,0 +1,165 @@
+//===-- DeclNodes.def - Metadata about Decl 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 declaration nodes within the AST. The
+// description of the declaration nodes uses six macros:
+//
+// DECL(Derived, Base) describes a normal declaration type Derived
+// and specifies its base class. Note that Derived should not have
+// the Decl suffix on it, while Base should.
+//
+// LAST_DECL(Derived, Base) is like DECL, but is used for the last
+// declaration in the list.
+//
+// ABSTRACT_DECL(Derived, Base) describes an abstract class that is
+// used to specify a classification of declarations. For example,
+// TagDecl is an abstract class used to describe the various kinds of
+// "tag" declarations (unions, structs, classes, enums).
+//
+// DECL_CONTEXT(Decl) specifies that Decl is a kind of declaration
+// that is also a DeclContext.
+//
+// LAST_DECL_CONTEXT(Decl) is like DECL_CONTEXT, but is used for the
+// last declaration context.
+//
+// DECL_RANGE(CommonBase, Start, End) specifies a range of
+// declaration values that have a common (potentially indirect) base
+// class.
+//
+// LAST_DECL_RANGE(CommonBase, Start, End) is like DECL_RANGE, but is
+// used for the last declaration range.
+//
+// Note that, due to the use of ranges, the order of the these
+// declarations is significant. A declaration should be listed under
+// its base class.
+// ===----------------------------------------------------------------------===//
+
+#ifndef DECL
+# define DECL(Derived, Base)
+#endif
+
+#ifndef LAST_DECL
+# define LAST_DECL(Derived, Base) DECL(Derived, Base)
+#endif
+
+#ifndef ABSTRACT_DECL
+# define ABSTRACT_DECL(Derived, Base)
+#endif
+
+#ifndef DECL_CONTEXT
+# define DECL_CONTEXT(Decl)
+#endif
+
+#ifndef DECL_CONTEXT_BASE
+# define DECL_CONTEXT_BASE(Decl) DECL_CONTEXT(Decl)
+#endif
+
+#ifndef LAST_DECL_CONTEXT
+# define LAST_DECL_CONTEXT(Decl) DECL_CONTEXT(Decl)
+#endif
+
+#ifndef DECL_RANGE
+# define DECL_RANGE(CommonBase, Start, End)
+#endif
+
+#ifndef LAST_DECL_RANGE
+# define LAST_DECL_RANGE(CommonBase, Start, End) \
+ DECL_RANGE(CommonBase, Start, End)
+#endif
+
+DECL(TranslationUnit, Decl)
+ABSTRACT_DECL(Named, Decl)
+ DECL(Namespace, NamedDecl)
+ DECL(UsingDirective, NamedDecl)
+ DECL(NamespaceAlias, NamedDecl)
+ ABSTRACT_DECL(Type, NamedDecl)
+ DECL(Typedef, TypeDecl)
+ DECL(UnresolvedUsingTypename, TypeDecl)
+ ABSTRACT_DECL(Tag, TypeDecl)
+ DECL(Enum, TagDecl)
+ DECL(Record, TagDecl)
+ DECL(CXXRecord, RecordDecl)
+ DECL(ClassTemplateSpecialization, CXXRecordDecl)
+ DECL(ClassTemplatePartialSpecialization,
+ ClassTemplateSpecializationDecl)
+ DECL(TemplateTypeParm, TypeDecl)
+ ABSTRACT_DECL(Value, NamedDecl)
+ DECL(EnumConstant, ValueDecl)
+ DECL(UnresolvedUsingValue, ValueDecl)
+ ABSTRACT_DECL(Declarator, ValueDecl)
+ DECL(Function, DeclaratorDecl)
+ DECL(CXXMethod, FunctionDecl)
+ DECL(CXXConstructor, CXXMethodDecl)
+ DECL(CXXDestructor, CXXMethodDecl)
+ DECL(CXXConversion, CXXMethodDecl)
+ DECL(Field, DeclaratorDecl)
+ DECL(ObjCIvar, FieldDecl)
+ DECL(ObjCAtDefsField, FieldDecl)
+ DECL(Var, DeclaratorDecl)
+ DECL(ImplicitParam, VarDecl)
+ DECL(ParmVar, VarDecl)
+ DECL(NonTypeTemplateParm, VarDecl)
+ ABSTRACT_DECL(Template, NamedDecl)
+ DECL(FunctionTemplate, TemplateDecl)
+ DECL(ClassTemplate, TemplateDecl)
+ DECL(TemplateTemplateParm, TemplateDecl)
+ DECL(Using, NamedDecl)
+ DECL(UsingShadow, NamedDecl)
+ DECL(ObjCMethod, NamedDecl)
+ ABSTRACT_DECL(ObjCContainer, NamedDecl)
+ DECL(ObjCCategory, ObjCContainerDecl)
+ DECL(ObjCProtocol, ObjCContainerDecl)
+ DECL(ObjCInterface, ObjCContainerDecl)
+ ABSTRACT_DECL(ObjCImpl, ObjCContainerDecl)
+ DECL(ObjCCategoryImpl, ObjCImplDecl)
+ DECL(ObjCImplementation, ObjCImplDecl)
+ DECL(ObjCProperty, NamedDecl)
+ DECL(ObjCCompatibleAlias, NamedDecl)
+DECL(LinkageSpec, Decl)
+DECL(ObjCPropertyImpl, Decl)
+DECL(ObjCForwardProtocol, Decl)
+DECL(ObjCClass, Decl)
+DECL(FileScopeAsm, Decl)
+DECL(Friend, Decl)
+DECL(FriendTemplate, Decl)
+DECL(StaticAssert, Decl)
+LAST_DECL(Block, Decl)
+
+// Declaration contexts. DECL_CONTEXT_BASE indicates that it has subclasses.
+DECL_CONTEXT(TranslationUnit)
+DECL_CONTEXT(Namespace)
+DECL_CONTEXT(LinkageSpec)
+DECL_CONTEXT(ObjCMethod)
+DECL_CONTEXT_BASE(Tag)
+DECL_CONTEXT_BASE(Function)
+DECL_CONTEXT_BASE(ObjCContainer)
+LAST_DECL_CONTEXT(Block)
+
+// Declaration ranges
+DECL_RANGE(Named, Namespace, ObjCCompatibleAlias)
+DECL_RANGE(ObjCContainer, ObjCCategory, ObjCImplementation)
+DECL_RANGE(Field, Field, ObjCAtDefsField)
+DECL_RANGE(Type, Typedef, TemplateTypeParm)
+DECL_RANGE(Tag, Enum, ClassTemplatePartialSpecialization)
+DECL_RANGE(Record, Record, ClassTemplatePartialSpecialization)
+DECL_RANGE(Value, EnumConstant, NonTypeTemplateParm)
+DECL_RANGE(Declarator, Function, NonTypeTemplateParm)
+DECL_RANGE(Function, Function, CXXConversion)
+DECL_RANGE(Template, FunctionTemplate, TemplateTemplateParm)
+DECL_RANGE(ObjCImpl, ObjCCategoryImpl, ObjCImplementation)
+LAST_DECL_RANGE(Var, Var, NonTypeTemplateParm)
+
+#undef LAST_DECL_RANGE
+#undef DECL_RANGE
+#undef LAST_DECL_CONTEXT
+#undef DECL_CONTEXT_BASE
+#undef DECL_CONTEXT
+#undef ABSTRACT_DECL
+#undef LAST_DECL
+#undef DECL
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h
new file mode 100644
index 0000000..97d1656
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h
@@ -0,0 +1,1489 @@
+//===--- 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 "llvm/ADT/STLExtras.h"
+
+namespace clang {
+class Expr;
+class Stmt;
+class FunctionDecl;
+class AttributeList;
+class RecordDecl;
+class ObjCIvarDecl;
+class ObjCMethodDecl;
+class ObjCProtocolDecl;
+class ObjCCategoryDecl;
+class ObjCPropertyDecl;
+class ObjCPropertyImplDecl;
+class CXXBaseOrMemberInitializer;
+
+class ObjCListBase {
+ void operator=(const ObjCListBase &); // DO NOT IMPLEMENT
+ ObjCListBase(const ObjCListBase&); // DO NOT IMPLEMENT
+protected:
+ /// List is an array of pointers to objects that are not owned by this object.
+ void **List;
+ unsigned NumElts;
+
+public:
+ ObjCListBase() : List(0), NumElts(0) {}
+ ~ObjCListBase() {
+ assert(List == 0 && "Destroy should have been called before dtor");
+ }
+
+ void Destroy(ASTContext &Ctx);
+
+ 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(0) { }
+
+ 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);
+ void Destroy(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:
+ /// Bitfields must be first fields in this class so they pack with those
+ /// declared in class Decl.
+ /// instance (true) or class (false) method.
+ bool IsInstance : 1;
+ bool IsVariadic : 1;
+
+ // Synthesized declaration method for a property setter/getter
+ bool IsSynthesized : 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 : 6;
+
+ // Number of args separated by ':' in a method declaration.
+ unsigned NumSelectorArgs;
+
+ // Result type of this method.
+ QualType MethodDeclType;
+
+ // Type source information for the result type.
+ TypeSourceInfo *ResultTInfo;
+
+ /// ParamInfo - List of pointers to VarDecls for the formal parameters of this
+ /// Method.
+ ObjCList<ParmVarDecl> ParamInfo;
+
+ /// List of attributes for this method declaration.
+ SourceLocation EndLoc; // the location of the ';' or '}'.
+
+ // The following are only used for method definitions, null otherwise.
+ // FIXME: space savings opportunity, consider a sub-class.
+ Stmt *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;
+
+ ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
+ Selector SelInfo, QualType T,
+ TypeSourceInfo *ResultTInfo,
+ DeclContext *contextDecl,
+ bool isInstance = true,
+ bool isVariadic = false,
+ bool isSynthesized = false,
+ ImplementationControl impControl = None,
+ unsigned numSelectorArgs = 0)
+ : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
+ DeclContext(ObjCMethod),
+ IsInstance(isInstance), IsVariadic(isVariadic),
+ IsSynthesized(isSynthesized),
+ DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
+ NumSelectorArgs(numSelectorArgs), MethodDeclType(T),
+ ResultTInfo(ResultTInfo),
+ EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
+
+ virtual ~ObjCMethodDecl() {}
+
+ /// \brief A definition will return its interface declaration.
+ /// An interface declaration will return its definition.
+ /// Otherwise it will return itself.
+ virtual ObjCMethodDecl *getNextRedeclaration();
+
+public:
+
+ /// Destroy - Call destructors and release memory.
+ virtual void Destroy(ASTContext& C);
+
+ static ObjCMethodDecl *Create(ASTContext &C,
+ SourceLocation beginLoc,
+ SourceLocation endLoc, Selector SelInfo,
+ QualType T,
+ TypeSourceInfo *ResultTInfo,
+ DeclContext *contextDecl,
+ bool isInstance = true,
+ bool isVariadic = false,
+ bool isSynthesized = false,
+ ImplementationControl impControl = None,
+ unsigned numSelectorArgs = 0);
+
+ virtual ObjCMethodDecl *getCanonicalDecl();
+ const ObjCMethodDecl *getCanonicalDecl() const {
+ return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
+ }
+
+ ObjCDeclQualifier getObjCDeclQualifier() const {
+ return ObjCDeclQualifier(objcDeclQualifier);
+ }
+ void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
+
+ unsigned getNumSelectorArgs() const { return NumSelectorArgs; }
+ void setNumSelectorArgs(unsigned numSelectorArgs) {
+ NumSelectorArgs = numSelectorArgs;
+ }
+
+ // Location information, modeled after the Stmt API.
+ SourceLocation getLocStart() const { return getLocation(); }
+ SourceLocation getLocEnd() const { return EndLoc; }
+ void setEndLoc(SourceLocation Loc) { EndLoc = Loc; }
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getLocation(), EndLoc);
+ }
+
+ ObjCInterfaceDecl *getClassInterface();
+ const ObjCInterfaceDecl *getClassInterface() const {
+ return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
+ }
+
+ Selector getSelector() const { return getDeclName().getObjCSelector(); }
+
+ QualType getResultType() const { return MethodDeclType; }
+ void setResultType(QualType T) { MethodDeclType = T; }
+
+ TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
+ void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
+
+ // Iterator access to formal parameters.
+ unsigned param_size() const { return ParamInfo.size(); }
+ typedef ObjCList<ParmVarDecl>::iterator param_iterator;
+ param_iterator param_begin() const { return ParamInfo.begin(); }
+ param_iterator param_end() const { return ParamInfo.end(); }
+ // This method returns and of the parameters which are part of the selector
+ // name mangling requirements.
+ param_iterator sel_param_end() const {
+ return ParamInfo.begin() + NumSelectorArgs;
+ }
+
+ void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num,
+ unsigned numSelectorArgs) {
+ ParamInfo.set(List, Num, C);
+ NumSelectorArgs = numSelectorArgs;
+ }
+
+ // Iterator access to parameter types.
+ typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
+ typedef llvm::mapped_iterator<param_iterator, deref_fun> arg_type_iterator;
+
+ arg_type_iterator arg_type_begin() const {
+ return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
+ }
+ arg_type_iterator arg_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);
+
+ ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
+ void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
+ ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
+ void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
+
+ 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 isSynthesized() const { return IsSynthesized; }
+ void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
+
+ // Related to protocols declared in @protocol
+ void setDeclImplementation(ImplementationControl ic) {
+ DeclImplementation = ic;
+ }
+ ImplementationControl getImplementationControl() const {
+ return ImplementationControl(DeclImplementation);
+ }
+
+ virtual Stmt *getBody() const {
+ return (Stmt*) Body;
+ }
+ CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; }
+ void setBody(Stmt *B) { Body = B; }
+
+ /// \brief Returns whether this specific method is a definition.
+ bool isThisDeclarationADefinition() const { return Body; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCMethodDecl *D) { return true; }
+ 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));
+ }
+};
+
+/// ObjCMethodList - a linked list of methods with different signatures.
+struct ObjCMethodList {
+ ObjCMethodDecl *Method;
+ ObjCMethodList *Next;
+
+ ObjCMethodList() {
+ Method = 0;
+ Next = 0;
+ }
+ ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) {
+ Method = M;
+ Next = C;
+ }
+};
+
+/// ObjCContainerDecl - Represents a container for method declarations.
+/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
+/// ObjCProtocolDecl, and ObjCImplDecl.
+///
+class ObjCContainerDecl : public NamedDecl, public DeclContext {
+ // 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, SourceLocation L,
+ IdentifierInfo *Id)
+ : NamedDecl(DK, DC, L, Id), DeclContext(DK) {}
+
+ virtual ~ObjCContainerDecl() {}
+
+ // Iterator access to properties.
+ typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
+ 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;
+ 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;
+ 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;
+ 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) const;
+ ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
+ return getMethod(Sel, true/*isInstance*/);
+ }
+ ObjCMethodDecl *getClassMethod(Selector Sel) const {
+ return getMethod(Sel, false/*isInstance*/);
+ }
+ ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
+
+ ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
+
+ // Marks the end of the container.
+ SourceRange getAtEndRange() const {
+ return AtEnd;
+ }
+ void setAtEndRange(SourceRange atEnd) {
+ AtEnd = atEnd;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getLocation(), getAtEndRange().getEnd());
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCContainerDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= ObjCContainerFirst &&
+ K <= ObjCContainerLast;
+ }
+
+ 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));
+ }
+};
+
+/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
+///
+/// // 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.
+///
+/// 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 {
+ /// TypeForDecl - This indicates the Type object that represents this
+ /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
+ mutable Type *TypeForDecl;
+ friend class ASTContext;
+
+ /// Class's super class.
+ ObjCInterfaceDecl *SuperClass;
+
+ /// Protocols referenced in interface header declaration
+ ObjCProtocolList ReferencedProtocols;
+
+ /// List of categories defined for this class.
+ /// FIXME: Why is this a linked list??
+ ObjCCategoryDecl *CategoryList;
+
+ bool ForwardDecl:1; // declared with @class.
+ bool InternalInterface:1; // true - no @interface for @implementation
+
+ SourceLocation ClassLoc; // location of the class identifier.
+ SourceLocation SuperClassLoc; // location of the super class identifier.
+ SourceLocation EndLoc; // marks the '>', '}', or identifier.
+
+ ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
+ SourceLocation CLoc, bool FD, bool isInternal);
+
+ virtual ~ObjCInterfaceDecl() {}
+
+public:
+
+ /// Destroy - Call destructors and release memory.
+ virtual void Destroy(ASTContext& C);
+
+ static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation atLoc,
+ IdentifierInfo *Id,
+ SourceLocation ClassLoc = SourceLocation(),
+ bool ForwardDecl = false,
+ bool isInternal = false);
+ const ObjCProtocolList &getReferencedProtocols() const {
+ return 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 ? getInstanceMethod(Sel)
+ : getClassMethod(Sel);
+ }
+
+ typedef ObjCProtocolList::iterator protocol_iterator;
+ protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+ protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+ typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ protocol_loc_iterator protocol_loc_begin() const {
+ return ReferencedProtocols.loc_begin();
+ }
+ protocol_loc_iterator protocol_loc_end() const {
+ return ReferencedProtocols.loc_end();
+ }
+ unsigned protocol_size() const { return ReferencedProtocols.size(); }
+
+ typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ 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(); }
+
+ /// 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);
+ }
+
+ /// mergeClassExtensionProtocolList - Merge class extension's protocol list
+ /// into the protocol list for this class.
+ void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
+ unsigned Num,
+ const SourceLocation *Locs,
+ ASTContext &C);
+
+ bool isForwardDecl() const { return ForwardDecl; }
+ void setForwardDecl(bool val) { ForwardDecl = val; }
+
+ ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
+ void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
+
+ ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
+ void setCategoryList(ObjCCategoryDecl *category) {
+ CategoryList = category;
+ }
+
+ ObjCCategoryDecl* getClassExtension() const;
+
+ ObjCPropertyDecl
+ *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
+
+ /// isSuperClassOf - Return true if this class is the specified class or is a
+ /// super class of the specified interface class.
+ bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
+ // If RHS is derived from LHS it is OK; else it is not OK.
+ while (I != NULL) {
+ if (this == I)
+ return true;
+ I = I->getSuperClass();
+ }
+ return false;
+ }
+
+ ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
+ ObjCInterfaceDecl *&ClassDeclared);
+ ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
+ ObjCInterfaceDecl *ClassDeclared;
+ return lookupInstanceVariable(IVarName, ClassDeclared);
+ }
+
+ // 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*/);
+ }
+ ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
+
+ // Lookup a method in the classes implementation hierarchy.
+ ObjCMethodDecl *lookupPrivateInstanceMethod(const Selector &Sel);
+
+ // Location information, modeled after the Stmt API.
+ SourceLocation getLocStart() const { return getLocation(); } // '@'interface
+ SourceLocation getLocEnd() const { return EndLoc; }
+ void setLocEnd(SourceLocation LE) { EndLoc = LE; }
+
+ void setClassLoc(SourceLocation Loc) { ClassLoc = Loc; }
+ SourceLocation getClassLoc() const { return ClassLoc; }
+ void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; }
+ SourceLocation getSuperClassLoc() const { return SuperClassLoc; }
+
+ /// 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 InternalInterface; }
+ void setImplicitInterfaceDecl(bool val) { InternalInterface = val; }
+
+ /// 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);
+
+ // Low-level accessor
+ Type *getTypeForDecl() const { return TypeForDecl; }
+ void setTypeForDecl(Type *TD) const { TypeForDecl = TD; }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCInterfaceDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCInterface; }
+};
+
+/// 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 {
+public:
+ enum AccessControl {
+ None, Private, Protected, Public, Package
+ };
+
+private:
+ ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
+ QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW)
+ : FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
+ DeclAccess(ac) {}
+
+public:
+ static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
+ SourceLocation L, IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo,
+ AccessControl ac, Expr *BW = NULL);
+
+ /// \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;
+
+ void setAccessControl(AccessControl ac) { DeclAccess = ac; }
+
+ AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
+
+ AccessControl getCanonicalAccessControl() const {
+ return DeclAccess == None ? Protected : AccessControl(DeclAccess);
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCIvarDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCIvar; }
+private:
+ // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
+ unsigned DeclAccess : 3;
+};
+
+
+/// ObjCAtDefsFieldDecl - Represents a field declaration created by an
+/// @defs(...).
+class ObjCAtDefsFieldDecl : public FieldDecl {
+private:
+ ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ QualType T, Expr *BW)
+ : FieldDecl(ObjCAtDefsField, DC, L, Id, T,
+ /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
+ BW, /*Mutable=*/false) {}
+
+public:
+ static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ IdentifierInfo *Id, QualType T,
+ Expr *BW);
+
+ virtual void Destroy(ASTContext& C);
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
+};
+
+/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
+/// declare a pure abstract type (i.e no instance variables are permitted).
+/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
+/// feature with nice semantics and lousy syntax:-). Here is an example:
+///
+/// @protocol NSDraggingInfo <refproto1, refproto2>
+/// - (NSWindow *)draggingDestinationWindow;
+/// - (NSImage *)draggedImage;
+/// @end
+///
+/// This says that NSDraggingInfo requires two methods and requires everything
+/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
+/// well.
+///
+/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
+/// @end
+///
+/// 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 {
+ /// Referenced protocols
+ ObjCProtocolList ReferencedProtocols;
+
+ bool isForwardProtoDecl; // declared with @protocol.
+
+ SourceLocation EndLoc; // marks the '>' or identifier.
+
+ ObjCProtocolDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
+ : ObjCContainerDecl(ObjCProtocol, DC, L, Id),
+ isForwardProtoDecl(true) {
+ }
+
+ virtual ~ObjCProtocolDecl() {}
+
+public:
+ static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id);
+
+ /// Destroy - Call destructors and release memory.
+ virtual void Destroy(ASTContext& C);
+
+ const ObjCProtocolList &getReferencedProtocols() const {
+ return ReferencedProtocols;
+ }
+ typedef ObjCProtocolList::iterator protocol_iterator;
+ protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+ protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+ typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ protocol_loc_iterator protocol_loc_begin() const {
+ return ReferencedProtocols.loc_begin();
+ }
+ protocol_loc_iterator protocol_loc_end() const {
+ return ReferencedProtocols.loc_end();
+ }
+ unsigned protocol_size() const { return ReferencedProtocols.size(); }
+
+ /// 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);
+ }
+
+ 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*/);
+ }
+
+ bool isForwardDecl() const { return isForwardProtoDecl; }
+ void setForwardDecl(bool val) { isForwardProtoDecl = val; }
+
+ // Location information, modeled after the Stmt API.
+ SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
+ SourceLocation getLocEnd() const { return EndLoc; }
+ void setLocEnd(SourceLocation LE) { EndLoc = LE; }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCProtocolDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCProtocol; }
+};
+
+/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
+///
+/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
+///
+class ObjCClassDecl : public Decl {
+public:
+ class ObjCClassRef {
+ ObjCInterfaceDecl *ID;
+ SourceLocation L;
+ public:
+ ObjCClassRef(ObjCInterfaceDecl *d, SourceLocation l) : ID(d), L(l) {}
+ SourceLocation getLocation() const { return L; }
+ ObjCInterfaceDecl *getInterface() const { return ID; }
+ };
+private:
+ ObjCClassRef *ForwardDecls;
+ unsigned NumDecls;
+
+ ObjCClassDecl(DeclContext *DC, SourceLocation L,
+ ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs,
+ unsigned nElts, ASTContext &C);
+ virtual ~ObjCClassDecl() {}
+public:
+
+ /// Destroy - Call destructors and release memory.
+ virtual void Destroy(ASTContext& C);
+
+ static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ ObjCInterfaceDecl *const *Elts = 0,
+ const SourceLocation *Locs = 0,
+ unsigned nElts = 0);
+
+ virtual SourceRange getSourceRange() const;
+
+ typedef const ObjCClassRef* iterator;
+ iterator begin() const { return ForwardDecls; }
+ iterator end() const { return ForwardDecls + NumDecls; }
+ unsigned size() const { return NumDecls; }
+
+ /// setClassList - Set the list of forward classes.
+ void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
+ const SourceLocation *Locs, unsigned Num);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCClassDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCClass; }
+};
+
+/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
+/// For example:
+///
+/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
+///
+class ObjCForwardProtocolDecl : public Decl {
+ ObjCProtocolList ReferencedProtocols;
+
+ ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
+ ObjCProtocolDecl *const *Elts, unsigned nElts,
+ const SourceLocation *Locs, ASTContext &C);
+ virtual ~ObjCForwardProtocolDecl() {}
+
+public:
+ static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ ObjCProtocolDecl *const *Elts,
+ unsigned Num,
+ const SourceLocation *Locs);
+
+ static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L) {
+ return Create(C, DC, L, 0, 0, 0);
+ }
+
+ /// Destroy - Call destructors and release memory.
+ virtual void Destroy(ASTContext& C);
+
+ typedef ObjCProtocolList::iterator protocol_iterator;
+ protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+ protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+ typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ protocol_loc_iterator protocol_loc_begin() const {
+ return ReferencedProtocols.loc_begin();
+ }
+ protocol_loc_iterator protocol_loc_end() const {
+ return ReferencedProtocols.loc_end();
+ }
+
+ unsigned protocol_size() const { return ReferencedProtocols.size(); }
+
+ /// setProtocolList - Set the list of forward protocols.
+ void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
+ const SourceLocation *Locs, ASTContext &C) {
+ ReferencedProtocols.set(List, Num, Locs, C);
+ }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCForwardProtocol; }
+};
+
+/// 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 {
+ /// Interface belonging to this category
+ ObjCInterfaceDecl *ClassInterface;
+
+ /// 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 '@' in '@interface'
+ SourceLocation AtLoc;
+
+ /// \brief The location of the category name in this declaration.
+ SourceLocation CategoryNameLoc;
+
+ ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
+ SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
+ IdentifierInfo *Id)
+ : ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id),
+ ClassInterface(0), NextClassCategory(0), AtLoc(AtLoc),
+ CategoryNameLoc(CategoryNameLoc) {
+ }
+public:
+
+ static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation AtLoc,
+ SourceLocation ClassNameLoc,
+ SourceLocation CategoryNameLoc,
+ IdentifierInfo *Id);
+
+ ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
+ const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
+ void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
+
+ 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;
+ 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;
+ 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; }
+ void setNextClassCategory(ObjCCategoryDecl *Cat) {
+ NextClassCategory = Cat;
+ }
+ void insertNextClassCategory() {
+ NextClassCategory = ClassInterface->getCategoryList();
+ ClassInterface->setCategoryList(this);
+ }
+
+ bool IsClassExtension() const { return getIdentifier() == 0; }
+
+ typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ 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 getAtLoc() const { return AtLoc; }
+ void setAtLoc(SourceLocation At) { AtLoc = At; }
+
+ SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
+ void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtLoc, getAtEndRange().getEnd());
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCCategoryDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCategory; }
+};
+
+class ObjCImplDecl : public ObjCContainerDecl {
+ /// Class interface for this class/category implementation
+ ObjCInterfaceDecl *ClassInterface;
+
+protected:
+ ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ ObjCInterfaceDecl *classInterface)
+ : ObjCContainerDecl(DK, DC, L,
+ classInterface? classInterface->getIdentifier() : 0),
+ ClassInterface(classInterface) {}
+
+public:
+ virtual ~ObjCImplDecl() {}
+
+ 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;
+ 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 classof(const ObjCImplDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= ObjCImplFirst && K <= ObjCImplLast;
+ }
+};
+
+/// 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 {
+ // Category name
+ IdentifierInfo *Id;
+
+ ObjCCategoryImplDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ ObjCInterfaceDecl *classInterface)
+ : ObjCImplDecl(ObjCCategoryImpl, DC, L, classInterface), Id(Id) {}
+public:
+ static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id,
+ ObjCInterfaceDecl *classInterface);
+
+ /// getIdentifier - Get the identifier that names the category
+ /// interface associated with this implementation.
+ /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
+ /// to mean something different. For example:
+ /// ((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;
+
+ /// getName - Get the name of identifier for the class interface associated
+ /// with this implementation as a StringRef.
+ //
+ // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
+ // something different.
+ llvm::StringRef getName() const {
+ return Id ? Id->getNameStart() : "";
+ }
+
+ /// getNameAsCString - Get the name of identifier for the class
+ /// interface associated with this implementation as a C string
+ /// (const char*).
+ //
+ // FIXME: Deprecated, move clients to getName().
+ const char *getNameAsCString() const {
+ return Id ? Id->getNameStart() : "";
+ }
+
+ /// @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 classof(const ObjCCategoryImplDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
+};
+
+llvm::raw_ostream &operator<<(llvm::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
+///
+/// Typically, instance variables are specified in the class interface,
+/// *not* in the implementation. Nevertheless (for legacy reasons), we
+/// allow instance variables to be specified in the implementation. When
+/// specified, they need to be *identical* to the interface.
+///
+class ObjCImplementationDecl : public ObjCImplDecl {
+ /// Implementation Class's super class.
+ ObjCInterfaceDecl *SuperClass;
+ /// Support for ivar initialization.
+ /// IvarInitializers - The arguments used to initialize the ivars
+ CXXBaseOrMemberInitializer **IvarInitializers;
+ unsigned NumIvarInitializers;
+
+ ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
+ ObjCInterfaceDecl *classInterface,
+ ObjCInterfaceDecl *superDecl)
+ : ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
+ SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0) {}
+public:
+ static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ ObjCInterfaceDecl *classInterface,
+ ObjCInterfaceDecl *superDecl);
+
+ /// init_iterator - Iterates through the ivar initializer list.
+ typedef CXXBaseOrMemberInitializer **init_iterator;
+
+ /// init_const_iterator - Iterates through the ivar initializer list.
+ typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
+
+ /// init_begin() - Retrieve an iterator to the first initializer.
+ init_iterator init_begin() { return IvarInitializers; }
+ /// begin() - Retrieve an iterator to the first initializer.
+ init_const_iterator init_begin() const { return IvarInitializers; }
+
+ /// init_end() - Retrieve an iterator past the last initializer.
+ init_iterator init_end() {
+ return IvarInitializers + NumIvarInitializers;
+ }
+ /// end() - Retrieve an iterator past the last initializer.
+ init_const_iterator init_end() const {
+ return IvarInitializers + NumIvarInitializers;
+ }
+ /// getNumArgs - Number of ivars which must be initialized.
+ unsigned getNumIvarInitializers() const {
+ return NumIvarInitializers;
+ }
+
+ void setNumIvarInitializers(unsigned numNumIvarInitializers) {
+ NumIvarInitializers = numNumIvarInitializers;
+ }
+
+ void setIvarInitializers(ASTContext &C,
+ CXXBaseOrMemberInitializer ** initializers,
+ unsigned numInitializers);
+
+ /// 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 overriding the NamedDecl::getName, to mean
+ // something different.
+ llvm::StringRef getName() const {
+ assert(getIdentifier() && "Name is not a simple identifier");
+ return getIdentifier()->getName();
+ }
+
+ /// getNameAsCString - Get the name of identifier for the class
+ /// interface associated with this implementation as a C string
+ /// (const char*).
+ //
+ // FIXME: Move to StringRef API.
+ const char *getNameAsCString() const {
+ return getName().data();
+ }
+
+ /// @brief Get the name of the class associated with this interface.
+ //
+ // FIXME: Move to StringRef API.
+ std::string getNameAsString() const {
+ return getName();
+ }
+
+ const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
+ ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
+
+ void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
+
+ typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ 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 classof(const ObjCImplementationDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCImplementation; }
+};
+
+llvm::raw_ostream &operator<<(llvm::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 {
+ /// 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);
+
+ 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 classof(const ObjCCompatibleAliasDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
+
+};
+
+/// ObjCPropertyDecl - Represents one property declaration in an interface.
+/// For example:
+/// @property (assign, readwrite) int MyProperty;
+///
+class ObjCPropertyDecl : public NamedDecl {
+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
+ };
+
+ enum SetterKind { Assign, Retain, Copy };
+ enum PropertyControl { None, Required, Optional };
+private:
+ SourceLocation AtLoc; // location of @property
+ QualType DeclType;
+ unsigned PropertyAttributes : 8;
+
+ // @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, QualType T)
+ : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), DeclType(T),
+ PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
+ GetterName(Selector()),
+ SetterName(Selector()),
+ GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
+public:
+ static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ IdentifierInfo *Id, SourceLocation AtLocation,
+ QualType T,
+ PropertyControl propControl = None);
+ SourceLocation getAtLoc() const { return AtLoc; }
+ void setAtLoc(SourceLocation L) { AtLoc = L; }
+
+ QualType getType() const { return DeclType; }
+ void setType(QualType T) { DeclType = T; }
+
+ PropertyAttributeKind getPropertyAttributes() const {
+ return PropertyAttributeKind(PropertyAttributes);
+ }
+ void setPropertyAttributes(PropertyAttributeKind PRVal) {
+ PropertyAttributes |= PRVal;
+ }
+
+ void makeitReadWriteAttribute(void) {
+ PropertyAttributes &= ~OBJC_PR_readonly;
+ PropertyAttributes |= OBJC_PR_readwrite;
+ }
+
+ // Helper methods for accessing attributes.
+
+ /// isReadOnly - Return true iff the property has a setter.
+ bool isReadOnly() const {
+ return (PropertyAttributes & OBJC_PR_readonly);
+ }
+
+ /// 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_retain)
+ return Retain;
+ if (PropertyAttributes & OBJC_PR_copy)
+ return Copy;
+ 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;
+ }
+
+ /// Lookup a property by name in the specified DeclContext.
+ static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
+ IdentifierInfo *propertyID);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ObjCPropertyDecl *D) { return true; }
+ 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
+ /// 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)
+ : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
+ PropertyDecl(property), PropertyIvarDecl(ivarDecl),
+ GetterCXXConstructor(0), SetterCXXAssignment(0) {
+ assert (PK == Dynamic || PropertyIvarDecl);
+ }
+
+public:
+ static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation atLoc, SourceLocation L,
+ ObjCPropertyDecl *property,
+ Kind PK,
+ ObjCIvarDecl *ivarDecl);
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtLoc, getLocation());
+ }
+ SourceLocation getLocStart() const { 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;
+ }
+ void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
+
+ 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 classof(const ObjCPropertyImplDecl *D) { return true; }
+ static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
+};
+
+} // end namespace clang
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h
new file mode 100644
index 0000000..b7b90b1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h
@@ -0,0 +1,1433 @@
+//===-- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file 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/TemplateBase.h"
+#include "llvm/ADT/PointerUnion.h"
+#include <limits>
+
+namespace clang {
+
+class TemplateParameterList;
+class TemplateDecl;
+class FunctionTemplateDecl;
+class ClassTemplateDecl;
+class ClassTemplatePartialSpecializationDecl;
+class TemplateTypeParmDecl;
+class NonTypeTemplateParmDecl;
+class TemplateTemplateParmDecl;
+
+/// \brief Stores a template parameter of any kind.
+typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
+ TemplateTemplateParmDecl*> TemplateParameter;
+
+/// TemplateParameterList - Stores a list of template parameters for a
+/// TemplateDecl and its derived classes.
+class TemplateParameterList {
+ /// 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;
+
+ TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
+ NamedDecl **Params, unsigned NumParams,
+ SourceLocation RAngleLoc);
+
+public:
+ static TemplateParameterList *Create(ASTContext &C,
+ SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ NamedDecl **Params,
+ unsigned NumParams,
+ SourceLocation RAngleLoc);
+
+ /// iterator - Iterates through the template parameters in this list.
+ typedef NamedDecl** iterator;
+
+ /// const_iterator - Iterates through the template parameters in this list.
+ typedef NamedDecl* const* const_iterator;
+
+ iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
+ const_iterator begin() const {
+ return reinterpret_cast<NamedDecl * const *>(this + 1);
+ }
+ iterator end() { return begin() + NumParams; }
+ const_iterator end() const { return begin() + NumParams; }
+
+ unsigned size() const { return NumParams; }
+
+ 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];
+ }
+
+ /// \btief 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;
+
+ SourceLocation getTemplateLoc() const { return TemplateLoc; }
+ SourceLocation getLAngleLoc() const { return LAngleLoc; }
+ SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(TemplateLoc, RAngleLoc);
+ }
+};
+
+/// \brief A helper class for making template argument lists.
+class TemplateArgumentListBuilder {
+ TemplateArgument *StructuredArgs;
+ unsigned MaxStructuredArgs;
+ unsigned NumStructuredArgs;
+
+ llvm::SmallVector<TemplateArgument, 4> FlatArgs;
+ unsigned MaxFlatArgs;
+ unsigned NumFlatArgs;
+
+ bool AddingToPack;
+ unsigned PackBeginIndex;
+
+public:
+ TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
+ unsigned NumTemplateArgs)
+ : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
+ NumStructuredArgs(0), FlatArgs(0),
+ MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
+ AddingToPack(false), PackBeginIndex(0) { }
+
+ void Append(const TemplateArgument &Arg);
+ void BeginPack();
+ void EndPack();
+
+ unsigned flatSize() const { return FlatArgs.size(); }
+ const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); }
+
+ unsigned structuredSize() const {
+ // If we don't have any structured args, just reuse the flat size.
+ if (!StructuredArgs)
+ return flatSize();
+
+ return NumStructuredArgs;
+ }
+ const TemplateArgument *getStructuredArguments() const {
+ // If we don't have any structured args, just reuse the flat args.
+ if (!StructuredArgs)
+ return getFlatArguments();
+
+ return StructuredArgs;
+ }
+};
+
+/// \brief A template argument list.
+///
+/// FIXME: In the future, this class will be extended to support
+/// variadic templates and member templates, which will make some of
+/// the function names below make more sense.
+class TemplateArgumentList {
+ /// \brief The template argument list.
+ ///
+ /// The integer value will be non-zero to indicate that this
+ /// template argument list does own the pointer.
+ llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
+
+ /// \brief The number of template arguments in this template
+ /// argument list.
+ unsigned NumFlatArguments;
+
+ llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
+ unsigned NumStructuredArguments;
+
+ TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
+ void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
+public:
+ /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs'
+ /// it copies them into a locally new[]'d array. If passed "false", then it
+ /// just references the array passed in. This is only safe if the builder
+ /// outlives it, but saves a copy.
+ TemplateArgumentList(ASTContext &Context,
+ TemplateArgumentListBuilder &Builder,
+ bool TakeArgs);
+
+ /// Produces a shallow copy of the given template argument list. This
+ /// 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);
+
+ /// Used to release the memory associated with a TemplateArgumentList
+ /// object. FIXME: This is currently not called anywhere, but the
+ /// memory will still be freed when using a BumpPtrAllocator.
+ void Destroy(ASTContext &C);
+
+ ~TemplateArgumentList();
+
+ /// \brief Retrieve the template argument at a given index.
+ const TemplateArgument &get(unsigned Idx) const {
+ assert(Idx < NumFlatArguments && "Invalid template argument index");
+ return getFlatArgumentList()[Idx];
+ }
+
+ /// \brief Retrieve the template argument at a given index.
+ const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
+
+ /// \brief Retrieve the number of template arguments in this
+ /// template argument list.
+ unsigned size() const { return NumFlatArguments; }
+
+ /// \brief Retrieve the number of template arguments in the
+ /// flattened template argument list.
+ unsigned flat_size() const { return NumFlatArguments; }
+
+ /// \brief Retrieve the flattened template argument list.
+ const TemplateArgument *getFlatArgumentList() const {
+ return FlatArguments.getPointer();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Kinds of Templates
+//===----------------------------------------------------------------------===//
+
+/// TemplateDecl - 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 {
+protected:
+ // This is probably never used.
+ TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ DeclarationName Name)
+ : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
+
+ // Construct a template decl with the given name and parameters.
+ // Used when there is not templated element (tt-params, alias?).
+ TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params)
+ : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
+
+ // 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:
+ ~TemplateDecl();
+
+ /// 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 classof(const TemplateDecl *D) { return true; }
+ static bool classof(const FunctionTemplateDecl *D) { return true; }
+ static bool classof(const ClassTemplateDecl *D) { return true; }
+ static bool classof(const TemplateTemplateParmDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= TemplateFirst && K <= TemplateLast;
+ }
+
+protected:
+ NamedDecl *TemplatedDecl;
+ TemplateParameterList* 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 {
+public:
+ /// \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 are 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 TemplateArgumentListInfo *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);
+ }
+
+ /// \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->getFlatArgumentList(),
+ TemplateArguments->flat_size(),
+ Function->getASTContext());
+ }
+
+ static void
+ Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs, ASTContext &Context) {
+ ID.AddInteger(NumTemplateArgs);
+ for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+ 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, or
+/// member class.
+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)
+ : MemberAndTSK(IF, TSK - 1), PointOfInstantiation() {
+ 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);
+ }
+
+ /// \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:
+///
+/// template <class T> void foo(T);
+/// template <class T> class A {
+/// friend void foo<>(T);
+/// };
+class DependentFunctionTemplateSpecializationInfo {
+ union {
+ // Force sizeof to be a multiple of sizeof(void*) so that the
+ // trailing data is aligned.
+ void *Aligner;
+
+ struct {
+ /// The number of potential template candidates.
+ unsigned NumTemplates;
+
+ /// The number of template arguments.
+ unsigned NumArgs;
+ } d;
+ };
+
+ /// The locations of the left and right angle brackets.
+ SourceRange AngleLocs;
+
+ FunctionTemplateDecl * const *getTemplates() const {
+ return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
+ }
+
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc*>(
+ &getTemplates()[getNumTemplates()]);
+ }
+
+public:
+ DependentFunctionTemplateSpecializationInfo(
+ const UnresolvedSetImpl &Templates,
+ const TemplateArgumentListInfo &TemplateArgs);
+
+ /// \brief Returns the number of function templates that this might
+ /// be a specialization of.
+ unsigned getNumTemplates() const {
+ return d.NumTemplates;
+ }
+
+ /// \brief Returns the i'th template candidate.
+ FunctionTemplateDecl *getTemplate(unsigned I) const {
+ assert(I < getNumTemplates() && "template index out of range");
+ return getTemplates()[I];
+ }
+
+ /// \brief Returns the number of explicit template arguments that were given.
+ unsigned getNumTemplateArgs() const {
+ return d.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();
+ }
+};
+
+/// Declaration of a template function.
+class FunctionTemplateDecl : public TemplateDecl {
+ static void DeallocateCommon(void *Ptr);
+
+protected:
+ /// \brief Data that is common to all of the declarations of a given
+ /// function template.
+ struct Common {
+ Common() : InstantiatedFromMember(0, false) { }
+
+ /// \brief The function template specializations for this function
+ /// template, including explicit specializations and instantiations.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+
+ /// \brief The member function template from which this was most
+ /// directly instantiated (or null).
+ ///
+ /// The boolean value indicates whether this member function template
+ /// was explicitly specialized.
+ llvm::PointerIntPair<FunctionTemplateDecl*, 1, bool> InstantiatedFromMember;
+ };
+
+ /// \brief A pointer to the previous declaration (if this is a redeclaration)
+ /// or to the data that is common to all declarations of this function
+ /// template.
+ llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
+
+ /// \brief Retrieves the "common" pointer shared by all
+ /// (re-)declarations of the same function template. Calling this routine
+ /// may implicitly allocate memory for the common pointer.
+ Common *getCommonPtr();
+
+ FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl)
+ : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
+ CommonOrPrev((Common*)0) { }
+
+public:
+ void Destroy(ASTContext &C);
+
+ /// Get the underlying function declaration of the template.
+ FunctionDecl *getTemplatedDecl() const {
+ return static_cast<FunctionDecl*>(TemplatedDecl);
+ }
+
+ /// \brief Retrieve the set of function template specializations of this
+ /// function template.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+ return getCommonPtr()->Specializations;
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ const FunctionTemplateDecl *getPreviousDeclaration() const {
+ return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ FunctionTemplateDecl *getPreviousDeclaration() {
+ return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ }
+
+ /// \brief Set the previous declaration of this function template.
+ void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
+ if (Prev)
+ CommonOrPrev = Prev;
+ }
+
+ virtual FunctionTemplateDecl *getCanonicalDecl();
+
+ /// \brief Retrieve the member function template that this function template
+ /// was instantiated from.
+ ///
+ /// This routine will return non-NULL for member function templates of
+ /// class templates. For example, given:
+ ///
+ /// \code
+ /// template <typename T>
+ /// struct X {
+ /// template <typename U> void f();
+ /// };
+ /// \endcode
+ ///
+ /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
+ /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
+ /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
+ /// X<int>) for which getInstantiatedFromMemberTemplate() will return
+ /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
+ /// ClassTemplateDecl).
+ ///
+ /// \returns NULL if this is not an instantiation of a member function
+ /// template.
+ FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return getCommonPtr()->InstantiatedFromMember.getPointer();
+ }
+
+ void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
+ assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+ getCommonPtr()->InstantiatedFromMember.setPointer(FTD);
+ }
+
+ /// \brief Determines whether this template was a specialization of a
+ /// member template.
+ ///
+ /// In the following example, the function template \c X<int>::f is a
+ /// member specialization.
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct X {
+ /// template<typename U> void f(T, U);
+ /// };
+ ///
+ /// template<> template<typename T>
+ /// void X<int>::f(int, T);
+ /// \endcode
+ bool isMemberSpecialization() {
+ 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);
+ }
+
+ /// Create a template function node.
+ static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ DeclarationName Name,
+ TemplateParameterList *Params,
+ NamedDecl *Decl);
+
+ // Implement isa/cast/dyncast support
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const FunctionTemplateDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == FunctionTemplate; }
+};
+
+//===----------------------------------------------------------------------===//
+// Kinds of Template Parameters
+//===----------------------------------------------------------------------===//
+
+/// The TemplateParmPosition class 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 {
+protected:
+ // FIXME: This should probably never be called, but it's here as
+ TemplateParmPosition()
+ : Depth(0), Position(0)
+ { /* assert(0 && "Cannot create positionless template parameter"); */ }
+
+ 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; }
+
+ /// Get the position of the template parameter within its parameter list.
+ unsigned getPosition() const { return Position; }
+
+ /// Get the index of the template parameter within its parameter list.
+ unsigned getIndex() const { return Position; }
+};
+
+/// TemplateTypeParmDecl - Declaration of a template type parameter,
+/// e.g., "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 Whether this template type parameter inherited its
+ /// default argument.
+ bool InheritedDefault : 1;
+
+ /// \brief Whether this is a parameter pack.
+ bool ParameterPack : 1;
+
+ /// \brief The default template argument, if any.
+ TypeSourceInfo *DefaultArgument;
+
+ TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ bool Typename, QualType Type, bool ParameterPack)
+ : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
+ InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
+ TypeForDecl = Type.getTypePtr();
+ }
+
+public:
+ static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, unsigned D, unsigned P,
+ IdentifierInfo *Id, bool Typename,
+ bool ParameterPack);
+
+ /// \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; }
+
+ /// \brief Determine whether this template parameter has a default
+ /// argument.
+ bool hasDefaultArgument() const { return DefaultArgument != 0; }
+
+ /// \brief Retrieve the default argument, if any.
+ QualType getDefaultArgument() const { return DefaultArgument->getType(); }
+
+ /// \brief Retrieves the default argument's source information, if any.
+ TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
+
+ /// \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 InheritedDefault; }
+
+ /// \brief Set the default argument for this template parameter, and
+ /// whether that default argument was inherited from another
+ /// declaration.
+ void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
+ DefaultArgument = DefArg;
+ InheritedDefault = Inherited;
+ }
+
+ /// \brief Removes the default argument of this template parameter.
+ void removeDefaultArgument() {
+ DefaultArgument = 0;
+ InheritedDefault = false;
+ }
+
+ /// \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 { return ParameterPack; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const TemplateTypeParmDecl *D) { return true; }
+ 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
+ : public VarDecl, protected TemplateParmPosition {
+ /// \brief The default template argument, if any.
+ Expr *DefaultArgument;
+
+ NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
+ unsigned P, IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo)
+ : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
+ VarDecl::None),
+ TemplateParmPosition(D, P), DefaultArgument(0)
+ { }
+
+public:
+ static NonTypeTemplateParmDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
+ unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
+
+ using TemplateParmPosition::getDepth;
+ using TemplateParmPosition::getPosition;
+ using TemplateParmPosition::getIndex;
+
+ /// \brief Determine whether this template parameter has a default
+ /// argument.
+ bool hasDefaultArgument() const { return DefaultArgument; }
+
+ /// \brief Retrieve the default argument, if any.
+ Expr *getDefaultArgument() const { return DefaultArgument; }
+
+ /// \brief Retrieve the location of the default argument, if any.
+ SourceLocation getDefaultArgumentLoc() const;
+
+ /// \brief Set the default argument for this template parameter.
+ void setDefaultArgument(Expr *DefArg) {
+ DefaultArgument = DefArg;
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
+ 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
+ : public TemplateDecl, protected TemplateParmPosition {
+
+ /// \brief The default template argument, if any.
+ TemplateArgumentLoc DefaultArgument;
+
+ TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
+ unsigned D, unsigned P,
+ IdentifierInfo *Id, TemplateParameterList *Params)
+ : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
+ TemplateParmPosition(D, P), DefaultArgument()
+ { }
+
+public:
+ static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, unsigned D,
+ unsigned P, IdentifierInfo *Id,
+ TemplateParameterList *Params);
+
+ using TemplateParmPosition::getDepth;
+ using TemplateParmPosition::getPosition;
+ using TemplateParmPosition::getIndex;
+
+ /// \brief Determine whether this template parameter has a default
+ /// argument.
+ bool hasDefaultArgument() const {
+ return !DefaultArgument.getArgument().isNull();
+ }
+
+ /// \brief Retrieve the default argument, if any.
+ const TemplateArgumentLoc &getDefaultArgument() const {
+ return DefaultArgument;
+ }
+
+ /// \brief Set the default argument for this template parameter.
+ void setDefaultArgument(const TemplateArgumentLoc &DefArg) {
+ DefaultArgument = DefArg;
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const TemplateTemplateParmDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
+};
+
+/// \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.
+ TemplateArgumentList *TemplateArgs;
+ };
+
+ /// \brief The template that this specialization specializes
+ llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
+ SpecializedTemplate;
+
+ /// \brief The type-as-written of an explicit template specialization.
+ /// Does not apply to implicit specializations.
+ TypeSourceInfo *TypeAsWritten;
+
+ /// \brief The template arguments used to describe this specialization.
+ 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 L,
+ ClassTemplateDecl *SpecializedTemplate,
+ TemplateArgumentListBuilder &Builder,
+ ClassTemplateSpecializationDecl *PrevDecl);
+
+public:
+ static ClassTemplateSpecializationDecl *
+ Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
+ ClassTemplateDecl *SpecializedTemplate,
+ TemplateArgumentListBuilder &Builder,
+ ClassTemplateSpecializationDecl *PrevDecl);
+
+ virtual void Destroy(ASTContext& C);
+
+ virtual void getNameForDiagnostic(std::string &S,
+ const PrintingPolicy &Policy,
+ bool Qualified) const;
+
+ /// \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);
+ }
+
+ 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 (getSpecializationKind() != TSK_ImplicitInstantiation &&
+ getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
+ getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
+ return (ClassTemplateDecl*)0;
+
+ if (SpecializedPartialSpecialization *PartialSpec
+ = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+ return PartialSpec->PartialSpecialization;
+
+ return const_cast<ClassTemplateDecl*>(
+ 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,
+ TemplateArgumentList *TemplateArgs) {
+ SpecializedPartialSpecialization *PS
+ = new (getASTContext()) SpecializedPartialSpecialization();
+ PS->PartialSpecialization = PartialSpec;
+ PS->TemplateArgs = TemplateArgs;
+ SpecializedTemplate = PS;
+ }
+
+ /// \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) {
+ 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 TypeAsWritten;
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
+ getASTContext());
+ }
+
+ static void
+ Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs, ASTContext &Context) {
+ ID.AddInteger(NumTemplateArgs);
+ for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+ TemplateArgs[Arg].Profile(ID, Context);
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == ClassTemplateSpecialization ||
+ K == ClassTemplatePartialSpecialization;
+ }
+
+ static bool classof(const ClassTemplateSpecializationDecl *) {
+ return true;
+ }
+
+ static bool classof(const ClassTemplatePartialSpecializationDecl *) {
+ return true;
+ }
+};
+
+class ClassTemplatePartialSpecializationDecl
+ : public ClassTemplateSpecializationDecl {
+ /// \brief The list of template parameters
+ TemplateParameterList* TemplateParams;
+
+ /// \brief The source info for the template arguments as written.
+ /// FIXME: redundant with TypeAsWritten?
+ TemplateArgumentLoc *ArgsAsWritten;
+ unsigned NumArgsAsWritten;
+
+ /// \brief Sequence number indicating when this class template partial
+ /// specialization was added to the set of partial specializations for
+ /// its owning class template.
+ unsigned SequenceNumber;
+
+ /// \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 L,
+ TemplateParameterList *Params,
+ ClassTemplateDecl *SpecializedTemplate,
+ TemplateArgumentListBuilder &Builder,
+ TemplateArgumentLoc *ArgInfos,
+ unsigned NumArgInfos,
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber)
+ : ClassTemplateSpecializationDecl(Context,
+ ClassTemplatePartialSpecialization,
+ TK, DC, L, SpecializedTemplate, Builder,
+ PrevDecl),
+ TemplateParams(Params), ArgsAsWritten(ArgInfos),
+ NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
+ InstantiatedFromMember(0, false) { }
+
+public:
+ static ClassTemplatePartialSpecializationDecl *
+ Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
+ TemplateParameterList *Params,
+ ClassTemplateDecl *SpecializedTemplate,
+ TemplateArgumentListBuilder &Builder,
+ const TemplateArgumentListInfo &ArgInfos,
+ QualType CanonInjectedType,
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber);
+
+ /// Get the list of template parameters
+ TemplateParameterList *getTemplateParameters() const {
+ return TemplateParams;
+ }
+
+ /// Get the template arguments as written.
+ TemplateArgumentLoc *getTemplateArgsAsWritten() const {
+ return ArgsAsWritten;
+ }
+
+ /// Get the number of template arguments as written.
+ unsigned getNumTemplateArgsAsWritten() const {
+ return NumArgsAsWritten;
+ }
+
+ /// \brief Get the sequence number for this class template partial
+ /// specialization.
+ unsigned getSequenceNumber() const { return SequenceNumber; }
+
+ /// \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() {
+ ClassTemplatePartialSpecializationDecl *First
+ = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ return First->InstantiatedFromMember.getPointer();
+ }
+
+ void setInstantiatedFromMember(
+ ClassTemplatePartialSpecializationDecl *PartialSpec) {
+ ClassTemplatePartialSpecializationDecl *First
+ = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ 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>(getFirstDeclaration());
+ return First->InstantiatedFromMember.getInt();
+ }
+
+ /// \brief Note that this member template is a specialization.
+ void setMemberSpecialization() {
+ ClassTemplatePartialSpecializationDecl *First
+ = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ 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;
+ }
+
+ static bool classof(const ClassTemplatePartialSpecializationDecl *) {
+ return true;
+ }
+};
+
+/// Declaration of a class template.
+class ClassTemplateDecl : public TemplateDecl {
+ static void DeallocateCommon(void *Ptr);
+
+protected:
+ /// \brief Data that is common to all of the declarations of a given
+ /// class template.
+ struct Common {
+ Common() : InstantiatedFromMember(0, 0) {}
+
+ /// \brief The class template specializations for this class
+ /// template, including explicit specializations and instantiations.
+ llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
+
+ /// \brief The class template partial specializations for this class
+ /// template.
+ llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
+ PartialSpecializations;
+
+ /// \brief The injected-class-name type for this class template.
+ QualType InjectedClassNameType;
+
+ /// \brief The templated member class from which this was most
+ /// directly instantiated (or null).
+ ///
+ /// The boolean value indicates whether this member class template
+ /// was explicitly specialized.
+ llvm::PointerIntPair<ClassTemplateDecl *, 1, bool> InstantiatedFromMember;
+ };
+
+ // FIXME: Combine PreviousDeclaration with CommonPtr, as in
+ // FunctionTemplateDecl.
+
+ /// \brief Previous declaration of this class template.
+ ClassTemplateDecl *PreviousDeclaration;
+
+ /// \brief Pointer to the data that is common to all of the
+ /// declarations of this class template.
+ ///
+ /// The first declaration of a class template (e.g., the declaration
+ /// with no "previous declaration") owns this pointer.
+ Common *CommonPtr;
+
+ ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl,
+ ClassTemplateDecl *PrevDecl, Common *CommonPtr)
+ : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
+ PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
+
+ ~ClassTemplateDecl();
+
+public:
+ /// Get the underlying class declarations of the template.
+ CXXRecordDecl *getTemplatedDecl() const {
+ return static_cast<CXXRecordDecl *>(TemplatedDecl);
+ }
+
+ /// \brief Retrieve the previous declaration of this template.
+ ClassTemplateDecl *getPreviousDeclaration() const {
+ return PreviousDeclaration;
+ }
+
+ virtual ClassTemplateDecl *getCanonicalDecl();
+
+ /// Create a class template node.
+ static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ DeclarationName Name,
+ TemplateParameterList *Params,
+ NamedDecl *Decl,
+ ClassTemplateDecl *PrevDecl);
+
+ /// \brief Retrieve the set of specializations of this class template.
+ llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
+ return CommonPtr->Specializations;
+ }
+
+ /// \brief Retrieve the set of partial specializations of this class
+ /// template.
+ llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
+ getPartialSpecializations() {
+ return CommonPtr->PartialSpecializations;
+ }
+
+ /// \brief Retrieve the partial specializations as an ordered list.
+ void getPartialSpecializations(
+ llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
+
+ /// \brief Find a class template partial specialization with the given
+ /// type T.
+ ///
+ /// \brief 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 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(ASTContext &Context);
+
+ /// \brief Retrieve the member class template that this class template was
+ /// derived from.
+ ///
+ /// This routine will return non-NULL for templated member classes of
+ /// class templates. For example, given:
+ ///
+ /// \code
+ /// template <typename T>
+ /// struct X {
+ /// template <typename U> struct A {};
+ /// };
+ /// \endcode
+ ///
+ /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
+ /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
+ /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
+ /// X<int>) for which getInstantiatedFromMemberTemplate() will return
+ /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
+ ///
+ /// \returns null if this is not an instantiation of a member class template.
+ ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
+ return CommonPtr->InstantiatedFromMember.getPointer();
+ }
+
+ void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
+ assert(!CommonPtr->InstantiatedFromMember.getPointer());
+ CommonPtr->InstantiatedFromMember.setPointer(CTD);
+ }
+
+ /// \brief Determines whether this template was a specialization of a
+ /// member template.
+ ///
+ /// In the following example, the member template \c X<int>::Inner is a
+ /// member specialization.
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct X {
+ /// template<typename U> struct Inner;
+ /// };
+ ///
+ /// template<> template<typename T>
+ /// struct X<int>::Inner { /* ... */ };
+ /// \endcode
+ bool isMemberSpecialization() {
+ return CommonPtr->InstantiatedFromMember.getInt();
+ }
+
+ /// \brief Note that this member template is a specialization.
+ void setMemberSpecialization() {
+ assert(CommonPtr->InstantiatedFromMember.getPointer() &&
+ "Only member templates can be member template specializations");
+ CommonPtr->InstantiatedFromMember.setInt(true);
+ }
+
+ // Implement isa/cast/dyncast support
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ClassTemplateDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ClassTemplate; }
+
+ virtual void Destroy(ASTContext& C);
+};
+
+/// Declaration of a friend template. For example:
+///
+/// template <typename T> class A {
+/// friend class MyVector<T>; // not a friend template
+/// template <typename U> friend class B; // friend template
+/// template <typename U> friend class Foo<T>::Nested; // friend template
+class FriendTemplateDecl : public Decl {
+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)
+ {}
+
+public:
+ static FriendTemplateDecl *Create(ASTContext &Context,
+ DeclContext *DC, SourceLocation Loc,
+ unsigned NParams,
+ TemplateParameterList **Params,
+ FriendUnion Friend,
+ SourceLocation FriendLoc);
+
+ /// 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*>();
+ }
+
+ /// 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; }
+ static bool classof(const FriendTemplateDecl *D) { return true; }
+};
+
+/// Implementation of inline functions that require the template declarations
+inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
+ : Function(FTD) { }
+
+} /* end of namespace clang */
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/DeclVisitor.h
new file mode 100644
index 0000000..140e5c0
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclVisitor.h
@@ -0,0 +1,55 @@
+//===--- 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/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclTemplate.h"
+
+namespace clang {
+
+#define DISPATCH(NAME, CLASS) \
+ return static_cast<ImplClass*>(this)-> Visit##NAME(static_cast<CLASS*>(D))
+
+/// \brief A simple visitor class that helps create declaration visitors.
+template<typename ImplClass, typename RetTy=void>
+class DeclVisitor {
+public:
+ RetTy Visit(Decl *D) {
+ switch (D->getKind()) {
+ default: assert(false && "Decl that isn't part of DeclNodes.def!");
+#define DECL(Derived, Base) \
+ case Decl::Derived: DISPATCH(Derived##Decl, Derived##Decl);
+#define ABSTRACT_DECL(Derived, Base)
+#include "clang/AST/DeclNodes.def"
+ }
+ }
+
+ // If the implementation chooses not to implement a certain visit
+ // method, fall back to the parent.
+#define DECL(Derived, Base) \
+ RetTy Visit##Derived##Decl(Derived##Decl *D) { DISPATCH(Base, Base); }
+#define ABSTRACT_DECL(Derived, Base) DECL(Derived, Base)
+#include "clang/AST/DeclNodes.def"
+
+ RetTy VisitDecl(Decl *D) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_DECLVISITOR_H
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h
new file mode 100644
index 0000000..8a771d5
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h
@@ -0,0 +1,416 @@
+//===-- 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/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/Basic/PartialDiagnostic.h"
+
+namespace llvm {
+ template <typename T> struct DenseMapInfo;
+}
+
+namespace clang {
+ class CXXSpecialName;
+ class CXXOperatorIdName;
+ class CXXLiteralOperatorIdName;
+ class DeclarationNameExtra;
+ class IdentifierInfo;
+ class MultiKeywordSelector;
+ class UsingDirectiveDecl;
+
+/// 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
+ };
+
+private:
+ /// StoredNameKind - The kind of name that is actually stored in the
+ /// upper bits of the Ptr field. This is only used internally.
+ enum StoredNameKind {
+ StoredIdentifier = 0,
+ StoredObjCZeroArgSelector,
+ StoredObjCOneArgSelector,
+ StoredDeclarationNameExtra,
+ 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 {
+ if (getNameKind() >= CXXConstructorName &&
+ getNameKind() <= CXXConversionFunctionName)
+ return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
+ return 0;
+ }
+
+ /// getAsCXXOperatorIdName
+ CXXOperatorIdName *getAsCXXOperatorIdName() const {
+ if (getNameKind() == CXXOperatorName)
+ return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
+ return 0;
+ }
+
+ CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
+ if (getNameKind() == CXXLiteralOperatorName)
+ return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
+ return 0;
+ }
+
+ // 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;
+
+ /// getFETokenInfoAsVoid - Retrieves the front end-specified pointer
+ /// for this name as a void pointer.
+ void *getFETokenInfoAsVoid() 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);
+
+ /// getUsingDirectiveName - Return name for all using-directives.
+ static DeclarationName getUsingDirectiveName();
+
+ // operator bool() - Evaluates true when this declaration name is
+ // non-empty.
+ operator bool() const {
+ return ((Ptr & PtrMask) != 0) ||
+ (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
+ }
+
+ /// 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;
+
+ /// printName - Print the human-readable name to a stream.
+ void printName(llvm::raw_ostream &OS) 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 0;
+ }
+
+ /// 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;
+
+ /// 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 { return static_cast<T*>(getFETokenInfoAsVoid()); }
+
+ 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;
+};
+
+/// 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 {
+ ASTContext &Ctx;
+ void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
+ CXXOperatorIdName *CXXOperatorNames; // Operator names
+ void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
+
+ DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE
+ DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE
+
+public:
+ DeclarationNameTable(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) {
+ return getCXXSpecialName(DeclarationName::CXXConstructorName,
+ Ty.getUnqualifiedType());
+ }
+
+ /// getCXXDestructorName - Returns the name of a C++ destructor
+ /// for the given Type.
+ DeclarationName getCXXDestructorName(CanQualType Ty) {
+ return getCXXSpecialName(DeclarationName::CXXDestructorName,
+ Ty.getUnqualifiedType());
+ }
+
+ /// getCXXConversionFunctionName - Returns the name of a C++
+ /// conversion function for the given Type.
+ DeclarationName getCXXConversionFunctionName(CanQualType Ty) {
+ return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, 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);
+};
+
+/// 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(),
+ Diagnostic::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(),
+ Diagnostic::ak_declarationname);
+ return PD;
+}
+
+} // 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);
+
+ 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/contrib/llvm/tools/clang/include/clang/AST/DependentDiagnostic.h b/contrib/llvm/tools/clang/include/clang/AST/DependentDiagnostic.h
new file mode 100644
index 0000000..2bbe502
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/DependentDiagnostic.h
@@ -0,0 +1,192 @@
+//===-- 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_DEPENDENT_DIAGNOSTIC_H
+#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/Type.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;
+
+ union {
+ 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(0) {}
+ 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_iterator DeclContext::ddiag_begin() const {
+ assert(isDependentContext()
+ && "cannot iterate dependent diagnostics of non-dependent context");
+ const DependentStoredDeclsMap *Map
+ = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->LookupPtr);
+
+ if (!Map) return ddiag_iterator();
+ return ddiag_iterator(Map->FirstDiagnostic);
+}
+
+inline DeclContext::ddiag_iterator DeclContext::ddiag_end() const {
+ return ddiag_iterator();
+}
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/Expr.h b/contrib/llvm/tools/clang/include/clang/AST/Expr.h
new file mode 100644
index 0000000..66639e2
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/Expr.h
@@ -0,0 +1,3347 @@
+//===--- 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/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/ASTVector.h"
+#include "clang/AST/UsuallyTinyPtrVector.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+ class ASTContext;
+ class APValue;
+ class Decl;
+ class IdentifierInfo;
+ class ParmVarDecl;
+ class NamedDecl;
+ class ValueDecl;
+ class BlockDecl;
+ class CXXBaseSpecifier;
+ class CXXOperatorCallExpr;
+ class CXXMemberCallExpr;
+ class TemplateArgumentLoc;
+ class TemplateArgumentListInfo;
+
+/// \brief A simple array of base specifiers.
+typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray;
+
+/// 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;
+
+ virtual void ANCHOR(); // key function.
+protected:
+ /// TypeDependent - Whether this expression is type-dependent
+ /// (C++ [temp.dep.expr]).
+ bool TypeDependent : 1;
+
+ /// ValueDependent - Whether this expression is value-dependent
+ /// (C++ [temp.dep.constexpr]).
+ bool ValueDependent : 1;
+
+ Expr(StmtClass SC, QualType T, bool TD, bool VD)
+ : Stmt(SC), TypeDependent(TD), ValueDependent(VD) {
+ setType(T);
+ }
+
+ /// \brief Construct an empty expression.
+ explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
+
+public:
+ /// \brief Increases the reference count for this expression.
+ ///
+ /// Invoke the Retain() operation when this expression
+ /// is being shared by another owner.
+ Expr *Retain() {
+ Stmt::Retain();
+ return this;
+ }
+
+ 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 an expression will never 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 ValueDependent; }
+
+ /// \brief Set whether this expression is value-dependent or not.
+ void setValueDependent(bool VD) { 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 TypeDependent; }
+
+ /// \brief Set whether this expression is type-dependent or not.
+ void setTypeDependent(bool TD) { TypeDependent = TD; }
+
+ /// 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.
+ virtual SourceRange getSourceRange() const = 0;
+
+ /// getExprLoc - Return the preferred location for the arrow when diagnosing
+ /// a problem with a generic expression.
+ virtual SourceLocation getExprLoc() const { return getLocStart(); }
+
+ /// isUnusedResultAWarning - Return true if this immediate expression should
+ /// be warned about if the result is unused. If so, fill in Loc and Ranges
+ /// with location to warn on and the source range[s] to report with the
+ /// warning.
+ bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
+ SourceRange &R2, ASTContext &Ctx) const;
+
+ /// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
+ /// incomplete type other than void. Nonarray expressions that can be lvalues:
+ /// - name, where name must be a variable
+ /// - e[i]
+ /// - (e), where e must be an lvalue
+ /// - e.name, where e must be an lvalue
+ /// - e->name
+ /// - *e, the type of e cannot be a function type
+ /// - string-constant
+ /// - reference type [C++ [expr]]
+ /// - b ? x : y, where x and y are lvalues of suitable types [C++]
+ ///
+ enum isLvalueResult {
+ LV_Valid,
+ LV_NotObjectType,
+ LV_IncompleteVoidType,
+ LV_DuplicateVectorComponents,
+ LV_InvalidExpression,
+ LV_MemberFunction,
+ LV_SubObjCPropertySetting,
+ LV_ClassTemporary
+ };
+ isLvalueResult isLvalue(ASTContext &Ctx) const;
+
+ // Same as above, but excluding checks for non-object and void types in C
+ isLvalueResult isLvalueInternal(ASTContext &Ctx) const;
+
+ /// 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.
+ enum isModifiableLvalueResult {
+ MLV_Valid,
+ MLV_NotObjectType,
+ MLV_IncompleteVoidType,
+ MLV_DuplicateVectorComponents,
+ MLV_InvalidExpression,
+ MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
+ MLV_IncompleteType,
+ MLV_ConstQualified,
+ MLV_ArrayType,
+ MLV_NotBlockQualified,
+ MLV_ReadonlyProperty,
+ MLV_NoSetterProperty,
+ MLV_MemberFunction,
+ MLV_SubObjCPropertySetting,
+ MLV_ClassTemporary
+ };
+ isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
+ SourceLocation *Loc = 0) const;
+
+ /// \brief If this expression refers to a bit-field, retrieve the
+ /// declaration of that bit-field.
+ FieldDecl *getBitField();
+
+ const FieldDecl *getBitField() const {
+ return const_cast<Expr*>(this)->getBitField();
+ }
+
+ /// \brief Returns whether this expression refers to a vector element.
+ bool refersToVectorElement() const;
+
+ /// 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.
+ bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
+ SourceLocation *Loc = 0,
+ bool isEvaluated = true) const;
+ bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const {
+ llvm::APSInt X;
+ return isIntegerConstantExpr(X, Ctx, Loc);
+ }
+ /// isConstantInitializer - Returns true if this expression is a constant
+ /// initializer, which can be emitted at compile-time.
+ bool isConstantInitializer(ASTContext &Ctx) const;
+
+ /// EvalResult is a struct with detailed info about an evaluated expression.
+ struct EvalResult {
+ /// Val - This is the value the expression can be folded to.
+ APValue Val;
+
+ /// HasSideEffects - Whether the evaluated expression has side effects.
+ /// For example, (f() && 0) can be folded, but it still has side effects.
+ bool HasSideEffects;
+
+ /// Diag - If the expression is unfoldable, then Diag contains a note
+ /// diagnostic indicating why it's not foldable. DiagLoc indicates a caret
+ /// position for the error, and DiagExpr is the expression that caused
+ /// the error.
+ /// If the expression is foldable, but not an integer constant expression,
+ /// Diag contains a note diagnostic that describes why it isn't an integer
+ /// constant expression. If the expression *is* an integer constant
+ /// expression, then Diag will be zero.
+ unsigned Diag;
+ const Expr *DiagExpr;
+ SourceLocation DiagLoc;
+
+ EvalResult() : HasSideEffects(false), Diag(0), DiagExpr(0) {}
+
+ // isGlobalLValue - Return true if the evaluated lvalue expression
+ // is global.
+ bool isGlobalLValue() const;
+ // hasSideEffects - Return true if the evaluated expression has
+ // side effects.
+ bool hasSideEffects() const {
+ return HasSideEffects;
+ }
+ };
+
+ /// Evaluate - Return true if this is a constant which we can fold using
+ /// any crazy technique (that has nothing to do with language standards) that
+ /// we want to. If this function returns true, it returns the folded constant
+ /// in Result.
+ bool Evaluate(EvalResult &Result, 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.
+ bool EvaluateAsBooleanCondition(bool &Result, ASTContext &Ctx) const;
+
+ /// isEvaluatable - Call Evaluate to see if this expression can be constant
+ /// folded, but discard the result.
+ bool isEvaluatable(ASTContext &Ctx) const;
+
+ /// HasSideEffects - This routine returns true for all those expressions
+ /// which must be evaluated each time and must not be optimization away
+ /// or evaluated at compile time. Example is a function call, volatile
+ /// variable read.
+ bool HasSideEffects(ASTContext &Ctx) const;
+
+ /// EvaluateAsInt - Call Evaluate and return the folded integer. This
+ /// must be called on an expression that constant folds to an integer.
+ llvm::APSInt EvaluateAsInt(ASTContext &Ctx) const;
+
+ /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue
+ /// with link time known address.
+ bool EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const;
+
+ /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue.
+ bool EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const;
+
+ /// \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 - Return true if this is either an
+ /// integer constant expression with the value zero, or if this is one that is
+ /// cast to void*.
+ bool 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;
+
+ /// 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();
+
+ /// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
+ /// or CastExprs, returning their operand.
+ Expr *IgnoreParenCasts();
+
+ /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off any
+ /// ParenExpr or ImplicitCastExprs, returning their operand.
+ Expr *IgnoreParenImpCasts();
+
+ /// 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);
+
+ /// \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 this expression directly creates a
+ /// temporary object (of class type).
+ bool isTemporaryObject() const { return getTemporaryObject() != 0; }
+
+ /// \brief If this expression directly creates a temporary object of
+ /// class type, return the expression that actually constructs that
+ /// temporary object.
+ const Expr *getTemporaryObject() const;
+
+ const Expr *IgnoreParens() const {
+ return const_cast<Expr*>(this)->IgnoreParens();
+ }
+ const Expr *IgnoreParenCasts() const {
+ return const_cast<Expr*>(this)->IgnoreParenCasts();
+ }
+ const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const {
+ return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
+ }
+
+ static bool hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs);
+ static bool hasAnyValueDependentArguments(Expr** Exprs, unsigned NumExprs);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() >= firstExprConstant &&
+ T->getStmtClass() <= lastExprConstant;
+ }
+ static bool classof(const Expr *) { return true; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Primary Expressions.
+//===----------------------------------------------------------------------===//
+
+/// \brief Represents the qualifier that may precede a C++ name, e.g., the
+/// "std::" in "std::sort".
+struct NameQualifier {
+ /// \brief The nested name specifier.
+ NestedNameSpecifier *NNS;
+
+ /// \brief The source range covered by the nested name specifier.
+ SourceRange Range;
+};
+
+/// \brief Represents an explicit template argument list in C++, e.g.,
+/// the "<int>" in "sort<int>".
+struct ExplicitTemplateArgumentList {
+ /// \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.
+ /// The actual template arguments (if any) are stored after the
+ /// ExplicitTemplateArgumentList structure.
+ unsigned NumTemplateArgs;
+
+ /// \brief Retrieve the template arguments
+ TemplateArgumentLoc *getTemplateArgs() {
+ return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
+ }
+
+ /// \brief Retrieve the template arguments
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
+ }
+
+ void initializeFrom(const TemplateArgumentListInfo &List);
+ void copyInto(TemplateArgumentListInfo &List) const;
+ static std::size_t sizeFor(const TemplateArgumentListInfo &List);
+};
+
+/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
+/// enum, etc.
+class DeclRefExpr : public Expr {
+ enum {
+ // Flag on DecoratedD that specifies when this declaration reference
+ // expression has a C++ nested-name-specifier.
+ HasQualifierFlag = 0x01,
+ // Flag on DecoratedD that specifies when this declaration reference
+ // expression has an explicit C++ template argument list.
+ HasExplicitTemplateArgumentListFlag = 0x02
+ };
+
+ // DecoratedD - The declaration that we are referencing, plus two bits to
+ // indicate whether (1) the declaration's name was explicitly qualified and
+ // (2) the declaration's name was followed by an explicit template
+ // argument list.
+ llvm::PointerIntPair<ValueDecl *, 2> DecoratedD;
+
+ // Loc - The location of the declaration name itself.
+ SourceLocation Loc;
+
+ /// \brief Retrieve the qualifier that preceded the declaration name, if any.
+ NameQualifier *getNameQualifier() {
+ if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
+ return 0;
+
+ return reinterpret_cast<NameQualifier *> (this + 1);
+ }
+
+ /// \brief Retrieve the qualifier that preceded the member name, if any.
+ const NameQualifier *getNameQualifier() const {
+ return const_cast<DeclRefExpr *>(this)->getNameQualifier();
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+ if ((DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag) == 0)
+ return 0;
+
+ if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(
+ getNameQualifier() + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+ return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgumentList();
+ }
+
+ DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+ ValueDecl *D, SourceLocation NameLoc,
+ const TemplateArgumentListInfo *TemplateArgs,
+ QualType T);
+
+protected:
+ /// \brief Computes the type- and value-dependence flags for this
+ /// declaration reference expression.
+ void computeDependence();
+
+ DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) :
+ Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
+ computeDependence();
+ }
+
+public:
+ DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) :
+ Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
+ computeDependence();
+ }
+
+ /// \brief Construct an empty declaration reference expression.
+ explicit DeclRefExpr(EmptyShell Empty)
+ : Expr(DeclRefExprClass, Empty) { }
+
+ static DeclRefExpr *Create(ASTContext &Context,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ ValueDecl *D,
+ SourceLocation NameLoc,
+ QualType T,
+ const TemplateArgumentListInfo *TemplateArgs = 0);
+
+ ValueDecl *getDecl() { return DecoratedD.getPointer(); }
+ const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
+ void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); }
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+ virtual SourceRange getSourceRange() const;
+
+ /// \brief Determine whether this declaration reference was preceded by a
+ /// C++ nested-name-specifier, e.g., \c N::foo.
+ bool hasQualifier() const { return DecoratedD.getInt() & HasQualifierFlag; }
+
+ /// \brief If the name was qualified, retrieves the source range of
+ /// the nested-name-specifier that precedes the name. Otherwise,
+ /// returns an empty source range.
+ SourceRange getQualifierRange() const {
+ if (!hasQualifier())
+ return SourceRange();
+
+ return getNameQualifier()->Range;
+ }
+
+ /// \brief If the name was qualified, retrieves the nested-name-specifier
+ /// that precedes the name. Otherwise, returns NULL.
+ NestedNameSpecifier *getQualifier() const {
+ if (!hasQualifier())
+ return 0;
+
+ return getNameQualifier()->NNS;
+ }
+
+ /// \brief Determines whether this member expression actually had a C++
+ /// template argument list explicitly specified, e.g., x.f<int>.
+ bool hasExplicitTemplateArgumentList() const {
+ return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag;
+ }
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ if (hasExplicitTemplateArgumentList())
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
+
+ /// \brief Retrieve the location of the left angle bracket following the
+ /// member name ('<'), if any.
+ SourceLocation getLAngleLoc() const {
+ if (!hasExplicitTemplateArgumentList())
+ return SourceLocation();
+
+ return getExplicitTemplateArgumentList()->LAngleLoc;
+ }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ if (!hasExplicitTemplateArgumentList())
+ return 0;
+
+ return getExplicitTemplateArgumentList()->getTemplateArgs();
+ }
+
+ /// \brief Retrieve the number of template arguments provided as part of this
+ /// template-id.
+ unsigned getNumTemplateArgs() const {
+ if (!hasExplicitTemplateArgumentList())
+ return 0;
+
+ return getExplicitTemplateArgumentList()->NumTemplateArgs;
+ }
+
+ /// \brief Retrieve the location of the right angle bracket following the
+ /// template arguments ('>').
+ SourceLocation getRAngleLoc() const {
+ if (!hasExplicitTemplateArgumentList())
+ return SourceLocation();
+
+ return getExplicitTemplateArgumentList()->RAngleLoc;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DeclRefExprClass;
+ }
+ static bool classof(const DeclRefExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
+class PredefinedExpr : public Expr {
+public:
+ enum IdentType {
+ Func,
+ Function,
+ PrettyFunction,
+ /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+ /// 'virtual' keyword is omitted for virtual member functions.
+ PrettyFunctionNoVirtual
+ };
+
+private:
+ SourceLocation Loc;
+ IdentType Type;
+public:
+ PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
+ : Expr(PredefinedExprClass, type, type->isDependentType(),
+ type->isDependentType()), Loc(l), Type(IT) {}
+
+ /// \brief Construct an empty predefined expression.
+ explicit PredefinedExpr(EmptyShell Empty)
+ : Expr(PredefinedExprClass, Empty) { }
+
+ IdentType getIdentType() const { return Type; }
+ void setIdentType(IdentType IT) { Type = IT; }
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
+ static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == PredefinedExprClass;
+ }
+ static bool classof(const PredefinedExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+class IntegerLiteral : public Expr {
+ llvm::APInt Value;
+ SourceLocation Loc;
+public:
+ // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
+ // or UnsignedLongLongTy
+ IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l)
+ : Expr(IntegerLiteralClass, type, false, false), Value(V), Loc(l) {
+ assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
+ }
+
+ /// \brief Construct an empty integer literal.
+ explicit IntegerLiteral(EmptyShell Empty)
+ : Expr(IntegerLiteralClass, Empty) { }
+
+ const llvm::APInt &getValue() const { return Value; }
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ /// \brief Retrieve the location of the literal.
+ SourceLocation getLocation() const { return Loc; }
+
+ void setValue(const llvm::APInt &Val) { Value = Val; }
+ void setLocation(SourceLocation Location) { Loc = Location; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == IntegerLiteralClass;
+ }
+ static bool classof(const IntegerLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+class CharacterLiteral : public Expr {
+ unsigned Value;
+ SourceLocation Loc;
+ bool IsWide;
+public:
+ // type should be IntTy
+ CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l)
+ : Expr(CharacterLiteralClass, type, false, false), Value(value), Loc(l),
+ IsWide(iswide) {
+ }
+
+ /// \brief Construct an empty character literal.
+ CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
+
+ SourceLocation getLocation() const { return Loc; }
+ bool isWide() const { return IsWide; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ unsigned getValue() const { return Value; }
+
+ void setLocation(SourceLocation Location) { Loc = Location; }
+ void setWide(bool W) { IsWide = W; }
+ void setValue(unsigned Val) { Value = Val; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CharacterLiteralClass;
+ }
+ static bool classof(const CharacterLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+class FloatingLiteral : public Expr {
+ llvm::APFloat Value;
+ bool IsExact : 1;
+ SourceLocation Loc;
+public:
+ FloatingLiteral(const llvm::APFloat &V, bool isexact,
+ QualType Type, SourceLocation L)
+ : Expr(FloatingLiteralClass, Type, false, false), Value(V),
+ IsExact(isexact), Loc(L) {}
+
+ /// \brief Construct an empty floating-point literal.
+ explicit FloatingLiteral(EmptyShell Empty)
+ : Expr(FloatingLiteralClass, Empty), Value(0.0) { }
+
+ const llvm::APFloat &getValue() const { return Value; }
+ void setValue(const llvm::APFloat &Val) { Value = Val; }
+
+ bool isExact() const { return IsExact; }
+ void setExact(bool E) { 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; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == FloatingLiteralClass;
+ }
+ static bool classof(const FloatingLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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, 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; }
+
+ virtual SourceRange getSourceRange() const { return Val->getSourceRange(); }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ImaginaryLiteralClass;
+ }
+ static bool classof(const ImaginaryLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// StringLiteral - This represents a string literal expression, e.g. "foo"
+/// or L"bar" (wide strings). The actual string is returned by getStrData()
+/// 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 {
+ const char *StrData;
+ unsigned ByteLength;
+ bool IsWide;
+ unsigned NumConcatenated;
+ SourceLocation TokLocs[1];
+
+ StringLiteral(QualType Ty) : Expr(StringLiteralClass, Ty, false, false) {}
+
+protected:
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ /// This is the "fully general" constructor that allows representation of
+ /// strings formed from multiple concatenated tokens.
+ static StringLiteral *Create(ASTContext &C, const char *StrData,
+ unsigned ByteLength, bool Wide, QualType Ty,
+ const SourceLocation *Loc, unsigned NumStrs);
+
+ /// Simple constructor for string literals made from one token.
+ static StringLiteral *Create(ASTContext &C, const char *StrData,
+ unsigned ByteLength,
+ bool Wide, QualType Ty, SourceLocation Loc) {
+ return Create(C, StrData, ByteLength, Wide, Ty, &Loc, 1);
+ }
+
+ /// \brief Construct an empty string literal.
+ static StringLiteral *CreateEmpty(ASTContext &C, unsigned NumStrs);
+
+ llvm::StringRef getString() const {
+ return llvm::StringRef(StrData, ByteLength);
+ }
+ // FIXME: These are deprecated, replace with StringRef.
+ const char *getStrData() const { return StrData; }
+ unsigned getByteLength() const { return ByteLength; }
+
+ /// \brief Sets the string data to the given string data.
+ void setString(ASTContext &C, llvm::StringRef Str);
+
+ bool isWide() const { return IsWide; }
+ void setWide(bool W) { IsWide = W; }
+
+ bool containsNonAsciiOrNull() const {
+ llvm::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;
+ }
+
+ typedef const SourceLocation *tokloc_iterator;
+ tokloc_iterator tokloc_begin() const { return TokLocs; }
+ tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(TokLocs[0], TokLocs[NumConcatenated-1]);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == StringLiteralClass;
+ }
+ static bool classof(const StringLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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->isTypeDependent(), val->isValueDependent()),
+ 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; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(L, 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;
+ }
+ static bool classof(const ParenExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+/// 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.
+///
+/// __builtin_offsetof(type, a.b[10]) is represented as a unary operator whose
+/// subexpression is a compound literal with the various MemberExpr and
+/// ArraySubscriptExpr's applied to it. (This is only used in C)
+///
+class UnaryOperator : public Expr {
+public:
+ // Note that additions to this should also update the StmtVisitor class.
+ enum Opcode {
+ PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators
+ PreInc, PreDec, // [C99 6.5.3.1] Prefix increment and decrement operators.
+ AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators.
+ Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators.
+ Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators.
+ Real, Imag, // "__real expr"/"__imag expr" Extension.
+ Extension, // __extension__ marker.
+ OffsetOf // __builtin_offsetof
+ };
+private:
+ Stmt *Val;
+ Opcode Opc;
+ SourceLocation Loc;
+public:
+
+ UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
+ : Expr(UnaryOperatorClass, type,
+ input->isTypeDependent() && opc != OffsetOf,
+ input->isValueDependent()),
+ Val(input), Opc(opc), Loc(l) {}
+
+ /// \brief Build an empty unary operator.
+ explicit UnaryOperator(EmptyShell Empty)
+ : Expr(UnaryOperatorClass, Empty), Opc(AddrOf) { }
+
+ Opcode getOpcode() const { return 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 == PostInc || Op == PostDec;
+ }
+
+ /// isPostfix - Return true if this is a prefix operation, like --x.
+ static bool isPrefix(Opcode Op) {
+ return Op == PreInc || Op == PreDec;
+ }
+
+ bool isPrefix() const { return isPrefix(Opc); }
+ bool isPostfix() const { return isPostfix(Opc); }
+ bool isIncrementOp() const {return Opc==PreInc || Opc==PostInc; }
+ bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
+ bool isOffsetOfOp() const { return Opc == OffsetOf; }
+ static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; }
+ bool isArithmeticOp() const { return isArithmeticOp(Opc); }
+
+ /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+ /// corresponds to, e.g. "sizeof" or "[pre]++"
+ static const char *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);
+
+ virtual SourceRange getSourceRange() const {
+ if (isPostfix())
+ return SourceRange(Val->getLocStart(), Loc);
+ else
+ return SourceRange(Loc, Val->getLocEnd());
+ }
+ virtual SourceLocation getExprLoc() const { return Loc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnaryOperatorClass;
+ }
+ static bool classof(const UnaryOperator *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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 : public Expr {
+public:
+ // __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 getRange() const { return Range; }
+ };
+
+private:
+
+ 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;
+
+ OffsetOfExpr(ASTContext &C, QualType type,
+ SourceLocation OperatorLoc, TypeSourceInfo *tsi,
+ OffsetOfNode* compsPtr, unsigned numComps,
+ Expr** exprsPtr, unsigned numExprs,
+ SourceLocation RParenLoc);
+
+ explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
+ : Expr(OffsetOfExprClass, EmptyShell()),
+ TSInfo(0), NumComps(numComps), NumExprs(numExprs) {}
+
+public:
+
+ static OffsetOfExpr *Create(ASTContext &C, QualType type,
+ SourceLocation OperatorLoc, TypeSourceInfo *tsi,
+ OffsetOfNode* compsPtr, unsigned numComps,
+ Expr** exprsPtr, unsigned numExprs,
+ SourceLocation RParenLoc);
+
+ static OffsetOfExpr *CreateEmpty(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) {
+ assert(Idx < NumComps && "Subscript out of range");
+ return reinterpret_cast<OffsetOfNode *> (this + 1)[Idx];
+ }
+
+ void setComponent(unsigned Idx, OffsetOfNode ON) {
+ assert(Idx < NumComps && "Subscript out of range");
+ reinterpret_cast<OffsetOfNode *> (this + 1)[Idx] = ON;
+ }
+
+ unsigned getNumComponents() const {
+ return NumComps;
+ }
+
+ Expr* getIndexExpr(unsigned Idx) {
+ assert(Idx < NumExprs && "Subscript out of range");
+ return reinterpret_cast<Expr **>(
+ reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx];
+ }
+
+ void setIndexExpr(unsigned Idx, Expr* E) {
+ assert(Idx < NumComps && "Subscript out of range");
+ reinterpret_cast<Expr **>(
+ reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx] = E;
+ }
+
+ unsigned getNumExpressions() const {
+ return NumExprs;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(OperatorLoc, RParenLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OffsetOfExprClass;
+ }
+
+ static bool classof(const OffsetOfExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// SizeOfAlignOfExpr - [C99 6.5.3.4] - This is for sizeof/alignof, both of
+/// types and expressions.
+class SizeOfAlignOfExpr : public Expr {
+ bool isSizeof : 1; // true if sizeof, false if alignof.
+ bool isType : 1; // true if operand is a type, false if an expression
+ union {
+ TypeSourceInfo *Ty;
+ Stmt *Ex;
+ } Argument;
+ SourceLocation OpLoc, RParenLoc;
+
+protected:
+ virtual void DoDestroy(ASTContext& C);
+
+public:
+ SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo,
+ QualType resultType, SourceLocation op,
+ SourceLocation rp) :
+ Expr(SizeOfAlignOfExprClass, resultType,
+ false, // Never type-dependent (C++ [temp.dep.expr]p3).
+ // Value-dependent if the argument is type-dependent.
+ TInfo->getType()->isDependentType()),
+ isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
+ Argument.Ty = TInfo;
+ }
+
+ SizeOfAlignOfExpr(bool issizeof, Expr *E,
+ QualType resultType, SourceLocation op,
+ SourceLocation rp) :
+ Expr(SizeOfAlignOfExprClass, resultType,
+ false, // Never type-dependent (C++ [temp.dep.expr]p3).
+ // Value-dependent if the argument is type-dependent.
+ E->isTypeDependent()),
+ isSizeof(issizeof), isType(false), OpLoc(op), RParenLoc(rp) {
+ Argument.Ex = E;
+ }
+
+ /// \brief Construct an empty sizeof/alignof expression.
+ explicit SizeOfAlignOfExpr(EmptyShell Empty)
+ : Expr(SizeOfAlignOfExprClass, Empty) { }
+
+ bool isSizeOf() const { return isSizeof; }
+ void setSizeof(bool S) { isSizeof = S; }
+
+ bool isArgumentType() const { return 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<SizeOfAlignOfExpr*>(this)->getArgumentExpr();
+ }
+
+ void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
+ void setArgument(TypeSourceInfo *TInfo) {
+ Argument.Ty = TInfo;
+ 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(OpLoc, RParenLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == SizeOfAlignOfExprClass;
+ }
+ static bool classof(const SizeOfAlignOfExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+//===----------------------------------------------------------------------===//
+// 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,
+ SourceLocation rbracketloc)
+ : Expr(ArraySubscriptExprClass, t,
+ lhs->isTypeDependent() || rhs->isTypeDependent(),
+ lhs->isValueDependent() || rhs->isValueDependent()),
+ 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());
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getLHS()->getLocStart(), RBracketLoc);
+ }
+
+ SourceLocation getRBracketLoc() const { return RBracketLoc; }
+ void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
+
+ virtual SourceLocation getExprLoc() const { return getBase()->getExprLoc(); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ArraySubscriptExprClass;
+ }
+ static bool classof(const ArraySubscriptExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+/// 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, ARGS_START=1 };
+ Stmt **SubExprs;
+ unsigned NumArgs;
+ SourceLocation RParenLoc;
+
+protected:
+ // This version of the constructor is for derived classes.
+ CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, unsigned numargs,
+ QualType t, SourceLocation rparenloc);
+
+ virtual void DoDestroy(ASTContext& C);
+
+public:
+ CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t,
+ SourceLocation rparenloc);
+
+ /// \brief Build an empty call expression.
+ CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty);
+
+ ~CallExpr() {}
+
+ 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; }
+
+ /// getArg - Return the specified argument.
+ Expr *getArg(unsigned Arg) {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return cast<Expr>(SubExprs[Arg+ARGS_START]);
+ }
+ const Expr *getArg(unsigned Arg) const {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return cast<Expr>(SubExprs[Arg+ARGS_START]);
+ }
+
+ /// setArg - Set the specified argument.
+ void setArg(unsigned Arg, Expr *ArgExpr) {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ SubExprs[Arg+ARGS_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(ASTContext& C, unsigned NumArgs);
+
+ typedef ExprIterator arg_iterator;
+ typedef ConstExprIterator const_arg_iterator;
+
+ arg_iterator arg_begin() { return SubExprs+ARGS_START; }
+ arg_iterator arg_end() { return SubExprs+ARGS_START+getNumArgs(); }
+ const_arg_iterator arg_begin() const { return SubExprs+ARGS_START; }
+ const_arg_iterator arg_end() const { return SubExprs+ARGS_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; }
+
+ /// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
+ /// not, return 0.
+ unsigned isBuiltinCall(ASTContext &Context) 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;
+
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getCallee()->getLocStart(), RParenLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() >= firstCallExprConstant &&
+ T->getStmtClass() <= lastCallExprConstant;
+ }
+ static bool classof(const CallExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F.
+///
+class MemberExpr : public Expr {
+ /// Extra data stored in some member expressions.
+ struct MemberNameQualifier : public NameQualifier {
+ DeclAccessPair FoundDecl;
+ };
+
+ /// 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;
+
+ /// MemberLoc - This is the location of the member name.
+ SourceLocation MemberLoc;
+
+ /// 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 MemberNameQualifier
+ /// structure is allocated immediately after the MemberExpr.
+ bool HasQualifierOrFoundDecl : 1;
+
+ /// \brief True if this member expression specified a template argument list
+ /// explicitly, e.g., x->f<int>. When true, an ExplicitTemplateArgumentList
+ /// structure (and its TemplateArguments) are allocated immediately after
+ /// the MemberExpr or, if the member expression also has a qualifier, after
+ /// the MemberNameQualifier structure.
+ bool HasExplicitTemplateArgumentList : 1;
+
+ /// \brief Retrieve the qualifier that preceded the member name, if any.
+ MemberNameQualifier *getMemberQualifier() {
+ assert(HasQualifierOrFoundDecl);
+ return reinterpret_cast<MemberNameQualifier *> (this + 1);
+ }
+
+ /// \brief Retrieve the qualifier that preceded the member name, if any.
+ const MemberNameQualifier *getMemberQualifier() const {
+ return const_cast<MemberExpr *>(this)->getMemberQualifier();
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+ if (!HasExplicitTemplateArgumentList)
+ return 0;
+
+ if (!HasQualifierOrFoundDecl)
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(
+ getMemberQualifier() + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+ return const_cast<MemberExpr *>(this)->getExplicitTemplateArgumentList();
+ }
+
+public:
+ MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl,
+ SourceLocation l, QualType ty)
+ : Expr(MemberExprClass, ty,
+ base->isTypeDependent(), base->isValueDependent()),
+ Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
+ HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
+
+ /// \brief Build an empty member reference expression.
+ explicit MemberExpr(EmptyShell Empty)
+ : Expr(MemberExprClass, Empty), HasQualifierOrFoundDecl(false),
+ HasExplicitTemplateArgumentList(false) { }
+
+ static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
+ NestedNameSpecifier *qual, SourceRange qualrange,
+ ValueDecl *memberdecl, DeclAccessPair founddecl,
+ SourceLocation l,
+ const TemplateArgumentListInfo *targs,
+ QualType ty);
+
+ 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 getMemberQualifier()->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() != 0; }
+
+ /// \brief If the member name was qualified, retrieves the source range of
+ /// the nested-name-specifier that precedes the member name. Otherwise,
+ /// returns an empty source range.
+ SourceRange getQualifierRange() const {
+ if (!HasQualifierOrFoundDecl)
+ return SourceRange();
+
+ return getMemberQualifier()->Range;
+ }
+
+ /// \brief If the member name was qualified, retrieves the
+ /// nested-name-specifier that precedes the member name. Otherwise, returns
+ /// NULL.
+ NestedNameSpecifier *getQualifier() const {
+ if (!HasQualifierOrFoundDecl)
+ return 0;
+
+ return getMemberQualifier()->NNS;
+ }
+
+ /// \brief Determines whether this member expression actually had a C++
+ /// template argument list explicitly specified, e.g., x.f<int>.
+ bool hasExplicitTemplateArgumentList() const {
+ return HasExplicitTemplateArgumentList;
+ }
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ if (hasExplicitTemplateArgumentList())
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
+
+ /// \brief Retrieve the location of the left angle bracket following the
+ /// member name ('<'), if any.
+ SourceLocation getLAngleLoc() const {
+ if (!HasExplicitTemplateArgumentList)
+ return SourceLocation();
+
+ return getExplicitTemplateArgumentList()->LAngleLoc;
+ }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ if (!HasExplicitTemplateArgumentList)
+ return 0;
+
+ return getExplicitTemplateArgumentList()->getTemplateArgs();
+ }
+
+ /// \brief Retrieve the number of template arguments provided as part of this
+ /// template-id.
+ unsigned getNumTemplateArgs() const {
+ if (!HasExplicitTemplateArgumentList)
+ return 0;
+
+ return getExplicitTemplateArgumentList()->NumTemplateArgs;
+ }
+
+ /// \brief Retrieve the location of the right angle bracket following the
+ /// template arguments ('>').
+ SourceLocation getRAngleLoc() const {
+ if (!HasExplicitTemplateArgumentList)
+ return SourceLocation();
+
+ return getExplicitTemplateArgumentList()->RAngleLoc;
+ }
+
+ 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; }
+
+ virtual SourceRange getSourceRange() const {
+ // If we have an implicit base (like a C++ implicit this),
+ // make sure not to return its location
+ SourceLocation EndLoc = MemberLoc;
+ if (HasExplicitTemplateArgumentList)
+ EndLoc = getRAngleLoc();
+
+ SourceLocation BaseLoc = getBase()->getLocStart();
+ if (BaseLoc.isInvalid())
+ return SourceRange(MemberLoc, EndLoc);
+ return SourceRange(BaseLoc, EndLoc);
+ }
+
+ virtual SourceLocation getExprLoc() const { return MemberLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == MemberExprClass;
+ }
+ static bool classof(const MemberExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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.
+ TypeSourceInfo *TInfo;
+ Stmt *Init;
+ bool FileScope;
+public:
+ // FIXME: Can compound literals be value-dependent?
+ CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
+ QualType T, Expr *init, bool fileScope)
+ : Expr(CompoundLiteralExprClass, T,
+ tinfo->getType()->isDependentType(), false),
+ LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {}
+
+ /// \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 FileScope; }
+ void setFileScope(bool FS) { FileScope = FS; }
+
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+ void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+
+ TypeSourceInfo *getTypeSourceInfo() const { return TInfo; }
+ void setTypeSourceInfo(TypeSourceInfo* tinfo) { TInfo = tinfo; }
+
+ virtual SourceRange getSourceRange() const {
+ // FIXME: Init should never be null.
+ if (!Init)
+ return SourceRange();
+ if (LParenLoc.isInvalid())
+ return Init->getSourceRange();
+ return SourceRange(LParenLoc, Init->getLocEnd());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CompoundLiteralExprClass;
+ }
+ static bool classof(const CompoundLiteralExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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 {
+public:
+ /// CastKind - the kind of cast this represents.
+ enum CastKind {
+ /// CK_Unknown - Unknown cast kind.
+ /// FIXME: The goal is to get rid of this and make all casts have a
+ /// kind so that the AST client doesn't have to try to figure out what's
+ /// going on.
+ CK_Unknown,
+
+ /// CK_BitCast - Used for reinterpret_cast.
+ CK_BitCast,
+
+ /// CK_NoOp - Used for const_cast.
+ CK_NoOp,
+
+ /// CK_BaseToDerived - Base to derived class casts.
+ CK_BaseToDerived,
+
+ /// CK_DerivedToBase - Derived to base class casts.
+ CK_DerivedToBase,
+
+ /// CK_UncheckedDerivedToBase - Derived to base class casts that
+ /// assume that the derived pointer is not null.
+ CK_UncheckedDerivedToBase,
+
+ /// CK_Dynamic - Dynamic cast.
+ CK_Dynamic,
+
+ /// CK_ToUnion - Cast to union (GCC extension).
+ CK_ToUnion,
+
+ /// CK_ArrayToPointerDecay - Array to pointer decay.
+ CK_ArrayToPointerDecay,
+
+ // CK_FunctionToPointerDecay - Function to pointer decay.
+ CK_FunctionToPointerDecay,
+
+ /// CK_NullToMemberPointer - Null pointer to member pointer.
+ CK_NullToMemberPointer,
+
+ /// CK_BaseToDerivedMemberPointer - Member pointer in base class to
+ /// member pointer in derived class.
+ CK_BaseToDerivedMemberPointer,
+
+ /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
+ /// member pointer in base class.
+ CK_DerivedToBaseMemberPointer,
+
+ /// CK_UserDefinedConversion - Conversion using a user defined type
+ /// conversion function.
+ CK_UserDefinedConversion,
+
+ /// CK_ConstructorConversion - Conversion by constructor
+ CK_ConstructorConversion,
+
+ /// CK_IntegralToPointer - Integral to pointer
+ CK_IntegralToPointer,
+
+ /// CK_PointerToIntegral - Pointer to integral
+ CK_PointerToIntegral,
+
+ /// CK_ToVoid - Cast to void.
+ CK_ToVoid,
+
+ /// CK_VectorSplat - Casting from an integer/floating type to an extended
+ /// vector type with the same element type as the src type. Splats the
+ /// src expression into the destination expression.
+ CK_VectorSplat,
+
+ /// CK_IntegralCast - Casting between integral types of different size.
+ CK_IntegralCast,
+
+ /// CK_IntegralToFloating - Integral to floating point.
+ CK_IntegralToFloating,
+
+ /// CK_FloatingToIntegral - Floating point to integral.
+ CK_FloatingToIntegral,
+
+ /// CK_FloatingCast - Casting between floating types of different size.
+ CK_FloatingCast,
+
+ /// CK_MemberPointerToBoolean - Member pointer to boolean
+ CK_MemberPointerToBoolean,
+
+ /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c
+ /// pointer
+ CK_AnyPointerToObjCPointerCast,
+ /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block
+ /// pointer
+ CK_AnyPointerToBlockPointerCast
+
+ };
+
+private:
+ CastKind Kind;
+ Stmt *Op;
+
+ /// BasePath - For derived-to-base and base-to-derived casts, the base array
+ /// contains the inheritance path.
+ CXXBaseSpecifierArray BasePath;
+
+ void CheckBasePath() const {
+#ifndef NDEBUG
+ switch (getCastKind()) {
+ case CK_DerivedToBase:
+ case CK_UncheckedDerivedToBase:
+ case CK_DerivedToBaseMemberPointer:
+ case CK_BaseToDerived:
+ case CK_BaseToDerivedMemberPointer:
+ assert(!BasePath.empty() && "Cast kind should have a base path!");
+ break;
+
+ // These should not have an inheritance path.
+ case CK_Unknown:
+ case CK_BitCast:
+ case CK_NoOp:
+ case CK_Dynamic:
+ case CK_ToUnion:
+ case CK_ArrayToPointerDecay:
+ case CK_FunctionToPointerDecay:
+ case CK_NullToMemberPointer:
+ case CK_UserDefinedConversion:
+ case CK_ConstructorConversion:
+ case CK_IntegralToPointer:
+ case CK_PointerToIntegral:
+ case CK_ToVoid:
+ case CK_VectorSplat:
+ case CK_IntegralCast:
+ case CK_IntegralToFloating:
+ case CK_FloatingToIntegral:
+ case CK_FloatingCast:
+ case CK_MemberPointerToBoolean:
+ case CK_AnyPointerToObjCPointerCast:
+ case CK_AnyPointerToBlockPointerCast:
+ assert(BasePath.empty() && "Cast kind should not have a base path!");
+ break;
+ }
+#endif
+ }
+
+protected:
+ CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath) :
+ Expr(SC, ty,
+ // 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())),
+ Kind(kind), Op(op), BasePath(BasePath) {
+ CheckBasePath();
+ }
+
+ /// \brief Construct an empty cast.
+ CastExpr(StmtClass SC, EmptyShell Empty)
+ : Expr(SC, Empty) { }
+
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ CastKind getCastKind() const { return Kind; }
+ void setCastKind(CastKind K) { 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();
+ }
+
+ const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() >= firstCastExprConstant &&
+ T->getStmtClass() <= lastCastExprConstant;
+ }
+ static bool classof(const CastExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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. For example:
+///
+/// @code
+/// class Base { };
+/// class Derived : public Base { };
+/// void f(Derived d) {
+/// Base& b = d; // initializer is an ImplicitCastExpr to an lvalue of type Base
+/// }
+/// @endcode
+class ImplicitCastExpr : public CastExpr {
+ /// LvalueCast - Whether this cast produces an lvalue.
+ bool LvalueCast;
+
+public:
+ ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath, bool Lvalue)
+ : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePath),
+ LvalueCast(Lvalue) { }
+
+ /// \brief Construct an empty implicit cast.
+ explicit ImplicitCastExpr(EmptyShell Shell)
+ : CastExpr(ImplicitCastExprClass, Shell) { }
+
+ virtual SourceRange getSourceRange() const {
+ return getSubExpr()->getSourceRange();
+ }
+
+ /// isLvalueCast - Whether this cast produces an lvalue.
+ bool isLvalueCast() const { return LvalueCast; }
+
+ /// setLvalueCast - Set whether this cast produces an lvalue.
+ void setLvalueCast(bool Lvalue) { LvalueCast = Lvalue; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ImplicitCastExprClass;
+ }
+ static bool classof(const ImplicitCastExpr *) { return true; }
+};
+
+/// 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. 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, CastKind kind,
+ Expr *op, CXXBaseSpecifierArray BasePath,
+ TypeSourceInfo *writtenTy)
+ : CastExpr(SC, exprTy, kind, op, BasePath), TInfo(writtenTy) {}
+
+ /// \brief Construct an empty explicit cast.
+ ExplicitCastExpr(StmtClass SC, EmptyShell Shell)
+ : CastExpr(SC, Shell) { }
+
+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;
+ }
+ static bool classof(const ExplicitCastExpr *) { return true; }
+};
+
+/// 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 : public ExplicitCastExpr {
+ SourceLocation LPLoc; // the location of the left paren
+ SourceLocation RPLoc; // the location of the right paren
+public:
+ CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ SourceLocation l, SourceLocation r)
+ : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, BasePath,
+ writtenTy), LPLoc(l), RPLoc(r) {}
+
+ /// \brief Construct an empty C-style explicit cast.
+ explicit CStyleCastExpr(EmptyShell Shell)
+ : ExplicitCastExpr(CStyleCastExprClass, Shell) { }
+
+ SourceLocation getLParenLoc() const { return LPLoc; }
+ void setLParenLoc(SourceLocation L) { LPLoc = L; }
+
+ SourceLocation getRParenLoc() const { return RPLoc; }
+ void setRParenLoc(SourceLocation L) { RPLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(LPLoc, getSubExpr()->getSourceRange().getEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CStyleCastExprClass;
+ }
+ static bool classof(const CStyleCastExpr *) { return true; }
+};
+
+/// \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:
+ enum Opcode {
+ // Operators listed in order of precedence.
+ // Note that additions to this should also update the StmtVisitor class.
+ PtrMemD, PtrMemI, // [C++ 5.5] Pointer-to-member operators.
+ Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators.
+ Add, Sub, // [C99 6.5.6] Additive operators.
+ Shl, Shr, // [C99 6.5.7] Bitwise shift operators.
+ LT, GT, LE, GE, // [C99 6.5.8] Relational operators.
+ EQ, NE, // [C99 6.5.9] Equality operators.
+ And, // [C99 6.5.10] Bitwise AND operator.
+ Xor, // [C99 6.5.11] Bitwise XOR operator.
+ Or, // [C99 6.5.12] Bitwise OR operator.
+ LAnd, // [C99 6.5.13] Logical AND operator.
+ LOr, // [C99 6.5.14] Logical OR operator.
+ Assign, MulAssign,// [C99 6.5.16] Assignment operators.
+ DivAssign, RemAssign,
+ AddAssign, SubAssign,
+ ShlAssign, ShrAssign,
+ AndAssign, XorAssign,
+ OrAssign,
+ Comma // [C99 6.5.17] Comma operator.
+ };
+private:
+ enum { LHS, RHS, END_EXPR };
+ Stmt* SubExprs[END_EXPR];
+ Opcode Opc;
+ SourceLocation OpLoc;
+public:
+
+ BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+ SourceLocation opLoc)
+ : Expr(BinaryOperatorClass, ResTy,
+ lhs->isTypeDependent() || rhs->isTypeDependent(),
+ lhs->isValueDependent() || rhs->isValueDependent()),
+ Opc(opc), OpLoc(opLoc) {
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+ assert(!isCompoundAssignmentOp() &&
+ "Use ArithAssignBinaryOperator for compound assignments");
+ }
+
+ /// \brief Construct an empty binary operator.
+ explicit BinaryOperator(EmptyShell Empty)
+ : Expr(BinaryOperatorClass, Empty), Opc(Comma) { }
+
+ SourceLocation getOperatorLoc() const { return OpLoc; }
+ void setOperatorLoc(SourceLocation L) { OpLoc = L; }
+
+ Opcode getOpcode() const { return 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd());
+ }
+
+ /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+ /// corresponds to, e.g. "<<=".
+ static const char *getOpcodeStr(Opcode Op);
+
+ /// \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 isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; }
+ bool isAdditiveOp() const { return Opc == Add || Opc == Sub; }
+ static bool isShiftOp(Opcode Opc) { return Opc == Shl || Opc == Shr; }
+ bool isShiftOp() const { return isShiftOp(Opc); }
+
+ static bool isBitwiseOp(Opcode Opc) { return Opc >= And && Opc <= Or; }
+ bool isBitwiseOp() const { return isBitwiseOp(Opc); }
+
+ static bool isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; }
+ bool isRelationalOp() const { return isRelationalOp(Opc); }
+
+ static bool isEqualityOp(Opcode Opc) { return Opc == EQ || Opc == NE; }
+ bool isEqualityOp() const { return isEqualityOp(Opc); }
+
+ static bool isComparisonOp(Opcode Opc) { return Opc >= LT && Opc <= NE; }
+ bool isComparisonOp() const { return isComparisonOp(Opc); }
+
+ static bool isLogicalOp(Opcode Opc) { return Opc == LAnd || Opc == LOr; }
+ bool isLogicalOp() const { return isLogicalOp(Opc); }
+
+ bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
+ bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
+ bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
+
+ static bool classof(const Stmt *S) {
+ return S->getStmtClass() >= firstBinaryOperatorConstant &&
+ S->getStmtClass() <= lastBinaryOperatorConstant;
+ }
+ static bool classof(const BinaryOperator *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+protected:
+ BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+ SourceLocation opLoc, bool dead)
+ : Expr(CompoundAssignOperatorClass, ResTy,
+ lhs->isTypeDependent() || rhs->isTypeDependent(),
+ lhs->isValueDependent() || rhs->isValueDependent()),
+ Opc(opc), OpLoc(opLoc) {
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+ }
+
+ BinaryOperator(StmtClass SC, EmptyShell Empty)
+ : Expr(SC, Empty), Opc(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 aritmetic 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, QualType CompLHSType,
+ QualType CompResultType,
+ SourceLocation OpLoc)
+ : BinaryOperator(lhs, rhs, opc, ResType, OpLoc, 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 CompoundAssignOperator *) { return true; }
+ static bool classof(const Stmt *S) {
+ return S->getStmtClass() == CompoundAssignOperatorClass;
+ }
+};
+
+/// ConditionalOperator - The ?: operator. Note that LHS may be null when the
+/// GNU "missing LHS" extension is in use.
+///
+class ConditionalOperator : public Expr {
+ enum { COND, LHS, RHS, END_EXPR };
+ Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
+ SourceLocation QuestionLoc, ColonLoc;
+public:
+ ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
+ SourceLocation CLoc, Expr *rhs, QualType t)
+ : Expr(ConditionalOperatorClass, t,
+ // 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 && lhs->isTypeDependent()) || (rhs && rhs->isTypeDependent())),
+ (cond->isValueDependent() ||
+ (lhs && lhs->isValueDependent()) ||
+ (rhs && rhs->isValueDependent()))),
+ QuestionLoc(QLoc),
+ ColonLoc(CLoc) {
+ SubExprs[COND] = cond;
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+ }
+
+ /// \brief Build an empty conditional operator.
+ explicit ConditionalOperator(EmptyShell Empty)
+ : Expr(ConditionalOperatorClass, Empty) { }
+
+ // getCond - Return the expression representing the condition for
+ // the ?: operator.
+ Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
+ void setCond(Expr *E) { SubExprs[COND] = E; }
+
+ // getTrueExpr - Return the subexpression representing the value of the ?:
+ // expression if the condition evaluates to true. In most cases this value
+ // will be the same as getLHS() except a GCC extension allows the left
+ // subexpression to be omitted, and instead of the condition be returned.
+ // e.g: x ?: y is shorthand for x ? x : y, except that the expression "x"
+ // is only evaluated once.
+ Expr *getTrueExpr() const {
+ return cast<Expr>(SubExprs[LHS] ? SubExprs[LHS] : SubExprs[COND]);
+ }
+
+ // getTrueExpr - 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_or_null<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 getQuestionLoc() const { return QuestionLoc; }
+ void setQuestionLoc(SourceLocation L) { QuestionLoc = L; }
+
+ SourceLocation getColonLoc() const { return ColonLoc; }
+ void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ConditionalOperatorClass;
+ }
+ static bool classof(const ConditionalOperator *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// AddrLabelExpr - The GNU address of label extension, representing &&label.
+class AddrLabelExpr : public Expr {
+ SourceLocation AmpAmpLoc, LabelLoc;
+ LabelStmt *Label;
+public:
+ AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L,
+ QualType t)
+ : Expr(AddrLabelExprClass, t, 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AmpAmpLoc, LabelLoc);
+ }
+
+ LabelStmt *getLabel() const { return Label; }
+ void setLabel(LabelStmt *S) { Label = S; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == AddrLabelExprClass;
+ }
+ static bool classof(const AddrLabelExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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.
+class StmtExpr : public Expr {
+ Stmt *SubStmt;
+ SourceLocation LParenLoc, RParenLoc;
+public:
+ // FIXME: Does type-dependence need to be computed differently?
+ StmtExpr(CompoundStmt *substmt, QualType T,
+ SourceLocation lp, SourceLocation rp) :
+ Expr(StmtExprClass, T, T->isDependentType(), 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(LParenLoc, 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;
+ }
+ static bool classof(const StmtExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// TypesCompatibleExpr - GNU builtin-in function __builtin_types_compatible_p.
+/// This AST node represents a function that returns 1 if two *types* (not
+/// expressions) are compatible. The result of this built-in function can be
+/// used in integer constant expressions.
+class TypesCompatibleExpr : public Expr {
+ QualType Type1;
+ QualType Type2;
+ SourceLocation BuiltinLoc, RParenLoc;
+public:
+ TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc,
+ QualType t1, QualType t2, SourceLocation RP) :
+ Expr(TypesCompatibleExprClass, ReturnType, false, false),
+ Type1(t1), Type2(t2), BuiltinLoc(BLoc), RParenLoc(RP) {}
+
+ /// \brief Build an empty __builtin_type_compatible_p expression.
+ explicit TypesCompatibleExpr(EmptyShell Empty)
+ : Expr(TypesCompatibleExprClass, Empty) { }
+
+ QualType getArgType1() const { return Type1; }
+ void setArgType1(QualType T) { Type1 = T; }
+ QualType getArgType2() const { return Type2; }
+ void setArgType2(QualType T) { Type2 = T; }
+
+ SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+ void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(BuiltinLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == TypesCompatibleExprClass;
+ }
+ static bool classof(const TypesCompatibleExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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;
+
+protected:
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ // FIXME: Can a shufflevector be value-dependent? Does type-dependence need
+ // to be computed differently?
+ ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr,
+ QualType Type, SourceLocation BLoc,
+ SourceLocation RP) :
+ Expr(ShuffleVectorExprClass, Type, Type->isDependentType(), false),
+ BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) {
+
+ SubExprs = new (C) Stmt*[nexpr];
+ for (unsigned i = 0; i < nexpr; i++)
+ SubExprs[i] = args[i];
+ }
+
+ /// \brief Build an empty vector-shuffle expression.
+ explicit ShuffleVectorExpr(EmptyShell Empty)
+ : Expr(ShuffleVectorExprClass, Empty), SubExprs(0) { }
+
+ SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+ void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(BuiltinLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ShuffleVectorExprClass;
+ }
+ static bool classof(const ShuffleVectorExpr *) { return true; }
+
+ ~ShuffleVectorExpr() {}
+
+ /// 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; }
+
+ /// 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(ASTContext &C, Expr ** Exprs, unsigned NumExprs);
+
+ unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) {
+ assert((N < NumExprs - 2) && "Shuffle idx out of range!");
+ return getExpr(N+2)->EvaluateAsInt(Ctx).getZExtValue();
+ }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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;
+public:
+ ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t,
+ SourceLocation RP, bool TypeDependent, bool ValueDependent)
+ : Expr(ChooseExprClass, t, TypeDependent, ValueDependent),
+ BuiltinLoc(BLoc), RParenLoc(RP) {
+ 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(ASTContext &C) const;
+
+ /// getChosenSubExpr - Return the subexpression chosen according to the
+ /// condition.
+ Expr *getChosenSubExpr(ASTContext &C) const {
+ return isConditionTrue(C) ? 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(BuiltinLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ChooseExprClass;
+ }
+ static bool classof(const ChooseExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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, 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(TokenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == GNUNullExprClass;
+ }
+ static bool classof(const GNUNullExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// VAArgExpr, used for the builtin function __builtin_va_arg.
+class VAArgExpr : public Expr {
+ Stmt *Val;
+ SourceLocation BuiltinLoc, RParenLoc;
+public:
+ VAArgExpr(SourceLocation BLoc, Expr* e, QualType t, SourceLocation RPLoc)
+ : Expr(VAArgExprClass, t, t->isDependentType(), false),
+ Val(e),
+ BuiltinLoc(BLoc),
+ RParenLoc(RPLoc) { }
+
+ /// \brief Create an empty __builtin_va_arg expression.
+ explicit VAArgExpr(EmptyShell Empty) : Expr(VAArgExprClass, Empty) { }
+
+ const Expr *getSubExpr() const { return cast<Expr>(Val); }
+ Expr *getSubExpr() { return cast<Expr>(Val); }
+ void setSubExpr(Expr *E) { Val = E; }
+
+ SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+ void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(BuiltinLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == VAArgExprClass;
+ }
+ static bool classof(const VAArgExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// @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.
+///
+/// Given the semantic form of the initializer list, one can retrieve
+/// the original syntactic form of that initializer list (if it
+/// exists) using getSyntacticForm(). Since many initializer lists
+/// have the same syntactic and semantic forms, getSyntacticForm() may
+/// return NULL, indicating that the current 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;
+
+ /// Contains the initializer list that describes the syntactic form
+ /// written in the source code.
+ InitListExpr *SyntacticForm;
+
+ /// If this initializer list initializes a union, specifies which
+ /// field within the union will be initialized.
+ FieldDecl *UnionFieldInit;
+
+ /// Whether this initializer list originally had a GNU array-range
+ /// designator in it. This is a temporary marker used by CodeGen.
+ bool HadArrayRangeDesignator;
+
+public:
+ InitListExpr(ASTContext &C, SourceLocation lbraceloc,
+ Expr **initexprs, unsigned numinits,
+ SourceLocation rbraceloc);
+
+ /// \brief Build an empty initializer list.
+ explicit InitListExpr(ASTContext &C, EmptyShell Empty)
+ : Expr(InitListExprClass, Empty), InitExprs(C) { }
+
+ unsigned getNumInits() const { return InitExprs.size(); }
+
+ 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;
+ }
+
+ /// \brief Reserve space for some number of initializers.
+ void reserveInits(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(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
+ /// accomodate the new entry.
+ Expr *updateInit(ASTContext &C, unsigned Init, Expr *expr);
+
+ /// \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 UnionFieldInit; }
+ void setInitializedFieldInUnion(FieldDecl *FD) { UnionFieldInit = 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();
+ }
+
+ SourceLocation getLBraceLoc() const { return LBraceLoc; }
+ void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+ void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
+
+ /// @brief Retrieve the initializer list that describes the
+ /// syntactic form of the initializer.
+ ///
+ ///
+ InitListExpr *getSyntacticForm() const { return SyntacticForm; }
+ void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; }
+
+ bool hadArrayRangeDesignator() const { return HadArrayRangeDesignator; }
+ void sawArrayRangeDesignator(bool ARD = true) {
+ HadArrayRangeDesignator = ARD;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(LBraceLoc, RBraceLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == InitListExprClass;
+ }
+ static bool classof(const InitListExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+ typedef InitExprsTy::iterator iterator;
+ typedef InitExprsTy::reverse_iterator reverse_iterator;
+
+ iterator begin() { return InitExprs.begin(); }
+ iterator end() { return InitExprs.end(); }
+ reverse_iterator rbegin() { return InitExprs.rbegin(); }
+ reverse_iterator rend() { return InitExprs.rend(); }
+};
+
+/// @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 initalization expression will be 1.0.
+class DesignatedInitExpr : public Expr {
+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;
+
+ /// \brief The designators in this designated initialization
+ /// expression.
+ Designator *Designators;
+
+ /// 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;
+
+
+ DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumDesignators,
+ const Designator *Designators,
+ SourceLocation EqualOrColonLoc, bool GNUSyntax,
+ Expr **IndexExprs, unsigned NumIndexExprs,
+ Expr *Init);
+
+ explicit DesignatedInitExpr(unsigned NumSubExprs)
+ : Expr(DesignatedInitExprClass, EmptyShell()),
+ NumDesignators(0), Designators(0), NumSubExprs(NumSubExprs) { }
+
+protected:
+ virtual void DoDestroy(ASTContext &C);
+
+ void DestroyDesignators(ASTContext &C);
+
+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();
+
+ FieldDecl *getField() {
+ assert(Kind == FieldDesignator && "Only valid on a field designator");
+ if (Field.NameOrField & 0x01)
+ return 0;
+ 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 getStartLocation() const {
+ if (Kind == FieldDesignator)
+ return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
+ else
+ return getLBracketLoc();
+ }
+ };
+
+ static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators,
+ unsigned NumDesignators,
+ Expr **IndexExprs, unsigned NumIndexExprs,
+ SourceLocation EqualOrColonLoc,
+ bool GNUSyntax, Expr *Init);
+
+ static DesignatedInitExpr *CreateEmpty(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;
+ }
+
+ Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
+
+ void setDesignators(ASTContext &C, const Designator *Desigs,
+ unsigned NumDesigs);
+
+ Expr *getArrayIndex(const Designator& D);
+ Expr *getArrayRangeStart(const Designator& D);
+ Expr *getArrayRangeEnd(const Designator& D);
+
+ /// @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) {
+ assert(Idx < NumSubExprs && "Subscript out of range");
+ char* Ptr = static_cast<char*>(static_cast<void *>(this));
+ Ptr += sizeof(DesignatedInitExpr);
+ return reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx];
+ }
+
+ void setSubExpr(unsigned Idx, Expr *E) {
+ assert(Idx < NumSubExprs && "Subscript out of range");
+ char* Ptr = static_cast<char*>(static_cast<void *>(this));
+ Ptr += sizeof(DesignatedInitExpr);
+ reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx] = E;
+ }
+
+ /// \brief Replaces the designator at index @p Idx with the series
+ /// of designators in [First, Last).
+ void ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First,
+ const Designator *Last);
+
+ virtual SourceRange getSourceRange() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DesignatedInitExprClass;
+ }
+ static bool classof(const DesignatedInitExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \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, false, 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;
+ }
+ static bool classof(const ImplicitValueInitExpr *) { return true; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange();
+ }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+class ParenListExpr : public Expr {
+ Stmt **Exprs;
+ unsigned NumExprs;
+ SourceLocation LParenLoc, RParenLoc;
+
+protected:
+ virtual void DoDestroy(ASTContext& C);
+
+public:
+ ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
+ unsigned numexprs, SourceLocation rparenloc);
+
+ ~ParenListExpr() {}
+
+ /// \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); }
+
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(LParenLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ParenListExprClass;
+ }
+ static bool classof(const ParenListExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+//===----------------------------------------------------------------------===//
+// 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, Expr *base, IdentifierInfo &accessor,
+ SourceLocation loc)
+ : Expr(ExtVectorElementExprClass, ty, base->isTypeDependent(),
+ base->isValueDependent()),
+ 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(llvm::SmallVectorImpl<unsigned> &Elts) const;
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getBase()->getLocStart(), 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;
+ }
+ static bool classof(const ExtVectorElementExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+/// 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;
+ bool HasBlockDeclRefExprs;
+public:
+ BlockExpr(BlockDecl *BD, QualType ty, bool hasBlockDeclRefExprs)
+ : Expr(BlockExprClass, ty, ty->isDependentType(), false),
+ TheBlock(BD), HasBlockDeclRefExprs(hasBlockDeclRefExprs) {}
+
+ /// \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();
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getCaretLocation(), getBody()->getLocEnd());
+ }
+
+ /// getFunctionType - Return the underlying function type for this block.
+ const FunctionType *getFunctionType() const;
+
+ /// hasBlockDeclRefExprs - Return true iff the block has BlockDeclRefExpr
+ /// inside of the block that reference values outside the block.
+ bool hasBlockDeclRefExprs() const { return HasBlockDeclRefExprs; }
+ void setHasBlockDeclRefExprs(bool BDRE) { HasBlockDeclRefExprs = BDRE; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == BlockExprClass;
+ }
+ static bool classof(const BlockExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// BlockDeclRefExpr - A reference to a declared variable, function,
+/// enum, etc.
+class BlockDeclRefExpr : public Expr {
+ ValueDecl *D;
+ SourceLocation Loc;
+ bool IsByRef : 1;
+ bool ConstQualAdded : 1;
+public:
+ // FIXME: Fix type/value dependence!
+ BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef,
+ bool constAdded = false)
+ : Expr(BlockDeclRefExprClass, t, false, false), D(d), Loc(l), IsByRef(ByRef),
+ ConstQualAdded(constAdded) {}
+
+ // \brief Build an empty reference to a declared variable in a
+ // block.
+ explicit BlockDeclRefExpr(EmptyShell Empty)
+ : Expr(BlockDeclRefExprClass, Empty) { }
+
+ ValueDecl *getDecl() { return D; }
+ const ValueDecl *getDecl() const { return D; }
+ void setDecl(ValueDecl *VD) { D = VD; }
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ bool isByRef() const { return IsByRef; }
+ void setByRef(bool BR) { IsByRef = BR; }
+
+ bool isConstQualAdded() const { return ConstQualAdded; }
+ void setConstQualAdded(bool C) { ConstQualAdded = C; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == BlockDeclRefExprClass;
+ }
+ static bool classof(const BlockDeclRefExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h
new file mode 100644
index 0000000..0c493f3
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h
@@ -0,0 +1,2262 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Expr interface and subclasses for C++ expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPRCXX_H
+#define LLVM_CLANG_AST_EXPRCXX_H
+
+#include "clang/Basic/TypeTraits.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/AST/TemplateBase.h"
+
+namespace clang {
+
+ class CXXConstructorDecl;
+ class CXXDestructorDecl;
+ class CXXMethodDecl;
+ class CXXTemporary;
+ class TemplateArgumentListInfo;
+
+//===--------------------------------------------------------------------===//
+// 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;
+
+public:
+ CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
+ Expr **args, unsigned numargs, QualType t,
+ SourceLocation operatorloc)
+ : CallExpr(C, CXXOperatorCallExprClass, fn, args, numargs, t, operatorloc),
+ Operator(Op) {}
+ explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
+ CallExpr(C, CXXOperatorCallExprClass, Empty) { }
+
+
+ /// getOperator - Returns the kind of overloaded operator that this
+ /// expression refers to.
+ OverloadedOperatorKind getOperator() const { return Operator; }
+ void setOperator(OverloadedOperatorKind Kind) { Operator = Kind; }
+
+ /// getOperatorLoc - 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(); }
+
+ virtual SourceRange getSourceRange() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXOperatorCallExprClass;
+ }
+ static bool classof(const CXXOperatorCallExpr *) { return true; }
+};
+
+/// CXXMemberCallExpr - 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, Expr **args, unsigned numargs,
+ QualType t, SourceLocation rparenloc)
+ : CallExpr(C, CXXMemberCallExprClass, fn, args, numargs, t, rparenloc) {}
+
+ CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
+ : CallExpr(C, CXXMemberCallExprClass, Empty) { }
+
+ /// getImplicitObjectArgument - Retrieves the implicit object
+ /// argument for the member call. For example, in "x.f(5)", this
+ /// operation would return "x".
+ Expr *getImplicitObjectArgument();
+
+ virtual SourceRange getSourceRange() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXMemberCallExprClass;
+ }
+ static bool classof(const CXXMemberCallExpr *) { return true; }
+};
+
+/// CXXNamedCastExpr - Abstract class common to all of the C++ "named"
+/// casts, @c static_cast, @c dynamic_cast, @c reinterpret_cast, or @c
+/// const_cast.
+///
+/// This abstract class is inherited by all of the classes
+/// representing "named" casts, e.g., CXXStaticCastExpr,
+/// CXXDynamicCastExpr, CXXReinterpretCastExpr, and CXXConstCastExpr.
+class CXXNamedCastExpr : public ExplicitCastExpr {
+private:
+ SourceLocation Loc; // the location of the casting op
+
+protected:
+ CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ SourceLocation l)
+ : ExplicitCastExpr(SC, ty, kind, op, BasePath, writtenTy), Loc(l) {}
+
+ explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell)
+ : ExplicitCastExpr(SC, Shell) { }
+
+public:
+ const char *getCastName() const;
+
+ /// \brief Retrieve the location of the cast operator keyword, e.g.,
+ /// "static_cast".
+ SourceLocation getOperatorLoc() const { return Loc; }
+ void setOperatorLoc(SourceLocation L) { Loc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd());
+ }
+ static bool classof(const Stmt *T) {
+ switch (T->getStmtClass()) {
+ case CXXStaticCastExprClass:
+ case CXXDynamicCastExprClass:
+ case CXXReinterpretCastExprClass:
+ case CXXConstCastExprClass:
+ return true;
+ default:
+ return false;
+ }
+ }
+ static bool classof(const CXXNamedCastExpr *) { return true; }
+};
+
+/// CXXStaticCastExpr - 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 : public CXXNamedCastExpr {
+public:
+ CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ SourceLocation l)
+ : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, BasePath, writtenTy, l) {}
+
+ explicit CXXStaticCastExpr(EmptyShell Empty)
+ : CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXStaticCastExprClass;
+ }
+ static bool classof(const CXXStaticCastExpr *) { return true; }
+};
+
+/// CXXDynamicCastExpr - A C++ @c dynamic_cast expression
+/// (C++ [expr.dynamic.cast]), which may perform a run-time check to
+/// determine how to perform the type cast.
+///
+/// This expression node represents a dynamic cast, e.g.,
+/// @c dynamic_cast<Derived*>(BasePtr).
+class CXXDynamicCastExpr : public CXXNamedCastExpr {
+public:
+ CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ SourceLocation l)
+ : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, BasePath,
+ writtenTy, l) {}
+
+ explicit CXXDynamicCastExpr(EmptyShell Empty)
+ : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXDynamicCastExprClass;
+ }
+ static bool classof(const CXXDynamicCastExpr *) { return true; }
+};
+
+/// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++
+/// [expr.reinterpret.cast]), which provides a differently-typed view
+/// of a value but performs no actual work at run time.
+///
+/// This expression node represents a reinterpret cast, e.g.,
+/// @c reinterpret_cast<int>(VoidPtr).
+class CXXReinterpretCastExpr : public CXXNamedCastExpr {
+public:
+ CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath,
+ TypeSourceInfo *writtenTy, SourceLocation l)
+ : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, BasePath,
+ writtenTy, l) {}
+
+ explicit CXXReinterpretCastExpr(EmptyShell Empty)
+ : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty) { }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXReinterpretCastExprClass;
+ }
+ static bool classof(const CXXReinterpretCastExpr *) { return true; }
+};
+
+/// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]),
+/// which can remove type qualifiers but does not change the underlying value.
+///
+/// This expression node represents a const cast, e.g.,
+/// @c const_cast<char*>(PtrToConstChar).
+class CXXConstCastExpr : public CXXNamedCastExpr {
+public:
+ CXXConstCastExpr(QualType ty, Expr *op, TypeSourceInfo *writtenTy,
+ SourceLocation l)
+ : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op,
+ CXXBaseSpecifierArray(), writtenTy, l) {}
+
+ explicit CXXConstCastExpr(EmptyShell Empty)
+ : CXXNamedCastExpr(CXXConstCastExprClass, Empty) { }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXConstCastExprClass;
+ }
+ static bool classof(const CXXConstCastExpr *) { return true; }
+};
+
+/// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal.
+///
+class CXXBoolLiteralExpr : public Expr {
+ bool Value;
+ SourceLocation Loc;
+public:
+ CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
+ Expr(CXXBoolLiteralExprClass, Ty, false, false), Value(val), Loc(l) {}
+
+ explicit CXXBoolLiteralExpr(EmptyShell Empty)
+ : Expr(CXXBoolLiteralExprClass, Empty) { }
+
+ bool getValue() const { return Value; }
+ void setValue(bool V) { Value = V; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXBoolLiteralExprClass;
+ }
+ static bool classof(const CXXBoolLiteralExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXNullPtrLiteralExpr - [C++0x 2.14.7] C++ Pointer Literal
+class CXXNullPtrLiteralExpr : public Expr {
+ SourceLocation Loc;
+public:
+ CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
+ Expr(CXXNullPtrLiteralExprClass, Ty, false, false), Loc(l) {}
+
+ explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
+ : Expr(CXXNullPtrLiteralExprClass, Empty) { }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXNullPtrLiteralExprClass;
+ }
+ static bool classof(const CXXNullPtrLiteralExpr *) { return true; }
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXTypeidExpr - A C++ @c typeid expression (C++ [expr.typeid]), which gets
+/// the 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,
+ // 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(Operand), Range(R) { }
+
+ CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
+ : Expr(CXXTypeidExprClass, Ty,
+ // 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(Operand), Range(R) { }
+
+ CXXTypeidExpr(EmptyShell Empty, bool isExpr)
+ : Expr(CXXTypeidExprClass, Empty) {
+ if (isExpr)
+ Operand = (Expr*)0;
+ else
+ Operand = (TypeSourceInfo*)0;
+ }
+
+ 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() 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;
+ }
+
+ virtual SourceRange getSourceRange() const { return Range; }
+ void setSourceRange(SourceRange R) { Range = R; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXTypeidExprClass;
+ }
+ static bool classof(const CXXTypeidExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXThisExpr - Represents the "this" expression in C++, which 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,
+ // 'this' is type-dependent if the class type of the enclosing
+ // member function is dependent (C++ [temp.dep.expr]p2)
+ Type->isDependentType(), Type->isDependentType()),
+ Loc(L), Implicit(isImplicit) { }
+
+ CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ bool isImplicit() const { return Implicit; }
+ void setImplicit(bool I) { Implicit = I; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXThisExprClass;
+ }
+ static bool classof(const CXXThisExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXThrowExpr - [C++ 15] C++ Throw Expression. This handles
+/// 'throw' and 'throw' assignment-expression. When
+/// assignment-expression isn't present, Op will be null.
+///
+class CXXThrowExpr : public Expr {
+ Stmt *Op;
+ SourceLocation ThrowLoc;
+public:
+ // Ty is the void type which is used as the result type of the
+ // exepression. The l is the location of the throw keyword. expr
+ // can by null, if the optional expression to throw isn't present.
+ CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
+ Expr(CXXThrowExprClass, Ty, false, false), Op(expr), ThrowLoc(l) {}
+ CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
+
+ const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
+ Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
+ void setSubExpr(Expr *E) { Op = E; }
+
+ SourceLocation getThrowLoc() const { return ThrowLoc; }
+ void setThrowLoc(SourceLocation L) { ThrowLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ if (getSubExpr() == 0)
+ return SourceRange(ThrowLoc, ThrowLoc);
+ return SourceRange(ThrowLoc, getSubExpr()->getSourceRange().getEnd());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXThrowExprClass;
+ }
+ static bool classof(const CXXThrowExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXDefaultArgExpr - 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 : public 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;
+
+protected:
+ CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
+ : Expr(SC,
+ param->hasUnparsedDefaultArg()
+ ? param->getType().getNonReferenceType()
+ : param->getDefaultArg()->getType(),
+ false, false),
+ Param(param, false), Loc(Loc) { }
+
+ CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
+ Expr *SubExpr)
+ : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) {
+ *reinterpret_cast<Expr **>(this + 1) = SubExpr;
+ }
+
+protected:
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
+
+
+ // Param is the parameter whose default argument is used by this
+ // expression.
+ static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc,
+ ParmVarDecl *Param) {
+ return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param);
+ }
+
+ // Param is the parameter whose default argument is used by this
+ // expression, and SubExpr is the expression that will actually be used.
+ static CXXDefaultArgExpr *Create(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(); }
+
+ /// isExprStored - Return true if this expression owns the expression.
+ bool isExprStored() const { return Param.getInt(); }
+
+ // Retrieve the actual argument to the function call.
+ const Expr *getExpr() const {
+ if (Param.getInt())
+ return *reinterpret_cast<Expr const * const*> (this + 1);
+ return getParam()->getDefaultArg();
+ }
+ Expr *getExpr() {
+ if (Param.getInt())
+ return *reinterpret_cast<Expr **> (this + 1);
+ return getParam()->getDefaultArg();
+ }
+
+ void setExpr(Expr *E) {
+ Param.setInt(true);
+ Param.setPointer((ParmVarDecl*)E);
+ }
+
+ /// \brief Retrieve the location where this default argument was actually
+ /// used.
+ SourceLocation getUsedLocation() const { return Loc; }
+ void setUsedLocation(SourceLocation L) { Loc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ // Default argument expressions have no representation in the
+ // source, so they have an empty source range.
+ return SourceRange();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXDefaultArgExprClass;
+ }
+ static bool classof(const CXXDefaultArgExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXTemporary - Represents a C++ temporary.
+class CXXTemporary {
+ /// Destructor - The destructor that needs to be called.
+ const CXXDestructorDecl *Destructor;
+
+ CXXTemporary(const CXXDestructorDecl *destructor)
+ : Destructor(destructor) { }
+ ~CXXTemporary() { }
+
+public:
+ static CXXTemporary *Create(ASTContext &C,
+ const CXXDestructorDecl *Destructor);
+
+ void Destroy(ASTContext &Ctx);
+
+ const CXXDestructorDecl *getDestructor() const { return Destructor; }
+};
+
+/// \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(), false, false),
+ Temp(temp), SubExpr(subexpr) { }
+ ~CXXBindTemporaryExpr() { }
+
+protected:
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ CXXBindTemporaryExpr(EmptyShell Empty)
+ : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
+
+ static CXXBindTemporaryExpr *Create(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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SubExpr->getSourceRange();
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXBindTemporaryExprClass;
+ }
+ static bool classof(const CXXBindTemporaryExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXBindReferenceExpr - Represents binding an expression to a reference.
+/// In the example:
+///
+/// const int &i = 10;
+///
+/// a bind reference expression is inserted to indicate that 10 is bound to
+/// a reference, and that a temporary needs to be created to hold the
+/// value.
+class CXXBindReferenceExpr : public Expr {
+ // SubExpr - The expression being bound.
+ Stmt *SubExpr;
+
+ // ExtendsLifetime - Whether binding this reference extends the lifetime of
+ // the expression being bound. FIXME: Add C++ reference.
+ bool ExtendsLifetime;
+
+ /// RequiresTemporaryCopy - Whether binding the subexpression requires a
+ /// temporary copy.
+ bool RequiresTemporaryCopy;
+
+ CXXBindReferenceExpr(Expr *subexpr, bool ExtendsLifetime,
+ bool RequiresTemporaryCopy)
+ : Expr(CXXBindReferenceExprClass, subexpr->getType(), false, false),
+ SubExpr(subexpr), ExtendsLifetime(ExtendsLifetime),
+ RequiresTemporaryCopy(RequiresTemporaryCopy) { }
+ ~CXXBindReferenceExpr() { }
+
+protected:
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ static CXXBindReferenceExpr *Create(ASTContext &C, Expr *SubExpr,
+ bool ExtendsLifetime,
+ bool RequiresTemporaryCopy);
+
+ const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+ Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+ void setSubExpr(Expr *E) { SubExpr = E; }
+
+ virtual SourceRange getSourceRange() const {
+ return SubExpr->getSourceRange();
+ }
+
+ /// requiresTemporaryCopy - Whether binding the subexpression requires a
+ /// temporary copy.
+ bool requiresTemporaryCopy() const { return RequiresTemporaryCopy; }
+
+ // extendsLifetime - Whether binding this reference extends the lifetime of
+ // the expression being bound. FIXME: Add C++ reference.
+ bool extendsLifetime() { return ExtendsLifetime; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXBindReferenceExprClass;
+ }
+ static bool classof(const CXXBindReferenceExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXConstructExpr - Represents a call to a C++ constructor.
+class CXXConstructExpr : public Expr {
+public:
+ enum ConstructionKind {
+ CK_Complete,
+ CK_NonVirtualBase,
+ CK_VirtualBase
+ };
+
+private:
+ CXXConstructorDecl *Constructor;
+
+ SourceLocation Loc;
+ bool Elidable : 1;
+ bool ZeroInitialization : 1;
+ unsigned ConstructKind : 2;
+ Stmt **Args;
+ unsigned NumArgs;
+
+protected:
+ CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
+ SourceLocation Loc,
+ CXXConstructorDecl *d, bool elidable,
+ Expr **args, unsigned numargs,
+ bool ZeroInitialization = false,
+ ConstructionKind ConstructKind = CK_Complete);
+ ~CXXConstructExpr() { }
+
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ /// \brief Construct an empty C++ construction expression that will store
+ /// \p numargs arguments.
+ CXXConstructExpr(EmptyShell Empty, ASTContext &C, unsigned numargs);
+
+ static CXXConstructExpr *Create(ASTContext &C, QualType T,
+ SourceLocation Loc,
+ CXXConstructorDecl *D, bool Elidable,
+ Expr **Args, unsigned NumArgs,
+ bool ZeroInitialization = false,
+ ConstructionKind ConstructKind = CK_Complete);
+
+
+ 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 this construction first requires
+ /// zero-initialization before the initializer is called.
+ bool requiresZeroInitialization() const { return ZeroInitialization; }
+ void setRequiresZeroInitialization(bool ZeroInit) {
+ ZeroInitialization = ZeroInit;
+ }
+
+ /// \brief Determines 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;
+
+ 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() const { return reinterpret_cast<Expr **>(Args); }
+ unsigned getNumArgs() const { return NumArgs; }
+
+ /// getArg - 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]);
+ }
+
+ /// setArg - Set the specified argument.
+ void setArg(unsigned Arg, Expr *ArgExpr) {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ Args[Arg] = ArgExpr;
+ }
+
+ virtual SourceRange getSourceRange() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXConstructExprClass ||
+ T->getStmtClass() == CXXTemporaryObjectExprClass;
+ }
+ static bool classof(const CXXConstructExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXFunctionalCastExpr - Represents an explicit C++ type conversion
+/// that uses "functional" notion (C++ [expr.type.conv]). Example: @c
+/// x = int(0.5);
+class CXXFunctionalCastExpr : public ExplicitCastExpr {
+ SourceLocation TyBeginLoc;
+ SourceLocation RParenLoc;
+public:
+ CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy,
+ SourceLocation tyBeginLoc, CastKind kind,
+ Expr *castExpr, CXXBaseSpecifierArray BasePath,
+ SourceLocation rParenLoc)
+ : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr,
+ BasePath, writtenTy),
+ TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+
+ explicit CXXFunctionalCastExpr(EmptyShell Shell)
+ : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell) { }
+
+ SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+ void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(TyBeginLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXFunctionalCastExprClass;
+ }
+ static bool classof(const CXXFunctionalCastExpr *) { return true; }
+};
+
+/// @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. If N == 0 but no
+/// constructor will be called (because the functional cast is
+/// performing a value-initialized an object whose class type has no
+/// user-declared constructors), CXXZeroInitValueExpr will represent
+/// the functional cast. Finally, 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 {
+ SourceLocation TyBeginLoc;
+ SourceLocation RParenLoc;
+
+public:
+ CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons,
+ QualType writtenTy, SourceLocation tyBeginLoc,
+ Expr **Args,unsigned NumArgs,
+ SourceLocation rParenLoc,
+ bool ZeroInitialization = false);
+
+ ~CXXTemporaryObjectExpr() { }
+
+ SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(TyBeginLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXTemporaryObjectExprClass;
+ }
+ static bool classof(const CXXTemporaryObjectExpr *) { return true; }
+};
+
+/// CXXZeroInitValueExpr - [C++ 5.2.3p2]
+/// Expression "T()" which creates a value-initialized rvalue of type
+/// T, which is either a non-class type or a class type without any
+/// user-defined constructors.
+///
+class CXXZeroInitValueExpr : public Expr {
+ SourceLocation TyBeginLoc;
+ SourceLocation RParenLoc;
+
+public:
+ CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc,
+ SourceLocation rParenLoc ) :
+ Expr(CXXZeroInitValueExprClass, ty, false, false),
+ TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+ explicit CXXZeroInitValueExpr(EmptyShell Shell)
+ : Expr(CXXZeroInitValueExprClass, Shell) { }
+
+ SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+
+ void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ /// @brief Whether this initialization expression was
+ /// implicitly-generated.
+ bool isImplicit() const {
+ return TyBeginLoc.isInvalid() && RParenLoc.isInvalid();
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(TyBeginLoc, RParenLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXZeroInitValueExprClass;
+ }
+ static bool classof(const CXXZeroInitValueExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXNewExpr - A new expression for memory allocation and constructor calls,
+/// e.g: "new CXXNewExpr(foo)".
+class CXXNewExpr : public Expr {
+ // Was the usage ::new, i.e. is the global new to be used?
+ bool GlobalNew : 1;
+ // Was the form (type-id) used? Otherwise, it was new-type-id.
+ bool ParenTypeId : 1;
+ // Is there an initializer? If not, built-ins are uninitialized, else they're
+ // value-initialized.
+ bool Initializer : 1;
+ // Do we allocate an array? If so, the first SubExpr is the size expression.
+ bool Array : 1;
+ // The number of placement new arguments.
+ unsigned NumPlacementArgs : 14;
+ // The number of constructor arguments. This may be 1 even for non-class
+ // types; use the pseudo copy constructor.
+ unsigned NumConstructorArgs : 14;
+ // Contains an optional array size expression, any number of optional
+ // placement arguments, and any number of optional constructor arguments,
+ // in that order.
+ Stmt **SubExprs;
+ // Points to the allocation function used.
+ FunctionDecl *OperatorNew;
+ // Points to the deallocation function used in case of error. May be null.
+ FunctionDecl *OperatorDelete;
+ // Points to the constructor used. Cannot be null if AllocType is a record;
+ // it would still point at the default constructor (even an implicit one).
+ // Must be null for all other types.
+ CXXConstructorDecl *Constructor;
+
+ SourceLocation StartLoc;
+ SourceLocation EndLoc;
+
+public:
+ CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
+ Expr **placementArgs, unsigned numPlaceArgs, bool ParenTypeId,
+ Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
+ Expr **constructorArgs, unsigned numConsArgs,
+ FunctionDecl *operatorDelete, QualType ty,
+ SourceLocation startLoc, SourceLocation endLoc);
+ explicit CXXNewExpr(EmptyShell Shell)
+ : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
+
+ void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs,
+ unsigned numConsArgs);
+
+ virtual void DoDestroy(ASTContext &C);
+
+ QualType getAllocatedType() const {
+ assert(getType()->isPointerType());
+ return getType()->getAs<PointerType>()->getPointeeType();
+ }
+
+ FunctionDecl *getOperatorNew() const { return OperatorNew; }
+ void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
+ FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+ void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
+ CXXConstructorDecl *getConstructor() const { return Constructor; }
+ void setConstructor(CXXConstructorDecl *D) { Constructor = D; }
+
+ bool isArray() const { return Array; }
+ Expr *getArraySize() {
+ return Array ? cast<Expr>(SubExprs[0]) : 0;
+ }
+ const Expr *getArraySize() const {
+ return Array ? cast<Expr>(SubExprs[0]) : 0;
+ }
+
+ unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
+ Expr *getPlacementArg(unsigned i) {
+ assert(i < NumPlacementArgs && "Index out of range");
+ return cast<Expr>(SubExprs[Array + i]);
+ }
+ const Expr *getPlacementArg(unsigned i) const {
+ assert(i < NumPlacementArgs && "Index out of range");
+ return cast<Expr>(SubExprs[Array + i]);
+ }
+
+ bool isGlobalNew() const { return GlobalNew; }
+ void setGlobalNew(bool V) { GlobalNew = V; }
+ bool isParenTypeId() const { return ParenTypeId; }
+ void setParenTypeId(bool V) { ParenTypeId = V; }
+ bool hasInitializer() const { return Initializer; }
+ void setHasInitializer(bool V) { Initializer = V; }
+
+ unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
+ Expr *getConstructorArg(unsigned i) {
+ assert(i < NumConstructorArgs && "Index out of range");
+ return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
+ }
+ const Expr *getConstructorArg(unsigned i) const {
+ assert(i < NumConstructorArgs && "Index out of range");
+ return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
+ }
+
+ typedef ExprIterator arg_iterator;
+ typedef ConstExprIterator const_arg_iterator;
+
+ arg_iterator placement_arg_begin() {
+ return SubExprs + Array;
+ }
+ arg_iterator placement_arg_end() {
+ return SubExprs + Array + getNumPlacementArgs();
+ }
+ const_arg_iterator placement_arg_begin() const {
+ return SubExprs + Array;
+ }
+ const_arg_iterator placement_arg_end() const {
+ return SubExprs + Array + getNumPlacementArgs();
+ }
+
+ arg_iterator constructor_arg_begin() {
+ return SubExprs + Array + getNumPlacementArgs();
+ }
+ arg_iterator constructor_arg_end() {
+ return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+ }
+ const_arg_iterator constructor_arg_begin() const {
+ return SubExprs + Array + getNumPlacementArgs();
+ }
+ const_arg_iterator constructor_arg_end() const {
+ return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+ }
+
+ typedef Stmt **raw_arg_iterator;
+ raw_arg_iterator raw_arg_begin() { return SubExprs; }
+ raw_arg_iterator raw_arg_end() {
+ return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+ }
+ const_arg_iterator raw_arg_begin() const { return SubExprs; }
+ const_arg_iterator raw_arg_end() const { return constructor_arg_end(); }
+
+
+ SourceLocation getStartLoc() const { return StartLoc; }
+ void setStartLoc(SourceLocation L) { StartLoc = L; }
+ SourceLocation getEndLoc() const { return EndLoc; }
+ void setEndLoc(SourceLocation L) { EndLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(StartLoc, EndLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXNewExprClass;
+ }
+ static bool classof(const CXXNewExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXDeleteExpr - A delete expression for memory deallocation and destructor
+/// calls, e.g. "delete[] pArray".
+class CXXDeleteExpr : public Expr {
+ // 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;
+ // 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;
+public:
+ CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm,
+ FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
+ : Expr(CXXDeleteExprClass, ty, false, false), GlobalDelete(globalDelete),
+ ArrayForm(arrayForm), OperatorDelete(operatorDelete), Argument(arg),
+ Loc(loc) { }
+
+ bool isGlobalDelete() const { return GlobalDelete; }
+ bool isArrayForm() const { return ArrayForm; }
+
+ FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+
+ Expr *getArgument() { return cast<Expr>(Argument); }
+ const Expr *getArgument() const { return cast<Expr>(Argument); }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(Loc, Argument->getLocEnd());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXDeleteExprClass;
+ }
+ static bool classof(const CXXDeleteExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \brief Structure used to store 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.
+ NestedNameSpecifier *Qualifier;
+
+ /// \brief The source range that covers the nested-name-specifier, if
+ /// present.
+ SourceRange QualifierRange;
+
+ /// \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;
+
+public:
+ CXXPseudoDestructorExpr(ASTContext &Context,
+ Expr *Base, bool isArrow, SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ TypeSourceInfo *ScopeType,
+ SourceLocation ColonColonLoc,
+ SourceLocation TildeLoc,
+ PseudoDestructorTypeStorage DestroyedType)
+ : Expr(CXXPseudoDestructorExprClass,
+ Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0,
+ false, 0, false,
+ false, 0, 0,
+ FunctionType::ExtInfo())),
+ /*isTypeDependent=*/(Base->isTypeDependent() ||
+ (DestroyedType.getTypeSourceInfo() &&
+ DestroyedType.getTypeSourceInfo()->getType()->isDependentType())),
+ /*isValueDependent=*/Base->isValueDependent()),
+ Base(static_cast<Stmt *>(Base)), IsArrow(isArrow),
+ OperatorLoc(OperatorLoc), Qualifier(Qualifier),
+ QualifierRange(QualifierRange),
+ ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc),
+ DestroyedType(DestroyedType) { }
+
+ void setBase(Expr *E) { Base = E; }
+ 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 Qualifier != 0; }
+
+ /// \brief If the member name was qualified, retrieves the source range of
+ /// the nested-name-specifier that precedes the member name. Otherwise,
+ /// returns an empty source range.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief If the member name was qualified, retrieves the
+ /// nested-name-specifier that precedes the member name. Otherwise, returns
+ /// NULL.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Determine whether this pseudo-destructor expression was written
+ /// using an '->' (otherwise, it used a '.').
+ bool isArrow() const { return IsArrow; }
+ void setArrow(bool A) { IsArrow = A; }
+
+ /// \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();
+ }
+
+ virtual SourceRange getSourceRange() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXPseudoDestructorExprClass;
+ }
+ static bool classof(const CXXPseudoDestructorExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// UnaryTypeTraitExpr - A GCC or MS unary type trait, as used in the
+/// implementation of TR1/C++0x type trait templates.
+/// Example:
+/// __is_pod(int) == true
+/// __is_enum(std::string) == false
+class UnaryTypeTraitExpr : public Expr {
+ /// UTT - The trait.
+ UnaryTypeTrait UTT;
+
+ /// Loc - The location of the type trait keyword.
+ SourceLocation Loc;
+
+ /// RParen - The location of the closing paren.
+ SourceLocation RParen;
+
+ /// QueriedType - The type we're testing.
+ QualType QueriedType;
+
+public:
+ UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt, QualType queried,
+ SourceLocation rparen, QualType ty)
+ : Expr(UnaryTypeTraitExprClass, ty, false, queried->isDependentType()),
+ UTT(utt), Loc(loc), RParen(rparen), QueriedType(queried) { }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
+
+ UnaryTypeTrait getTrait() const { return UTT; }
+
+ QualType getQueriedType() const { return QueriedType; }
+
+ bool EvaluateTrait(ASTContext&) const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnaryTypeTraitExprClass;
+ }
+ static bool classof(const UnaryTypeTraitExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \brief A reference to an overloaded function set, either an
+/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
+class OverloadExpr : public Expr {
+ /// 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;
+
+ /// The common name of these declarations.
+ DeclarationName Name;
+
+ /// The scope specifier, if any.
+ NestedNameSpecifier *Qualifier;
+
+ /// The source range of the scope specifier.
+ SourceRange QualifierRange;
+
+ /// The location of the name.
+ SourceLocation NameLoc;
+
+ /// True if the name was a template-id.
+ bool HasExplicitTemplateArgs;
+
+protected:
+ OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool Dependent,
+ NestedNameSpecifier *Qualifier, SourceRange QRange,
+ DeclarationName Name, SourceLocation NameLoc,
+ bool HasTemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+public:
+ /// Computes whether an unresolved lookup on the given declarations
+ /// and optional template arguments is type- and value-dependent.
+ static bool ComputeDependence(UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End,
+ const TemplateArgumentListInfo *Args);
+
+ /// Finds the overloaded expression in the given expression of
+ /// OverloadTy.
+ ///
+ /// \return the expression (which must be there) and true if it is
+ /// within an address-of operator.
+ static llvm::PointerIntPair<OverloadExpr*,1> find(Expr *E) {
+ assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
+
+ bool op = false;
+ E = E->IgnoreParens();
+ if (isa<UnaryOperator>(E))
+ op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
+ return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
+ }
+
+ /// 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);
+ }
+
+ /// Gets the number of declarations in the unresolved set.
+ unsigned getNumDecls() const { return NumResults; }
+
+ /// Gets the name looked up.
+ DeclarationName getName() const { return Name; }
+ void setName(DeclarationName N) { Name = N; }
+
+ /// Gets the location of the name.
+ SourceLocation getNameLoc() const { return NameLoc; }
+ void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
+
+ /// Fetches the nested-name qualifier, if one was given.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// Fetches the range of the nested-name qualifier.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Determines whether this expression had an explicit
+ /// template argument list, e.g. f<int>.
+ bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below
+
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
+ }
+
+ ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+ if (hasExplicitTemplateArgs())
+ return &getExplicitTemplateArgs();
+ return 0;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedLookupExprClass ||
+ T->getStmtClass() == UnresolvedMemberExprClass;
+ }
+ static bool classof(const OverloadExpr *) { return true; }
+};
+
+/// \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 : public OverloadExpr {
+ /// 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;
+
+ UnresolvedLookupExpr(ASTContext &C, QualType T, bool Dependent,
+ CXXRecordDecl *NamingClass,
+ NestedNameSpecifier *Qualifier, SourceRange QRange,
+ DeclarationName Name, SourceLocation NameLoc,
+ bool RequiresADL, bool Overloaded, bool HasTemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End)
+ : OverloadExpr(UnresolvedLookupExprClass, C, T, Dependent, Qualifier,
+ QRange, Name, NameLoc, HasTemplateArgs, Begin, End),
+ RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
+ {}
+
+public:
+ static UnresolvedLookupExpr *Create(ASTContext &C,
+ bool Dependent,
+ CXXRecordDecl *NamingClass,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool ADL, bool Overloaded,
+ UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End) {
+ return new(C) UnresolvedLookupExpr(C,
+ Dependent ? C.DependentTy : C.OverloadTy,
+ Dependent, NamingClass,
+ Qualifier, QualifierRange,
+ Name, NameLoc, ADL, Overloaded, false,
+ Begin, End);
+ }
+
+ static UnresolvedLookupExpr *Create(ASTContext &C,
+ bool Dependent,
+ CXXRecordDecl *NamingClass,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool ADL,
+ const TemplateArgumentListInfo &Args,
+ UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End);
+
+ /// 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; }
+
+ // Note that, inconsistently with the explicit-template-argument AST
+ // nodes, users are *forbidden* from calling these methods on objects
+ // without explicit template arguments.
+
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
+ }
+
+ /// Gets a reference to the explicit template argument list.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
+ }
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs().copyInto(List);
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs().LAngleLoc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs().RAngleLoc;
+ }
+
+ TemplateArgumentLoc const *getTemplateArgs() const {
+ return getExplicitTemplateArgs().getTemplateArgs();
+ }
+
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs().NumTemplateArgs;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ SourceRange Range(getNameLoc());
+ if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
+ if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
+ return Range;
+ }
+
+ virtual StmtIterator child_begin();
+ virtual StmtIterator child_end();
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedLookupExprClass;
+ }
+ static bool classof(const UnresolvedLookupExpr *) { return true; }
+};
+
+/// \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 on 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 : public Expr {
+ /// The name of the entity we will be referencing.
+ DeclarationName Name;
+
+ /// Location of the name of the declaration we're referencing.
+ SourceLocation Loc;
+
+ /// QualifierRange - The source range that covers the
+ /// nested-name-specifier.
+ SourceRange QualifierRange;
+
+ /// \brief The nested-name-specifier that qualifies this unresolved
+ /// declaration name.
+ NestedNameSpecifier *Qualifier;
+
+ /// \brief Whether the name includes explicit template arguments.
+ bool HasExplicitTemplateArgs;
+
+ DependentScopeDeclRefExpr(QualType T,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool HasExplicitTemplateArgs)
+ : Expr(DependentScopeDeclRefExprClass, T, true, true),
+ Name(Name), Loc(NameLoc),
+ QualifierRange(QualifierRange), Qualifier(Qualifier),
+ HasExplicitTemplateArgs(HasExplicitTemplateArgs)
+ {}
+
+public:
+ static DependentScopeDeclRefExpr *Create(ASTContext &C,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo *TemplateArgs = 0);
+
+ /// \brief Retrieve the name that this expression refers to.
+ DeclarationName getDeclName() const { return Name; }
+
+ /// \brief Retrieve the location of the name within the expression.
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Retrieve the source range of the nested-name-specifier.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Retrieve the nested-name-specifier that qualifies this
+ /// declaration.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// Determines whether this lookup had explicit template arguments.
+ bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+
+ // Note that, inconsistently with the explicit-template-argument AST
+ // nodes, users are *forbidden* from calling these methods on objects
+ // without explicit template arguments.
+
+ /// Gets a reference to the explicit template argument list.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
+ }
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs().copyInto(List);
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs().LAngleLoc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs().RAngleLoc;
+ }
+
+ TemplateArgumentLoc const *getTemplateArgs() const {
+ return getExplicitTemplateArgs().getTemplateArgs();
+ }
+
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs().NumTemplateArgs;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ SourceRange Range(QualifierRange.getBegin(), getLocation());
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ return Range;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DependentScopeDeclRefExprClass;
+ }
+ static bool classof(const DependentScopeDeclRefExpr *) { return true; }
+
+ virtual StmtIterator child_begin();
+ virtual StmtIterator child_end();
+};
+
+class CXXExprWithTemporaries : public Expr {
+ Stmt *SubExpr;
+
+ CXXTemporary **Temps;
+ unsigned NumTemps;
+
+ CXXExprWithTemporaries(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps,
+ unsigned NumTemps);
+ ~CXXExprWithTemporaries();
+
+protected:
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ CXXExprWithTemporaries(EmptyShell Empty)
+ : Expr(CXXExprWithTemporariesClass, Empty),
+ SubExpr(0), Temps(0), NumTemps(0) {}
+
+ static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr,
+ CXXTemporary **Temps,
+ unsigned NumTemps);
+
+ unsigned getNumTemporaries() const { return NumTemps; }
+ void setNumTemporaries(ASTContext &C, unsigned N);
+
+ CXXTemporary *getTemporary(unsigned i) {
+ assert(i < NumTemps && "Index out of range");
+ return Temps[i];
+ }
+ const CXXTemporary *getTemporary(unsigned i) const {
+ return const_cast<CXXExprWithTemporaries*>(this)->getTemporary(i);
+ }
+ void setTemporary(unsigned i, CXXTemporary *T) {
+ assert(i < NumTemps && "Index out of range");
+ Temps[i] = T;
+ }
+
+ Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+ const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+ void setSubExpr(Expr *E) { SubExpr = E; }
+
+ virtual SourceRange getSourceRange() const {
+ return SubExpr->getSourceRange();
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXExprWithTemporariesClass;
+ }
+ static bool classof(const CXXExprWithTemporaries *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \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 \c T(a1, a2, ..., aN),
+/// where \c T is some type and \c a1, a2, ..., aN are values, and
+/// either \C T is a dependent type or one or more of the \c a'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 : public Expr {
+ /// \brief The starting location of the type
+ SourceLocation TyBeginLoc;
+
+ /// \brief The type being constructed.
+ QualType 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(SourceLocation TyBegin,
+ QualType T,
+ SourceLocation LParenLoc,
+ Expr **Args,
+ unsigned NumArgs,
+ SourceLocation RParenLoc);
+
+public:
+ static CXXUnresolvedConstructExpr *Create(ASTContext &C,
+ SourceLocation TyBegin,
+ QualType T,
+ SourceLocation LParenLoc,
+ Expr **Args,
+ unsigned NumArgs,
+ SourceLocation RParenLoc);
+
+ /// \brief Retrieve the source location where the type begins.
+ SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+ void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+
+ /// \brief Retrieve the type that is being constructed, as specified
+ /// in the source code.
+ QualType getTypeAsWritten() const { return Type; }
+ void setTypeAsWritten(QualType T) { Type = T; }
+
+ /// \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 reinterpret_cast<Expr**>(this + 1); }
+ arg_iterator arg_end() { return arg_begin() + NumArgs; }
+
+ typedef const Expr* const * const_arg_iterator;
+ const_arg_iterator arg_begin() const {
+ return reinterpret_cast<const Expr* const *>(this + 1);
+ }
+ 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);
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(TyBeginLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXUnresolvedConstructExprClass;
+ }
+ static bool classof(const CXXUnresolvedConstructExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \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 : public Expr {
+ /// \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 explicitly-specified template
+ /// arguments.
+ bool HasExplicitTemplateArgs : 1;
+
+ /// \brief The location of the '->' or '.' operator.
+ SourceLocation OperatorLoc;
+
+ /// \brief The nested-name-specifier that precedes the member name, if any.
+ NestedNameSpecifier *Qualifier;
+
+ /// \brief The source range covering the nested name specifier.
+ SourceRange QualifierRange;
+
+ /// \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 Qualifier and QualifierRange, 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
+ DeclarationName Member;
+
+ /// \brief The location of the member name.
+ SourceLocation MemberLoc;
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+ assert(HasExplicitTemplateArgs);
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+ return const_cast<CXXDependentScopeMemberExpr *>(this)
+ ->getExplicitTemplateArgumentList();
+ }
+
+ CXXDependentScopeMemberExpr(ASTContext &C,
+ Expr *Base, QualType BaseType, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *FirstQualifierFoundInScope,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs);
+
+public:
+ CXXDependentScopeMemberExpr(ASTContext &C,
+ Expr *Base, QualType BaseType,
+ bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *FirstQualifierFoundInScope,
+ DeclarationName Member,
+ SourceLocation MemberLoc)
+ : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
+ Base(Base), BaseType(BaseType), IsArrow(IsArrow),
+ HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc),
+ Qualifier(Qualifier), QualifierRange(QualifierRange),
+ FirstQualifierFoundInScope(FirstQualifierFoundInScope),
+ Member(Member), MemberLoc(MemberLoc) { }
+
+ static CXXDependentScopeMemberExpr *
+ Create(ASTContext &C,
+ Expr *Base, QualType BaseType, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *FirstQualifierFoundInScope,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs);
+
+ /// \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 { return Base == 0; }
+
+ /// \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);
+ }
+ void setBase(Expr *E) { Base = E; }
+
+ QualType getBaseType() const { return BaseType; }
+
+ /// \brief Determine whether this member expression used the '->'
+ /// operator; otherwise, it used the '.' operator.
+ bool isArrow() const { return IsArrow; }
+ void setArrow(bool A) { IsArrow = A; }
+
+ /// \brief Retrieve the location of the '->' or '.' operator.
+ SourceLocation getOperatorLoc() const { return OperatorLoc; }
+ void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+ /// \brief Retrieve the nested-name-specifier that qualifies the member
+ /// name.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Retrieve the source range covering the nested-name-specifier
+ /// that qualifies the member name.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \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.
+ DeclarationName getMember() const { return Member; }
+ void setMember(DeclarationName N) { Member = N; }
+
+ // \brief Retrieve the location of the name of the member that this
+ // expression refers to.
+ SourceLocation getMemberLoc() const { return MemberLoc; }
+ void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+
+ /// \brief Determines whether this member expression actually had a C++
+ /// template argument list explicitly specified, e.g., x.f<int>.
+ bool hasExplicitTemplateArgs() const {
+ return HasExplicitTemplateArgs;
+ }
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ assert(HasExplicitTemplateArgs);
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
+
+ /// \brief Retrieve the location of the left angle bracket following the
+ /// member name ('<'), if any.
+ SourceLocation getLAngleLoc() const {
+ assert(HasExplicitTemplateArgs);
+ return getExplicitTemplateArgumentList()->LAngleLoc;
+ }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ assert(HasExplicitTemplateArgs);
+ return getExplicitTemplateArgumentList()->getTemplateArgs();
+ }
+
+ /// \brief Retrieve the number of template arguments provided as part of this
+ /// template-id.
+ unsigned getNumTemplateArgs() const {
+ assert(HasExplicitTemplateArgs);
+ return getExplicitTemplateArgumentList()->NumTemplateArgs;
+ }
+
+ /// \brief Retrieve the location of the right angle bracket following the
+ /// template arguments ('>').
+ SourceLocation getRAngleLoc() const {
+ assert(HasExplicitTemplateArgs);
+ return getExplicitTemplateArgumentList()->RAngleLoc;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ SourceRange Range;
+ if (!isImplicitAccess())
+ Range.setBegin(Base->getSourceRange().getBegin());
+ else if (getQualifier())
+ Range.setBegin(getQualifierRange().getBegin());
+ else
+ Range.setBegin(MemberLoc);
+
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ else
+ Range.setEnd(MemberLoc);
+ return Range;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXDependentScopeMemberExprClass;
+ }
+ static bool classof(const CXXDependentScopeMemberExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \brief Represents a C++ member access expression for which lookup
+/// produced a set of overloaded functions.
+///
+/// The member access may be explicit or implicit:
+/// struct A {
+/// int a, b;
+/// int explicitAccess() { return this->a + this->A::b; }
+/// int implicitAccess() { return a + A::b; }
+/// };
+///
+/// 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 : public OverloadExpr {
+ /// \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;
+
+ UnresolvedMemberExpr(ASTContext &C, QualType T, bool Dependent,
+ bool HasUnresolvedUsing,
+ Expr *Base, QualType BaseType, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+public:
+ static UnresolvedMemberExpr *
+ Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing,
+ Expr *Base, QualType BaseType, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+ /// \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 { return Base == 0; }
+
+ /// \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);
+ }
+ void setBase(Expr *E) { Base = E; }
+
+ QualType getBaseType() const { return BaseType; }
+
+ /// \brief Determine whether this member expression used the '->'
+ /// operator; otherwise, it used the '.' operator.
+ bool isArrow() const { return IsArrow; }
+ void setArrow(bool A) { IsArrow = A; }
+
+ /// \brief Retrieve the location of the '->' or '.' operator.
+ SourceLocation getOperatorLoc() const { return OperatorLoc; }
+ void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+ /// \brief Retrieves the naming class of this lookup.
+ CXXRecordDecl *getNamingClass() const;
+
+ /// \brief Retrieve the name of the member that this expression
+ /// refers to.
+ DeclarationName getMemberName() const { return getName(); }
+ void setMemberName(DeclarationName N) { setName(N); }
+
+ // \brief Retrieve the location of the name of the member that this
+ // expression refers to.
+ SourceLocation getMemberLoc() const { return getNameLoc(); }
+ void setMemberLoc(SourceLocation L) { setNameLoc(L); }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name.
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
+ }
+
+ /// \brief Copies the template arguments into the given structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs().copyInto(List);
+ }
+
+ /// \brief Retrieve the location of the left angle bracket following
+ /// the member name ('<').
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs().LAngleLoc;
+ }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return getExplicitTemplateArgs().getTemplateArgs();
+ }
+
+ /// \brief Retrieve the number of template arguments provided as
+ /// part of this template-id.
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs().NumTemplateArgs;
+ }
+
+ /// \brief Retrieve the location of the right angle bracket
+ /// following the template arguments ('>').
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs().RAngleLoc;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ SourceRange Range;
+ if (!isImplicitAccess())
+ Range.setBegin(Base->getSourceRange().getBegin());
+ else if (getQualifier())
+ Range.setBegin(getQualifierRange().getBegin());
+ else
+ Range.setBegin(getMemberLoc());
+
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ else
+ Range.setEnd(getMemberLoc());
+ return Range;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedMemberExprClass;
+ }
+ static bool classof(const UnresolvedMemberExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() {
+ if (isa<UnresolvedLookupExpr>(this))
+ return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs();
+ else
+ return cast<UnresolvedMemberExpr>(this)->getExplicitTemplateArgs();
+}
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h
new file mode 100644
index 0000000..8a09f4e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h
@@ -0,0 +1,815 @@
+//===--- 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/Expr.h"
+#include "clang/Basic/IdentifierTable.h"
+
+namespace clang {
+ class IdentifierInfo;
+ class ASTContext;
+ class ObjCMethodDecl;
+ class ObjCPropertyDecl;
+
+/// 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, 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtLoc, String->getLocEnd());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCStringLiteralClass;
+ }
+ static bool classof(const ObjCStringLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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, EncodedType->getType()->isDependentType(),
+ EncodedType->getType()->isDependentType()),
+ 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;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtLoc, RParenLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCEncodeExprClass;
+ }
+ static bool classof(const ObjCEncodeExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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, 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtLoc, 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;
+ }
+ static bool classof(const ObjCSelectorExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCProtocolExpr used for protocol expression in Objective-C. This is used
+/// as: @protocol(foo), as in:
+/// obj conformsToProtocol:@protocol(foo)]
+/// The return type is "Protocol*".
+class ObjCProtocolExpr : public Expr {
+ ObjCProtocolDecl *TheProtocol;
+ SourceLocation AtLoc, RParenLoc;
+public:
+ ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
+ SourceLocation at, SourceLocation rp)
+ : Expr(ObjCProtocolExprClass, T, false, false), TheProtocol(protocol),
+ AtLoc(at), RParenLoc(rp) {}
+ explicit ObjCProtocolExpr(EmptyShell Empty)
+ : Expr(ObjCProtocolExprClass, Empty) {}
+
+ ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
+ void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
+
+ SourceLocation getAtLoc() const { return AtLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setAtLoc(SourceLocation L) { AtLoc = L; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtLoc, RParenLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCProtocolExprClass;
+ }
+ static bool classof(const ObjCProtocolExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
+class ObjCIvarRefExpr : public Expr {
+ class ObjCIvarDecl *D;
+ SourceLocation Loc;
+ Stmt *Base;
+ 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, Expr *base,
+ bool arrow = false, bool freeIvar = false) :
+ Expr(ObjCIvarRefExprClass, t, /*TypeDependent=*/false,
+ base->isValueDependent()), D(d),
+ Loc(l), Base(base), 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return isFreeIvar() ? SourceRange(Loc)
+ : SourceRange(getBase()->getLocStart(), Loc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCIvarRefExprClass;
+ }
+ static bool classof(const ObjCIvarRefExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
+/// property.
+///
+class ObjCPropertyRefExpr : public Expr {
+private:
+ ObjCPropertyDecl *AsProperty;
+ SourceLocation IdLoc;
+ Stmt *Base;
+public:
+ ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
+ SourceLocation l, Expr *base)
+ : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false,
+ base->isValueDependent()),
+ AsProperty(PD), IdLoc(l), Base(base) {
+ }
+
+ explicit ObjCPropertyRefExpr(EmptyShell Empty)
+ : Expr(ObjCPropertyRefExprClass, Empty) {}
+
+ ObjCPropertyDecl *getProperty() const { return AsProperty; }
+ void setProperty(ObjCPropertyDecl *D) { AsProperty = D; }
+
+ const Expr *getBase() const { return cast<Expr>(Base); }
+ Expr *getBase() { return cast<Expr>(Base); }
+ void setBase(Expr *base) { Base = base; }
+
+ SourceLocation getLocation() const { return IdLoc; }
+ void setLocation(SourceLocation L) { IdLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getBase()->getLocStart(), IdLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCPropertyRefExprClass;
+ }
+ static bool classof(const ObjCPropertyRefExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCImplicitSetterGetterRefExpr - A dot-syntax expression to access two
+/// methods; one to set a value to an 'ivar' (Setter) and the other to access
+/// an 'ivar' (Setter).
+/// An example for use of this AST is:
+/// @code
+/// @interface Test { }
+/// - (Test *)crash;
+/// - (void)setCrash: (Test*)value;
+/// @end
+/// void foo(Test *p1, Test *p2)
+/// {
+/// p2.crash = p1.crash; // Uses ObjCImplicitSetterGetterRefExpr AST
+/// }
+/// @endcode
+class ObjCImplicitSetterGetterRefExpr : public Expr {
+ /// Setter - Setter method user declared for setting its 'ivar' to a value
+ ObjCMethodDecl *Setter;
+ /// Getter - Getter method user declared for accessing 'ivar' it controls.
+ ObjCMethodDecl *Getter;
+ /// Location of the member in the dot syntax notation. This is location
+ /// of the getter method.
+ SourceLocation MemberLoc;
+ // FIXME: Swizzle these into a single pointer.
+ Stmt *Base;
+ ObjCInterfaceDecl *InterfaceDecl;
+ /// Location of the receiver class in the dot syntax notation
+ /// used to call a class method setter/getter.
+ SourceLocation ClassLoc;
+
+public:
+ ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter,
+ QualType t,
+ ObjCMethodDecl *setter,
+ SourceLocation l, Expr *base)
+ : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false,
+ base->isValueDependent()),
+ Setter(setter), Getter(getter), MemberLoc(l), Base(base),
+ InterfaceDecl(0), ClassLoc(SourceLocation()) {
+ }
+ ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter,
+ QualType t,
+ ObjCMethodDecl *setter,
+ SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL)
+ : Expr(ObjCImplicitSetterGetterRefExprClass, t, false, false),
+ Setter(setter), Getter(getter), MemberLoc(l), Base(0), InterfaceDecl(C),
+ ClassLoc(CL) {
+ }
+ explicit ObjCImplicitSetterGetterRefExpr(EmptyShell Empty)
+ : Expr(ObjCImplicitSetterGetterRefExprClass, Empty){}
+
+ ObjCMethodDecl *getGetterMethod() const { return Getter; }
+ ObjCMethodDecl *getSetterMethod() const { return Setter; }
+ ObjCInterfaceDecl *getInterfaceDecl() const { return InterfaceDecl; }
+ void setGetterMethod(ObjCMethodDecl *D) { Getter = D; }
+ void setSetterMethod(ObjCMethodDecl *D) { Setter = D; }
+ void setInterfaceDecl(ObjCInterfaceDecl *D) { InterfaceDecl = D; }
+
+ virtual SourceRange getSourceRange() const {
+ if (Base)
+ return SourceRange(getBase()->getLocStart(), MemberLoc);
+ return SourceRange(ClassLoc, MemberLoc);
+ }
+ const Expr *getBase() const { return cast_or_null<Expr>(Base); }
+ Expr *getBase() { return cast_or_null<Expr>(Base); }
+ void setBase(Expr *base) { Base = base; }
+
+ SourceLocation getLocation() const { return MemberLoc; }
+ void setLocation(SourceLocation L) { MemberLoc = L; }
+ SourceLocation getClassLoc() const { return ClassLoc; }
+ void setClassLoc(SourceLocation L) { ClassLoc = L; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCImplicitSetterGetterRefExprClass;
+ }
+ static bool classof(const ObjCImplicitSetterGetterRefExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \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:
+///
+class ObjCMessageExpr : public Expr {
+ /// \brief The number of arguments in the message send, not
+ /// including the receiver.
+ unsigned NumArgs : 16;
+
+ /// \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 : 8;
+
+ /// \brief When the message expression is a send to 'super', this is
+ /// the location of the 'super' keyword.
+ SourceLocation SuperLoc;
+
+ /// \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;
+
+ /// \brief The source locations of the open and close square
+ /// brackets ('[' and ']', respectively).
+ SourceLocation LBracLoc, RBracLoc;
+
+ ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
+ : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0),
+ HasMethod(0), SelectorOrMethod(0) { }
+
+ ObjCMessageExpr(QualType T,
+ SourceLocation LBracLoc,
+ SourceLocation SuperLoc,
+ bool IsInstanceSuper,
+ QualType SuperType,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+ ObjCMessageExpr(QualType T,
+ SourceLocation LBracLoc,
+ TypeSourceInfo *Receiver,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+ ObjCMessageExpr(QualType T,
+ SourceLocation LBracLoc,
+ Expr *Receiver,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+
+ /// \brief Retrieve the pointer value of the message receiver.
+ void *getReceiverPointer() const {
+ return *const_cast<void **>(
+ reinterpret_cast<const void * const*>(this + 1));
+ }
+
+ /// \brief Set the pointer value of the message receiver.
+ void setReceiverPointer(void *Value) {
+ *reinterpret_cast<void **>(this + 1) = Value;
+ }
+
+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 LBrac 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 NumArgs The number of arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+ SourceLocation LBracLoc,
+ SourceLocation SuperLoc,
+ bool IsInstanceSuper,
+ QualType SuperType,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+
+ /// \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 LBrac 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 NumArgs The number of arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+ SourceLocation LBracLoc,
+ TypeSourceInfo *Receiver,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+
+ /// \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 LBrac 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 NumArgs The number of arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+ SourceLocation LBracLoc,
+ Expr *Receiver,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+
+ /// \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(ASTContext &Context, unsigned NumArgs);
+
+ /// \brief Determine the kind of receiver that this message is being
+ /// sent to.
+ ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
+
+ /// \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 receiver of an instance message.
+ ///
+ /// \brief Returns the object expression 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 0;
+ }
+ 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 0;
+ }
+
+ 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 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 0;
+ }
+
+ ObjCMethodDecl *getMethodDecl() {
+ if (HasMethod)
+ return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
+
+ return 0;
+ }
+
+ void setMethodDecl(ObjCMethodDecl *MD) {
+ HasMethod = true;
+ SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
+ }
+
+ /// \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.
+ Stmt **getArgs() {
+ return reinterpret_cast<Stmt **>(this + 1) + 1;
+ }
+ const Stmt * const *getArgs() const {
+ return reinterpret_cast<const Stmt * const *>(this + 1) + 1;
+ }
+
+ /// getArg - Return the specified argument.
+ Expr *getArg(unsigned Arg) {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return cast<Expr>(getArgs()[Arg]);
+ }
+ const Expr *getArg(unsigned Arg) const {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return cast<Expr>(getArgs()[Arg]);
+ }
+ /// setArg - Set the specified argument.
+ void setArg(unsigned Arg, Expr *ArgExpr) {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ getArgs()[Arg] = ArgExpr;
+ }
+
+ SourceLocation getLeftLoc() const { return LBracLoc; }
+ SourceLocation getRightLoc() const { return RBracLoc; }
+
+ void setLeftLoc(SourceLocation L) { LBracLoc = L; }
+ void setRightLoc(SourceLocation L) { RBracLoc = L; }
+
+ void setSourceRange(SourceRange R) {
+ LBracLoc = R.getBegin();
+ RBracLoc = R.getEnd();
+ }
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(LBracLoc, RBracLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCMessageExprClass;
+ }
+ static bool classof(const ObjCMessageExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+ typedef ExprIterator arg_iterator;
+ typedef ConstExprIterator const_arg_iterator;
+
+ arg_iterator arg_begin() { return getArgs(); }
+ arg_iterator arg_end() { return getArgs() + NumArgs; }
+ const_arg_iterator arg_begin() const { return getArgs(); }
+ const_arg_iterator arg_end() const { return getArgs() + NumArgs; }
+};
+
+/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
+/// which refers to the object on which the current method is executing.
+///
+/// FIXME: This class is intended for removal, once its remaining
+/// clients have been altered to represent "super" internally.
+class ObjCSuperExpr : public Expr {
+ SourceLocation Loc;
+public:
+ ObjCSuperExpr(SourceLocation L, QualType Type)
+ : Expr(ObjCSuperExprClass, Type, false, false), Loc(L) { }
+ explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {}
+
+ SourceLocation getLoc() const { return Loc; }
+ void setLoc(SourceLocation L) { Loc = L; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCSuperExprClass;
+ }
+ static bool classof(const ObjCSuperExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
+/// (similiar 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;
+
+ /// IsArrow - True if this is "X->F", false if this is "X.F".
+ bool IsArrow;
+public:
+ ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
+ : Expr(ObjCIsaExprClass, ty, /*TypeDependent=*/false,
+ base->isValueDependent()),
+ Base(base), IsaMemberLoc(l), 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
+ }
+
+ virtual SourceLocation getExprLoc() const { return IsaMemberLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCIsaExprClass;
+ }
+ static bool classof(const ObjCIsaExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h
new file mode 100644
index 0000000..79e4451
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h
@@ -0,0 +1,192 @@
+//===--- 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.x
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <vector>
+namespace clang {
+
+class ASTConsumer;
+class Decl;
+class DeclContext;
+class ExternalSemaSource; // layering violation required for downcasting
+class Stmt;
+
+/// \brief The deserialized representation of a set of declarations
+/// with the same name that are visible in a given context.
+struct VisibleDeclaration {
+ /// \brief The name of the declarations.
+ DeclarationName Name;
+
+ /// \brief The ID numbers of all of the declarations with this name.
+ ///
+ /// These declarations have not necessarily been de-serialized.
+ llvm::SmallVector<unsigned, 4> Declarations;
+};
+
+/// \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 {
+ /// \brief Whether this AST source also provides information for
+ /// semantic analysis.
+ bool SemaSource;
+
+ friend class ExternalSemaSource;
+
+public:
+ ExternalASTSource() : SemaSource(false) { }
+
+ virtual ~ExternalASTSource();
+
+ /// \brief Resolve a type ID into a type, potentially building a new
+ /// type.
+ virtual QualType GetType(uint32_t ID) = 0;
+
+ /// \brief Resolve a declaration ID into a declaration, potentially
+ /// building a new declaration.
+ virtual Decl *GetDecl(uint32_t ID) = 0;
+
+ /// \brief Resolve a selector ID into a selector.
+ virtual Selector GetSelector(uint32_t ID) = 0;
+
+ /// \brief Returns the number of selectors known to the external AST
+ /// source.
+ virtual uint32_t GetNumKnownSelectors() = 0;
+
+ /// \brief Resolve the offset of a statement in the decl stream 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.
+ virtual Stmt *GetDeclStmt(uint64_t Offset) = 0;
+
+ /// \brief Read all of the declarations lexically stored in a
+ /// declaration context.
+ ///
+ /// \param DC The declaration context whose declarations will be
+ /// read.
+ ///
+ /// \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.
+ ///
+ /// \returns true if there was an error while reading the
+ /// declarations for this declaration context.
+ virtual bool ReadDeclsLexicallyInContext(DeclContext *DC,
+ llvm::SmallVectorImpl<uint32_t> &Decls) = 0;
+
+ /// \brief Read all of the declarations visible from a declaration
+ /// context.
+ ///
+ /// \param DC The declaration context whose visible declarations
+ /// will be read.
+ ///
+ /// \param Decls A vector of visible declaration structures,
+ /// providing the mapping from each name visible in the declaration
+ /// context to the declaration IDs of declarations with that name.
+ ///
+ /// \returns true if there was an error while reading the
+ /// declarations for this declaration context.
+ virtual bool ReadDeclsVisibleInContext(DeclContext *DC,
+ llvm::SmallVectorImpl<VisibleDeclaration> & Decls) = 0;
+
+ /// \brief Function that will be invoked when we begin parsing a new
+ /// translation unit involving this external AST source.
+ virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
+
+ /// \brief Print any statistics that have been gathered regarding
+ /// the external AST source.
+ virtual void PrintStats();
+};
+
+/// \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, T* (ExternalASTSource::*Get)(uint64_t 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.
+ operator bool() 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 pointer to a statement.
+typedef LazyOffsetPtr<Stmt, &ExternalASTSource::GetDeclStmt> LazyDeclStmtPtr;
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
diff --git a/contrib/llvm/tools/clang/include/clang/AST/FullExpr.h b/contrib/llvm/tools/clang/include/clang/AST/FullExpr.h
new file mode 100644
index 0000000..bb81bf0
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/FullExpr.h
@@ -0,0 +1,89 @@
+//===--- FullExpr.h - C++ full expression class -----------------*- 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 FullExpr interface, to be used for type safe handling
+// of full expressions.
+//
+// Full expressions are described in C++ [intro.execution]p12.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_FULLEXPR_H
+#define LLVM_CLANG_AST_FULLEXPR_H
+
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+ class ASTContext;
+ class CXXTemporary;
+ class Expr;
+
+class FullExpr {
+ struct ExprAndTemporaries {
+ Expr *SubExpr;
+
+ unsigned NumTemps;
+
+ typedef CXXTemporary** temps_iterator;
+
+ temps_iterator temps_begin() {
+ return reinterpret_cast<CXXTemporary **>(this + 1);
+ }
+ temps_iterator temps_end() {
+ return temps_begin() + NumTemps;
+ }
+ };
+
+ typedef llvm::PointerUnion<Expr *, ExprAndTemporaries *> SubExprTy;
+ SubExprTy SubExpr;
+
+ FullExpr() { }
+
+public:
+ static FullExpr Create(ASTContext &Context, Expr *SubExpr,
+ CXXTemporary **Temps, unsigned NumTemps);
+ void Destroy(ASTContext &Context);
+
+ Expr *getExpr() {
+ if (Expr *E = SubExpr.dyn_cast<Expr *>())
+ return E;
+
+ return SubExpr.get<ExprAndTemporaries *>()->SubExpr;
+ }
+
+ const Expr *getExpr() const {
+ return const_cast<FullExpr*>(this)->getExpr();
+ }
+
+ typedef CXXTemporary** temps_iterator;
+
+ temps_iterator temps_begin() {
+ if (ExprAndTemporaries *ET = SubExpr.dyn_cast<ExprAndTemporaries *>())
+ return ET->temps_begin();
+
+ return 0;
+ }
+ temps_iterator temps_end() {
+ if (ExprAndTemporaries *ET = SubExpr.dyn_cast<ExprAndTemporaries *>())
+ return ET->temps_end();
+
+ return 0;
+ }
+
+ void *getAsOpaquePtr() const { return SubExpr.getOpaqueValue(); }
+
+ static FullExpr getFromOpaquePtr(void *Ptr) {
+ FullExpr E;
+ E.SubExpr = SubExprTy::getFromOpaqueValue(Ptr);
+ return E;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/Makefile b/contrib/llvm/tools/clang/include/clang/AST/Makefile
new file mode 100644
index 0000000..a25977c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/Makefile
@@ -0,0 +1,13 @@
+LEVEL = ../../../../..
+BUILT_SOURCES = StmtNodes.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(LEVEL)/Makefile.common
+
+INPUT_TDS = $(PROJ_SRC_DIR)/StmtNodes.td
+
+$(ObjDir)/StmtNodes.inc.tmp : StmtNodes.td $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang statement node tables with tblgen"
+ $(Verb) $(TableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $<
+
diff --git a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h
new file mode 100644
index 0000000..1594b09
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h
@@ -0,0 +1,202 @@
+//===--- 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"
+
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace clang {
+
+class ASTContext;
+class NamespaceDecl;
+class IdentifierInfo;
+struct PrintingPolicy;
+class Type;
+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), or the global specifier ('::', must be the
+/// first specifier).
+class NestedNameSpecifier : public llvm::FoldingSetNode {
+ /// \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> 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 = 0,
+ /// \brief A namespace, stored as a Namespace*.
+ Namespace = 1,
+ /// \brief A type, stored as a Type*.
+ TypeSpec = 2,
+ /// \brief A type that was preceded by the 'template' keyword,
+ /// stored as a Type*.
+ TypeSpecWithTemplate = 3,
+ /// \brief The global specifier '::'. There is no stored value.
+ Global = 4
+ };
+
+private:
+ /// \brief Builds the global specifier.
+ NestedNameSpecifier() : Prefix(0, 0), Specifier(0) { }
+
+ /// \brief Copy constructor used internally to clone nested name
+ /// specifiers.
+ NestedNameSpecifier(const NestedNameSpecifier &Other)
+ : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
+ Specifier(Other.Specifier) {
+ }
+
+ NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not implement
+
+ /// \brief Either find or insert the given nested name specifier
+ /// mockup in the given context.
+ static NestedNameSpecifier *FindOrInsert(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(ASTContext &Context,
+ NestedNameSpecifier *Prefix,
+ IdentifierInfo *II);
+
+ /// \brief Builds a nested name specifier that names a namespace.
+ static NestedNameSpecifier *Create(ASTContext &Context,
+ NestedNameSpecifier *Prefix,
+ NamespaceDecl *NS);
+
+ /// \brief Builds a nested name specifier that names a type.
+ static NestedNameSpecifier *Create(ASTContext &Context,
+ NestedNameSpecifier *Prefix,
+ bool Template, 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(ASTContext &Context, IdentifierInfo *II);
+
+ /// \brief Returns the nested name specifier representing the global
+ /// scope.
+ static NestedNameSpecifier *GlobalSpecifier(ASTContext &Context);
+
+ /// \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 {
+ if (Specifier == 0)
+ return Global;
+ return (SpecifierKind)Prefix.getInt();
+ }
+
+ /// \brief Retrieve the identifier stored in this nested name
+ /// specifier.
+ IdentifierInfo *getAsIdentifier() const {
+ if (Prefix.getInt() == Identifier)
+ return (IdentifierInfo *)Specifier;
+
+ return 0;
+ }
+
+ /// \brief Retrieve the namespace stored in this nested name
+ /// specifier.
+ NamespaceDecl *getAsNamespace() const {
+ if (Prefix.getInt() == Namespace)
+ return (NamespaceDecl *)Specifier;
+
+ return 0;
+ }
+
+ /// \brief Retrieve the type stored in this nested name specifier.
+ Type *getAsType() const {
+ if (Prefix.getInt() == TypeSpec ||
+ Prefix.getInt() == TypeSpecWithTemplate)
+ return (Type *)Specifier;
+
+ return 0;
+ }
+
+ /// \brief Whether this nested name specifier refers to a dependent
+ /// type or not.
+ bool isDependent() const;
+
+ /// \brief Print this nested name specifier to the given output
+ /// stream.
+ void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddPointer(Prefix.getOpaqueValue());
+ ID.AddPointer(Specifier);
+ }
+
+ void Destroy(ASTContext &Context);
+
+ /// \brief Dump the nested name specifier to standard output to aid
+ /// in debugging.
+ void dump(const LangOptions &LO);
+};
+
+/// 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),
+ Diagnostic::ak_nestednamespec);
+ return DB;
+}
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h b/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h
new file mode 100644
index 0000000..f826e11
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h
@@ -0,0 +1,50 @@
+//===--- 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_PARENTMAP_H
+#define LLVM_CLANG_PARENTMAP_H
+
+namespace clang {
+class Stmt;
+class Expr;
+
+class ParentMap {
+ void* Impl;
+public:
+ ParentMap(Stmt* ASTRoot);
+ ~ParentMap();
+
+ Stmt *getParent(Stmt*) const;
+ Stmt *getParentIgnoreParens(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));
+ }
+
+ bool hasParent(Stmt* S) const {
+ return getParent(S) != 0;
+ }
+
+ bool isConsumedExpr(Expr *E) const;
+
+ bool isConsumedExpr(const Expr *E) const {
+ return isConsumedExpr(const_cast<Expr*>(E));
+ }
+};
+
+} // end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h
new file mode 100644
index 0000000..70d65d3
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h
@@ -0,0 +1,110 @@
+//===--- 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_PRETTY_PRINTER_H
+#define LLVM_CLANG_AST_PRETTY_PRINTER_H
+
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace clang {
+
+class Stmt;
+class TagDecl;
+class LangOptions;
+
+class PrinterHelper {
+public:
+ virtual ~PrinterHelper();
+ virtual bool handledStmt(Stmt* E, llvm::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)
+ : Indentation(2), LangOpts(LO), SuppressSpecifiers(false),
+ SuppressTag(false), SuppressScope(false),
+ Dump(false), ConstantArraySizeAsWritten(false),
+ AnonymousTagLocations(true) { }
+
+ /// \brief The number of spaces to use to indent each line.
+ unsigned Indentation : 8;
+
+ /// \brief What language we're printing.
+ const LangOptions &LangOpts;
+
+ /// \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 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 True when we are "dumping" rather than "pretty-printing",
+ /// where dumping involves printing the internal details of the AST
+ /// and pretty-printing involves printing something similar to
+ /// source code.
+ bool Dump : 1;
+
+ /// \brief Whether we should print the sizes of constant array expressions
+ /// as written in the sources.
+ ///
+ /// This flag is determines whether arrays 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;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h
new file mode 100644
index 0000000..2b3229e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h
@@ -0,0 +1,251 @@
+//===--- 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_LAYOUTINFO_H
+#define LLVM_CLANG_AST_LAYOUTINFO_H
+
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/DeclCXX.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 {
+ /// Size - Size of record in bits.
+ uint64_t Size;
+
+ /// DataSize - Size of record in bits without tail padding.
+ uint64_t DataSize;
+
+ /// FieldOffsets - Array of field offsets in bits.
+ uint64_t *FieldOffsets;
+
+ // Alignment - Alignment of record in bits.
+ unsigned Alignment;
+
+ // FieldCount - Number of fields.
+ unsigned FieldCount;
+
+public:
+ /// PrimaryBaseInfo - Contains info about a primary base.
+ struct PrimaryBaseInfo {
+ PrimaryBaseInfo() {}
+
+ PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual)
+ : Value(Base, Base && IsVirtual) {}
+
+ /// Value - Points to the primary base. The single-bit value
+ /// will be non-zero when the primary base is virtual.
+ llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Value;
+
+ /// getBase - Returns the primary base.
+ const CXXRecordDecl *getBase() const { return Value.getPointer(); }
+
+ /// isVirtual - Returns whether the primary base is virtual or not.
+ bool isVirtual() const { return Value.getInt(); }
+
+ friend bool operator==(const PrimaryBaseInfo &X, const PrimaryBaseInfo &Y) {
+ return X.Value == Y.Value;
+ }
+ };
+
+ /// primary_base_info_iterator - An iterator for iterating the primary base
+ /// class chain.
+ class primary_base_info_iterator {
+ /// Current - The current base class info.
+ PrimaryBaseInfo Current;
+
+ public:
+ primary_base_info_iterator() {}
+ primary_base_info_iterator(PrimaryBaseInfo Info) : Current(Info) {}
+
+ const PrimaryBaseInfo &operator*() const { return Current; }
+
+ primary_base_info_iterator& operator++() {
+ const CXXRecordDecl *RD = Current.getBase();
+ Current = RD->getASTContext().getASTRecordLayout(RD).getPrimaryBaseInfo();
+ return *this;
+ }
+
+ friend bool operator==(const primary_base_info_iterator &X,
+ const primary_base_info_iterator &Y) {
+ return X.Current == Y.Current;
+ }
+ friend bool operator!=(const primary_base_info_iterator &X,
+ const primary_base_info_iterator &Y) {
+ return !(X == Y);
+ }
+ };
+
+private:
+ /// CXXRecordLayoutInfo - Contains C++ specific layout information.
+ struct CXXRecordLayoutInfo {
+ /// NonVirtualSize - The non-virtual size (in bits) of an object, which is
+ /// the size of the object without virtual bases.
+ uint64_t NonVirtualSize;
+
+ /// NonVirtualAlign - The non-virtual alignment (in bits) of an object,
+ /// which is the alignment of the object without virtual bases.
+ uint64_t NonVirtualAlign;
+
+ /// 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.
+ uint64_t SizeOfLargestEmptySubobject;
+
+ /// PrimaryBase - The primary base info for this record.
+ PrimaryBaseInfo PrimaryBase;
+
+ /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
+ typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsetsMapTy;
+
+ /// BaseOffsets - Contains a map from base classes to their offset.
+ BaseOffsetsMapTy BaseOffsets;
+
+ /// VBaseOffsets - Contains a map from vbase classes to their offset.
+ BaseOffsetsMapTy 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(ASTContext &Ctx, uint64_t size, unsigned alignment,
+ unsigned datasize, const uint64_t *fieldoffsets,
+ unsigned fieldcount);
+
+ // Constructor for C++ records.
+ typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
+ ASTRecordLayout(ASTContext &Ctx,
+ uint64_t size, unsigned alignment, uint64_t datasize,
+ const uint64_t *fieldoffsets, unsigned fieldcount,
+ uint64_t nonvirtualsize, unsigned nonvirtualalign,
+ uint64_t SizeOfLargestEmptySubobject,
+ const CXXRecordDecl *PrimaryBase,
+ bool PrimaryBaseIsVirtual,
+ const BaseOffsetsMapTy& BaseOffsets,
+ const BaseOffsetsMapTy& VBaseOffsets);
+
+ ~ASTRecordLayout() {}
+
+ void Destroy(ASTContext &Ctx);
+
+ ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
+ void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
+public:
+
+ /// getAlignment - Get the record alignment in bits.
+ unsigned getAlignment() const { return Alignment; }
+
+ /// getSize - Get the record size in bits.
+ uint64_t 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 bits.
+ uint64_t getDataSize() const {
+ return DataSize;
+ }
+
+ /// getNonVirtualSize - Get the non-virtual size (in bits) of an object,
+ /// which is the size of the object without virtual bases.
+ uint64_t getNonVirtualSize() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return CXXInfo->NonVirtualSize;
+ }
+
+ /// getNonVirtualSize - Get the non-virtual alignment (in bits) of an object,
+ /// which is the alignment of the object without virtual bases.
+ unsigned getNonVirtualAlign() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return CXXInfo->NonVirtualAlign;
+ }
+
+ /// getPrimaryBaseInfo - Get the primary base info.
+ const PrimaryBaseInfo &getPrimaryBaseInfo() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return CXXInfo->PrimaryBase;
+ }
+
+ // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+ const CXXRecordDecl *getPrimaryBase() const {
+ return getPrimaryBaseInfo().getBase();
+ }
+
+ // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+ bool getPrimaryBaseWasVirtual() const {
+ return getPrimaryBaseInfo().isVirtual();
+ }
+
+ /// getBaseClassOffset - Get the offset, in bits, for the given base class.
+ uint64_t 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 bits, for the given base class.
+ uint64_t 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];
+ }
+
+ uint64_t getSizeOfLargestEmptySubobject() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+ return CXXInfo->SizeOfLargestEmptySubobject;
+ }
+
+ primary_base_info_iterator primary_base_begin() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return primary_base_info_iterator(getPrimaryBaseInfo());
+ }
+
+ primary_base_info_iterator primary_base_end() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return primary_base_info_iterator();
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h
new file mode 100644
index 0000000..07865e0
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -0,0 +1,768 @@
+//===--- 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 "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+#define DISPATCH(NAME, CLASS, Var) \
+return getDerived().Visit ## NAME(static_cast<CLASS*>(Var))
+
+// We use preprocessor meta-programming to generate the Visit*()
+// methods for all subclasses of Stmt, Decl, and Type. Some of the
+// generated definitions, however, need to be customized. The
+// meta-programming technique we use doesn't let us select which
+// methods to generate. Therefore we have to generate ALL of them in
+// a helper class RecursiveASTVisitorImpl, and override the ones we
+// don't like in a child class RecursiveASTVisitor (C++ doesn't allow
+// overriding a method in the same class).
+//
+// Do not use this class directly - use RecursiveASTVisitor instead.
+template<typename Derived>
+class RecursiveASTVisitorImpl {
+public:
+ /// \brief Return a reference to the derived class.
+ Derived &getDerived() { return *static_cast<Derived*>(this); }
+
+ /// \brief Recursively visit a statement or expression, by
+ /// dispatching to Visit*() based on the argument's dynamic type.
+ /// This is NOT meant to be overridden by a subclass.
+ ///
+ /// \returns true if the visitation was terminated early, false
+ /// otherwise (including when the argument is NULL).
+ bool Visit(Stmt *S);
+
+ /// \brief Recursively visit a type, by dispatching to
+ /// Visit*Type() based on the argument's getTypeClass() property.
+ /// This is NOT meant to be overridden by a subclass.
+ ///
+ /// \returns true if the visitation was terminated early, false
+ /// otherwise (including when the argument is a Null type).
+ bool Visit(QualType T);
+
+ /// \brief Recursively visit a declaration, by dispatching to
+ /// Visit*Decl() based on the argument's dynamic type. This is
+ /// NOT meant to be overridden by a subclass.
+ ///
+ /// \returns true if the visitation was terminated early, false
+ /// otherwise (including when the argument is NULL).
+ bool Visit(Decl *D);
+
+ /// \brief Recursively visit a C++ nested-name-specifier.
+ ///
+ /// \returns true if the visitation was terminated early, false otherwise.
+ bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+ /// \brief Recursively visit a template name.
+ ///
+ /// \returns true if the visitation was terminated early, false otherwise.
+ bool VisitTemplateName(TemplateName Template);
+
+ /// \brief Recursively visit a template argument.
+ ///
+ /// \returns true if the visitation was terminated early, false otherwise.
+ bool VisitTemplateArgument(const TemplateArgument &Arg);
+
+ /// \brief Recursively visit a set of template arguments.
+ ///
+ /// \returns true if the visitation was terminated early, false otherwise.
+ bool VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs);
+
+ // 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) \
+bool Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT, S); }
+#include "clang/AST/StmtNodes.inc"
+
+ // If the implementation doesn't implement binary operator methods, fall back
+ // on VisitBinaryOperator.
+#define BINOP_FALLBACK(NAME) \
+bool VisitBin ## NAME(BinaryOperator *S) { \
+DISPATCH(BinaryOperator, BinaryOperator, S); \
+}
+ 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) \
+bool VisitBin ## NAME(CompoundAssignOperator *S) { \
+DISPATCH(CompoundAssignOperator, CompoundAssignOperator, S); \
+}
+ 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) \
+bool VisitUnary ## NAME(UnaryOperator *S) { \
+DISPATCH(UnaryOperator, UnaryOperator, S); \
+}
+ 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(OffsetOf)
+#undef UNARYOP_FALLBACK
+
+ /// \brief Basis for statement and expression visitation, which
+ /// visits all of the substatements and subexpressions.
+ ///
+ /// The relation between Visit(Stmt *S) and this method is that
+ /// the former dispatches to Visit*() based on S's dynamic type,
+ /// which forwards the call up the inheritance chain until
+ /// reaching VisitStmt(), which then calls Visit() on each
+ /// substatement/subexpression.
+ bool VisitStmt(Stmt *S);
+
+ /// \brief Basis for type visitation, which by default does nothing.
+ ///
+ /// The relation between Visit(QualType T) and this method is
+ /// that the former dispatches to Visit*Type(), which forwards the
+ /// call up the inheritance chain until reaching VisitType().
+ bool VisitType(Type *T);
+
+#define TYPE(Class, Base) \
+ bool Visit##Class##Type(Class##Type *T);
+#include "clang/AST/TypeNodes.def"
+
+ /// \brief Basis for declaration and definition visitation, which
+ /// visits all of the subnodes.
+ ///
+ /// The relation between Visit(Decl *) and this method is that the
+ /// former dispatches to Visit*Decl(), which forwards the call up
+ /// the inheritance chain until reaching VisitDecl().
+ bool VisitDecl(Decl *D);
+
+#define DECL(Class, Base) \
+ bool Visit##Class##Decl(Class##Decl *D) { \
+ return getDerived().Visit##Base(D); \
+ }
+#define ABSTRACT_DECL(Class, Base) DECL(Class, Base)
+#include "clang/AST/DeclNodes.def"
+};
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::Visit(Stmt *S) {
+ if (!S)
+ return false;
+
+ // 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()) {
+ case BinaryOperator::PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator, S);
+ case BinaryOperator::PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator, S);
+ case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator, S);
+ case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator, S);
+ case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator, S);
+ case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator, S);
+ case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator, S);
+ case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator, S);
+ case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator, S);
+
+ case BinaryOperator::LT: DISPATCH(BinLT, BinaryOperator, S);
+ case BinaryOperator::GT: DISPATCH(BinGT, BinaryOperator, S);
+ case BinaryOperator::LE: DISPATCH(BinLE, BinaryOperator, S);
+ case BinaryOperator::GE: DISPATCH(BinGE, BinaryOperator, S);
+ case BinaryOperator::EQ: DISPATCH(BinEQ, BinaryOperator, S);
+ case BinaryOperator::NE: DISPATCH(BinNE, BinaryOperator, S);
+
+ case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator, S);
+ case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator, S);
+ case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator, S);
+ case BinaryOperator::LAnd: DISPATCH(BinLAnd, BinaryOperator, S);
+ case BinaryOperator::LOr : DISPATCH(BinLOr, BinaryOperator, S);
+ case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator, S);
+ case BinaryOperator::MulAssign:
+ DISPATCH(BinMulAssign, CompoundAssignOperator, S);
+ case BinaryOperator::DivAssign:
+ DISPATCH(BinDivAssign, CompoundAssignOperator, S);
+ case BinaryOperator::RemAssign:
+ DISPATCH(BinRemAssign, CompoundAssignOperator, S);
+ case BinaryOperator::AddAssign:
+ DISPATCH(BinAddAssign, CompoundAssignOperator, S);
+ case BinaryOperator::SubAssign:
+ DISPATCH(BinSubAssign, CompoundAssignOperator, S);
+ case BinaryOperator::ShlAssign:
+ DISPATCH(BinShlAssign, CompoundAssignOperator, S);
+ case BinaryOperator::ShrAssign:
+ DISPATCH(BinShrAssign, CompoundAssignOperator, S);
+ case BinaryOperator::AndAssign:
+ DISPATCH(BinAndAssign, CompoundAssignOperator, S);
+ case BinaryOperator::OrAssign:
+ DISPATCH(BinOrAssign, CompoundAssignOperator, S);
+ case BinaryOperator::XorAssign:
+ DISPATCH(BinXorAssign, CompoundAssignOperator, S);
+ case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator, S);
+ }
+ } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+ switch (UnOp->getOpcode()) {
+ case UnaryOperator::PostInc: DISPATCH(UnaryPostInc, UnaryOperator, S);
+ case UnaryOperator::PostDec: DISPATCH(UnaryPostDec, UnaryOperator, S);
+ case UnaryOperator::PreInc: DISPATCH(UnaryPreInc, UnaryOperator, S);
+ case UnaryOperator::PreDec: DISPATCH(UnaryPreDec, UnaryOperator, S);
+ case UnaryOperator::AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator, S);
+ case UnaryOperator::Deref: DISPATCH(UnaryDeref, UnaryOperator, S);
+ case UnaryOperator::Plus: DISPATCH(UnaryPlus, UnaryOperator, S);
+ case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator, S);
+ case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator, S);
+ case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator, S);
+ case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator, S);
+ case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator, S);
+ case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator, S);
+ case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator, S);
+ }
+ }
+
+ // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+ switch (S->getStmtClass()) {
+ case Stmt::NoStmtClass: break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) \
+case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+ }
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::Visit(QualType T) {
+ if (T.isNull())
+ return false;
+
+ switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Base)
+#define TYPE(Class, Base) \
+ case Type::Class: DISPATCH(Class##Type, Class##Type, T.getTypePtr());
+#include "clang/AST/TypeNodes.def"
+ }
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::Visit(Decl *D) {
+ if (!D)
+ return false;
+
+ switch (D->getKind()) {
+#define ABSTRACT_DECL(Class, Base)
+#define DECL(Class, Base) \
+ case Decl::Class: DISPATCH(Class##Decl, Class##Decl, D);
+#include "clang/AST/DeclNodes.def"
+ }
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitNestedNameSpecifier(
+ NestedNameSpecifier *NNS) {
+ if (NNS->getPrefix() &&
+ getDerived().VisitNestedNameSpecifier(NNS->getPrefix()))
+ return true;
+
+ switch (NNS->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::Global:
+ return false;
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ return Visit(QualType(NNS->getAsType(), 0));
+ }
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTemplateName(TemplateName Template) {
+ if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+ return DTN->getQualifier() &&
+ getDerived().VisitNestedNameSpecifier(DTN->getQualifier());
+
+ if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+ return getDerived().VisitNestedNameSpecifier(QTN->getQualifier());
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArgument(
+ const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ return false;
+
+ case TemplateArgument::Type:
+ return Visit(Arg.getAsType());
+
+ case TemplateArgument::Template:
+ return getDerived().VisitTemplateName(Arg.getAsTemplate());
+
+ case TemplateArgument::Expression:
+ return getDerived().Visit(Arg.getAsExpr());
+
+ case TemplateArgument::Pack:
+ return getDerived().VisitTemplateArguments(Arg.pack_begin(),
+ Arg.pack_size());
+ }
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArguments(
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ for (unsigned I = 0; I != NumArgs; ++I)
+ if (getDerived().VisitTemplateArgument(Args[I]))
+ return true;
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitStmt(Stmt *Node) {
+ for (Stmt::child_iterator C = Node->child_begin(), CEnd = Node->child_end();
+ C != CEnd; ++C) {
+ if (Visit(*C))
+ return true;
+ }
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitType(Type *T) {
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitBuiltinType(BuiltinType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitComplexType(ComplexType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitPointerType(PointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitBlockPointerType(
+ BlockPointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitReferenceType(ReferenceType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitLValueReferenceType(
+ LValueReferenceType *T) {
+ return getDerived().VisitReferenceType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitRValueReferenceType(
+ RValueReferenceType *T) {
+ return getDerived().VisitReferenceType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitMemberPointerType(
+ MemberPointerType *T) {
+ if (Visit(QualType(T->getClass(), 0)) || Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitArrayType(ArrayType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitConstantArrayType(
+ ConstantArrayType *T) {
+ return getDerived().VisitArrayType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitIncompleteArrayType(
+ IncompleteArrayType *T) {
+ return getDerived().VisitArrayType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitVariableArrayType(
+ VariableArrayType *T) {
+ if (Visit(T->getSizeExpr()))
+ return true;
+
+ return getDerived().VisitArrayType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedArrayType(
+ DependentSizedArrayType *T) {
+ if (T->getSizeExpr() && Visit(T->getSizeExpr()))
+ return true;
+
+ return getDerived().VisitArrayType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedExtVectorType(
+ DependentSizedExtVectorType *T) {
+ if ((T->getSizeExpr() && Visit(T->getSizeExpr())) ||
+ Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitVectorType(VectorType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitExtVectorType(ExtVectorType *T) {
+ return getDerived().VisitVectorType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitFunctionType(FunctionType *T) {
+ if (Visit(T->getResultType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitFunctionNoProtoType(
+ FunctionNoProtoType *T) {
+ return getDerived().VisitFunctionType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitFunctionProtoType(
+ FunctionProtoType *T) {
+ for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
+ AEnd = T->arg_type_end();
+ A != AEnd; ++A) {
+ if (Visit(*A))
+ return true;
+ }
+
+ for (FunctionProtoType::exception_iterator E = T->exception_begin(),
+ EEnd = T->exception_end();
+ E != EEnd; ++E) {
+ if (Visit(*E))
+ return true;
+ }
+
+ return getDerived().VisitFunctionType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitUnresolvedUsingType(
+ UnresolvedUsingType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTypedefType(TypedefType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfExprType(TypeOfExprType *T) {
+ if (Visit(T->getUnderlyingExpr()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfType(TypeOfType *T) {
+ if (Visit(T->getUnderlyingType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDecltypeType(DecltypeType *T) {
+ if (Visit(T->getUnderlyingExpr()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTagType(TagType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitRecordType(RecordType *T) {
+ return getDerived().VisitTagType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitEnumType(EnumType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTemplateTypeParmType(
+ TemplateTypeParmType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitSubstTemplateTypeParmType(
+ SubstTemplateTypeParmType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTemplateSpecializationType(
+ TemplateSpecializationType *T) {
+ if (getDerived().VisitTemplateName(T->getTemplateName()) ||
+ getDerived().VisitTemplateArguments(T->getArgs(), T->getNumArgs()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitInjectedClassNameType(
+ InjectedClassNameType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitElaboratedType(ElaboratedType *T) {
+ if (T->getQualifier() &&
+ getDerived().VisitNestedNameSpecifier(T->getQualifier()))
+ return true;
+ if (Visit(T->getNamedType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDependentNameType(
+ DependentNameType *T) {
+ if (T->getQualifier() &&
+ getDerived().VisitNestedNameSpecifier(T->getQualifier()))
+ return true;
+
+ if (T->getTemplateId() &&
+ getDerived().VisitTemplateSpecializationType(
+ const_cast<TemplateSpecializationType *>(T->getTemplateId())))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitObjCInterfaceType(
+ ObjCInterfaceType *T) {
+ return getDerived().VisitObjCObjectType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectType(ObjCObjectType *T) {
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (T->getBaseType().getTypePtr() != T)
+ if (Visit(T->getBaseType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectPointerType(
+ ObjCObjectPointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDecl(Decl *D) {
+ if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
+ for (DeclContext::decl_iterator Child = DC->decls_begin(),
+ ChildEnd = DC->decls_end();
+ Child != ChildEnd; ++Child)
+ if (Visit(*Child))
+ return true;
+
+ return false;
+ }
+
+ return false;
+}
+
+/// \brief A visitor that recursively walks the entire Clang AST.
+///
+/// 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 Visit*
+/// methods (except Visit()) for declaration, type, statement,
+/// expression, or other AST nodes where the visitor should customize
+/// behavior. Returning "true" from one of these overridden functions
+/// will abort the entire traversal. An overridden Visit* method
+/// will not descend further into the AST for that node unless
+/// Base::Visit* is called.
+template<typename Derived>
+class RecursiveASTVisitor : public RecursiveASTVisitorImpl<Derived> {
+ typedef RecursiveASTVisitorImpl<Derived> Impl;
+public:
+ typedef RecursiveASTVisitor<Derived> Base;
+
+ bool VisitDeclaratorDecl(DeclaratorDecl *D);
+ bool VisitFunctionDecl(FunctionDecl *D);
+ bool VisitVarDecl(VarDecl *D);
+ bool VisitBlockDecl(BlockDecl *D);
+ bool VisitDeclStmt(DeclStmt *S);
+ bool VisitFunctionType(FunctionType *F);
+ bool VisitFunctionProtoType(FunctionProtoType *F);
+};
+
+#define DEFINE_VISIT(Type, Name, Statement) \
+ template<typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Visit ## Type (Type *Name) { \
+ if (Impl::Visit ## Type (Name)) return true; \
+ { Statement; } \
+ return false; \
+ }
+
+DEFINE_VISIT(DeclaratorDecl, D, {
+ if (TypeSourceInfo *TInfo = D->getTypeSourceInfo())
+ return this->Visit(TInfo->getType());
+ })
+
+DEFINE_VISIT(FunctionDecl, D, {
+ if (D->isThisDeclarationADefinition())
+ return this->Visit(D->getBody());
+ })
+
+DEFINE_VISIT(VarDecl, D, return this->Visit(D->getInit()))
+
+DEFINE_VISIT(BlockDecl, D, return this->Visit(D->getBody()))
+
+DEFINE_VISIT(DeclStmt, S, {
+ for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
+ I != E; ++I) {
+ if (this->Visit(*I))
+ return true;
+ }
+ })
+
+// FunctionType is the common base class of FunctionNoProtoType (a
+// K&R-style function declaration that has no information about
+// its arguments) and FunctionProtoType.
+DEFINE_VISIT(FunctionType, F, return this->Visit(F->getResultType()))
+
+DEFINE_VISIT(FunctionProtoType, F, {
+ for (unsigned i = 0; i != F->getNumArgs(); ++i) {
+ if (this->Visit(F->getArgType(i)))
+ return true;
+ }
+ for (unsigned i = 0; i != F->getNumExceptions(); ++i) {
+ if (this->Visit(F->getExceptionType(i)))
+ return true;
+ }
+ })
+
+#undef DEFINE_VISIT
+
+#undef DISPATCH
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
diff --git a/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h b/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h
new file mode 100644
index 0000000..01f4b29
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h
@@ -0,0 +1,179 @@
+//===-- 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 "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Casting.h"
+#include <iterator>
+
+namespace clang {
+
+/// \brief Provides common interface for the Decls that can be redeclared.
+template<typename decl_type>
+class Redeclarable {
+
+protected:
+ // FIXME: PointerIntPair is a value class that should not be inherited from.
+ // This should change to using containment.
+ struct DeclLink : public llvm::PointerIntPair<decl_type *, 1, bool> {
+ DeclLink(decl_type *D, bool isLatest)
+ : llvm::PointerIntPair<decl_type *, 1, bool>(D, isLatest) { }
+
+ typedef llvm::PointerIntPair<decl_type *, 1, bool> base_type;
+
+ bool NextIsPrevious() const { return base_type::getInt() == false; }
+ bool NextIsLatest() const { return base_type::getInt() == true; }
+ decl_type *getNext() const { return base_type::getPointer(); }
+ };
+
+ struct PreviousDeclLink : public DeclLink {
+ PreviousDeclLink(decl_type *D) : DeclLink(D, false) { }
+ };
+
+ struct LatestDeclLink : public DeclLink {
+ LatestDeclLink(decl_type *D) : DeclLink(D, true) { }
+ };
+
+ /// \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;
+
+public:
+ Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { }
+
+ /// \brief Return the previous declaration of this declaration or NULL if this
+ /// is the first declaration.
+ decl_type *getPreviousDeclaration() {
+ if (RedeclLink.NextIsPrevious())
+ return RedeclLink.getNext();
+ return 0;
+ }
+ const decl_type *getPreviousDeclaration() const {
+ return const_cast<decl_type *>(
+ static_cast<const decl_type*>(this))->getPreviousDeclaration();
+ }
+
+ /// \brief Return the first declaration of this declaration or itself if this
+ /// is the only declaration.
+ decl_type *getFirstDeclaration() {
+ decl_type *D = static_cast<decl_type*>(this);
+ while (D->getPreviousDeclaration())
+ D = D->getPreviousDeclaration();
+ return D;
+ }
+
+ /// \brief Return the first declaration of this declaration or itself if this
+ /// is the only declaration.
+ const decl_type *getFirstDeclaration() const {
+ const decl_type *D = static_cast<const decl_type*>(this);
+ while (D->getPreviousDeclaration())
+ D = D->getPreviousDeclaration();
+ return D;
+ }
+
+ /// \brief Returns the most recent (re)declaration of this declaration.
+ decl_type *getMostRecentDeclaration() {
+ return getFirstDeclaration()->RedeclLink.getNext();
+ }
+
+ /// \brief Returns the most recent (re)declaration of this declaration.
+ const decl_type *getMostRecentDeclaration() const {
+ return getFirstDeclaration()->RedeclLink.getNext();
+ }
+
+ /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
+ /// first and only declaration.
+ void setPreviousDeclaration(decl_type *PrevDecl) {
+ decl_type *First;
+
+ 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.
+ RedeclLink = PreviousDeclLink(llvm::cast<decl_type>(
+ PrevDecl->getMostRecentDeclaration()));
+ First = PrevDecl->getFirstDeclaration();
+ assert(First->RedeclLink.NextIsLatest() && "Expected first");
+ } else {
+ // Make this first.
+ First = static_cast<decl_type*>(this);
+ }
+
+ // First one will point to this one as latest.
+ First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
+ }
+
+ /// \brief Iterates through all the redeclarations of the same decl.
+ class redecl_iterator {
+ /// Current - The current declaration.
+ decl_type *Current;
+ decl_type *Starter;
+
+ 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(0) { }
+ explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) { }
+
+ reference operator*() const { return Current; }
+ pointer operator->() const { return Current; }
+
+ redecl_iterator& operator++() {
+ assert(Current && "Advancing while iterator has reached end");
+ // Get either previous decl or latest decl.
+ decl_type *Next = Current->RedeclLink.getNext();
+ Current = (Next != Starter ? Next : 0);
+ 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;
+ }
+ };
+
+ /// \brief Returns iterator for all the redeclarations of the same decl.
+ /// It will iterate at least once (when this decl is the only one).
+ redecl_iterator redecls_begin() const {
+ return redecl_iterator(const_cast<decl_type*>(
+ static_cast<const decl_type*>(this)));
+ }
+ redecl_iterator redecls_end() const { return redecl_iterator(); }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h
new file mode 100644
index 0000000..9deae15
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h
@@ -0,0 +1,1381 @@
+//===--- 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 "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/StmtIterator.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/FullExpr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/ASTContext.h"
+#include <string>
+using llvm::dyn_cast_or_null;
+
+namespace llvm {
+ class FoldingSetNodeID;
+}
+
+namespace clang {
+ class ASTContext;
+ class Expr;
+ class Decl;
+ class ParmVarDecl;
+ class QualType;
+ class IdentifierInfo;
+ class SourceManager;
+ class StringLiteral;
+ class SwitchStmt;
+
+ //===----------------------------------------------------------------------===//
+ // ExprIterator - Iterators 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).
+ //===----------------------------------------------------------------------===//
+
+ class Stmt;
+ class Expr;
+
+ class ExprIterator {
+ Stmt** I;
+ public:
+ ExprIterator(Stmt** i) : I(i) {}
+ ExprIterator() : I(0) {}
+ ExprIterator& operator++() { ++I; return *this; }
+ ExprIterator operator-(size_t i) { return I-i; }
+ ExprIterator operator+(size_t i) { return I+i; }
+ Expr* operator[](size_t idx);
+ // FIXME: Verify that this will correctly return a signed distance.
+ signed operator-(const ExprIterator& R) const { return I - R.I; }
+ Expr* operator*() const;
+ Expr* operator->() const;
+ bool operator==(const ExprIterator& R) const { return I == R.I; }
+ bool operator!=(const ExprIterator& R) const { return I != R.I; }
+ bool operator>(const ExprIterator& R) const { return I > R.I; }
+ bool operator>=(const ExprIterator& R) const { return I >= R.I; }
+ };
+
+ class ConstExprIterator {
+ const Stmt * const *I;
+ public:
+ ConstExprIterator(const Stmt * const *i) : I(i) {}
+ ConstExprIterator() : I(0) {}
+ ConstExprIterator& operator++() { ++I; return *this; }
+ ConstExprIterator operator+(size_t i) const { return I+i; }
+ ConstExprIterator operator-(size_t i) const { return I-i; }
+ const Expr * operator[](size_t idx) const;
+ signed operator-(const ConstExprIterator& R) const { return I - R.I; }
+ const Expr * operator*() const;
+ const Expr * operator->() const;
+ bool operator==(const ConstExprIterator& R) const { return I == R.I; }
+ bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
+ bool operator>(const ConstExprIterator& R) const { return I > R.I; }
+ bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
+ };
+
+//===----------------------------------------------------------------------===//
+// AST classes for statements.
+//===----------------------------------------------------------------------===//
+
+/// Stmt - This represents one statement.
+///
+class 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"
+};
+private:
+ /// \brief The statement class.
+ const unsigned sClass : 8;
+
+ /// \brief The reference count for this statement.
+ unsigned RefCount : 24;
+
+ // Make vanilla 'new' and 'delete' illegal for Stmts.
+protected:
+ void* operator new(size_t bytes) throw() {
+ assert(0 && "Stmts cannot be allocated with regular 'new'.");
+ return 0;
+ }
+ void operator delete(void* data) throw() {
+ assert(0 && "Stmts cannot be released with regular 'delete'.");
+ }
+
+public:
+ // Only allow allocation of Stmts using the allocator in ASTContext
+ // or by doing a placement new.
+ void* operator new(size_t bytes, ASTContext& C,
+ unsigned alignment = 8) throw() {
+ return ::operator new(bytes, C, alignment);
+ }
+
+ void* operator new(size_t bytes, ASTContext* C,
+ unsigned alignment = 8) throw() {
+ return ::operator new(bytes, *C, alignment);
+ }
+
+ void* operator new(size_t bytes, void* mem) throw() {
+ return mem;
+ }
+
+ void operator delete(void*, ASTContext&, unsigned) throw() { }
+ void operator delete(void*, ASTContext*, unsigned) throw() { }
+ void operator delete(void*, std::size_t) throw() { }
+ void operator delete(void*, void*) throw() { }
+
+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:
+ /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
+ /// recursively release child AST nodes.
+ void DestroyChildren(ASTContext& Ctx);
+
+ /// \brief Construct an empty statement.
+ explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC), RefCount(1) {
+ if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
+ }
+
+ /// \brief Virtual method that performs the actual destruction of
+ /// this statement.
+ ///
+ /// Subclasses should override this method (not Destroy()) to
+ /// provide class-specific destruction.
+ virtual void DoDestroy(ASTContext &Ctx);
+
+public:
+ Stmt(StmtClass SC) : sClass(SC), RefCount(1) {
+ if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
+ }
+ virtual ~Stmt() {}
+
+#ifndef NDEBUG
+ /// \brief True if this statement's refcount is in a valid state.
+ /// Should be used only in assertions.
+ bool isRetained() const {
+ return (RefCount >= 1);
+ }
+#endif
+
+ /// \brief Destroy the current statement and its children.
+ void Destroy(ASTContext &Ctx) {
+ assert(RefCount >= 1);
+ if (--RefCount == 0)
+ DoDestroy(Ctx);
+ }
+
+ /// \brief Increases the reference count for this statement.
+ ///
+ /// Invoke the Retain() operation when this statement or expression
+ /// is being shared by another owner.
+ Stmt *Retain() {
+ assert(RefCount >= 1);
+ ++RefCount;
+ return this;
+ }
+
+ StmtClass getStmtClass() const {
+ assert(RefCount >= 1 && "Referencing already-destroyed statement!");
+ return (StmtClass)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.
+ virtual SourceRange getSourceRange() const = 0;
+ SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
+ SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
+
+ // global temp stats (until we have a per-module visitor)
+ static void addStmtClass(const StmtClass s);
+ static bool CollectingStats(bool Enable = false);
+ static void PrintStats();
+
+ /// dump - This does a local dump of the specified AST fragment. It dumps the
+ /// specified node and a few nodes underneath it, but not the whole subtree.
+ /// This is useful in a debugger.
+ void dump() const;
+ void dump(SourceManager &SM) const;
+
+ /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
+ void dumpAll() const;
+ void dumpAll(SourceManager &SM) const;
+
+ /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
+ /// back to its original source language syntax.
+ void dumpPretty(ASTContext& Context) const;
+ void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper,
+ const PrintingPolicy &Policy,
+ unsigned Indentation = 0) const {
+ printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation);
+ }
+ void printPretty(llvm::raw_ostream &OS, ASTContext &Context,
+ 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;
+
+ // Implement isa<T> support.
+ static bool classof(const Stmt *) { return true; }
+
+ /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
+ /// contain implicit control-flow in the order their subexpressions
+ /// are evaluated. This predicate returns true if this statement has
+ /// such implicit control-flow. Such statements are also specially handled
+ /// within CFGs.
+ bool hasImplicitControlFlow() const;
+
+ /// Child Iterators: All subclasses must implement child_begin and child_end
+ /// 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;
+
+ virtual child_iterator child_begin() = 0;
+ virtual child_iterator child_end() = 0;
+
+ const_child_iterator child_begin() const {
+ return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
+ }
+
+ const_child_iterator child_end() const {
+ return const_child_iterator(const_cast<Stmt*>(this)->child_end());
+ }
+
+ /// \brief Produce a unique representation of the given statement.
+ ///
+ /// \brief ID once the profiling operation is complete, will contain
+ /// the unique representation of the given statement.
+ ///
+ /// \brief Context the AST context in which the statement resides
+ ///
+ /// \brief 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, ASTContext &Context,
+ bool Canonical);
+};
+
+/// 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;
+
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+
+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; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(StartLoc, EndLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DeclStmtClass;
+ }
+ static bool classof(const DeclStmt *) { return true; }
+
+ // Iterators over subexpressions.
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+ typedef DeclGroupRef::iterator decl_iterator;
+ typedef DeclGroupRef::const_iterator const_decl_iterator;
+
+ 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(); }
+};
+
+/// NullStmt - This is the null statement ";": C99 6.8.3p3.
+///
+class NullStmt : public Stmt {
+ SourceLocation SemiLoc;
+public:
+ NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
+
+ /// \brief Build an empty null statement.
+ explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { }
+
+ SourceLocation getSemiLoc() const { return SemiLoc; }
+ void setSemiLoc(SourceLocation L) { SemiLoc = L; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == NullStmtClass;
+ }
+ static bool classof(const NullStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CompoundStmt - This represents a group of statements like { stmt stmt }.
+///
+class CompoundStmt : public Stmt {
+ Stmt** Body;
+ unsigned NumStmts;
+ SourceLocation LBracLoc, RBracLoc;
+public:
+ CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
+ SourceLocation LB, SourceLocation RB)
+ : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
+ if (NumStmts == 0) {
+ Body = 0;
+ return;
+ }
+
+ Body = new (C) Stmt*[NumStmts];
+ memcpy(Body, StmtStart, numStmts * sizeof(*Body));
+ }
+
+ // \brief Build an empty compound statement.
+ explicit CompoundStmt(EmptyShell Empty)
+ : Stmt(CompoundStmtClass, Empty), Body(0), NumStmts(0) { }
+
+ void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts);
+
+ bool body_empty() const { return NumStmts == 0; }
+ unsigned size() const { return NumStmts; }
+
+ typedef Stmt** body_iterator;
+ body_iterator body_begin() { return Body; }
+ body_iterator body_end() { return Body + NumStmts; }
+ Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
+
+ typedef Stmt* const * const_body_iterator;
+ const_body_iterator body_begin() const { return Body; }
+ const_body_iterator body_end() const { return Body + NumStmts; }
+ const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
+
+ 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());
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(LBracLoc, RBracLoc);
+ }
+
+ SourceLocation getLBracLoc() const { return LBracLoc; }
+ void setLBracLoc(SourceLocation L) { LBracLoc = L; }
+ SourceLocation getRBracLoc() const { return RBracLoc; }
+ void setRBracLoc(SourceLocation L) { RBracLoc = L; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CompoundStmtClass;
+ }
+ static bool classof(const CompoundStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+// 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;
+
+ SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
+
+public:
+ const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
+
+ SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
+
+ void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
+
+ Stmt *getSubStmt() { return v_getSubStmt(); }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CaseStmtClass ||
+ T->getStmtClass() == DefaultStmtClass;
+ }
+ static bool classof(const SwitchCase *) { return true; }
+protected:
+ virtual Stmt* v_getSubStmt() = 0;
+};
+
+class CaseStmt : public SwitchCase {
+ enum { SUBSTMT, LHS, RHS, END_EXPR };
+ Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
+ // GNU "case 1 ... 4" extension
+ SourceLocation CaseLoc;
+ SourceLocation EllipsisLoc;
+ SourceLocation ColonLoc;
+
+ virtual Stmt* v_getSubStmt() { return getSubStmt(); }
+public:
+ CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
+ SourceLocation ellipsisLoc, SourceLocation colonLoc)
+ : SwitchCase(CaseStmtClass) {
+ SubExprs[SUBSTMT] = 0;
+ SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
+ SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
+ CaseLoc = caseLoc;
+ EllipsisLoc = ellipsisLoc;
+ ColonLoc = colonLoc;
+ }
+
+ /// \brief Build an empty switch case statement.
+ explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { }
+
+ SourceLocation getCaseLoc() const { return CaseLoc; }
+ void setCaseLoc(SourceLocation L) { CaseLoc = 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); }
+
+
+ virtual SourceRange getSourceRange() const {
+ // 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 SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CaseStmtClass;
+ }
+ static bool classof(const CaseStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+class DefaultStmt : public SwitchCase {
+ Stmt* SubStmt;
+ SourceLocation DefaultLoc;
+ SourceLocation ColonLoc;
+ virtual Stmt* v_getSubStmt() { return getSubStmt(); }
+public:
+ DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
+ SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL),
+ ColonLoc(CL) {}
+
+ /// \brief Build an empty default statement.
+ explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { }
+
+ Stmt *getSubStmt() { return SubStmt; }
+ const Stmt *getSubStmt() const { return SubStmt; }
+ void setSubStmt(Stmt *S) { SubStmt = S; }
+
+ SourceLocation getDefaultLoc() const { return DefaultLoc; }
+ void setDefaultLoc(SourceLocation L) { DefaultLoc = L; }
+ SourceLocation getColonLoc() const { return ColonLoc; }
+ void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(DefaultLoc, SubStmt->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DefaultStmtClass;
+ }
+ static bool classof(const DefaultStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+class LabelStmt : public Stmt {
+ IdentifierInfo *Label;
+ Stmt *SubStmt;
+ SourceLocation IdentLoc;
+public:
+ LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
+ : Stmt(LabelStmtClass), Label(label),
+ SubStmt(substmt), IdentLoc(IL) {}
+
+ // \brief Build an empty label statement.
+ explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
+
+ SourceLocation getIdentLoc() const { return IdentLoc; }
+ IdentifierInfo *getID() const { return Label; }
+ void setID(IdentifierInfo *II) { Label = II; }
+ 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(IdentLoc, SubStmt->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == LabelStmtClass;
+ }
+ static bool classof(const LabelStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+/// IfStmt - This represents an if/then/else.
+///
+class IfStmt : public Stmt {
+ enum { COND, THEN, ELSE, END_EXPR };
+ Stmt* SubExprs[END_EXPR];
+
+ /// \brief If non-NULL, the declaration in the "if" statement.
+ VarDecl *Var;
+
+ SourceLocation IfLoc;
+ SourceLocation ElseLoc;
+
+public:
+ IfStmt(SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then,
+ SourceLocation EL = SourceLocation(), Stmt *elsev = 0)
+ : Stmt(IfStmtClass), Var(var), IfLoc(IL), ElseLoc(EL) {
+ SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+ SubExprs[THEN] = then;
+ SubExprs[ELSE] = elsev;
+ }
+
+ /// \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 { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
+ 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; }
+
+ virtual SourceRange getSourceRange() const {
+ if (SubExprs[ELSE])
+ return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
+ else
+ return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == IfStmtClass;
+ }
+ static bool classof(const IfStmt *) { return true; }
+
+ // Iterators over subexpressions. The iterators will include iterating
+ // over the initialization expression referenced by the condition variable.
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+};
+
+/// SwitchStmt - This represents a 'switch' stmt.
+///
+class SwitchStmt : public Stmt {
+ enum { COND, BODY, END_EXPR };
+ Stmt* SubExprs[END_EXPR];
+ VarDecl *Var;
+ // This points to a linked list of case and default statements.
+ SwitchCase *FirstCase;
+ SourceLocation SwitchLoc;
+
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+
+public:
+ SwitchStmt(VarDecl *Var, Expr *cond)
+ : Stmt(SwitchStmtClass), Var(Var), FirstCase(0)
+ {
+ SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+ SubExprs[BODY] = NULL;
+ }
+
+ /// \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 { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
+ const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+ const Stmt *getBody() const { return SubExprs[BODY]; }
+ const SwitchCase *getSwitchCaseList() const { return FirstCase; }
+
+ 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; }
+
+ /// \brief Set the case list for this switch statement.
+ ///
+ /// The caller is responsible for incrementing the retain counts on
+ /// all of the SwitchCase statements in this list.
+ void setSwitchCaseList(SwitchCase *SC) { FirstCase = 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->Retain();
+ SC->setNextSwitchCase(FirstCase);
+ FirstCase = SC;
+ }
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == SwitchStmtClass;
+ }
+ static bool classof(const SwitchStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+/// WhileStmt - This represents a 'while' stmt.
+///
+class WhileStmt : public Stmt {
+ enum { COND, BODY, END_EXPR };
+ VarDecl *Var;
+ Stmt* SubExprs[END_EXPR];
+ SourceLocation WhileLoc;
+public:
+ WhileStmt(VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL)
+ : Stmt(WhileStmtClass), Var(Var)
+ {
+ SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+ SubExprs[BODY] = body;
+ WhileLoc = 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 { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
+ 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == WhileStmtClass;
+ }
+ static bool classof(const WhileStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+};
+
+/// DoStmt - This represents a 'do/while' stmt.
+///
+class DoStmt : public Stmt {
+ enum { COND, BODY, END_EXPR };
+ Stmt* SubExprs[END_EXPR];
+ SourceLocation DoLoc;
+ 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(DoLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DoStmtClass;
+ }
+ static bool classof(const DoStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+/// 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 {
+ enum { INIT, COND, INC, BODY, END_EXPR };
+ Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
+ VarDecl *CondVar;
+ SourceLocation ForLoc;
+ SourceLocation LParenLoc, RParenLoc;
+
+public:
+ ForStmt(Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body,
+ SourceLocation FL, SourceLocation LP, SourceLocation RP)
+ : Stmt(ForStmtClass), CondVar(condVar), ForLoc(FL), LParenLoc(LP),
+ RParenLoc(RP)
+ {
+ SubExprs[INIT] = Init;
+ SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
+ SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
+ SubExprs[BODY] = Body;
+ }
+
+ /// \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 { return CondVar; }
+ void setConditionVariable(VarDecl *V) { CondVar = V; }
+
+ 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ForStmtClass;
+ }
+ static bool classof(const ForStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+};
+
+/// GotoStmt - This represents a direct goto.
+///
+class GotoStmt : public Stmt {
+ LabelStmt *Label;
+ SourceLocation GotoLoc;
+ SourceLocation LabelLoc;
+public:
+ GotoStmt(LabelStmt *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) { }
+
+ LabelStmt *getLabel() const { return Label; }
+ void setLabel(LabelStmt *S) { Label = S; }
+
+ SourceLocation getGotoLoc() const { return GotoLoc; }
+ void setGotoLoc(SourceLocation L) { GotoLoc = L; }
+ SourceLocation getLabelLoc() const { return LabelLoc; }
+ void setLabelLoc(SourceLocation L) { LabelLoc = L; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(GotoLoc, LabelLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == GotoStmtClass;
+ }
+ static bool classof(const GotoStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// 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();
+ const Expr *getTarget() const;
+ void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(GotoLoc, Target->getLocEnd());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == IndirectGotoStmtClass;
+ }
+ static bool classof(const IndirectGotoStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+/// 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(ContinueLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ContinueStmtClass;
+ }
+ static bool classof(const ContinueStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// BreakStmt - This represents a break.
+///
+class BreakStmt : public Stmt {
+ SourceLocation BreakLoc;
+public:
+ BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
+
+ /// \brief Build an empty break statement.
+ explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
+
+ SourceLocation getBreakLoc() const { return BreakLoc; }
+ void setBreakLoc(SourceLocation L) { BreakLoc = L; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == BreakStmtClass;
+ }
+ static bool classof(const BreakStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+/// 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 {
+ Stmt *RetExpr;
+ SourceLocation RetLoc;
+ const VarDecl *NRVOCandidate;
+
+public:
+ ReturnStmt(SourceLocation RL)
+ : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
+
+ ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
+ : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
+ 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; }
+
+ virtual SourceRange getSourceRange() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ReturnStmtClass;
+ }
+ static bool classof(const ReturnStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// AsmStmt - This represents a GNU inline-assembly statement extension.
+///
+class AsmStmt : public Stmt {
+ SourceLocation AsmLoc, RParenLoc;
+ StringLiteral *AsmStr;
+
+ bool IsSimple;
+ bool IsVolatile;
+ bool MSAsm;
+
+ unsigned NumOutputs;
+ unsigned NumInputs;
+ unsigned NumClobbers;
+
+ // FIXME: If we wanted to, we could allocate all of these in one big array.
+ IdentifierInfo **Names;
+ StringLiteral **Constraints;
+ Stmt **Exprs;
+ StringLiteral **Clobbers;
+
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+
+public:
+ AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
+ bool msasm, 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 AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
+ Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
+
+ SourceLocation getAsmLoc() const { return AsmLoc; }
+ void setAsmLoc(SourceLocation L) { AsmLoc = L; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ bool isVolatile() const { return IsVolatile; }
+ void setVolatile(bool V) { IsVolatile = V; }
+ bool isSimple() const { return IsSimple; }
+ void setSimple(bool V) { IsSimple = V; }
+ bool isMSAsm() const { return MSAsm; }
+ void setMSAsm(bool V) { MSAsm = V; }
+
+ //===--- 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;
+ public:
+ AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
+ AsmStringPiece(unsigned OpNo, char Modifier)
+ : MyKind(Operand), Str(), OperandNo(OpNo) {
+ Str += Modifier;
+ }
+
+ bool isString() const { return MyKind == String; }
+ bool isOperand() const { return MyKind == Operand; }
+
+ const std::string &getString() const {
+ assert(isString());
+ return Str;
+ }
+
+ unsigned getOperandNo() const {
+ assert(isOperand());
+ return OperandNo;
+ }
+
+ /// getModifier - Get the modifier for this operand, if present. This
+ /// returns '\0' if there was no modifier.
+ char getModifier() const {
+ assert(isOperand());
+ return Str[0];
+ }
+ };
+
+ /// 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(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
+ ASTContext &C, unsigned &DiagOffs) const;
+
+
+ //===--- Output operands ---===//
+
+ unsigned getNumOutputs() const { return NumOutputs; }
+
+ IdentifierInfo *getOutputIdentifier(unsigned i) const {
+ return Names[i];
+ }
+
+ llvm::StringRef getOutputName(unsigned i) const {
+ if (IdentifierInfo *II = getOutputIdentifier(i))
+ return II->getName();
+
+ return llvm::StringRef();
+ }
+
+ /// getOutputConstraint - Return the constraint string for the specified
+ /// output operand. All output constraints are known to be non-empty (either
+ /// '=' or '+').
+ llvm::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<AsmStmt*>(this)->getOutputExpr(i);
+ }
+
+ /// 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] == '+';
+ }
+
+ /// getNumPlusOperands - Return the number of output operands that have a "+"
+ /// constraint.
+ unsigned getNumPlusOperands() const;
+
+ //===--- Input operands ---===//
+
+ unsigned getNumInputs() const { return NumInputs; }
+
+ IdentifierInfo *getInputIdentifier(unsigned i) const {
+ return Names[i + NumOutputs];
+ }
+
+ llvm::StringRef getInputName(unsigned i) const {
+ if (IdentifierInfo *II = getInputIdentifier(i))
+ return II->getName();
+
+ return llvm::StringRef();
+ }
+
+ /// getInputConstraint - Return the specified input constraint. Unlike output
+ /// constraints, these can be empty.
+ llvm::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);
+
+ const Expr *getInputExpr(unsigned i) const {
+ return const_cast<AsmStmt*>(this)->getInputExpr(i);
+ }
+
+ void setOutputsAndInputsAndClobbers(ASTContext &C,
+ IdentifierInfo **Names,
+ StringLiteral **Constraints,
+ Stmt **Exprs,
+ unsigned NumOutputs,
+ unsigned NumInputs,
+ StringLiteral **Clobbers,
+ unsigned NumClobbers);
+
+ //===--- 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(llvm::StringRef SymbolicName) const;
+
+ unsigned getNumClobbers() const { return NumClobbers; }
+ StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
+ const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AsmLoc, RParenLoc);
+ }
+
+ static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
+ static bool classof(const AsmStmt *) { return true; }
+
+ // Input expr iterators.
+
+ typedef ExprIterator inputs_iterator;
+ typedef ConstExprIterator const_inputs_iterator;
+
+ inputs_iterator begin_inputs() {
+ return &Exprs[0] + NumOutputs;
+ }
+
+ inputs_iterator end_inputs() {
+ return &Exprs[0] + NumOutputs + NumInputs;
+ }
+
+ const_inputs_iterator begin_inputs() const {
+ return &Exprs[0] + NumOutputs;
+ }
+
+ const_inputs_iterator end_inputs() const {
+ return &Exprs[0] + NumOutputs + NumInputs;
+ }
+
+ // Output expr iterators.
+
+ typedef ExprIterator outputs_iterator;
+ typedef ConstExprIterator const_outputs_iterator;
+
+ outputs_iterator begin_outputs() {
+ return &Exprs[0];
+ }
+ outputs_iterator end_outputs() {
+ return &Exprs[0] + NumOutputs;
+ }
+
+ const_outputs_iterator begin_outputs() const {
+ return &Exprs[0];
+ }
+ const_outputs_iterator end_outputs() const {
+ return &Exprs[0] + NumOutputs;
+ }
+
+ // Child iterators
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h
new file mode 100644
index 0000000..4e87c27
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h
@@ -0,0 +1,113 @@
+//===--- 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/Stmt.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;
+
+protected:
+ virtual void DoDestroy(ASTContext& Ctx);
+
+public:
+ CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
+ : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
+ HandlerBlock(handlerBlock) {}
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(CatchLoc, 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;
+ }
+ static bool classof(const CXXCatchStmt *) { return true; }
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// CXXTryStmt - A C++ try block, including all handlers.
+///
+class CXXTryStmt : public Stmt {
+ SourceLocation TryLoc;
+ unsigned NumHandlers;
+
+ CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
+ unsigned numHandlers);
+
+public:
+ static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
+ Stmt *tryBlock, Stmt **handlers,
+ unsigned numHandlers);
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getTryLoc(), getEndLoc());
+ }
+
+ SourceLocation getTryLoc() const { return TryLoc; }
+ SourceLocation getEndLoc() const {
+ Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
+ return Stmts[NumHandlers]->getLocEnd();
+ }
+
+ CompoundStmt *getTryBlock() {
+ Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
+ return llvm::cast<CompoundStmt>(Stmts[0]);
+ }
+ const CompoundStmt *getTryBlock() const {
+ Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
+ return llvm::cast<CompoundStmt>(Stmts[0]);
+ }
+
+ unsigned getNumHandlers() const { return NumHandlers; }
+ CXXCatchStmt *getHandler(unsigned i) {
+ Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
+ return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+ }
+ const CXXCatchStmt *getHandler(unsigned i) const {
+ Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
+ return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXTryStmtClass;
+ }
+ static bool classof(const CXXTryStmt *) { return true; }
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtGraphTraits.h b/contrib/llvm/tools/clang/include/clang/AST/StmtGraphTraits.h
new file mode 100644
index 0000000..25d0152
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/StmtGraphTraits.h
@@ -0,0 +1,83 @@
+//===--- 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_STMT_GRAPHTRAITS_H
+#define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
+
+#include "clang/AST/Stmt.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/DepthFirstIterator.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/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h b/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h
new file mode 100644
index 0000000..a48f4e6
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h
@@ -0,0 +1,150 @@
+//===--- StmtIterator.h - Iterators for Statements ------------------------===//
+//
+// 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_STMT_ITR_H
+#define LLVM_CLANG_AST_STMT_ITR_H
+
+#include "llvm/System/DataTypes.h"
+#include <cassert>
+#include <iterator>
+
+namespace clang {
+
+class Stmt;
+class Decl;
+class VariableArrayType;
+
+class StmtIteratorBase {
+protected:
+ enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3,
+ Flags = 0x3 };
+
+ Stmt **stmt;
+ union { Decl *decl; Decl **DGI; };
+ uintptr_t RawVAPtr;
+ Decl **DGE;
+
+ bool inDecl() const {
+ return (RawVAPtr & Flags) == DeclMode;
+ }
+
+ bool inDeclGroup() const {
+ return (RawVAPtr & Flags) == DeclGroupMode;
+ }
+
+ bool inSizeOfTypeVA() const {
+ return (RawVAPtr & Flags) == SizeOfTypeVAMode;
+ }
+
+ bool inStmt() const {
+ return (RawVAPtr & Flags) == 0;
+ }
+
+ VariableArrayType* getVAPtr() const {
+ return reinterpret_cast<VariableArrayType*>(RawVAPtr & ~Flags);
+ }
+
+ void setVAPtr(VariableArrayType* P) {
+ assert (inDecl() || 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), decl(0), RawVAPtr(0) {}
+ StmtIteratorBase(Decl *d, Stmt **s);
+ StmtIteratorBase(VariableArrayType *t);
+ StmtIteratorBase(Decl **dgi, Decl **dge);
+ StmtIteratorBase() : stmt(0), decl(0), 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(Decl *d, Stmt **s) : StmtIteratorBase(d, s) {}
+ StmtIteratorImpl(VariableArrayType* t) : StmtIteratorBase(t) {}
+
+ DERIVED& operator++() {
+ if (inDecl() || inDeclGroup()) {
+ if (getVAPtr()) NextVA();
+ else NextDecl();
+ }
+ else if (inSizeOfTypeVA())
+ NextVA();
+ else
+ ++stmt;
+
+ 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 && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr;
+ }
+
+ bool operator!=(const DERIVED& RHS) const {
+ return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr;
+ }
+
+ REFERENCE operator*() const {
+ return (REFERENCE) (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(VariableArrayType* t)
+ : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
+
+ StmtIterator(Decl* D, Stmt **s = 0)
+ : StmtIteratorImpl<StmtIterator,Stmt*&>(D, s) {}
+};
+
+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/contrib/llvm/tools/clang/include/clang/AST/StmtNodes.def b/contrib/llvm/tools/clang/include/clang/AST/StmtNodes.def
new file mode 100644
index 0000000..3a23e49
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/StmtNodes.def
@@ -0,0 +1,165 @@
+//===-- StmtNodes.def - Metadata about Stmt 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 Node info database.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef FIRST_STMT
+#define FIRST_STMT(CLASS)
+#define LAST_STMT(CLASS)
+#endif
+
+#ifndef FIRST_EXPR
+#define FIRST_EXPR(CLASS)
+#define LAST_EXPR(CLASS)
+#endif
+
+#ifndef EXPR
+# define EXPR(Type, Base) STMT(Type, Base)
+#endif
+
+#ifndef ABSTRACT_EXPR
+# define ABSTRACT_EXPR(Type, Base) EXPR(Type, Base)
+#endif
+
+// Normal Statements.
+STMT(NullStmt , Stmt)
+FIRST_STMT(NullStmt)
+STMT(CompoundStmt , Stmt)
+STMT(CaseStmt , SwitchCase)
+STMT(DefaultStmt , SwitchCase)
+STMT(LabelStmt , Stmt)
+STMT(IfStmt , Stmt)
+STMT(SwitchStmt , Stmt)
+STMT(WhileStmt , Stmt)
+STMT(DoStmt , Stmt)
+STMT(ForStmt , Stmt)
+STMT(GotoStmt , Stmt)
+STMT(IndirectGotoStmt, Stmt)
+STMT(ContinueStmt , Stmt)
+STMT(BreakStmt , Stmt)
+STMT(ReturnStmt , Stmt)
+STMT(DeclStmt , Stmt)
+STMT(SwitchCase , Stmt)
+
+// GNU Stmt Extensions
+STMT(AsmStmt , Stmt)
+
+// Obj-C statements
+STMT(ObjCAtTryStmt , Stmt)
+STMT(ObjCAtCatchStmt , Stmt)
+STMT(ObjCAtFinallyStmt , Stmt)
+STMT(ObjCAtThrowStmt , Stmt)
+STMT(ObjCAtSynchronizedStmt , Stmt)
+// Obj-C2 statements
+STMT(ObjCForCollectionStmt, Stmt)
+
+// C++ statements
+STMT(CXXCatchStmt, Stmt)
+STMT(CXXTryStmt , Stmt)
+
+LAST_STMT(CXXTryStmt)
+
+// Expressions.
+ABSTRACT_EXPR(Expr , Stmt)
+EXPR(PredefinedExpr , Expr)
+EXPR(DeclRefExpr , Expr)
+EXPR(IntegerLiteral , Expr)
+EXPR(FloatingLiteral , Expr)
+EXPR(ImaginaryLiteral , Expr)
+EXPR(StringLiteral , Expr)
+EXPR(CharacterLiteral , Expr)
+EXPR(ParenExpr , Expr)
+EXPR(UnaryOperator , Expr)
+EXPR(OffsetOfExpr , Expr)
+EXPR(SizeOfAlignOfExpr , Expr)
+EXPR(ArraySubscriptExpr , Expr)
+EXPR(CallExpr , Expr)
+EXPR(MemberExpr , Expr)
+ABSTRACT_EXPR(CastExpr , Expr)
+EXPR(BinaryOperator , Expr)
+EXPR(CompoundAssignOperator, BinaryOperator)
+EXPR(ConditionalOperator , Expr)
+EXPR(ImplicitCastExpr , CastExpr)
+ABSTRACT_EXPR(ExplicitCastExpr, CastExpr)
+EXPR(CStyleCastExpr , ExplicitCastExpr)
+EXPR(CompoundLiteralExpr , Expr)
+EXPR(ExtVectorElementExpr , Expr)
+EXPR(InitListExpr , Expr)
+EXPR(DesignatedInitExpr , Expr)
+EXPR(ImplicitValueInitExpr , Expr)
+EXPR(ParenListExpr , Expr)
+EXPR(VAArgExpr , Expr)
+
+// GNU Extensions.
+EXPR(AddrLabelExpr , Expr)
+EXPR(StmtExpr , Expr)
+EXPR(TypesCompatibleExpr , Expr)
+EXPR(ChooseExpr , Expr)
+EXPR(GNUNullExpr , Expr)
+
+// C++ Expressions.
+EXPR(CXXOperatorCallExpr , CallExpr)
+EXPR(CXXMemberCallExpr , CallExpr)
+ABSTRACT_EXPR(CXXNamedCastExpr , ExplicitCastExpr)
+EXPR(CXXStaticCastExpr , CXXNamedCastExpr)
+EXPR(CXXDynamicCastExpr , CXXNamedCastExpr)
+EXPR(CXXReinterpretCastExpr , CXXNamedCastExpr)
+EXPR(CXXConstCastExpr , CXXNamedCastExpr)
+EXPR(CXXFunctionalCastExpr , ExplicitCastExpr)
+EXPR(CXXTypeidExpr , Expr)
+EXPR(CXXBoolLiteralExpr , Expr)
+EXPR(CXXNullPtrLiteralExpr , Expr)
+EXPR(CXXThisExpr , Expr)
+EXPR(CXXThrowExpr , Expr)
+EXPR(CXXDefaultArgExpr , Expr)
+EXPR(CXXZeroInitValueExpr , Expr)
+EXPR(CXXNewExpr , Expr)
+EXPR(CXXDeleteExpr , Expr)
+EXPR(CXXPseudoDestructorExpr, Expr)
+EXPR(UnresolvedLookupExpr , Expr)
+EXPR(UnaryTypeTraitExpr , Expr)
+EXPR(DependentScopeDeclRefExpr , Expr)
+EXPR(CXXConstructExpr , Expr)
+EXPR(CXXBindTemporaryExpr , Expr)
+EXPR(CXXBindReferenceExpr , Expr)
+EXPR(CXXExprWithTemporaries , Expr)
+EXPR(CXXTemporaryObjectExpr , CXXConstructExpr)
+EXPR(CXXUnresolvedConstructExpr, Expr)
+EXPR(CXXDependentScopeMemberExpr, Expr)
+EXPR(UnresolvedMemberExpr , Expr)
+
+// Obj-C Expressions.
+EXPR(ObjCStringLiteral , Expr)
+EXPR(ObjCEncodeExpr , Expr)
+EXPR(ObjCMessageExpr , Expr)
+EXPR(ObjCSelectorExpr , Expr)
+EXPR(ObjCProtocolExpr , Expr)
+EXPR(ObjCIvarRefExpr , Expr)
+EXPR(ObjCPropertyRefExpr , Expr)
+EXPR(ObjCImplicitSetterGetterRefExpr , Expr)
+EXPR(ObjCSuperExpr , Expr)
+EXPR(ObjCIsaExpr , Expr)
+
+// Clang Extensions.
+EXPR(ShuffleVectorExpr , Expr)
+EXPR(BlockExpr , Expr)
+EXPR(BlockDeclRefExpr , Expr)
+
+FIRST_EXPR(PredefinedExpr)
+LAST_EXPR(BlockDeclRefExpr)
+
+#undef ABSTRACT_EXPR
+#undef EXPR
+#undef STMT
+#undef FIRST_STMT
+#undef LAST_STMT
+#undef FIRST_EXPR
+#undef LAST_EXPR
diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtNodes.td b/contrib/llvm/tools/clang/include/clang/AST/StmtNodes.td
new file mode 100644
index 0000000..60c94a6
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/StmtNodes.td
@@ -0,0 +1,127 @@
+class Stmt<bit abstract = 0> {
+ 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 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;
+def CaseStmt : DStmt<SwitchCase>;
+def DefaultStmt : DStmt<SwitchCase>;
+
+// GNU Extensions
+def AsmStmt : Stmt;
+
+// Obj-C statements
+def ObjCAtTryStmt : Stmt;
+def ObjCAtCatchStmt : Stmt;
+def ObjCAtFinallyStmt : Stmt;
+def ObjCAtThrowStmt : Stmt;
+def ObjCAtSynchronizedStmt : Stmt;
+def ObjCForCollectionStmt : Stmt;
+
+// C++ statments
+def CXXCatchStmt : Stmt;
+def CXXTryStmt : 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 SizeOfAlignOfExpr : DStmt<Expr>;
+def ArraySubscriptExpr : DStmt<Expr>;
+def CallExpr : DStmt<Expr>;
+def MemberExpr : DStmt<Expr>;
+def CastExpr : DStmt<Expr, 1>;
+def BinaryOperator : DStmt<Expr>;
+def CompoundAssignOperator : DStmt<BinaryOperator>;
+def ConditionalOperator : DStmt<Expr>;
+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 ImplicitValueInitExpr : DStmt<Expr>;
+def ParenListExpr : DStmt<Expr>;
+def VAArgExpr : DStmt<Expr>;
+
+// GNU Extensions.
+def AddrLabelExpr : DStmt<Expr>;
+def StmtExpr : DStmt<Expr>;
+def TypesCompatibleExpr : 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 CXXBoolLiteralExpr : DStmt<Expr>;
+def CXXNullPtrLiteralExpr : DStmt<Expr>;
+def CXXThisExpr : DStmt<Expr>;
+def CXXThrowExpr : DStmt<Expr>;
+def CXXDefaultArgExpr : DStmt<Expr>;
+def CXXZeroInitValueExpr : DStmt<Expr>;
+def CXXNewExpr : DStmt<Expr>;
+def CXXDeleteExpr : DStmt<Expr>;
+def CXXPseudoDestructorExpr : DStmt<Expr>;
+def UnresolvedLookupExpr : DStmt<Expr>;
+def UnaryTypeTraitExpr : DStmt<Expr>;
+def DependentScopeDeclRefExpr : DStmt<Expr>;
+def CXXConstructExpr : DStmt<Expr>;
+def CXXBindTemporaryExpr : DStmt<Expr>;
+def CXXBindReferenceExpr : DStmt<Expr>;
+def CXXExprWithTemporaries : DStmt<Expr>;
+def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
+def CXXUnresolvedConstructExpr : DStmt<Expr>;
+def CXXDependentScopeMemberExpr : DStmt<Expr>;
+def UnresolvedMemberExpr : DStmt<Expr>;
+
+// Obj-C Expressions.
+def ObjCStringLiteral : 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 ObjCImplicitSetterGetterRefExpr : DStmt<Expr>;
+def ObjCSuperExpr : DStmt<Expr>;
+def ObjCIsaExpr : DStmt<Expr>;
+
+// Clang Extensions.
+def ShuffleVectorExpr : DStmt<Expr>;
+def BlockExpr : DStmt<Expr>;
+def BlockDeclRefExpr : DStmt<Expr>;
diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h b/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h
new file mode 100644
index 0000000..269aa4c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h
@@ -0,0 +1,344 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file 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"
+
+namespace clang {
+
+/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
+/// 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCForCollectionStmtClass;
+ }
+ static bool classof(const ObjCForCollectionStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCAtCatchStmt - This 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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtCatchLoc, Body->getLocEnd());
+ }
+
+ bool hasEllipsis() const { return getCatchParamDecl() == 0; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCAtCatchStmtClass;
+ }
+ static bool classof(const ObjCAtCatchStmt *) { return true; }
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
+class ObjCAtFinallyStmt : public Stmt {
+ Stmt *AtFinallyStmt;
+ SourceLocation AtFinallyLoc;
+public:
+ ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
+ : Stmt(ObjCAtFinallyStmtClass),
+ AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
+
+ explicit ObjCAtFinallyStmt(EmptyShell Empty) :
+ Stmt(ObjCAtFinallyStmtClass, Empty) { }
+
+ const Stmt *getFinallyBody() const { return AtFinallyStmt; }
+ Stmt *getFinallyBody() { return AtFinallyStmt; }
+ void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
+ }
+
+ SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
+ void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCAtFinallyStmtClass;
+ }
+ static bool classof(const ObjCAtFinallyStmt *) { return true; }
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCAtTryStmt - This represent objective-c's over-all
+/// @try ... @catch ... @finally statement.
+class ObjCAtTryStmt : public Stmt {
+private:
+ // The location of the
+ 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(ASTContext &Context, SourceLocation atTryLoc,
+ Stmt *atTryStmt,
+ Stmt **CatchStmts, unsigned NumCatchStmts,
+ Stmt *atFinallyStmt);
+ static ObjCAtTryStmt *CreateEmpty(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;
+ }
+
+ /// Retrieve the @finally statement, if any.
+ const ObjCAtFinallyStmt *getFinallyStmt() const {
+ if (!HasFinally)
+ return 0;
+
+ return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
+ }
+ ObjCAtFinallyStmt *getFinallyStmt() {
+ if (!HasFinally)
+ return 0;
+
+ 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;
+ }
+
+ virtual SourceRange getSourceRange() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCAtTryStmtClass;
+ }
+ static bool classof(const ObjCAtTryStmt *) { return true; }
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
+/// Example: @synchronized (sem) {
+/// do-something;
+/// }
+///
+class ObjCAtSynchronizedStmt : public Stmt {
+private:
+ enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
+ Stmt* SubStmts[END_EXPR];
+ SourceLocation AtSynchronizedLoc;
+
+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; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
+ }
+ static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
+class ObjCAtThrowStmt : public Stmt {
+ Stmt *Throw;
+ SourceLocation AtThrowLoc;
+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; }
+
+ virtual SourceRange getSourceRange() const {
+ if (Throw)
+ return SourceRange(AtThrowLoc, Throw->getLocEnd());
+ else
+ return SourceRange(AtThrowLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCAtThrowStmtClass;
+ }
+ static bool classof(const ObjCAtThrowStmt *) { return true; }
+
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h
new file mode 100644
index 0000000..8078451
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h
@@ -0,0 +1,177 @@
+//===--- 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 interface.
+//
+//===----------------------------------------------------------------------===//
+
+#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/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+
+namespace clang {
+
+#define DISPATCH(NAME, CLASS) \
+ return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<CLASS*>(S))
+
+/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
+/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
+template<typename ImplClass, typename RetTy=void>
+class StmtVisitor {
+public:
+ RetTy Visit(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 (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+ switch (BinOp->getOpcode()) {
+ default: assert(0 && "Unknown binary operator!");
+ case BinaryOperator::PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator);
+ case BinaryOperator::PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator);
+ case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator);
+ case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator);
+ case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator);
+ case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator);
+ case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator);
+ case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator);
+ case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator);
+
+ case BinaryOperator::LT: DISPATCH(BinLT, BinaryOperator);
+ case BinaryOperator::GT: DISPATCH(BinGT, BinaryOperator);
+ case BinaryOperator::LE: DISPATCH(BinLE, BinaryOperator);
+ case BinaryOperator::GE: DISPATCH(BinGE, BinaryOperator);
+ case BinaryOperator::EQ: DISPATCH(BinEQ, BinaryOperator);
+ case BinaryOperator::NE: DISPATCH(BinNE, BinaryOperator);
+
+ case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator);
+ case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator);
+ case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator);
+ case BinaryOperator::LAnd: DISPATCH(BinLAnd, BinaryOperator);
+ case BinaryOperator::LOr : DISPATCH(BinLOr, BinaryOperator);
+ case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator);
+ case BinaryOperator::MulAssign:
+ DISPATCH(BinMulAssign, CompoundAssignOperator);
+ case BinaryOperator::DivAssign:
+ DISPATCH(BinDivAssign, CompoundAssignOperator);
+ case BinaryOperator::RemAssign:
+ DISPATCH(BinRemAssign, CompoundAssignOperator);
+ case BinaryOperator::AddAssign:
+ DISPATCH(BinAddAssign, CompoundAssignOperator);
+ case BinaryOperator::SubAssign:
+ DISPATCH(BinSubAssign, CompoundAssignOperator);
+ case BinaryOperator::ShlAssign:
+ DISPATCH(BinShlAssign, CompoundAssignOperator);
+ case BinaryOperator::ShrAssign:
+ DISPATCH(BinShrAssign, CompoundAssignOperator);
+ case BinaryOperator::AndAssign:
+ DISPATCH(BinAndAssign, CompoundAssignOperator);
+ case BinaryOperator::OrAssign:
+ DISPATCH(BinOrAssign, CompoundAssignOperator);
+ case BinaryOperator::XorAssign:
+ DISPATCH(BinXorAssign, CompoundAssignOperator);
+ case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator);
+ }
+ } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+ switch (UnOp->getOpcode()) {
+ default: assert(0 && "Unknown unary operator!");
+ case UnaryOperator::PostInc: DISPATCH(UnaryPostInc, UnaryOperator);
+ case UnaryOperator::PostDec: DISPATCH(UnaryPostDec, UnaryOperator);
+ case UnaryOperator::PreInc: DISPATCH(UnaryPreInc, UnaryOperator);
+ case UnaryOperator::PreDec: DISPATCH(UnaryPreDec, UnaryOperator);
+ case UnaryOperator::AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator);
+ case UnaryOperator::Deref: DISPATCH(UnaryDeref, UnaryOperator);
+ case UnaryOperator::Plus: DISPATCH(UnaryPlus, UnaryOperator);
+ case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator);
+ case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator);
+ case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator);
+ case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator);
+ case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator);
+ case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator);
+ case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator);
+ }
+ }
+
+ // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+ switch (S->getStmtClass()) {
+ default: assert(0 && "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(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(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(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(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(OffsetOf)
+#undef UNARYOP_FALLBACK
+
+ // Base case, ignore it. :)
+ RetTy VisitStmt(Stmt *Node) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h
new file mode 100644
index 0000000..8b38001
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h
@@ -0,0 +1,482 @@
+//===-- 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 "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TemplateName.h"
+
+namespace llvm {
+ class FoldingSetNodeID;
+}
+
+namespace clang {
+
+class Decl;
+class DiagnosticBuilder;
+class Expr;
+class TypeSourceInfo;
+
+/// \brief Represents a template argument within a class template
+/// specialization.
+class TemplateArgument {
+ union {
+ uintptr_t TypeOrValue;
+ struct {
+ char Value[sizeof(llvm::APSInt)];
+ void *Type;
+ } Integer;
+ struct {
+ TemplateArgument *Args;
+ unsigned NumArgs;
+ bool CopyArgs;
+ } Args;
+ };
+
+public:
+ /// \brief The type 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. Its value is stored in the
+ /// TypeOrValue field.
+ Type,
+ /// The template argument is a declaration that was provided for a pointer
+ /// or reference non-type template parameter.
+ Declaration,
+ /// 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 value- or type-dependent expression
+ /// stored in an Expr*.
+ Expression,
+ /// The template argument is actually a parameter pack. Arguments are stored
+ /// in the Args struct.
+ Pack
+ } Kind;
+
+ /// \brief Construct an empty, invalid template argument.
+ TemplateArgument() : TypeOrValue(0), Kind(Null) { }
+
+ /// \brief Construct a template type argument.
+ TemplateArgument(QualType T) : Kind(Type) {
+ TypeOrValue = 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(Decl *D) : Kind(Declaration) {
+ // FIXME: Need to be sure we have the "canonical" declaration!
+ TypeOrValue = reinterpret_cast<uintptr_t>(D);
+ }
+
+ /// \brief Construct an integral constant template argument.
+ TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) {
+ new (Integer.Value) llvm::APSInt(Value);
+ 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.
+ TemplateArgument(TemplateName Name) : Kind(Template) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(Name.getAsVoidPointer());
+ }
+
+ /// \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) : Kind(Expression) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(E);
+ }
+
+ /// \brief Copy constructor for a template argument.
+ TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+ if (Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else if (Kind == Pack) {
+ Args.NumArgs = Other.Args.NumArgs;
+ Args.Args = new TemplateArgument[Args.NumArgs];
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I] = Other.Args.Args[I];
+ }
+ else
+ TypeOrValue = Other.TypeOrValue;
+ }
+
+ TemplateArgument& operator=(const TemplateArgument& Other) {
+ // FIXME: Does not provide the strong guarantee for exception
+ // safety.
+ using llvm::APSInt;
+
+ // FIXME: Handle Packs
+ assert(Kind != Pack && "FIXME: Handle packs");
+ assert(Other.Kind != Pack && "FIXME: Handle packs");
+
+ if (Kind == Other.Kind && Kind == Integral) {
+ // Copy integral values.
+ *this->getAsIntegral() = *Other.getAsIntegral();
+ Integer.Type = Other.Integer.Type;
+ } else {
+ // Destroy the current integral value, if that's what we're holding.
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+
+ Kind = Other.Kind;
+
+ if (Other.Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else
+ TypeOrValue = Other.TypeOrValue;
+ }
+
+ return *this;
+ }
+
+ ~TemplateArgument() {
+ using llvm::APSInt;
+
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+ else if (Kind == Pack && Args.CopyArgs)
+ delete[] Args.Args;
+ }
+
+ /// \brief Return the kind of stored template argument.
+ ArgKind getKind() const { return Kind; }
+
+ /// \brief Determine whether this template argument has no value.
+ bool isNull() const { return Kind == Null; }
+
+ /// \brief Retrieve the template argument as a type.
+ QualType getAsType() const {
+ if (Kind != Type)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
+ }
+
+ /// \brief Retrieve the template argument as a declaration.
+ Decl *getAsDecl() const {
+ if (Kind != Declaration)
+ return 0;
+ return reinterpret_cast<Decl *>(TypeOrValue);
+ }
+
+ /// \brief Retrieve the template argument as a template name.
+ TemplateName getAsTemplate() const {
+ if (Kind != Template)
+ return TemplateName();
+
+ return TemplateName::getFromVoidPointer(
+ reinterpret_cast<void *> (TypeOrValue));
+ }
+
+ /// \brief Retrieve the template argument as an integral value.
+ llvm::APSInt *getAsIntegral() {
+ if (Kind != Integral)
+ return 0;
+ return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
+ }
+
+ const llvm::APSInt *getAsIntegral() const {
+ return const_cast<TemplateArgument*>(this)->getAsIntegral();
+ }
+
+ /// \brief Retrieve the type of the integral value.
+ QualType getIntegralType() const {
+ if (Kind != Integral)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(Integer.Type);
+ }
+
+ void setIntegralType(QualType T) {
+ assert(Kind == Integral &&
+ "Cannot set the integral type of a non-integral template argument");
+ Integer.Type = T.getAsOpaquePtr();
+ }
+
+ /// \brief Retrieve the template argument as an expression.
+ Expr *getAsExpr() const {
+ if (Kind != Expression)
+ return 0;
+
+ return reinterpret_cast<Expr *>(TypeOrValue);
+ }
+
+ /// \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(Kind == Pack);
+ return Args.Args;
+ }
+
+ /// \brief Iterator referencing one past the last argument of a template
+ /// argument pack.
+ pack_iterator pack_end() const {
+ assert(Kind == Pack);
+ return Args.Args + Args.NumArgs;
+ }
+
+ /// \brief The number of template arguments in the given template argument
+ /// pack.
+ unsigned pack_size() const {
+ assert(Kind == Pack);
+ return Args.NumArgs;
+ }
+
+ /// \brief Construct a template argument pack.
+ void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
+
+ /// \brief Used to insert TemplateArguments into FoldingSets.
+ void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const;
+};
+
+/// Location information for a TemplateArgument.
+struct TemplateArgumentLocInfo {
+private:
+ union {
+ Expr *Expression;
+ TypeSourceInfo *Declarator;
+ struct {
+ unsigned QualifierRange[2];
+ unsigned TemplateNameLoc;
+ } Template;
+ };
+
+#ifndef NDEBUG
+ enum Kind {
+ K_None,
+ K_TypeSourceInfo,
+ K_Expression,
+ K_Template
+ } Kind;
+#endif
+
+public:
+ TemplateArgumentLocInfo()
+ : Expression(0)
+#ifndef NDEBUG
+ , Kind(K_None)
+#endif
+ {}
+
+ TemplateArgumentLocInfo(TypeSourceInfo *TInfo)
+ : Declarator(TInfo)
+#ifndef NDEBUG
+ , Kind(K_TypeSourceInfo)
+#endif
+ {}
+
+ TemplateArgumentLocInfo(Expr *E)
+ : Expression(E)
+#ifndef NDEBUG
+ , Kind(K_Expression)
+#endif
+ {}
+
+ TemplateArgumentLocInfo(SourceRange QualifierRange,
+ SourceLocation TemplateNameLoc)
+#ifndef NDEBUG
+ : Kind(K_Template)
+#endif
+ {
+ Template.QualifierRange[0] = QualifierRange.getBegin().getRawEncoding();
+ Template.QualifierRange[1] = QualifierRange.getEnd().getRawEncoding();
+ Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
+ }
+
+ TypeSourceInfo *getAsTypeSourceInfo() const {
+ assert(Kind == K_TypeSourceInfo);
+ return Declarator;
+ }
+
+ Expr *getAsExpr() const {
+ assert(Kind == K_Expression);
+ return Expression;
+ }
+
+ SourceRange getTemplateQualifierRange() const {
+ assert(Kind == K_Template);
+ return SourceRange(
+ SourceLocation::getFromRawEncoding(Template.QualifierRange[0]),
+ SourceLocation::getFromRawEncoding(Template.QualifierRange[1]));
+ }
+
+ SourceLocation getTemplateNameLoc() const {
+ assert(Kind == K_Template);
+ return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
+ }
+
+#ifndef NDEBUG
+ void validateForArgument(const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Type:
+ assert(Kind == K_TypeSourceInfo);
+ break;
+ case TemplateArgument::Expression:
+ case TemplateArgument::Declaration:
+ assert(Kind == K_Expression);
+ break;
+ case TemplateArgument::Template:
+ assert(Kind == K_Template);
+ break;
+ case TemplateArgument::Integral:
+ case TemplateArgument::Pack:
+ assert(Kind == K_None);
+ break;
+ case TemplateArgument::Null:
+ llvm_unreachable("source info for null template argument?");
+ }
+ }
+#endif
+};
+
+/// 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,
+ SourceRange QualifierRange,
+ SourceLocation TemplateNameLoc)
+ : Argument(Argument), LocInfo(QualifierRange, TemplateNameLoc) {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ }
+
+ /// \brief - Fetches the primary location of the argument.
+ SourceLocation getLocation() const {
+ if (Argument.getKind() == TemplateArgument::Template)
+ return getTemplateNameLoc();
+
+ return getSourceRange().getBegin();
+ }
+
+ /// \brief - Fetches the full source range of the argument.
+ SourceRange getSourceRange() const;
+
+ 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();
+ }
+
+ SourceRange getTemplateQualifierRange() const {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ return LocInfo.getTemplateQualifierRange();
+ }
+
+ SourceLocation getTemplateNameLoc() const {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ return LocInfo.getTemplateNameLoc();
+ }
+};
+
+/// A convenient class for passing around template argument
+/// information. Designed to be passed by reference.
+class TemplateArgumentListInfo {
+ llvm::SmallVector<TemplateArgumentLoc, 8> Arguments;
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+
+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();
+ }
+
+ const TemplateArgumentLoc &operator[](unsigned I) const {
+ return Arguments[I];
+ }
+
+ void addArgument(const TemplateArgumentLoc &Loc) {
+ Arguments.push_back(Loc);
+ }
+};
+
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const TemplateArgument &Arg);
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h
new file mode 100644
index 0000000..2e3b6df
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h
@@ -0,0 +1,372 @@
+//===--- 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 "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "clang/Basic/OperatorKinds.h"
+
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace clang {
+
+class DependentTemplateName;
+class DiagnosticBuilder;
+class IdentifierInfo;
+class NestedNameSpecifier;
+struct PrintingPolicy;
+class QualifiedTemplateName;
+class NamedDecl;
+class TemplateDecl;
+
+/// \brief A structure for storing the information associated with an
+/// overloaded template name.
+class OverloadedTemplateStorage {
+ union {
+ unsigned Size;
+ NamedDecl *Storage[1];
+ };
+
+ friend class ASTContext;
+
+ OverloadedTemplateStorage(unsigned Size) : Size(Size) {}
+
+ NamedDecl **getStorage() {
+ return &Storage[1];
+ }
+ NamedDecl * const *getStorage() const {
+ return &Storage[1];
+ }
+
+public:
+ typedef NamedDecl *const *iterator;
+
+ unsigned size() const { return Size; }
+
+ iterator begin() const { return getStorage(); }
+ iterator end() const { return getStorage() + size(); }
+};
+
+/// \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 *,
+ OverloadedTemplateStorage *,
+ QualifiedTemplateName *,
+ DependentTemplateName *> StorageType;
+
+ StorageType Storage;
+
+ explicit TemplateName(void *Ptr) {
+ Storage = StorageType::getFromOpaqueValue(Ptr);
+ }
+
+public:
+ TemplateName() : Storage() { }
+ explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
+ explicit TemplateName(OverloadedTemplateStorage *Storage)
+ : Storage(Storage) { }
+ explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
+ explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
+
+ /// \brief Determine whether this template name is NULL.
+ bool isNull() const { return Storage.isNull(); }
+
+ /// \brief Retrieve the 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 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 {
+ return Storage.dyn_cast<OverloadedTemplateStorage *>();
+ }
+
+ /// \brief Retrieve the underlying qualified template name
+ /// structure, if any.
+ QualifiedTemplateName *getAsQualifiedTemplateName() const {
+ return Storage.dyn_cast<QualifiedTemplateName *>();
+ }
+
+ /// \brief Retrieve the underlying dependent template name
+ /// structure, if any.
+ DependentTemplateName *getAsDependentTemplateName() const {
+ return Storage.dyn_cast<DependentTemplateName *>();
+ }
+
+ /// \brief Determines whether this is a dependent template name.
+ bool isDependent() 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(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
+ bool SuppressNNS = false) 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 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/contrib/llvm/tools/clang/include/clang/AST/Type.h b/contrib/llvm/tools/clang/include/clang/AST/Type.h
new file mode 100644
index 0000000..c24bddb
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/Type.h
@@ -0,0 +1,3527 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Type interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPE_H
+#define LLVM_CLANG_AST_TYPE_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Linkage.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/type_traits.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+namespace clang {
+ enum {
+ TypeAlignmentInBits = 3,
+ 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 TypedefDecl;
+ class TemplateDecl;
+ class TemplateTypeParmDecl;
+ class NonTypeTemplateParmDecl;
+ class TemplateTemplateParmDecl;
+ class TagDecl;
+ class RecordDecl;
+ class CXXRecordDecl;
+ class EnumDecl;
+ class FieldDecl;
+ class ObjCInterfaceDecl;
+ class ObjCProtocolDecl;
+ class ObjCMethodDecl;
+ class UnresolvedUsingTypenameDecl;
+ class Expr;
+ class Stmt;
+ class SourceLocation;
+ class StmtIteratorBase;
+ class TemplateArgument;
+ class TemplateArgumentLoc;
+ class TemplateArgumentListInfo;
+ class Type;
+ class ElaboratedType;
+ 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"
+
+/// Qualifiers - 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 {
+ /// The maximum supported address space number.
+ /// 24 bits should be enough for anyone.
+ MaxAddressSpace = 0xffffffu,
+
+ /// The width of the "fast" qualifier mask.
+ FastWidth = 2,
+
+ /// The fast qualifier mask.
+ FastMask = (1 << FastWidth) - 1
+ };
+
+ Qualifiers() : Mask(0) {}
+
+ 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);
+ }
+
+ 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;
+ }
+
+ /// hasNonFastQualifiers - 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;
+ }
+
+ /// hasQualifiers - Return true if the set contains any qualifiers.
+ bool hasQualifiers() const { return Mask; }
+ bool empty() const { return !Mask; }
+
+ /// \brief 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());
+ }
+ }
+
+ bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
+ bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
+
+ 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;
+ }
+
+ std::string getAsString() const;
+ std::string getAsString(const PrintingPolicy &Policy) const {
+ std::string Buffer;
+ getAsStringInternal(Buffer, Policy);
+ return Buffer;
+ }
+ void getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger(Mask);
+ }
+
+private:
+
+ // bits: |0 1 2|3 .. 4|5 .. 31|
+ // |C R V|GCAttr|AddrSpace|
+ uint32_t Mask;
+
+ static const uint32_t GCAttrMask = 0x18;
+ static const uint32_t GCAttrShift = 3;
+ static const uint32_t AddressSpaceMask = ~(CVRMask | GCAttrMask);
+ static const uint32_t AddressSpaceShift = 5;
+};
+
+
+/// ExtQuals - We can encode up to three 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' and 'restrict' qualifiers in
+/// two low bits on the QualType pointer; a third bit records whether
+/// the pointer is an ExtQuals node. 'const' was chosen because it is
+/// orders of magnitude more common than the other two qualifiers, in
+/// both library and user code. It's relatively rare to see
+/// 'restrict' in user code, but many standard C headers are saturated
+/// with 'restrict' declarations, so that representing them efficiently
+/// is a critical goal of this representation.
+class ExtQuals : 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.
+
+ /// Context - the context to which this set belongs. We save this
+ /// here so that QualifierCollector can use it to reapply extended
+ /// qualifiers to an arbitrary type without requiring a context to
+ /// be pushed through every single API dealing with qualifiers.
+ ASTContext& Context;
+
+ /// BaseType - the underlying type that this qualifies
+ const Type *BaseType;
+
+ /// Quals - the immutable set of qualifiers applied by this
+ /// node; always contains extended qualifiers.
+ Qualifiers Quals;
+
+public:
+ ExtQuals(ASTContext& Context, const Type *Base, Qualifiers Quals)
+ : Context(Context), BaseType(Base), 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 hasVolatile() const { return Quals.hasVolatile(); }
+
+ bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
+ Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
+
+ bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
+ unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
+
+ const Type *getBaseType() const { return BaseType; }
+
+ ASTContext &getContext() const { return Context; }
+
+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);
+ }
+};
+
+/// CallingConv - Specifies the calling convention that a function uses.
+enum CallingConv {
+ CC_Default,
+ CC_C, // __attribute__((cdecl))
+ CC_X86StdCall, // __attribute__((stdcall))
+ CC_X86FastCall, // __attribute__((fastcall))
+ CC_X86ThisCall // __attribute__((thiscall))
+};
+
+
+/// QualType - 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*>();
+ }
+
+ QualType getUnqualifiedTypeSlow() const;
+
+ 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 should really return a const Type, but it's not worth
+ /// changing all the users right now.
+ Type *getTypePtr() const {
+ if (hasLocalNonFastQualifiers())
+ return const_cast<Type*>(getExtQualsUnsafe()->getBaseType());
+ return const_cast<Type*>(getTypePtrUnsafe());
+ }
+
+ void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+ static QualType getFromOpaquePtr(void *Ptr) {
+ QualType T;
+ T.Value.setFromOpaqueValue(Ptr);
+ return T;
+ }
+
+ Type &operator*() const {
+ return *getTypePtr();
+ }
+
+ Type *operator->() const {
+ return getTypePtr();
+ }
+
+ bool isCanonical() const;
+ bool isCanonicalAsParam() const;
+
+ /// isNull - 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 (hasLocalNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
+ }
+
+ /// \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 {
+ Qualifiers Quals;
+ if (hasLocalNonFastQualifiers())
+ Quals = getExtQualsUnsafe()->getQualifiers();
+ Quals.addFastQualifiers(getLocalFastQualifiers());
+ return Quals;
+ }
+
+ /// \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 {
+ unsigned CVR = getLocalFastQualifiers();
+ if (isLocalVolatileQualified())
+ CVR |= Qualifiers::Volatile;
+ return CVR;
+ }
+
+ /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// applied to this type.
+ unsigned getCVRQualifiers() const;
+
+ /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// applied to this type, looking through any number of unqualified array
+ /// types to their element types' qualifiers.
+ unsigned getCVRQualifiersThroughArrayTypes() const;
+
+ bool isConstant(ASTContext& Ctx) const {
+ return QualType::isConstant(*this, Ctx);
+ }
+
+ // Don't promise in the API that anything besides 'const' can be
+ // easily added.
+
+ /// addConst - add the specified type qualifier to this QualType.
+ void addConst() {
+ addFastQualifiers(Qualifiers::Const);
+ }
+ QualType withConst() const {
+ return withFastQualifiers(Qualifiers::Const);
+ }
+
+ void addFastQualifiers(unsigned TQs) {
+ assert(!(TQs & ~Qualifiers::FastMask)
+ && "non-fast qualifier bits set in mask!");
+ Value.setInt(Value.getInt() | TQs);
+ }
+
+ // FIXME: The remove* functions are semantically broken, because they might
+ // not remove a qualifier stored on a typedef. Most of the with* functions
+ // have the same problem.
+ void removeConst();
+ void removeVolatile();
+ void removeRestrict();
+ void removeCVRQualifiers(unsigned Mask);
+
+ void removeFastQualifiers() { Value.setInt(0); }
+ void removeFastQualifiers(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 withExactFastQualifiers(unsigned TQs) const {
+ return withoutFastQualifiers().withFastQualifiers(TQs);
+ }
+
+ // Removes fast qualifiers, but leaves any extended qualifiers in place.
+ QualType withoutFastQualifiers() const {
+ QualType T = *this;
+ T.removeFastQualifiers();
+ return T;
+ }
+
+ /// \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 Return the unqualified form of the given type, which might be
+ /// desugared to eliminate qualifiers introduced via typedefs.
+ QualType getUnqualifiedType() const {
+ QualType T = getLocalUnqualifiedType();
+ if (!T.hasQualifiers())
+ return T;
+
+ return getUnqualifiedTypeSlow();
+ }
+
+ bool isMoreQualifiedThan(QualType Other) const;
+ bool isAtLeastAsQualifiedAs(QualType Other) const;
+ QualType getNonReferenceType() const;
+
+ /// getDesugaredType - 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 {
+ return QualType::getDesugaredType(*this);
+ }
+
+ /// operator==/!= - 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;
+
+ std::string getAsString(const PrintingPolicy &Policy) const {
+ std::string S;
+ getAsStringInternal(S, Policy);
+ return S;
+ }
+ void getAsStringInternal(std::string &Str,
+ const PrintingPolicy &Policy) const;
+
+ void dump(const char *s) const;
+ void dump() const;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddPointer(getAsOpaquePtr());
+ }
+
+ /// getAddressSpace - Return the address space of this type.
+ inline unsigned getAddressSpace() const;
+
+ /// GCAttrTypesAttr - Returns gc attribute of this type.
+ inline Qualifiers::GC getObjCGCAttr() const;
+
+ /// isObjCGCWeak true when Type is objc's weak.
+ bool isObjCGCWeak() const {
+ return getObjCGCAttr() == Qualifiers::Weak;
+ }
+
+ /// isObjCGCStrong true when Type is objc's strong.
+ bool isObjCGCStrong() const {
+ return getObjCGCAttr() == Qualifiers::Strong;
+ }
+
+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);
+};
+
+} // 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<const ::clang::QualType> {
+ typedef ::clang::Type* SimpleType;
+ static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
+ return Val.getTypePtr();
+ }
+};
+template<> struct simplify_type< ::clang::QualType>
+ : public simplify_type<const ::clang::QualType> {};
+
+// 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 {
+
+/// Type - This is 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:
+ 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&); // DO NOT IMPLEMENT.
+ void operator=(const Type&); // DO NOT IMPLEMENT.
+
+ QualType CanonicalType;
+
+ /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
+ unsigned TC : 8;
+
+ /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
+ /// Note that this should stay at the end of the ivars for Type so that
+ /// subclasses can pack their bitfields into the same word.
+ bool Dependent : 1;
+
+ /// \brief Whether the linkage of this type is already known.
+ mutable bool LinkageKnown : 1;
+
+ /// \brief Linkage of this type.
+ mutable unsigned CachedLinkage : 2;
+
+protected:
+ /// \brief Compute the linkage of this type.
+ virtual Linkage getLinkageImpl() const;
+
+ enum { BitsRemainingInType = 20 };
+
+ // silence VC++ warning C4355: 'this' : used in base member initializer list
+ Type *this_() { return this; }
+ Type(TypeClass tc, QualType Canonical, bool dependent)
+ : CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
+ TC(tc), Dependent(dependent), LinkageKnown(false),
+ CachedLinkage(NoLinkage) {}
+ virtual ~Type() {}
+ virtual void Destroy(ASTContext& C);
+ friend class ASTContext;
+
+public:
+ TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
+
+ bool isCanonicalUnqualified() const {
+ return CanonicalType.getTypePtr() == this;
+ }
+
+ /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
+ /// object types, function types, and incomplete types.
+
+ /// \brief Determines whether the type describes an object in memory.
+ ///
+ /// Note that this definition of object type corresponds to the C++
+ /// definition of object type, which includes incomplete types, as
+ /// opposed to the C definition (which does not include incomplete
+ /// types).
+ bool isObjectType() const;
+
+ /// isIncompleteType - 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.
+ bool isIncompleteType() const;
+
+ /// isIncompleteOrObjectType - Return true if this is an incomplete or object
+ /// type, in other words, not a function type.
+ bool isIncompleteOrObjectType() const {
+ return !isFunctionType();
+ }
+
+ /// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
+ bool isPODType() const;
+
+ /// isLiteralType - Return true if this is a literal type
+ /// (C++0x [basic.types]p10)
+ bool isLiteralType() const;
+
+ /// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
+ /// types that have a non-constant expression. This does not include "[]".
+ bool isVariablyModifiedType() const;
+
+ /// Helper methods to distinguish type categories. All type predicates
+ /// operate on the canonical type, ignoring typedefs and qualifiers.
+
+ /// isSpecificBuiltinType - Test for a particular builtin type.
+ bool isSpecificBuiltinType(unsigned K) 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 isAnyCharacterType() const;
+ bool isIntegralType() 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 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 isDerivedType() const; // C99 6.2.5p20
+ bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
+ bool isAggregateType() 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 isArrayType() const;
+ bool isConstantArrayType() const;
+ bool isIncompleteArrayType() const;
+ bool isVariableArrayType() const;
+ bool isDependentSizedArrayType() const;
+ bool isRecordType() const;
+ bool isClassType() const;
+ bool isStructureType() 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 *any* ObjC object.
+ // 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 isObjCIdType() const; // id
+ bool isObjCClassType() const; // Class
+ bool isObjCSelType() const; // Class
+ bool isObjCBuiltinType() const; // 'id' or 'Class'
+ bool isTemplateTypeParmType() const; // C++ template type parameter
+ bool isNullPtrType() const; // C++0x nullptr_t
+
+ /// isDependentType - 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 Dependent; }
+ bool isOverloadableType() const;
+
+ /// \brief Determine wither this type is a C++ elaborated-type-specifier.
+ bool isElaboratedTypeSpecifier() const;
+
+ /// hasPointerRepresentation - 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;
+
+ /// hasObjCPointerRepresentation - Whether this type can represent
+ /// an objective pointer type for the purpose of GC'ability
+ bool hasObjCPointerRepresentation() 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.
+ // 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 ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
+ const CXXRecordDecl *getCXXRecordDeclForPointerType() 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;
+
+ // Member-template getAs<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;
+
+ /// getArrayElementTypeNoTypeQual - If this is an array type, return the
+ /// element type of the array, potentially with type qualifiers missing.
+ /// This method should never be used when type qualifiers are meaningful.
+ const Type *getArrayElementTypeNoTypeQual() const;
+
+ /// getPointeeType - If this is a pointer, ObjC object pointer, or block
+ /// pointer, this returns the respective pointee.
+ QualType getPointeeType() const;
+
+ /// getUnqualifiedDesugaredType() - 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
+
+ /// isSignedIntegerType - Return true if this is an integer type that is
+ /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
+ /// an enum decl which has a signed representation, or a vector of signed
+ /// integer element type.
+ bool isSignedIntegerType() const;
+
+ /// isUnsignedIntegerType - Return true if this is an integer type that is
+ /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
+ /// decl which has an unsigned representation, or a vector of unsigned integer
+ /// element type.
+ bool isUnsignedIntegerType() const;
+
+ /// isConstantSizeType - 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;
+
+ /// isSpecifierType - Returns true if this type can be represented by some
+ /// set of type specifiers.
+ bool isSpecifierType() const;
+
+ /// \brief Determine the linkage of this type.
+ Linkage getLinkage() const;
+
+ /// \brief Note that the linkage is no longer known.
+ void ClearLinkageCache();
+
+ const char *getTypeClassName() const;
+
+ QualType getCanonicalTypeInternal() const {
+ return CanonicalType;
+ }
+ CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
+ void dump() const;
+ static bool classof(const Type *) { return true; }
+};
+
+template <> inline const TypedefType *Type::getAs() const {
+ return dyn_cast<TypedefType>(this);
+}
+
+// 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); \
+}
+#include "clang/AST/TypeNodes.def"
+
+
+/// BuiltinType - 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 {
+ Void,
+
+ Bool, // This is bool and/or _Bool.
+ Char_U, // This is 'char' for targets where char is unsigned.
+ UChar, // This is explicitly qualified unsigned char.
+ Char16, // This is 'char16_t' for C++.
+ Char32, // This is 'char32_t' for C++.
+ UShort,
+ UInt,
+ ULong,
+ ULongLong,
+ UInt128, // __uint128_t
+
+ Char_S, // This is 'char' for targets where char is signed.
+ SChar, // This is explicitly qualified signed char.
+ WChar, // This is 'wchar_t' for C++.
+ Short,
+ Int,
+ Long,
+ LongLong,
+ Int128, // __int128_t
+
+ Float, Double, LongDouble,
+
+ NullPtr, // This is the type of C++0x 'nullptr'.
+
+ Overload, // This represents the type of an overloaded function declaration.
+ Dependent, // This represents the type of a type-dependent expression.
+
+ UndeducedAuto, // In C++0x, this represents the type of an auto variable
+ // that has not been deduced yet.
+
+ /// The primitive Objective C 'id' type. The type pointed to by the
+ /// user-visible 'id' type. Only ever shows up in an AST as the base
+ /// type of an ObjCObjectType.
+ ObjCId,
+
+ /// The primitive Objective C 'Class' type. The type pointed to by the
+ /// user-visible 'Class' type. Only ever shows up in an AST as the
+ /// base type of an ObjCObjectType.
+ ObjCClass,
+
+ ObjCSel // This represents the ObjC 'SEL' type.
+ };
+private:
+ Kind TypeKind;
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
+public:
+ BuiltinType(Kind K)
+ : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent)),
+ TypeKind(K) {}
+
+ Kind getKind() const { return TypeKind; }
+ const char *getName(const LangOptions &LO) const;
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ bool isInteger() const {
+ return TypeKind >= Bool && TypeKind <= Int128;
+ }
+
+ bool isSignedInteger() const {
+ return TypeKind >= Char_S && TypeKind <= Int128;
+ }
+
+ bool isUnsignedInteger() const {
+ return TypeKind >= Bool && TypeKind <= UInt128;
+ }
+
+ bool isFloatingPoint() const {
+ return TypeKind >= Float && TypeKind <= LongDouble;
+ }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
+ static bool classof(const BuiltinType *) { return true; }
+};
+
+/// ComplexType - C99 6.2.5p11 - Complex values. 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()),
+ ElementType(Element) {
+ }
+ friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
+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; }
+ static bool classof(const ComplexType *) { return true; }
+};
+
+/// 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()), PointeeType(Pointee) {
+ }
+ friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
+public:
+
+ 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() == Pointer; }
+ static bool classof(const PointerType *) { return true; }
+};
+
+/// BlockPointerType - 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()),
+ PointeeType(Pointee) {
+ }
+ friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
+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;
+ }
+ static bool classof(const BlockPointerType *) { return true; }
+};
+
+/// ReferenceType - Base for LValueReferenceType and RValueReferenceType
+///
+class ReferenceType : public Type, public llvm::FoldingSetNode {
+ QualType PointeeType;
+
+ /// 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
+ bool SpelledAsLValue;
+
+ /// True if the inner type is a reference type. This only happens
+ /// in non-canonical forms.
+ bool InnerRef;
+
+protected:
+ ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
+ bool SpelledAsLValue) :
+ Type(tc, CanonicalRef, Referencee->isDependentType()),
+ PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
+ InnerRef(Referencee->isReferenceType()) {
+ }
+
+ virtual Linkage getLinkageImpl() const;
+
+public:
+ bool isSpelledAsLValue() const { return SpelledAsLValue; }
+ bool isInnerRef() const { return InnerRef; }
+
+ QualType getPointeeTypeAsWritten() const { return PointeeType; }
+ QualType getPointeeType() const {
+ // FIXME: this might strip inner qualifiers; okay?
+ const ReferenceType *T = this;
+ while (T->InnerRef)
+ T = T->PointeeType->getAs<ReferenceType>();
+ return T->PointeeType;
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, PointeeType, SpelledAsLValue);
+ }
+ 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;
+ }
+ static bool classof(const ReferenceType *) { return true; }
+};
+
+/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference
+///
+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;
+ }
+ static bool classof(const LValueReferenceType *) { return true; }
+};
+
+/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference
+///
+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;
+ }
+ static bool classof(const RValueReferenceType *) { return true; }
+};
+
+/// MemberPointerType - C++ 8.3.3 - Pointers to members
+///
+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()),
+ PointeeType(Pointee), Class(Cls) {
+ }
+ friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
+public:
+
+ QualType getPointeeType() const { return PointeeType; }
+
+ const Type *getClass() const { return Class; }
+
+ 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;
+ }
+ static bool classof(const MemberPointerType *) { return true; }
+};
+
+/// ArrayType - C99 6.7.5.2 - Array Declarators.
+///
+class ArrayType : public Type, public llvm::FoldingSetNode {
+public:
+ /// ArraySizeModifier - 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:
+ /// ElementType - The element type of the array.
+ QualType ElementType;
+
+ // NOTE: VC++ treats enums as signed, avoid using the ArraySizeModifier enum
+ /// NOTE: These fields are packed into the bitfields space in the Type class.
+ unsigned SizeModifier : 2;
+
+ /// IndexTypeQuals - Capture qualifiers in declarations like:
+ /// 'int X[static restrict 4]'. For function parameters only.
+ unsigned IndexTypeQuals : 3;
+
+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)
+ : Type(tc, can, et->isDependentType() || tc == DependentSizedArray),
+ ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
+
+ friend class ASTContext; // ASTContext creates these.
+
+ virtual Linkage getLinkageImpl() const;
+
+public:
+ QualType getElementType() const { return ElementType; }
+ ArraySizeModifier getSizeModifier() const {
+ return ArraySizeModifier(SizeModifier);
+ }
+ Qualifiers getIndexTypeQualifiers() const {
+ return Qualifiers::fromCVRMask(IndexTypeQuals);
+ }
+ unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == ConstantArray ||
+ T->getTypeClass() == VariableArray ||
+ T->getTypeClass() == IncompleteArray ||
+ T->getTypeClass() == DependentSizedArray;
+ }
+ static bool classof(const ArrayType *) { return true; }
+};
+
+/// ConstantArrayType - This class 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),
+ Size(size) {}
+protected:
+ ConstantArrayType(TypeClass tc, QualType et, QualType can,
+ const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
+ : ArrayType(tc, et, can, sm, tq), 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); }
+
+ 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;
+ }
+ static bool classof(const ConstantArrayType *) { return true; }
+};
+
+/// IncompleteArrayType - This class represents C arrays 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) {}
+ 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;
+ }
+ static bool classof(const IncompleteArrayType *) { return true; }
+
+ 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);
+ }
+};
+
+/// VariableArrayType - This class represents C arrays with a specified size
+/// which 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 {
+ /// SizeExpr - An assignment expression. VLA's are only permitted within
+ /// a function block.
+ Stmt *SizeExpr;
+ /// Brackets - 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),
+ SizeExpr((Stmt*) e), Brackets(brackets) {}
+ friend class ASTContext; // ASTContext creates these.
+ virtual void Destroy(ASTContext& C);
+
+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;
+ }
+ static bool classof(const VariableArrayType *) { return true; }
+
+ friend class StmtIteratorBase;
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ assert(0 && "Cannnot unique VariableArrayTypes.");
+ }
+};
+
+/// DependentSizedArrayType - This type 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 {
+ 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;
+
+ /// Brackets - The left and right array brackets.
+ SourceRange Brackets;
+
+ DependentSizedArrayType(ASTContext &Context, QualType et, QualType can,
+ Expr *e, ArraySizeModifier sm, unsigned tq,
+ SourceRange brackets)
+ : ArrayType(DependentSizedArray, et, can, sm, tq),
+ Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {}
+ friend class ASTContext; // ASTContext creates these.
+ virtual void Destroy(ASTContext& C);
+
+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;
+ }
+ static bool classof(const DependentSizedArrayType *) { return true; }
+
+ friend class StmtIteratorBase;
+
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, getElementType(),
+ getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+ QualType ET, ArraySizeModifier SizeMod,
+ unsigned TypeQuals, Expr *E);
+};
+
+/// DependentSizedExtVectorType - This type represent 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 {
+ ASTContext &Context;
+ Expr *SizeExpr;
+ /// ElementType - The element type of the array.
+ QualType ElementType;
+ SourceLocation loc;
+
+ DependentSizedExtVectorType(ASTContext &Context, QualType ElementType,
+ QualType can, Expr *SizeExpr, SourceLocation loc)
+ : Type (DependentSizedExtVector, can, true),
+ Context(Context), SizeExpr(SizeExpr), ElementType(ElementType),
+ loc(loc) {}
+ friend class ASTContext;
+ virtual void Destroy(ASTContext& C);
+
+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;
+ }
+ static bool classof(const DependentSizedExtVectorType *) { return true; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, getElementType(), getSizeExpr());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+ QualType ElementType, Expr *SizeExpr);
+};
+
+
+/// VectorType - 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 {
+protected:
+ /// ElementType - The element type of the vector.
+ QualType ElementType;
+
+ /// NumElements - The number of elements in the vector.
+ unsigned NumElements;
+
+ /// AltiVec - True if this is for an Altivec vector.
+ bool AltiVec;
+
+ /// Pixel - True if this is for an Altivec vector pixel.
+ bool Pixel;
+
+ VectorType(QualType vecType, unsigned nElements, QualType canonType,
+ bool isAltiVec, bool isPixel) :
+ Type(Vector, canonType, vecType->isDependentType()),
+ ElementType(vecType), NumElements(nElements),
+ AltiVec(isAltiVec), Pixel(isPixel) {}
+ VectorType(TypeClass tc, QualType vecType, unsigned nElements,
+ QualType canonType, bool isAltiVec, bool isPixel)
+ : Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
+ NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
+ friend class ASTContext; // ASTContext creates these.
+
+ virtual Linkage getLinkageImpl() const;
+
+public:
+
+ QualType getElementType() const { return ElementType; }
+ unsigned getNumElements() const { return NumElements; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ bool isAltiVec() const { return AltiVec; }
+
+ bool isPixel() const { return Pixel; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getElementType(), getNumElements(), getTypeClass(),
+ AltiVec, Pixel);
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
+ unsigned NumElements, TypeClass TypeClass,
+ bool isAltiVec, bool isPixel) {
+ ID.AddPointer(ElementType.getAsOpaquePtr());
+ ID.AddInteger(NumElements);
+ ID.AddInteger(TypeClass);
+ ID.AddBoolean(isAltiVec);
+ ID.AddBoolean(isPixel);
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
+ }
+ static bool classof(const VectorType *) { return true; }
+};
+
+/// 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, false, false) {}
+ 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) < NumElements;
+ return false;
+ }
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == ExtVector;
+ }
+ static bool classof(const ExtVectorType *) { return true; }
+};
+
+/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
+/// class of FunctionNoProtoType and FunctionProtoType.
+///
+class FunctionType : public Type {
+ virtual void ANCHOR(); // Key function for FunctionType.
+
+ /// SubClassData - This field is owned by the subclass, put here to pack
+ /// tightly with the ivars in Type.
+ bool SubClassData : 1;
+
+ /// TypeQuals - 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;
+
+ /// NoReturn - Indicates if the function type is attribute noreturn.
+ unsigned NoReturn : 1;
+
+ /// RegParm - How many arguments to pass inreg.
+ unsigned RegParm : 3;
+
+ /// CallConv - The calling convention used by the function.
+ unsigned CallConv : 3;
+
+ // The type returned by the function.
+ QualType ResultType;
+
+ public:
+ // This class is used for passing arround the information needed to
+ // construct a call. It is not actually used for storage, just for
+ // factoring together common arguments.
+ // If you add a field (say Foo), other than the obvious places (both, constructors,
+ // compile failures), what you need to update is
+ // * Operetor==
+ // * getFoo
+ // * withFoo
+ // * functionType. Add Foo, getFoo.
+ // * ASTContext::getFooType
+ // * ASTContext::mergeFunctionTypes
+ // * FunctionNoProtoType::Profile
+ // * FunctionProtoType::Profile
+ // * TypePrinter::PrintFunctionProto
+ // * PCH read and write
+ // * Codegen
+
+ class ExtInfo {
+ public:
+ // Constructor with no defaults. Use this when you know that you
+ // have all the elements (when reading a PCH file for example).
+ ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) :
+ NoReturn(noReturn), RegParm(regParm), CC(cc) {}
+
+ // Constructor with all defaults. Use when for example creating a
+ // function know to use defaults.
+ ExtInfo() : NoReturn(false), RegParm(0), CC(CC_Default) {}
+
+ bool getNoReturn() const { return NoReturn; }
+ unsigned getRegParm() const { return RegParm; }
+ CallingConv getCC() const { return CC; }
+
+ bool operator==(const ExtInfo &Other) const {
+ return getNoReturn() == Other.getNoReturn() &&
+ getRegParm() == Other.getRegParm() &&
+ getCC() == Other.getCC();
+ }
+ bool operator!=(const ExtInfo &Other) const {
+ return !(*this == Other);
+ }
+
+ // 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 {
+ return ExtInfo(noReturn, getRegParm(), getCC());
+ }
+
+ ExtInfo withRegParm(unsigned RegParm) const {
+ return ExtInfo(getNoReturn(), RegParm, getCC());
+ }
+
+ ExtInfo withCallingConv(CallingConv cc) const {
+ return ExtInfo(getNoReturn(), getRegParm(), cc);
+ }
+
+ private:
+ // True if we have __attribute__((noreturn))
+ bool NoReturn;
+ // The value passed to __attribute__((regparm(x)))
+ unsigned RegParm;
+ // The calling convention as specified via
+ // __attribute__((cdecl|stdcall|fastcall|thiscall))
+ CallingConv CC;
+ };
+
+protected:
+ FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
+ unsigned typeQuals, QualType Canonical, bool Dependent,
+ const ExtInfo &Info)
+ : Type(tc, Canonical, Dependent),
+ SubClassData(SubclassInfo), TypeQuals(typeQuals),
+ NoReturn(Info.getNoReturn()),
+ RegParm(Info.getRegParm()), CallConv(Info.getCC()), ResultType(res) {}
+ bool getSubClassData() const { return SubClassData; }
+ unsigned getTypeQuals() const { return TypeQuals; }
+public:
+
+ QualType getResultType() const { return ResultType; }
+ unsigned getRegParmType() const { return RegParm; }
+ bool getNoReturnAttr() const { return NoReturn; }
+ CallingConv getCallConv() const { return (CallingConv)CallConv; }
+ ExtInfo getExtInfo() const {
+ return ExtInfo(NoReturn, RegParm, (CallingConv)CallConv);
+ }
+
+ static llvm::StringRef getNameForCallConv(CallingConv CC);
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == FunctionNoProto ||
+ T->getTypeClass() == FunctionProto;
+ }
+ static bool classof(const FunctionType *) { return true; }
+};
+
+/// FunctionNoProtoType - 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,
+ const ExtInfo &Info)
+ : FunctionType(FunctionNoProto, Result, false, 0, Canonical,
+ /*Dependent=*/false, Info) {}
+ friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
+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, getResultType(), getExtInfo());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
+ const ExtInfo &Info) {
+ ID.AddInteger(Info.getCC());
+ ID.AddInteger(Info.getRegParm());
+ ID.AddInteger(Info.getNoReturn());
+ ID.AddPointer(ResultType.getAsOpaquePtr());
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == FunctionNoProto;
+ }
+ static bool classof(const FunctionNoProtoType *) { return true; }
+};
+
+/// FunctionProtoType - Represents a prototype with argument type info, e.g.
+/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
+/// arguments, not as having a single void argument. 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 {
+ /// hasAnyDependentType - Determine whether there are any dependent
+ /// types within the arguments passed in.
+ static bool hasAnyDependentType(const QualType *ArgArray, unsigned numArgs) {
+ for (unsigned Idx = 0; Idx < numArgs; ++Idx)
+ if (ArgArray[Idx]->isDependentType())
+ return true;
+
+ return false;
+ }
+
+ FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs,
+ bool isVariadic, unsigned typeQuals, bool hasExs,
+ bool hasAnyExs, const QualType *ExArray,
+ unsigned numExs, QualType Canonical,
+ const ExtInfo &Info)
+ : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
+ (Result->isDependentType() ||
+ hasAnyDependentType(ArgArray, numArgs)),
+ Info),
+ NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs),
+ AnyExceptionSpec(hasAnyExs) {
+ // Fill in the trailing argument array.
+ QualType *ArgInfo = reinterpret_cast<QualType*>(this+1);
+ for (unsigned i = 0; i != numArgs; ++i)
+ ArgInfo[i] = ArgArray[i];
+ // Fill in the exception array.
+ QualType *Ex = ArgInfo + numArgs;
+ for (unsigned i = 0; i != numExs; ++i)
+ Ex[i] = ExArray[i];
+ }
+
+ /// NumArgs - The number of arguments this function has, not counting '...'.
+ unsigned NumArgs : 20;
+
+ /// NumExceptions - The number of types in the exception spec, if any.
+ unsigned NumExceptions : 10;
+
+ /// HasExceptionSpec - Whether this function has an exception spec at all.
+ bool HasExceptionSpec : 1;
+
+ /// AnyExceptionSpec - Whether this function has a throw(...) spec.
+ bool AnyExceptionSpec : 1;
+
+ /// ArgInfo - There is an variable size array after the class in memory that
+ /// holds the argument types.
+
+ /// Exceptions - There is another variable size array after ArgInfo that
+ /// holds the exception types.
+
+ friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
+public:
+ unsigned getNumArgs() const { return NumArgs; }
+ QualType getArgType(unsigned i) const {
+ assert(i < NumArgs && "Invalid argument number!");
+ return arg_type_begin()[i];
+ }
+
+ bool hasExceptionSpec() const { return HasExceptionSpec; }
+ bool hasAnyExceptionSpec() const { return AnyExceptionSpec; }
+ unsigned getNumExceptions() const { return NumExceptions; }
+ QualType getExceptionType(unsigned i) const {
+ assert(i < NumExceptions && "Invalid exception number!");
+ return exception_begin()[i];
+ }
+ bool hasEmptyExceptionSpec() const {
+ return hasExceptionSpec() && !hasAnyExceptionSpec() &&
+ getNumExceptions() == 0;
+ }
+
+ bool isVariadic() const { return getSubClassData(); }
+ unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
+
+ typedef const QualType *arg_type_iterator;
+ arg_type_iterator arg_type_begin() const {
+ return reinterpret_cast<const QualType *>(this+1);
+ }
+ arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
+
+ typedef const QualType *exception_iterator;
+ exception_iterator exception_begin() const {
+ // exceptions begin where arguments end
+ return arg_type_end();
+ }
+ exception_iterator exception_end() const {
+ return exception_begin() + NumExceptions;
+ }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == FunctionProto;
+ }
+ static bool classof(const FunctionProtoType *) { return true; }
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
+ arg_type_iterator ArgTys, unsigned NumArgs,
+ bool isVariadic, unsigned TypeQuals,
+ bool hasExceptionSpec, bool anyExceptionSpec,
+ unsigned NumExceptions, exception_iterator Exs,
+ const ExtInfo &ExtInfo);
+};
+
+
+/// \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),
+ 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;
+ }
+ static bool classof(const UnresolvedUsingType *) { return true; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ return Profile(ID, Decl);
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ UnresolvedUsingTypenameDecl *D) {
+ ID.AddPointer(D);
+ }
+};
+
+
+class TypedefType : public Type {
+ TypedefDecl *Decl;
+protected:
+ TypedefType(TypeClass tc, const TypedefDecl *D, QualType can)
+ : Type(tc, can, can->isDependentType()),
+ Decl(const_cast<TypedefDecl*>(D)) {
+ assert(!isa<TypedefType>(can) && "Invalid canonical type");
+ }
+ friend class ASTContext; // ASTContext creates these.
+public:
+
+ TypedefDecl *getDecl() const { return Decl; }
+
+ /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
+ /// potentially looking through *all* consecutive typedefs. This returns the
+ /// sum of the type qualifiers, so if you have:
+ /// typedef const int A;
+ /// typedef volatile A B;
+ /// looking through the typedefs for B will give you "const volatile A".
+ QualType LookThroughTypedefs() const;
+
+ bool isSugared() const { return true; }
+ QualType desugar() const;
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
+ static bool classof(const TypedefType *) { return true; }
+};
+
+/// TypeOfExprType (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 { return true; }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
+ static bool classof(const TypeOfExprType *) { return true; }
+};
+
+/// \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 {
+ ASTContext &Context;
+
+public:
+ DependentTypeOfExprType(ASTContext &Context, Expr *E)
+ : TypeOfExprType(E), Context(Context) { }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, getUnderlyingExpr());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+ Expr *E);
+};
+
+/// TypeOfType (GCC extension).
+class TypeOfType : public Type {
+ QualType TOType;
+ TypeOfType(QualType T, QualType can)
+ : Type(TypeOf, can, T->isDependentType()), 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; }
+ static bool classof(const TypeOfType *) { return true; }
+};
+
+/// DecltypeType (C++0x)
+class DecltypeType : public Type {
+ Expr *E;
+
+ // FIXME: We could get rid of UnderlyingType if we wanted to: We would have to
+ // Move getDesugaredType to ASTContext so that it can call getDecltypeForExpr
+ // from it.
+ 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 { return getUnderlyingType(); }
+
+ /// \brief Returns whether this type directly provides sugar.
+ bool isSugared() const { return !isDependentType(); }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
+ static bool classof(const DecltypeType *) { return true; }
+};
+
+/// \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 {
+ ASTContext &Context;
+
+public:
+ DependentDecltypeType(ASTContext &Context, Expr *E);
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, getUnderlyingExpr());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+ Expr *E);
+};
+
+class TagType : public Type {
+ /// Stores the TagDecl associated with this type. The decl will
+ /// point to the TagDecl that actually defines the entity (or is a
+ /// definition in progress), if there is such a definition. The
+ /// single-bit value will be non-zero when this tag is in the
+ /// process of being defined.
+ mutable llvm::PointerIntPair<TagDecl *, 1> decl;
+ friend class ASTContext;
+ friend class TagDecl;
+
+protected:
+ TagType(TypeClass TC, const TagDecl *D, QualType can);
+
+ virtual Linkage getLinkageImpl() const;
+
+public:
+ TagDecl *getDecl() const { return decl.getPointer(); }
+
+ /// @brief Determines whether this type is in the process of being
+ /// defined.
+ bool isBeingDefined() const { return decl.getInt(); }
+ void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
+ }
+ static bool classof(const TagType *) { return true; }
+ static bool classof(const RecordType *) { return true; }
+ static bool classof(const EnumType *) { return true; }
+};
+
+/// RecordType - This is 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; }
+
+ // FIXME: RecordType needs to check when it is created that all fields are in
+ // the same address space, and return that.
+ unsigned getAddressSpace() const { return 0; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const TagType *T);
+ static bool classof(const Type *T) {
+ return isa<TagType>(T) && classof(cast<TagType>(T));
+ }
+ static bool classof(const RecordType *) { return true; }
+};
+
+/// EnumType - This is 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 TagType *T);
+ static bool classof(const Type *T) {
+ return isa<TagType>(T) && classof(cast<TagType>(T));
+ }
+ static bool classof(const EnumType *) { return true; }
+};
+
+class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+ unsigned Depth : 15;
+ unsigned Index : 16;
+ unsigned ParameterPack : 1;
+ IdentifierInfo *Name;
+
+ TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N,
+ QualType Canon)
+ : Type(TemplateTypeParm, Canon, /*Dependent=*/true),
+ Depth(D), Index(I), ParameterPack(PP), Name(N) { }
+
+ TemplateTypeParmType(unsigned D, unsigned I, bool PP)
+ : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true),
+ Depth(D), Index(I), ParameterPack(PP), Name(0) { }
+
+ friend class ASTContext; // ASTContext creates these
+
+public:
+ unsigned getDepth() const { return Depth; }
+ unsigned getIndex() const { return Index; }
+ bool isParameterPack() const { return ParameterPack; }
+ IdentifierInfo *getName() const { return Name; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Depth, Index, ParameterPack, Name);
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
+ unsigned Index, bool ParameterPack,
+ IdentifierInfo *Name) {
+ ID.AddInteger(Depth);
+ ID.AddInteger(Index);
+ ID.AddBoolean(ParameterPack);
+ ID.AddPointer(Name);
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == TemplateTypeParm;
+ }
+ static bool classof(const TemplateTypeParmType *T) { return true; }
+};
+
+/// \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()),
+ Replaced(Param) { }
+
+ friend class ASTContext;
+
+public:
+ IdentifierInfo *getName() const { return Replaced->getName(); }
+
+ /// 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;
+ }
+ static bool classof(const SubstTemplateTypeParmType *T) { return true; }
+};
+
+/// \brief Represents the type of a template specialization as written
+/// in the source code.
+///
+/// Template specialization types represent the syntactic form of a
+/// template-id that refers to a type, e.g., @c vector<int>. Some
+/// template specialization types are syntactic sugar, whose canonical
+/// type will point to some other type node that represents the
+/// instantiation or class template specialization. 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>>.
+///
+/// Other template specialization types, for which the template name
+/// is dependent, may be canonical types. These types are always
+/// dependent.
+class TemplateSpecializationType
+ : public Type, public llvm::FoldingSetNode {
+
+ // The ASTContext is currently needed in order to profile expressions.
+ // FIXME: avoid this.
+ //
+ // The bool is whether this is a current instantiation.
+ llvm::PointerIntPair<ASTContext*, 1, bool> ContextAndCurrentInstantiation;
+
+ /// \brief The name of the template being specialized.
+ TemplateName Template;
+
+ /// \brief - The number of template arguments named in this class
+ /// template specialization.
+ unsigned NumArgs;
+
+ TemplateSpecializationType(ASTContext &Context,
+ TemplateName T,
+ bool IsCurrentInstantiation,
+ const TemplateArgument *Args,
+ unsigned NumArgs, QualType Canon);
+
+ virtual void Destroy(ASTContext& C);
+
+ friend class ASTContext; // ASTContext creates these
+
+public:
+ /// \brief Determine whether any of the given template arguments are
+ /// dependent.
+ static bool anyDependentTemplateArguments(const TemplateArgument *Args,
+ unsigned NumArgs);
+
+ static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
+ unsigned NumArgs);
+
+ static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &);
+
+ /// \brief Print a template argument list, including the '<' and '>'
+ /// enclosing the template arguments.
+ static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
+ unsigned NumArgs,
+ const PrintingPolicy &Policy);
+
+ static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args,
+ unsigned NumArgs,
+ const PrintingPolicy &Policy);
+
+ static std::string PrintTemplateArgumentList(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 ContextAndCurrentInstantiation.getInt();
+ }
+
+ typedef const TemplateArgument * iterator;
+
+ iterator begin() const { return getArgs(); }
+ iterator end() const;
+
+ /// \brief Retrieve the name of the template that we are specializing.
+ TemplateName getTemplateName() const { return Template; }
+
+ /// \brief Retrieve the template arguments.
+ const TemplateArgument *getArgs() const {
+ return reinterpret_cast<const TemplateArgument *>(this + 1);
+ }
+
+ /// \brief Retrieve the number of template arguments.
+ unsigned getNumArgs() const { return NumArgs; }
+
+ /// \brief Retrieve a specific template argument as a type.
+ /// \precondition @c isArgType(Arg)
+ const TemplateArgument &getArg(unsigned Idx) const;
+
+ bool isSugared() const {
+ return !isDependentType() || isCurrentInstantiation();
+ }
+ QualType desugar() const { return getCanonicalTypeInternal(); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Template, isCurrentInstantiation(), getArgs(), NumArgs,
+ *ContextAndCurrentInstantiation.getPointer());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
+ bool IsCurrentInstantiation,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
+ ASTContext &Context);
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == TemplateSpecialization;
+ }
+ static bool classof(const TemplateSpecializationType *T) { return true; }
+};
+
+/// \brief 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 TagDecl; // TagDecl mutilates the Decl
+ InjectedClassNameType(CXXRecordDecl *D, QualType TST)
+ : Type(InjectedClassName, QualType(), true),
+ 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 { return Decl; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == InjectedClassName;
+ }
+ static bool classof(const InjectedClassNameType *T) { return true; }
+};
+
+/// \brief The kind of a tag type.
+enum TagTypeKind {
+ /// \brief The "struct" keyword.
+ TTK_Struct,
+ /// \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 "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 {
+ /// Keyword - Encodes an ElaboratedTypeKeyword enumeration constant.
+ unsigned Keyword : 3;
+
+protected:
+ TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
+ QualType Canonical, bool dependent)
+ : Type(tc, Canonical, dependent), Keyword(Keyword) {}
+
+public:
+ virtual ~TypeWithKeyword(); // pin vtable to Type.cpp
+
+ ElaboratedTypeKeyword getKeyword() const {
+ return static_cast<ElaboratedTypeKeyword>(Keyword);
+ }
+
+ /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST)
+ /// into an elaborated type keyword.
+ static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
+
+ /// getTagTypeKindForTypeSpec - 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);
+
+ /// getKeywordForTagDeclKind - Converts a TagTypeKind into an
+ /// elaborated type keyword.
+ static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
+
+ /// getTagTypeKindForKeyword - 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 const char *getKeywordName(ElaboratedTypeKeyword Keyword);
+
+ static const char *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 {
+
+ /// \brief The nested name specifier containing the qualifier.
+ NestedNameSpecifier *NNS;
+
+ /// \brief 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()),
+ NNS(NNS), NamedType(NamedType) {
+ assert(!(Keyword == ETK_None && NNS == 0) &&
+ "ElaboratedType cannot have elaborated type keyword "
+ "and name qualifier both null.");
+ }
+
+ friend class ASTContext; // ASTContext creates these
+
+public:
+
+ /// \brief Retrieve the qualification on this type.
+ NestedNameSpecifier *getQualifier() const { return NNS; }
+
+ /// \brief Retrieve the type named by the qualified-id.
+ QualType getNamedType() const { return NamedType; }
+
+ /// \brief Remove a single level of sugar.
+ QualType desugar() const { return getNamedType(); }
+
+ /// \brief 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;
+ }
+ static bool classof(const ElaboratedType *T) { return true; }
+};
+
+/// \brief Represents a qualified type name for which the type name is
+/// dependent.
+///
+/// DependentNameType represents a class of dependent types that involve a
+/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent)
+/// 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).
+class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
+
+ /// \brief The nested name specifier containing the qualifier.
+ NestedNameSpecifier *NNS;
+
+ typedef llvm::PointerUnion<const IdentifierInfo *,
+ const TemplateSpecializationType *> NameType;
+
+ /// \brief The type that this typename specifier refers to.
+ NameType Name;
+
+ DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name, QualType CanonType)
+ : TypeWithKeyword(Keyword, DependentName, CanonType, true),
+ NNS(NNS), Name(Name) {
+ assert(NNS->isDependent() &&
+ "DependentNameType requires a dependent nested-name-specifier");
+ }
+
+ DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+ const TemplateSpecializationType *Ty, QualType CanonType)
+ : TypeWithKeyword(Keyword, DependentName, CanonType, true),
+ NNS(NNS), Name(Ty) {
+ assert(NNS->isDependent() &&
+ "DependentNameType requires a dependent nested-name-specifier");
+ }
+
+ friend class ASTContext; // ASTContext creates these
+
+public:
+
+ /// \brief Retrieve the qualification on this type.
+ NestedNameSpecifier *getQualifier() const { return NNS; }
+
+ /// \brief 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.dyn_cast<const IdentifierInfo *>();
+ }
+
+ /// \brief Retrieve the type named by the typename specifier as a
+ /// type specialization.
+ const TemplateSpecializationType *getTemplateId() const {
+ return Name.dyn_cast<const TemplateSpecializationType *>();
+ }
+
+ 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, NameType Name) {
+ ID.AddInteger(Keyword);
+ ID.AddPointer(NNS);
+ ID.AddPointer(Name.getOpaqueValue());
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == DependentName;
+ }
+ static bool classof(const DependentNameType *T) { return true; }
+};
+
+/// ObjCObjectType - Represents a class type in Objective C.
+/// Every Objective C type is a combination of a base type and a
+/// list of protocols.
+///
+/// Given the following declarations:
+/// @class C;
+/// @protocol P;
+///
+/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType
+/// with base C and no protocols.
+///
+/// 'C<P>' is an ObjCObjectType with base C and protocol list [P].
+///
+/// 'id' is a TypedefType which is sugar for an ObjCPointerType whose
+/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType
+/// and no protocols.
+///
+/// 'id<P>' is an ObjCPointerType whose pointee is an ObjCObjecType
+/// 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 {
+ // Pad the bit count up so that NumProtocols is 2-byte aligned
+ unsigned : BitsRemainingInType - 16;
+
+ /// \brief The number of protocols stored after the
+ /// ObjCObjectPointerType node.
+ ///
+ /// These protocols are those written directly on the type. If
+ /// protocol qualifiers ever become additive, the iterators will
+ /// get kindof complicated.
+ ///
+ /// In the canonical object type, these are sorted alphabetically
+ /// and uniqued.
+ unsigned NumProtocols : 16;
+
+ /// Either a BuiltinType or an InterfaceType or sugar for either.
+ QualType BaseType;
+
+ ObjCProtocolDecl * const *getProtocolStorage() const {
+ return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
+ }
+
+ ObjCProtocolDecl **getProtocolStorage();
+
+protected:
+ ObjCObjectType(QualType Canonical, QualType Base,
+ ObjCProtocolDecl * const *Protocols, unsigned NumProtocols);
+
+ enum Nonce_ObjCInterface { Nonce_ObjCInterface };
+ ObjCObjectType(enum Nonce_ObjCInterface)
+ : Type(ObjCInterface, QualType(), false),
+ NumProtocols(0),
+ BaseType(QualType(this_(), 0)) {}
+
+protected:
+ Linkage getLinkageImpl() const; // key function
+
+public:
+ /// getBaseType - 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 ObjCPointerType)
+ /// - 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;
+
+ typedef ObjCProtocolDecl * const *qual_iterator;
+
+ qual_iterator qual_begin() const { return getProtocolStorage(); }
+ qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
+
+ bool qual_empty() const { return getNumProtocols() == 0; }
+
+ /// getNumProtocols - Return the number of qualifying protocols in this
+ /// interface type, or 0 if there are none.
+ unsigned getNumProtocols() const { return NumProtocols; }
+
+ /// \brief Fetch a protocol by index.
+ ObjCProtocolDecl *getProtocol(unsigned I) const {
+ assert(I < getNumProtocols() && "Out-of-range protocol access");
+ return qual_begin()[I];
+ }
+
+ 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;
+ }
+ static bool classof(const ObjCObjectType *) { return true; }
+};
+
+/// ObjCObjectTypeImpl - 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,
+ ObjCProtocolDecl * const *Protocols,
+ unsigned NumProtocols)
+ : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {}
+
+public:
+ void Destroy(ASTContext& C); // key function
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ QualType Base,
+ ObjCProtocolDecl *const *protocols,
+ unsigned NumProtocols);
+};
+
+inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
+ return reinterpret_cast<ObjCProtocolDecl**>(
+ static_cast<ObjCObjectTypeImpl*>(this) + 1);
+}
+
+/// ObjCInterfaceType - 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 {
+ ObjCInterfaceDecl *Decl;
+
+ ObjCInterfaceType(const ObjCInterfaceDecl *D)
+ : ObjCObjectType(Nonce_ObjCInterface),
+ Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
+ friend class ASTContext; // ASTContext creates these.
+public:
+ void Destroy(ASTContext& C); // key function
+
+ /// getDecl - 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;
+ }
+ static bool classof(const ObjCInterfaceType *) { return true; }
+
+ // 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 {
+ if (const ObjCInterfaceType *T =
+ getBaseType()->getAs<ObjCInterfaceType>())
+ return T->getDecl();
+ return 0;
+}
+
+/// ObjCObjectPointerType - Used to represent 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, false),
+ PointeeType(Pointee) {}
+ friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
+public:
+ void Destroy(ASTContext& C);
+
+ /// getPointeeType - Gets the type pointed to by this ObjC pointer.
+ /// The result will always be an ObjCObjectType or sugar thereof.
+ QualType getPointeeType() const { return PointeeType; }
+
+ /// getObjCObjectType - Gets the type pointed to by this ObjC
+ /// pointer. This method 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:
+ /// @class A; @protocol P; @protocol Q;
+ /// typedef A<P> AP;
+ /// typedef A A1;
+ /// typedef A1<P> A1P;
+ /// typedef A1P<Q> A1PQ;
+ /// 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->getAs<ObjCObjectType>();
+ }
+
+ /// getInterfaceType - 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 {
+ return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>();
+ }
+
+ /// getInterfaceDecl - 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();
+ }
+
+ /// isObjCIdType - 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();
+ }
+
+ /// isObjCClassType - 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();
+ }
+
+ /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some
+ /// non-empty set of protocols.
+ bool isObjCQualifiedIdType() const {
+ return getObjectType()->isObjCQualifiedId();
+ }
+
+ /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for
+ /// some non-empty set of protocols.
+ bool isObjCQualifiedClassType() const {
+ return getObjectType()->isObjCQualifiedClass();
+ }
+
+ /// 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;
+
+ 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(); }
+
+ /// getNumProtocols - Return the number of qualifying protocols on
+ /// the object type.
+ unsigned getNumProtocols() const {
+ return getObjectType()->getNumProtocols();
+ }
+
+ /// \brief 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); }
+
+ 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;
+ }
+ static bool classof(const ObjCObjectPointerType *) { return true; }
+};
+
+/// A qualifier set is used to build a set of qualifiers.
+class QualifierCollector : public Qualifiers {
+ ASTContext *Context;
+
+public:
+ QualifierCollector(Qualifiers Qs = Qualifiers())
+ : Qualifiers(Qs), Context(0) {}
+ QualifierCollector(ASTContext &Context, Qualifiers Qs = Qualifiers())
+ : Qualifiers(Qs), Context(&Context) {}
+
+ void setContext(ASTContext &C) { Context = &C; }
+
+ /// Collect any qualifiers on the given type and return an
+ /// unqualified type.
+ const Type *strip(QualType QT) {
+ addFastQualifiers(QT.getLocalFastQualifiers());
+ if (QT.hasLocalNonFastQualifiers()) {
+ const ExtQuals *EQ = QT.getExtQualsUnsafe();
+ Context = &EQ->getContext();
+ addQualifiers(EQ->getQualifiers());
+ return EQ->getBaseType();
+ }
+ return QT.getTypePtrUnsafe();
+ }
+
+ /// Apply the collected qualifiers to the given type.
+ QualType apply(QualType QT) const;
+
+ /// Apply the collected qualifiers to the given type.
+ QualType apply(const Type* T) const;
+
+};
+
+
+// Inline function definitions.
+
+inline bool QualType::isCanonical() const {
+ const Type *T = getTypePtr();
+ if (hasLocalQualifiers())
+ return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
+ return T->isCanonicalUnqualified();
+}
+
+inline bool QualType::isCanonicalAsParam() const {
+ if (hasLocalQualifiers()) return false;
+ const Type *T = getTypePtr();
+ return T->isCanonicalUnqualified() &&
+ !isa<FunctionType>(T) && !isa<ArrayType>(T);
+}
+
+inline bool QualType::isConstQualified() const {
+ return isLocalConstQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalConstQualified();
+}
+
+inline bool QualType::isRestrictQualified() const {
+ return isLocalRestrictQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalRestrictQualified();
+}
+
+
+inline bool QualType::isVolatileQualified() const {
+ return isLocalVolatileQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalVolatileQualified();
+}
+
+inline bool QualType::hasQualifiers() const {
+ return hasLocalQualifiers() ||
+ getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers();
+}
+
+inline Qualifiers QualType::getQualifiers() const {
+ Qualifiers Quals = getLocalQualifiers();
+ Quals.addQualifiers(
+ getTypePtr()->getCanonicalTypeInternal().getLocalQualifiers());
+ return Quals;
+}
+
+inline unsigned QualType::getCVRQualifiers() const {
+ return getLocalCVRQualifiers() |
+ getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers();
+}
+
+/// getCVRQualifiersThroughArrayTypes - If there are CVR qualifiers for this
+/// type, returns them. Otherwise, if this is an array type, recurses
+/// on the element type until some qualifiers have been found or a non-array
+/// type reached.
+inline unsigned QualType::getCVRQualifiersThroughArrayTypes() const {
+ if (unsigned Quals = getCVRQualifiers())
+ return Quals;
+ QualType CT = getTypePtr()->getCanonicalTypeInternal();
+ if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
+ return AT->getElementType().getCVRQualifiersThroughArrayTypes();
+ return 0;
+}
+
+inline void QualType::removeConst() {
+ removeFastQualifiers(Qualifiers::Const);
+}
+
+inline void QualType::removeRestrict() {
+ removeFastQualifiers(Qualifiers::Restrict);
+}
+
+inline void QualType::removeVolatile() {
+ QualifierCollector Qc;
+ const Type *Ty = Qc.strip(*this);
+ if (Qc.hasVolatile()) {
+ Qc.removeVolatile();
+ *this = Qc.apply(Ty);
+ }
+}
+
+inline void QualType::removeCVRQualifiers(unsigned Mask) {
+ assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
+
+ // Fast path: we don't need to touch the slow qualifiers.
+ if (!(Mask & ~Qualifiers::FastMask)) {
+ removeFastQualifiers(Mask);
+ return;
+ }
+
+ QualifierCollector Qc;
+ const Type *Ty = Qc.strip(*this);
+ Qc.removeCVRQualifiers(Mask);
+ *this = Qc.apply(Ty);
+}
+
+/// getAddressSpace - Return the address space of this type.
+inline unsigned QualType::getAddressSpace() const {
+ if (hasLocalNonFastQualifiers()) {
+ const ExtQuals *EQ = getExtQualsUnsafe();
+ if (EQ->hasAddressSpace())
+ return EQ->getAddressSpace();
+ }
+
+ QualType CT = getTypePtr()->getCanonicalTypeInternal();
+ if (CT.hasLocalNonFastQualifiers()) {
+ const ExtQuals *EQ = CT.getExtQualsUnsafe();
+ if (EQ->hasAddressSpace())
+ return EQ->getAddressSpace();
+ }
+
+ if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
+ return AT->getElementType().getAddressSpace();
+ if (const RecordType *RT = dyn_cast<RecordType>(CT))
+ return RT->getAddressSpace();
+ return 0;
+}
+
+/// getObjCGCAttr - Return the gc attribute of this type.
+inline Qualifiers::GC QualType::getObjCGCAttr() const {
+ if (hasLocalNonFastQualifiers()) {
+ const ExtQuals *EQ = getExtQualsUnsafe();
+ if (EQ->hasObjCGCAttr())
+ return EQ->getObjCGCAttr();
+ }
+
+ QualType CT = getTypePtr()->getCanonicalTypeInternal();
+ if (CT.hasLocalNonFastQualifiers()) {
+ const ExtQuals *EQ = CT.getExtQualsUnsafe();
+ if (EQ->hasObjCGCAttr())
+ return EQ->getObjCGCAttr();
+ }
+
+ if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
+ return AT->getElementType().getObjCGCAttr();
+ if (const ObjCObjectPointerType *PT = CT->getAs<ObjCObjectPointerType>())
+ return PT->getPointeeType().getObjCGCAttr();
+ // We most look at all pointer types, not just pointer to interface types.
+ if (const PointerType *PT = CT->getAs<PointerType>())
+ return PT->getPointeeType().getObjCGCAttr();
+ return Qualifiers::GCNone;
+}
+
+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);
+}
+
+/// isMoreQualifiedThan - 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 {
+ // FIXME: work on arbitrary qualifiers
+ unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes();
+ unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes();
+ if (getAddressSpace() != Other.getAddressSpace())
+ return false;
+ return MyQuals != OtherQuals && (MyQuals | OtherQuals) == MyQuals;
+}
+
+/// isAtLeastAsQualifiedAs - 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 {
+ // FIXME: work on arbitrary qualifiers
+ unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes();
+ unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes();
+ if (getAddressSpace() != Other.getAddressSpace())
+ return false;
+ return (MyQuals | OtherQuals) == MyQuals;
+}
+
+/// getNonReferenceType - 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 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->getPointeeType()->isFunctionType();
+ 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::isRecordType() const {
+ return isa<RecordType>(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::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::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;
+}
+
+/// \brief Determines whether this is a type for which one can define
+/// an overloaded operator.
+inline bool Type::isOverloadableType() const {
+ return isDependentType() || isRecordType() || isEnumeralType();
+}
+
+inline bool Type::hasPointerRepresentation() const {
+ return (isPointerType() || isReferenceType() || isBlockPointerType() ||
+ isObjCObjectPointerType() || isNullPtrType());
+}
+
+inline bool Type::hasObjCPointerRepresentation() const {
+ return isObjCObjectPointerType();
+}
+
+/// 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()),
+ Diagnostic::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()),
+ Diagnostic::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 = (llvm::is_same<T, ArrayType>::value ||
+ llvm::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 0;
+
+ // If this is a typedef for the type, strip the typedef off without
+ // losing all typedef information.
+ return cast<T>(getUnqualifiedDesugaredType());
+}
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h
new file mode 100644
index 0000000..f988f0e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h
@@ -0,0 +1,1308 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TypeLoc interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPELOC_H
+#define LLVM_CLANG_AST_TYPELOC_H
+
+#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Basic/Specifiers.h"
+
+namespace clang {
+ 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 cast/dyn_cast 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
+ void *Ty;
+ void *Data;
+
+public:
+ /// 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(0), Data(0) { }
+ TypeLoc(QualType ty, void *opaqueData)
+ : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
+ TypeLoc(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; }
+ 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 Get the type for which this source info wrapper provides
+ /// information.
+ QualType getType() const {
+ return QualType::getFromOpaquePtr(Ty);
+ }
+
+ 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 {
+ return SourceRange(getBeginLoc(), 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
+
+ /// \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(SourceLocation Loc) const {
+ initializeImpl(*this, Loc);
+ }
+
+ 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);
+ }
+
+ static bool classof(const TypeLoc *TL) { return true; }
+
+private:
+ static void initializeImpl(TypeLoc TL, SourceLocation Loc);
+ static TypeLoc getNextTypeLocImpl(TypeLoc TL);
+ static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
+};
+
+/// \brief Return the TypeLoc for a type source info.
+inline TypeLoc TypeSourceInfo::getTypeLoc() const {
+ return TypeLoc(Ty, (void*)(this + 1));
+}
+
+/// \brief Wrapper of type source information for a type with
+/// no direct quqlaifiers.
+class UnqualTypeLoc : public TypeLoc {
+public:
+ UnqualTypeLoc() {}
+ UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
+
+ Type *getTypePtr() const {
+ return reinterpret_cast<Type*>(Ty);
+ }
+
+ TypeLocClass getTypeLocClass() const {
+ return (TypeLocClass) getTypePtr()->getTypeClass();
+ }
+
+ static bool classof(const TypeLoc *TL) {
+ return !TL->getType().hasLocalQualifiers();
+ }
+ static bool classof(const UnqualTypeLoc *TL) { return true; }
+};
+
+/// \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 {
+ return UnqualTypeLoc(getTypePtr(), Data);
+ }
+
+ /// Initializes the local data of this type source info block to
+ /// provide no information.
+ void initializeLocal(SourceLocation Loc) {
+ // 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 size of the type source info data block.
+ unsigned getFullDataSize() const {
+ return getLocalDataSize() +
+ getFullDataSizeForType(getType().getLocalUnqualifiedType());
+ }
+
+ static bool classof(const TypeLoc *TL) {
+ return TL->getType().hasLocalQualifiers();
+ }
+ static bool classof(const QualifiedTypeLoc *TL) { return true; }
+};
+
+inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
+ if (isa<QualifiedTypeLoc>(this))
+ return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
+ return cast<UnqualTypeLoc>(*this);
+}
+
+/// 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.
+///
+/// \param Base a class from which to derive
+/// \param Derived the class deriving from this one
+/// \param TypeClass the concrete Type subclass associated with this
+/// location type
+/// \param LocalData the structure type of local location data for
+/// this type
+///
+/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
+/// else the world will end.
+///
+/// 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);
+ }
+
+public:
+ unsigned getLocalDataSize() const {
+ return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
+ }
+ // Give a default implementation that's useful for leaf types.
+ unsigned getFullDataSize() const {
+ return asDerived()->getLocalDataSize() + getInnerTypeSize();
+ }
+
+ static bool classofType(const Type *Ty) {
+ return TypeClass::classof(Ty);
+ }
+
+ static bool classof(const TypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
+ }
+ static bool classof(const UnqualTypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
+ }
+ static bool classof(const Derived *TL) {
+ return true;
+ }
+
+ TypeLoc getNextTypeLoc() const {
+ return getNextTypeLoc(asDerived()->getInnerType());
+ }
+
+ TypeClass *getTypePtr() const {
+ return cast<TypeClass>(Base::getTypePtr());
+ }
+
+protected:
+ unsigned getExtraLocalDataSize() const {
+ return 0;
+ }
+
+ 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 {
+ return getLocalData() + 1;
+ }
+
+ void *getNonLocalData() const {
+ return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
+ }
+
+ 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();
+ }
+
+ 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 {
+public:
+ static bool classof(const TypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
+ }
+ static bool classof(const UnqualTypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
+ }
+ static bool classof(const Derived *TL) {
+ return true;
+ }
+
+ 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) };
+
+ SourceLocation getNameLoc() const {
+ return this->getLocalData()->NameLoc;
+ }
+ void setNameLoc(SourceLocation Loc) {
+ this->getLocalData()->NameLoc = Loc;
+ }
+ SourceRange getLocalSourceRange() const {
+ return SourceRange(getNameLoc(), getNameLoc());
+ }
+ void initializeLocal(SourceLocation Loc) {
+ setNameLoc(Loc);
+ }
+
+ static bool classof(const TypeLoc *TL);
+ static bool classof(const TypeSpecTypeLoc *TL) { return true; }
+};
+
+
+struct BuiltinLocInfo {
+ SourceLocation BuiltinLoc;
+};
+
+/// \brief Wrapper for source info for builtin types.
+class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ BuiltinTypeLoc,
+ BuiltinType,
+ BuiltinLocInfo> {
+public:
+ enum { LocalDataSize = sizeof(BuiltinLocInfo) };
+
+ 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;
+ }
+
+ 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(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:
+ TypedefDecl *getTypedefDecl() const {
+ return getTypePtr()->getDecl();
+ }
+};
+
+/// \brief Wrapper for source info for injected class names of class
+/// templates.
+class InjectedClassNameTypeLoc :
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ InjectedClassNameTypeLoc,
+ InjectedClassNameType> {
+};
+
+/// \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 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> {
+};
+
+/// \brief Wrapper for substituted template type parameters.
+class SubstTemplateTypeParmTypeLoc :
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ SubstTemplateTypeParmTypeLoc,
+ SubstTemplateTypeParmType> {
+};
+
+
+struct ObjCProtocolListLocInfo {
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+ 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,
+ ObjCProtocolListLocInfo> {
+ // SourceLocations are stored after Info, one for each Protocol.
+ SourceLocation *getProtocolLocArray() const {
+ return (SourceLocation*) this->getExtraLocalData();
+ }
+
+public:
+ 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 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);
+ }
+
+ bool hasBaseTypeAsWritten() const {
+ return getLocalData()->HasBaseTypeAsWritten;
+ }
+
+ void setHasBaseTypeAsWritten(bool HasBaseType) {
+ getLocalData()->HasBaseTypeAsWritten = HasBaseType;
+ }
+
+ TypeLoc getBaseLoc() const {
+ return getInnerTypeLoc();
+ }
+
+ SourceRange getLocalSourceRange() const {
+ return SourceRange(getLAngleLoc(), getRAngleLoc());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setHasBaseTypeAsWritten(true);
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+ setProtocolLoc(i, Loc);
+ }
+
+ unsigned getExtraLocalDataSize() const {
+ return this->getNumProtocols() * sizeof(SourceLocation);
+ }
+
+ QualType getInnerType() const {
+ return getTypePtr()->getBaseType();
+ }
+};
+
+
+struct ObjCInterfaceLocInfo {
+ SourceLocation NameLoc;
+};
+
+/// \brief Wrapper for source info for ObjC interfaces.
+class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ 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());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setNameLoc(Loc);
+ }
+};
+
+
+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(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);
+ }
+};
+
+
+/// \brief Wrapper for source info for member pointers.
+class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
+ MemberPointerType> {
+public:
+ SourceLocation getStarLoc() const {
+ return getSigilLoc();
+ }
+ void setStarLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
+ }
+};
+
+/// 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 LParenLoc, RParenLoc;
+};
+
+/// \brief Wrapper for source info for functions.
+class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ FunctionTypeLoc,
+ FunctionType,
+ FunctionLocInfo> {
+ // ParmVarDecls* are stored after Info, one for each argument.
+ ParmVarDecl **getParmArray() const {
+ return (ParmVarDecl**) getExtraLocalData();
+ }
+
+public:
+ 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;
+ }
+
+ unsigned getNumArgs() const {
+ if (isa<FunctionNoProtoType>(getTypePtr()))
+ return 0;
+ return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
+ }
+ ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
+ void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
+
+ TypeLoc getResultLoc() const {
+ return getInnerTypeLoc();
+ }
+
+ SourceRange getLocalSourceRange() const {
+ return SourceRange(getLParenLoc(), getRParenLoc());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setLParenLoc(Loc);
+ setRParenLoc(Loc);
+ for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
+ setArg(i, NULL);
+ }
+
+ /// \brief Returns the size of the type source info data block that is
+ /// specific to this type.
+ unsigned getExtraLocalDataSize() const {
+ return getNumArgs() * sizeof(ParmVarDecl*);
+ }
+
+ QualType getInnerType() const { return getTypePtr()->getResultType(); }
+};
+
+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(SourceLocation Loc) {
+ setLBracketLoc(Loc);
+ setRBracketLoc(Loc);
+ setSizeExpr(NULL);
+ }
+
+ 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 LAngleLoc;
+ SourceLocation RAngleLoc;
+};
+
+class TemplateSpecializationTypeLoc :
+ public ConcreteTypeLoc<UnqualTypeLoc,
+ TemplateSpecializationTypeLoc,
+ TemplateSpecializationType,
+ TemplateSpecializationLocInfo> {
+public:
+ 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) {
+#ifndef NDEBUG
+ AI.validateForArgument(getTypePtr()->getArg(i));
+#endif
+ 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 {
+ return SourceRange(getTemplateNameLoc(), getRAngleLoc());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ setTemplateNameLoc(Loc);
+
+ for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
+ TemplateArgumentLocInfo Info;
+#ifndef NDEBUG
+ // If asserts are enabled, be sure to initialize the argument
+ // loc with the right kind of pointer.
+ switch (getTypePtr()->getArg(i).getKind()) {
+ case TemplateArgument::Expression:
+ case TemplateArgument::Declaration:
+ Info = TemplateArgumentLocInfo((Expr*) 0);
+ break;
+
+ case TemplateArgument::Type:
+ Info = TemplateArgumentLocInfo((TypeSourceInfo*) 0);
+ break;
+
+ case TemplateArgument::Template:
+ Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation());
+ break;
+
+ case TemplateArgument::Integral:
+ case TemplateArgument::Pack:
+ case TemplateArgument::Null:
+ // K_None is fine.
+ break;
+ }
+#endif
+ getArgInfos()[i] = Info;
+ }
+ }
+
+ unsigned getExtraLocalDataSize() const {
+ return getNumArgs() * sizeof(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(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;
+ }
+};
+
+// FIXME: location of the 'decltype' and parens.
+class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ DecltypeTypeLoc,
+ DecltypeType> {
+};
+
+struct ElaboratedLocInfo {
+ SourceLocation KeywordLoc;
+ SourceRange QualifierRange;
+};
+
+class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ ElaboratedTypeLoc,
+ ElaboratedType,
+ ElaboratedLocInfo> {
+public:
+ SourceLocation getKeywordLoc() const {
+ return this->getLocalData()->KeywordLoc;
+ }
+ void setKeywordLoc(SourceLocation Loc) {
+ this->getLocalData()->KeywordLoc = Loc;
+ }
+
+ SourceRange getQualifierRange() const {
+ return this->getLocalData()->QualifierRange;
+ }
+ void setQualifierRange(SourceRange Range) {
+ this->getLocalData()->QualifierRange = Range;
+ }
+
+ SourceRange getLocalSourceRange() const {
+ if (getKeywordLoc().isValid())
+ if (getQualifierRange().getEnd().isValid())
+ return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
+ else
+ return SourceRange(getKeywordLoc());
+ else
+ return getQualifierRange();
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setKeywordLoc(Loc);
+ setQualifierRange(SourceRange(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);
+ }
+};
+
+struct DependentNameLocInfo {
+ SourceLocation KeywordLoc;
+ SourceRange QualifierRange;
+ SourceLocation NameLoc;
+};
+
+class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ DependentNameTypeLoc,
+ DependentNameType,
+ DependentNameLocInfo> {
+public:
+ SourceLocation getKeywordLoc() const {
+ return this->getLocalData()->KeywordLoc;
+ }
+ void setKeywordLoc(SourceLocation Loc) {
+ this->getLocalData()->KeywordLoc = Loc;
+ }
+
+ SourceRange getQualifierRange() const {
+ return this->getLocalData()->QualifierRange;
+ }
+ void setQualifierRange(SourceRange Range) {
+ this->getLocalData()->QualifierRange = Range;
+ }
+
+ SourceLocation getNameLoc() const {
+ return this->getLocalData()->NameLoc;
+ }
+ void setNameLoc(SourceLocation Loc) {
+ this->getLocalData()->NameLoc = Loc;
+ }
+
+ SourceRange getLocalSourceRange() const {
+ if (getKeywordLoc().isValid())
+ return SourceRange(getKeywordLoc(), getNameLoc());
+ else
+ return SourceRange(getQualifierRange().getBegin(), getNameLoc());
+ }
+
+ void copy(DependentNameTypeLoc Loc) {
+ unsigned size = getFullDataSize();
+ assert(size == Loc.getFullDataSize());
+ memcpy(Data, Loc.Data, size);
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setKeywordLoc(Loc);
+ setQualifierRange(SourceRange(Loc));
+ setNameLoc(Loc);
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLocBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLocBuilder.h
new file mode 100644
index 0000000..e729488
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLocBuilder.h
@@ -0,0 +1,148 @@
+//===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines TypeLocBuilder, a class for building TypeLocs
+// bottom-up.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPELOCBUILDER_H
+#define LLVM_CLANG_AST_TYPELOCBUILDER_H
+
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+
+class TypeLocBuilder {
+ enum { InlineCapacity = 8 * sizeof(SourceLocation) };
+
+ /// The underlying location-data buffer. Data grows from the end
+ /// of the buffer backwards.
+ char *Buffer;
+
+ /// The capacity of the current buffer.
+ size_t Capacity;
+
+ /// The index of the first occupied byte in the buffer.
+ size_t Index;
+
+#ifndef NDEBUG
+ /// The last type pushed on this builder.
+ QualType LastTy;
+#endif
+
+ /// The inline buffer.
+ char InlineBuffer[InlineCapacity];
+
+ public:
+ TypeLocBuilder()
+ : Buffer(InlineBuffer), Capacity(InlineCapacity), Index(InlineCapacity)
+ {}
+
+ ~TypeLocBuilder() {
+ if (Buffer != InlineBuffer)
+ delete[] Buffer;
+ }
+
+ /// Ensures that this buffer has at least as much capacity as described.
+ void reserve(size_t Requested) {
+ if (Requested > Capacity)
+ // For now, match the request exactly.
+ grow(Requested);
+ }
+
+ /// Pushes a copy of the given TypeLoc onto this builder. The builder
+ /// must be empty for this to work.
+ void pushFullCopy(TypeLoc L) {
+#ifndef NDEBUG
+ assert(LastTy.isNull() && "pushing copy on non-empty TypeLocBuilder");
+ LastTy = L.getNextTypeLoc().getType();
+#endif
+ assert(Index == Capacity && "pushing copy on non-empty TypeLocBuilder");
+
+ unsigned Size = L.getFullDataSize();
+ TypeLoc Copy = pushImpl(L.getType(), Size);
+ memcpy(Copy.getOpaqueData(), L.getOpaqueData(), Size);
+ }
+
+ /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs
+ /// previously retrieved from this builder.
+ TypeSpecTypeLoc pushTypeSpec(QualType T) {
+ size_t LocalSize = TypeSpecTypeLoc::LocalDataSize;
+ return cast<TypeSpecTypeLoc>(pushImpl(T, LocalSize));
+ }
+
+
+ /// Pushes space for a new TypeLoc of the given type. Invalidates
+ /// any TypeLocs previously retrieved from this builder.
+ template <class TyLocType> TyLocType push(QualType T) {
+ size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize();
+ return cast<TyLocType>(pushImpl(T, LocalSize));
+ }
+
+ /// Creates a TypeSourceInfo for the given type.
+ TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) {
+#ifndef NDEBUG
+ assert(T == LastTy && "type doesn't match last type pushed!");
+#endif
+
+ size_t FullDataSize = Capacity - Index;
+ TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize);
+ memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
+ return DI;
+ }
+
+private:
+ TypeLoc pushImpl(QualType T, size_t LocalSize) {
+#ifndef NDEBUG
+ QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType();
+ assert(TLast == LastTy &&
+ "mismatch between last type and new type's inner type");
+ LastTy = T;
+#endif
+
+ // If we need to grow, grow by a factor of 2.
+ if (LocalSize > Index) {
+ size_t RequiredCapacity = Capacity + (LocalSize - Index);
+ size_t NewCapacity = Capacity * 2;
+ while (RequiredCapacity > NewCapacity)
+ NewCapacity *= 2;
+ grow(NewCapacity);
+ }
+
+ Index -= LocalSize;
+
+ return TypeLoc(T, &Buffer[Index]);
+ }
+
+ /// Grow to the given capacity.
+ void grow(size_t NewCapacity) {
+ assert(NewCapacity > Capacity);
+
+ // Allocate the new buffer and copy the old data into it.
+ char *NewBuffer = new char[NewCapacity];
+ unsigned NewIndex = Index + NewCapacity - Capacity;
+ memcpy(&NewBuffer[NewIndex],
+ &Buffer[Index],
+ Capacity - Index);
+
+ if (Buffer != InlineBuffer)
+ delete[] Buffer;
+
+ Buffer = NewBuffer;
+ Capacity = NewCapacity;
+ Index = NewIndex;
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLocNodes.def b/contrib/llvm/tools/clang/include/clang/AST/TypeLocNodes.def
new file mode 100644
index 0000000..4590e48
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLocNodes.def
@@ -0,0 +1,41 @@
+//===-- 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/contrib/llvm/tools/clang/include/clang/AST/TypeLocVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLocVisitor.h
new file mode 100644
index 0000000..50fc439
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLocVisitor.h
@@ -0,0 +1,62 @@
+//===--- 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(cast<CLASSNAME>(TyLoc))
+
+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/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def b/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def
new file mode 100644
index 0000000..02508af
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def
@@ -0,0 +1,119 @@
+//===-- 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 four 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(Typedef, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
+ABSTRACT_TYPE(Tag, Type)
+TYPE(Record, TagType)
+TYPE(Enum, TagType)
+NON_CANONICAL_TYPE(Elaborated, Type)
+DEPENDENT_TYPE(TemplateTypeParm, Type)
+NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
+DEPENDENT_TYPE(InjectedClassName, Type)
+DEPENDENT_TYPE(DependentName, Type)
+TYPE(ObjCObject, Type)
+TYPE(ObjCInterface, ObjCObjectType)
+TYPE(ObjCObjectPointer, Type)
+
+#ifdef LAST_TYPE
+LAST_TYPE(ObjCObjectPointer)
+#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/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h b/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h
new file mode 100644
index 0000000..1a050d2
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h
@@ -0,0 +1,56 @@
+//===-------------- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a function objects and specializations that
+// allow QualType values to be sorted, used in std::maps, std::sets,
+// llvm::DenseMaps, and llvm::DenseSets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TYPE_ORDERING_H
+#define LLVM_CLANG_TYPE_ORDERING_H
+
+#include "clang/AST/Type.h"
+#include <functional>
+
+namespace clang {
+
+/// QualTypeOrdering - 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;
+ }
+ };
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h
new file mode 100644
index 0000000..5c9c5285
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h
@@ -0,0 +1,52 @@
+//===--- 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<CLASS*>(T))
+
+template<typename ImplClass, typename RetTy=void>
+class TypeVisitor {
+public:
+ RetTy Visit(Type *T) {
+ // Top switch stmt: dispatch to VisitFooType for each FooType.
+ switch (T->getTypeClass()) {
+ default: assert(0 && "Unknown type class!");
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
+#include "clang/AST/TypeNodes.def"
+ }
+ }
+
+ // If the implementation chooses not to implement a certain visit method, fall
+ // back on superclass.
+#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(CLASS##Type *T) { \
+ DISPATCH(PARENT); \
+}
+#include "clang/AST/TypeNodes.def"
+
+ // Base case, ignore it. :)
+ RetTy VisitType(Type*) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h
new file mode 100644
index 0000000..a548b0b
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h
@@ -0,0 +1,186 @@
+//===-- 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 <iterator>
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/DeclAccessPair.h"
+
+namespace clang {
+
+/// The iterator over UnresolvedSets. Serves as both the const and
+/// non-const iterator.
+class UnresolvedSetIterator {
+private:
+ typedef llvm::SmallVectorImpl<DeclAccessPair> DeclsTy;
+ typedef DeclsTy::iterator IteratorTy;
+
+ IteratorTy ir;
+
+ friend class UnresolvedSetImpl;
+ friend class OverloadExpr;
+ explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
+ explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
+ ir(const_cast<DeclsTy::iterator>(ir)) {}
+
+ IteratorTy getIterator() const { return ir; }
+
+public:
+ UnresolvedSetIterator() {}
+
+ typedef std::iterator_traits<IteratorTy>::difference_type difference_type;
+ typedef NamedDecl *value_type;
+ typedef NamedDecl **pointer;
+ typedef NamedDecl *reference;
+ typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
+
+ NamedDecl *getDecl() const { return ir->getDecl(); }
+ AccessSpecifier getAccess() const { return ir->getAccess(); }
+ void setAccess(AccessSpecifier AS) { ir->setAccess(AS); }
+ DeclAccessPair getPair() const { return *ir; }
+
+ NamedDecl *operator*() const { return getDecl(); }
+
+ UnresolvedSetIterator &operator++() { ++ir; return *this; }
+ UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); }
+ UnresolvedSetIterator &operator--() { --ir; return *this; }
+ UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); }
+
+ UnresolvedSetIterator &operator+=(difference_type d) {
+ ir += d; return *this;
+ }
+ UnresolvedSetIterator operator+(difference_type d) const {
+ return UnresolvedSetIterator(ir + d);
+ }
+ UnresolvedSetIterator &operator-=(difference_type d) {
+ ir -= d; return *this;
+ }
+ UnresolvedSetIterator operator-(difference_type d) const {
+ return UnresolvedSetIterator(ir - d);
+ }
+ value_type operator[](difference_type d) const { return *(*this + d); }
+
+ difference_type operator-(const UnresolvedSetIterator &o) const {
+ return ir - o.ir;
+ }
+
+ bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; }
+ bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; }
+ bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; }
+ bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; }
+ bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; }
+ bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
+};
+
+/// UnresolvedSet - A set of unresolved declarations.
+class UnresolvedSetImpl {
+ typedef UnresolvedSetIterator::DeclsTy 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.ir->setDecl(New);
+ }
+
+ void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
+ I.ir->set(New, AS);
+ }
+
+ void erase(unsigned I) {
+ decls()[I] = decls().back();
+ decls().pop_back();
+ }
+
+ void erase(iterator I) {
+ *I.ir = decls().back();
+ decls().pop_back();
+ }
+
+ void setAccess(iterator I, AccessSpecifier AS) {
+ I.ir->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.ir, E.ir);
+ }
+
+ 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);
+ }
+};
+
+/// A set of unresolved declarations
+template <unsigned InlineCapacity> class UnresolvedSet :
+ public UnresolvedSetImpl {
+ llvm::SmallVector<DeclAccessPair, InlineCapacity> Decls;
+};
+
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/AST/UsuallyTinyPtrVector.h b/contrib/llvm/tools/clang/include/clang/AST/UsuallyTinyPtrVector.h
new file mode 100644
index 0000000..5ee40e0
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/UsuallyTinyPtrVector.h
@@ -0,0 +1,105 @@
+//===-- UsuallyTinyPtrVector.h - Pointer vector class -----------*- 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 UsuallyTinyPtrVector class, which is a vector that
+// optimizes the case where there is only one element.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_USUALLY_TINY_PTR_VECTOR_H
+#define LLVM_CLANG_AST_USUALLY_TINY_PTR_VECTOR_H
+
+#include <vector>
+
+namespace clang {
+
+/// \brief A vector class template that is optimized for storing a single
+/// pointer element.
+template<typename T>
+class UsuallyTinyPtrVector {
+ /// \brief Storage for the vector.
+ ///
+ /// When the low bit is zero, this is a T *. When the
+ /// low bit is one, this is a std::vector<T *> *.
+ mutable uintptr_t Storage;
+
+ typedef std::vector<T*> vector_type;
+
+public:
+ UsuallyTinyPtrVector() : Storage(0) { }
+ explicit UsuallyTinyPtrVector(T *Element)
+ : Storage(reinterpret_cast<uintptr_t>(Element)) { }
+
+ bool empty() const { return !Storage; }
+
+ typedef const T **iterator;
+ iterator begin() const;
+ iterator end() const;
+
+ void push_back(T *Method);
+ void Destroy();
+};
+
+template<typename T>
+typename UsuallyTinyPtrVector<T>::iterator
+UsuallyTinyPtrVector<T>::begin() const {
+ if ((Storage & 0x01) == 0)
+ return reinterpret_cast<iterator>(&Storage);
+
+ vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+ return &Vec->front();
+}
+
+
+template<typename T>
+typename UsuallyTinyPtrVector<T>::iterator
+UsuallyTinyPtrVector<T>::end() const {
+ if ((Storage & 0x01) == 0) {
+ if (Storage == 0)
+ return reinterpret_cast<iterator>(&Storage);
+
+ return reinterpret_cast<iterator>(&Storage) + 1;
+ }
+
+ vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+ return &Vec->front() + Vec->size();
+}
+
+template<typename T>
+void UsuallyTinyPtrVector<T>::push_back(T *Element) {
+ if (Storage == 0) {
+ // 0 -> 1 element.
+ Storage = reinterpret_cast<uintptr_t>(Element);
+ return;
+ }
+
+ vector_type *Vec;
+ if ((Storage & 0x01) == 0) {
+ // 1 -> 2 elements. Allocate a new vector and push the element into that
+ // vector.
+ Vec = new vector_type;
+ Vec->push_back(reinterpret_cast<T *>(Storage));
+ Storage = reinterpret_cast<uintptr_t>(Vec) | 0x01;
+ } else
+ Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+
+ // Add the new element to the vector.
+ Vec->push_back(Element);
+}
+
+template<typename T>
+void UsuallyTinyPtrVector<T>::Destroy() {
+ if (Storage & 0x01)
+ delete reinterpret_cast<vector_type *>(Storage & ~0x01);
+
+ Storage = 0;
+}
+
+}
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/LiveVariables.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/LiveVariables.h
new file mode 100644
index 0000000..44ab080
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/LiveVariables.h
@@ -0,0 +1,121 @@
+//===- 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_LIVEVARIABLES_H
+#define LLVM_CLANG_LIVEVARIABLES_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/Support/BlkExprDeclBitVector.h"
+#include "clang/Analysis/FlowSensitive/DataflowValues.h"
+
+namespace clang {
+
+class Stmt;
+class DeclRefExpr;
+class SourceManager;
+class AnalysisContext;
+
+struct LiveVariables_ValueTypes {
+
+ struct ObserverTy;
+
+ // We keep dataflow state for declarations and block-level expressions;
+ typedef StmtDeclBitVector_Types::ValTy ValTy;
+
+ // We need to keep track of both declarations and CFGBlock-level expressions,
+ // (so that we don't explore such expressions twice). We also want
+ // to compute liveness information for block-level expressions, since these
+ // act as "temporary" values.
+
+ struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy {
+ ObserverTy* Observer;
+ ValTy AlwaysLive;
+ AnalysisContext *AC;
+
+ AnalysisDataTy() : Observer(NULL), AC(NULL) {}
+ };
+
+ //===-----------------------------------------------------===//
+ // ObserverTy - Observer for uninitialized values queries.
+ //===-----------------------------------------------------===//
+
+ struct ObserverTy {
+ virtual ~ObserverTy() {}
+
+ /// ObserveStmt - A callback invoked right before invoking the
+ /// liveness transfer function on the given statement.
+ virtual void ObserveStmt(Stmt* S, const AnalysisDataTy& AD,
+ const ValTy& V) {}
+
+ virtual void ObserverKill(DeclRefExpr* DR) {}
+ };
+};
+
+class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
+ dataflow::backward_analysis_tag> {
+
+
+public:
+ typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
+
+ LiveVariables(AnalysisContext &AC);
+
+ /// IsLive - Return true if a variable is live at the end of a
+ /// specified block.
+ bool isLive(const CFGBlock* B, const VarDecl* D) const;
+
+ /// IsLive - 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) const;
+
+ /// IsLive - 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) const;
+
+ /// IsLive - Return true if a variable is live according to the
+ /// provided livness bitvector.
+ bool isLive(const ValTy& V, const VarDecl* D) const;
+
+ /// dumpLiveness - Print to stderr the liveness information encoded
+ /// by a specified bitvector.
+ void dumpLiveness(const ValTy& V, const SourceManager& M) const;
+
+ /// dumpBlockLiveness - Print to stderr the liveness information
+ /// associated with each basic block.
+ void dumpBlockLiveness(const SourceManager& M) const;
+
+ /// getNumDecls - Return the number of variables (declarations) that
+ /// whose liveness status is being tracked by the dataflow
+ /// analysis.
+ unsigned getNumDecls() const { return getAnalysisData().getNumDecls(); }
+
+ /// IntializeValues - This routine can perform extra initialization, but
+ /// for LiveVariables this does nothing since all that logic is in
+ /// the constructor.
+ void InitializeValues(const CFG& cfg) {}
+
+ void runOnCFG(CFG& cfg);
+
+ /// runOnAllBlocks - Propagate the dataflow values once for each block,
+ /// starting from the current dataflow values. 'recordStmtValues' indicates
+ /// whether the method should store dataflow values per each individual
+ /// block-level expression.
+ void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs,
+ bool recordStmtValues=false);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/PrintfFormatString.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/PrintfFormatString.h
new file mode 100644
index 0000000..e4f7c57
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/PrintfFormatString.h
@@ -0,0 +1,313 @@
+//==- PrintfFormatStrings.h - Analysis of printf format strings --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Handling of format string in printf and friends. The structure of format
+// strings for fprintf() are described in C99 7.19.6.1.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FPRINTF_FORMAT_H
+#define LLVM_CLANG_FPRINTF_FORMAT_H
+
+#include "clang/AST/CanonicalType.h"
+
+namespace clang {
+
+class ASTContext;
+
+namespace analyze_printf {
+
+class ArgTypeResult {
+public:
+ enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CStrTy,
+ WCStrTy };
+private:
+ const Kind K;
+ QualType T;
+ ArgTypeResult(bool) : K(InvalidTy) {}
+public:
+ ArgTypeResult(Kind k = UnknownTy) : K(k) {}
+ ArgTypeResult(QualType t) : K(SpecificTy), T(t) {}
+ ArgTypeResult(CanQualType t) : K(SpecificTy), T(t) {}
+
+ static ArgTypeResult Invalid() { return ArgTypeResult(true); }
+
+ bool isValid() const { return K != InvalidTy; }
+
+ const QualType *getSpecificType() const {
+ return K == SpecificTy ? &T : 0;
+ }
+
+ bool matchesType(ASTContext &C, QualType argTy) const;
+
+ bool matchesAnyObjCObjectRef() const { return K == ObjCPointerTy; }
+
+ QualType getRepresentativeType(ASTContext &C) const;
+};
+
+class ConversionSpecifier {
+public:
+ enum Kind {
+ InvalidSpecifier = 0,
+ // C99 conversion specifiers.
+ dArg, // 'd'
+ iArg, // 'i',
+ oArg, // 'o',
+ uArg, // 'u',
+ xArg, // 'x',
+ XArg, // 'X',
+ fArg, // 'f',
+ FArg, // 'F',
+ eArg, // 'e',
+ EArg, // 'E',
+ gArg, // 'g',
+ GArg, // 'G',
+ aArg, // 'a',
+ AArg, // 'A',
+ IntAsCharArg, // 'c'
+ CStrArg, // 's'
+ VoidPtrArg, // 'p'
+ OutIntPtrArg, // 'n'
+ PercentArg, // '%'
+ // MacOS X unicode extensions.
+ CArg, // 'C'
+ UnicodeStrArg, // 'S'
+ // Objective-C specific specifiers.
+ ObjCObjArg, // '@'
+ // GlibC specific specifiers.
+ PrintErrno, // 'm'
+ // Specifier ranges.
+ IntArgBeg = dArg,
+ IntArgEnd = iArg,
+ UIntArgBeg = oArg,
+ UIntArgEnd = XArg,
+ DoubleArgBeg = fArg,
+ DoubleArgEnd = AArg,
+ C99Beg = IntArgBeg,
+ C99End = DoubleArgEnd,
+ ObjCBeg = ObjCObjArg,
+ ObjCEnd = ObjCObjArg
+ };
+
+ ConversionSpecifier()
+ : Position(0), kind(InvalidSpecifier) {}
+
+ ConversionSpecifier(const char *pos, Kind k)
+ : Position(pos), kind(k) {}
+
+ const char *getStart() const {
+ return Position;
+ }
+
+ llvm::StringRef getCharacters() const {
+ return llvm::StringRef(getStart(), getLength());
+ }
+
+ bool consumesDataArgument() const {
+ switch (kind) {
+ case PercentArg:
+ case PrintErrno:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
+ bool isIntArg() const { return kind >= dArg && kind <= iArg; }
+ bool isUIntArg() const { return kind >= oArg && kind <= XArg; }
+ bool isDoubleArg() const { return kind >= fArg && kind <= AArg; }
+ Kind getKind() const { return kind; }
+ unsigned getLength() const {
+ // Conversion specifiers currently only are represented by
+ // single characters, but we be flexible.
+ return 1;
+ }
+
+private:
+ const char *Position;
+ Kind kind;
+};
+
+enum LengthModifier {
+ None,
+ AsChar, // 'hh'
+ AsShort, // 'h'
+ AsLong, // 'l'
+ AsLongLong, // 'll', 'q' (BSD, deprecated)
+ AsIntMax, // 'j'
+ AsSizeT, // 'z'
+ AsPtrDiff, // 't'
+ AsLongDouble, // 'L'
+ AsWideChar = AsLong // for '%ls'
+};
+
+class OptionalAmount {
+public:
+ enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
+
+ OptionalAmount(HowSpecified h, unsigned i, const char *st)
+ : start(st), hs(h), amt(i) {}
+
+ OptionalAmount(bool b = true)
+ : start(0), hs(b ? NotSpecified : Invalid), amt(0) {}
+
+ bool isInvalid() const {
+ return hs == Invalid;
+ }
+
+ HowSpecified getHowSpecified() const { return hs; }
+
+ 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 {
+ return start;
+ }
+
+ ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+private:
+ const char *start;
+ HowSpecified hs;
+ unsigned amt;
+};
+
+class FormatSpecifier {
+ LengthModifier LM;
+ unsigned IsLeftJustified : 1;
+ unsigned HasPlusPrefix : 1;
+ unsigned HasSpacePrefix : 1;
+ unsigned HasAlternativeForm : 1;
+ unsigned HasLeadingZeroes : 1;
+ /// Positional arguments, an IEEE extension:
+ /// IEEE Std 1003.1, 2004 Edition
+ /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
+ unsigned UsesPositionalArg : 1;
+ unsigned argIndex;
+ ConversionSpecifier CS;
+ OptionalAmount FieldWidth;
+ OptionalAmount Precision;
+public:
+ FormatSpecifier() : LM(None),
+ IsLeftJustified(0), HasPlusPrefix(0), HasSpacePrefix(0),
+ HasAlternativeForm(0), HasLeadingZeroes(0), UsesPositionalArg(0),
+ argIndex(0) {}
+
+ static FormatSpecifier Parse(const char *beg, const char *end);
+
+ // Methods for incrementally constructing the FormatSpecifier.
+ void setConversionSpecifier(const ConversionSpecifier &cs) {
+ CS = cs;
+ }
+ void setLengthModifier(LengthModifier lm) {
+ LM = lm;
+ }
+ void setIsLeftJustified() { IsLeftJustified = 1; }
+ void setHasPlusPrefix() { HasPlusPrefix = 1; }
+ void setHasSpacePrefix() { HasSpacePrefix = 1; }
+ void setHasAlternativeForm() { HasAlternativeForm = 1; }
+ void setHasLeadingZeros() { HasLeadingZeroes = 1; }
+ void setUsesPositionalArg() { UsesPositionalArg = 1; }
+
+ void setArgIndex(unsigned i) {
+ assert(CS.consumesDataArgument());
+ argIndex = i;
+ }
+
+ unsigned getArgIndex() const {
+ assert(CS.consumesDataArgument());
+ return argIndex;
+ }
+
+ // Methods for querying the format specifier.
+
+ const ConversionSpecifier &getConversionSpecifier() const {
+ return CS;
+ }
+
+ LengthModifier getLengthModifier() const {
+ return LM;
+ }
+
+ const OptionalAmount &getFieldWidth() const {
+ return FieldWidth;
+ }
+
+ void setFieldWidth(const OptionalAmount &Amt) {
+ FieldWidth = Amt;
+ }
+
+ void setPrecision(const OptionalAmount &Amt) {
+ Precision = Amt;
+ }
+
+ const OptionalAmount &getPrecision() const {
+ return Precision;
+ }
+
+ /// \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.
+ ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+ bool isLeftJustified() const { return (bool) IsLeftJustified; }
+ bool hasPlusPrefix() const { return (bool) HasPlusPrefix; }
+ bool hasAlternativeForm() const { return (bool) HasAlternativeForm; }
+ bool hasLeadingZeros() const { return (bool) HasLeadingZeroes; }
+ bool hasSpacePrefix() const { return (bool) HasSpacePrefix; }
+ bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
+};
+
+enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
+
+class FormatStringHandler {
+public:
+ FormatStringHandler() {}
+ virtual ~FormatStringHandler();
+
+ virtual void HandleIncompleteFormatSpecifier(const char *startSpecifier,
+ unsigned specifierLen) {}
+
+ virtual void HandleNullChar(const char *nullCharacter) {}
+
+ virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
+ PositionContext p) {}
+
+ virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
+
+ virtual bool
+ HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) { return true; }
+
+ virtual bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) {
+ return true;
+ }
+};
+
+bool ParseFormatString(FormatStringHandler &H,
+ const char *beg, const char *end);
+
+} // end printf namespace
+} // end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ReachableCode.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ReachableCode.h
new file mode 100644
index 0000000..e0c84f9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ReachableCode.h
@@ -0,0 +1,55 @@
+//===- 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_REACHABLECODE_H
+#define LLVM_CLANG_REACHABLECODE_H
+
+#include "clang/Basic/SourceLocation.h"
+
+//===----------------------------------------------------------------------===//
+// Forward declarations.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+ class BitVector;
+}
+
+namespace clang {
+ class AnalysisContext;
+ class CFGBlock;
+}
+
+//===----------------------------------------------------------------------===//
+// API.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+namespace reachable_code {
+
+class Callback {
+public:
+ virtual ~Callback() {}
+ virtual void HandleUnreachable(SourceLocation L, 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(AnalysisContext &AC, Callback &CB);
+
+}} // end namespace clang::reachable_code
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h
new file mode 100644
index 0000000..cd771ac
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -0,0 +1,77 @@
+//===- UninitializedValues.h - unintialized values 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 provides the interface for the Unintialized Values analysis,
+// a flow-sensitive analysis that detects when variable values are unintialized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_UNITVALS_H
+#define LLVM_CLANG_UNITVALS_H
+
+#include "clang/Analysis/Support/BlkExprDeclBitVector.h"
+#include "clang/Analysis/FlowSensitive/DataflowValues.h"
+
+namespace clang {
+
+ class BlockVarDecl;
+ class Expr;
+ class DeclRefExpr;
+ class VarDecl;
+
+/// UninitializedValues_ValueTypes - Utility class to wrap type declarations
+/// for dataflow values and dataflow analysis state for the
+/// Unitialized Values analysis.
+class UninitializedValues_ValueTypes {
+public:
+
+ struct ObserverTy;
+
+ struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy {
+ AnalysisDataTy() : Observer(NULL), FullUninitTaint(true) {}
+ virtual ~AnalysisDataTy() {}
+
+ ObserverTy* Observer;
+ bool FullUninitTaint;
+ };
+
+ typedef StmtDeclBitVector_Types::ValTy ValTy;
+
+ //===--------------------------------------------------------------------===//
+ // ObserverTy - Observer for querying DeclRefExprs that use an uninitalized
+ // value.
+ //===--------------------------------------------------------------------===//
+
+ struct ObserverTy {
+ virtual ~ObserverTy();
+ virtual void ObserveDeclRefExpr(ValTy& Val, AnalysisDataTy& AD,
+ DeclRefExpr* DR, VarDecl* VD) = 0;
+ };
+};
+
+/// UninitializedValues - Objects of this class encapsulate dataflow analysis
+/// information regarding what variable declarations in a function are
+/// potentially unintialized.
+class UninitializedValues :
+ public DataflowValues<UninitializedValues_ValueTypes> {
+public:
+ typedef UninitializedValues_ValueTypes::ObserverTy ObserverTy;
+
+ UninitializedValues(CFG &cfg) { getAnalysisData().setCFG(cfg); }
+
+ /// IntializeValues - Create initial dataflow values and meta data for
+ /// a given CFG. This is intended to be called by the dataflow solver.
+ void InitializeValues(const CFG& cfg);
+};
+
+
+void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
+ bool FullUninitTaint=false);
+} // end namespace clang
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h
new file mode 100644
index 0000000..9ebd93b
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h
@@ -0,0 +1,263 @@
+//=== 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 AnalysisContext, 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 "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+
+class Decl;
+class Stmt;
+class CFG;
+class CFGBlock;
+class LiveVariables;
+class ParentMap;
+class ImplicitParamDecl;
+class LocationContextManager;
+class StackFrameContext;
+
+/// AnalysisContext contains the context data for the function or method under
+/// analysis.
+class AnalysisContext {
+ const Decl *D;
+
+ // AnalysisContext owns the following data.
+ CFG *cfg;
+ bool builtCFG;
+ LiveVariables *liveness;
+ ParentMap *PM;
+ llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+ llvm::BumpPtrAllocator A;
+ bool AddEHEdges;
+public:
+ AnalysisContext(const Decl *d, bool addehedges = false)
+ : D(d), cfg(0), builtCFG(false), liveness(0), PM(0),
+ ReferencedBlockVars(0), AddEHEdges(addehedges) {}
+
+ ~AnalysisContext();
+
+ ASTContext &getASTContext() { return D->getASTContext(); }
+ const Decl *getDecl() { return D; }
+ /// 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 AddEHEdges; }
+ Stmt *getBody();
+ CFG *getCFG();
+ ParentMap &getParentMap();
+ LiveVariables *getLiveVariables();
+
+ typedef const VarDecl * const * referenced_decls_iterator;
+
+ std::pair<referenced_decls_iterator, referenced_decls_iterator>
+ getReferencedBlockVars(const BlockDecl *BD);
+
+ /// Return the ImplicitParamDecl* associated with 'self' if this
+ /// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise.
+ const ImplicitParamDecl *getSelfDecl() const;
+};
+
+class AnalysisContextManager {
+ typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
+ ContextMap Contexts;
+public:
+ ~AnalysisContextManager();
+
+ AnalysisContext *getContext(const Decl *D);
+
+ // Discard all previously created AnalysisContexts.
+ void clear();
+};
+
+class LocationContext : public llvm::FoldingSetNode {
+public:
+ enum ContextKind { StackFrame, Scope, Block };
+
+private:
+ ContextKind Kind;
+ AnalysisContext *Ctx;
+ const LocationContext *Parent;
+
+protected:
+ LocationContext(ContextKind k, AnalysisContext *ctx,
+ const LocationContext *parent)
+ : Kind(k), Ctx(ctx), Parent(parent) {}
+
+public:
+ virtual ~LocationContext();
+
+ ContextKind getKind() const { return Kind; }
+
+ AnalysisContext *getAnalysisContext() const { return Ctx; }
+
+ const LocationContext *getParent() const { return Parent; }
+
+ bool isParentOf(const LocationContext *LC) const;
+
+ const Decl *getDecl() const { return getAnalysisContext()->getDecl(); }
+
+ CFG *getCFG() const { return getAnalysisContext()->getCFG(); }
+
+ LiveVariables *getLiveVariables() const {
+ return getAnalysisContext()->getLiveVariables();
+ }
+
+ ParentMap &getParentMap() const {
+ return getAnalysisContext()->getParentMap();
+ }
+
+ const ImplicitParamDecl *getSelfDecl() const {
+ return Ctx->getSelfDecl();
+ }
+
+ const StackFrameContext *getCurrentStackFrame() const;
+ const StackFrameContext *
+ getStackFrameForDeclContext(const DeclContext *DC) const;
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
+
+ static bool classof(const LocationContext*) { return true; }
+
+public:
+ static void ProfileCommon(llvm::FoldingSetNodeID &ID,
+ ContextKind ck,
+ AnalysisContext *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(AnalysisContext *ctx, const LocationContext *parent,
+ const Stmt *s, const CFGBlock *blk, unsigned idx)
+ : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk),
+ Index(idx) {}
+
+public:
+ ~StackFrameContext() {}
+
+ const Stmt *getCallSite() const { return CallSite; }
+
+ const CFGBlock *getCallSiteBlock() const { return Block; }
+
+ unsigned getIndex() const { return Index; }
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+
+ static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *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(AnalysisContext *ctx, const LocationContext *parent,
+ const Stmt *s)
+ : LocationContext(Scope, ctx, parent), Enter(s) {}
+
+public:
+ ~ScopeContext() {}
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+
+ static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *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 {
+ // FIXME: Add back context-sensivity (we don't want libAnalysis to know
+ // about MemRegion).
+ const BlockDecl *BD;
+
+ friend class LocationContextManager;
+
+ BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
+ const BlockDecl *bd)
+ : LocationContext(Block, ctx, parent), BD(bd) {}
+
+public:
+ ~BlockInvocationContext() {}
+
+ const BlockDecl *getBlockDecl() const { return BD; }
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+
+ static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
+ const LocationContext *parent, const BlockDecl *bd) {
+ ProfileCommon(ID, Block, ctx, parent, bd);
+ }
+
+ static bool classof(const LocationContext* Ctx) {
+ return Ctx->getKind() == Block;
+ }
+};
+
+class LocationContextManager {
+ llvm::FoldingSet<LocationContext> Contexts;
+public:
+ ~LocationContextManager();
+
+ const StackFrameContext *getStackFrame(AnalysisContext *ctx,
+ const LocationContext *parent,
+ const Stmt *s, const CFGBlock *blk,
+ unsigned idx);
+
+ const ScopeContext *getScope(AnalysisContext *ctx,
+ const LocationContext *parent,
+ const Stmt *s);
+
+ /// Discard all previously created LocationContext objects.
+ void clear();
+private:
+ template <typename LOC, typename DATA>
+ const LOC *getLocationContext(AnalysisContext *ctx,
+ const LocationContext *parent,
+ const DATA *d);
+};
+
+} // end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h
new file mode 100644
index 0000000..e98a3df
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- 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_DIAGNOSTICANALYSIS_H
+#define LLVM_CLANG_DIAGNOSTICANALYSIS_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+ namespace diag {
+ enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,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/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h
new file mode 100644
index 0000000..b7256c9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h
@@ -0,0 +1,512 @@
+//===--- 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_CFG_H
+#define LLVM_CLANG_CFG_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/Basic/SourceLocation.h"
+#include <cassert>
+
+namespace llvm {
+ class raw_ostream;
+}
+namespace clang {
+ class Decl;
+ class Stmt;
+ class Expr;
+ class CFG;
+ class PrinterHelper;
+ class LangOptions;
+ class ASTContext;
+
+namespace {
+// An element of the CFG for implicit descructor calls implied by the language
+// rules.
+class Dtor {
+ // Statement that introduces the variable.
+ Stmt *S;
+ // A token which ends the scope, return, goto, throw, }.
+ SourceLocation Loc;
+public:
+ Dtor(Stmt *s, SourceLocation l) : S(s), Loc(l) {
+ }
+ SourceLocation getLoc() { return Loc; }
+ Stmt *getStmt() { return S; }
+};
+}
+
+/// CFGElement - Represents a top-level expression in a basic block.
+class CFGElement {
+ llvm::PointerIntPair<Stmt *, 2> Data;
+public:
+ enum Type { StartScope, EndScope };
+ explicit CFGElement() {}
+ CFGElement(Stmt *S, bool lvalue) : Data(S, lvalue ? 1 : 0) {}
+ CFGElement(Stmt *S, Type t) : Data(S, t == StartScope ? 2 : 3) {}
+ // CFGElement(Dtor *S, Type t) : Data(reinterpret_cast<Stmt*>(S), 4) {}
+ Stmt *getStmt() const { return Data.getPointer(); }
+ bool asLValue() const { return Data.getInt() == 1; }
+ bool asStartScope() const { return Data.getInt() == 2; }
+ bool asEndScope() const { return Data.getInt() == 3; }
+ bool asDtor() const { return Data.getInt() == 4; }
+ operator Stmt*() const { return getStmt(); }
+ operator bool() const { return getStmt() != 0; }
+ operator Dtor*() const { return reinterpret_cast<Dtor*>(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
+///
+class CFGBlock {
+ class StatementList {
+ typedef BumpVector<CFGElement> ImplTy;
+ ImplTy Impl;
+ public:
+ StatementList(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;
+
+ void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
+ CFGElement front() const { return Impl.back(); }
+ CFGElement 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.
+ StatementList Stmts;
+
+ /// 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.
+ Stmt *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;
+
+ /// Predecessors/Successors - Keep track of the predecessor / successor
+ /// CFG blocks.
+ typedef BumpVector<CFGBlock*> AdjacentBlocks;
+ AdjacentBlocks Preds;
+ AdjacentBlocks Succs;
+
+public:
+ explicit CFGBlock(unsigned blockid, BumpVectorContext &C)
+ : Stmts(C), Label(NULL), Terminator(NULL), LoopTarget(NULL),
+ BlockID(blockid), Preds(C, 1), Succs(C, 1) {}
+ ~CFGBlock() {}
+
+ // Statement iterators
+ typedef StatementList::iterator iterator;
+ typedef StatementList::const_iterator const_iterator;
+ typedef StatementList::reverse_iterator reverse_iterator;
+ typedef StatementList::const_reverse_iterator const_reverse_iterator;
+
+ CFGElement front() const { return Stmts.front(); }
+ CFGElement back() const { return Stmts.back(); }
+
+ iterator begin() { return Stmts.begin(); }
+ iterator end() { return Stmts.end(); }
+ const_iterator begin() const { return Stmts.begin(); }
+ const_iterator end() const { return Stmts.end(); }
+
+ reverse_iterator rbegin() { return Stmts.rbegin(); }
+ reverse_iterator rend() { return Stmts.rend(); }
+ const_reverse_iterator rbegin() const { return Stmts.rbegin(); }
+ const_reverse_iterator rend() const { return Stmts.rend(); }
+
+ unsigned size() const { return Stmts.size(); }
+ bool empty() const { return Stmts.empty(); }
+
+ CFGElement operator[](size_t i) const { return Stmts[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(); }
+
+ // Manipulation of block contents
+
+ void setTerminator(Stmt* Statement) { Terminator = Statement; }
+ void setLabel(Stmt* Statement) { Label = Statement; }
+ void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
+
+ Stmt* getTerminator() { return Terminator; }
+ const Stmt* getTerminator() const { return Terminator; }
+
+ Stmt* getTerminatorCondition();
+
+ const Stmt* getTerminatorCondition() const {
+ return const_cast<CFGBlock*>(this)->getTerminatorCondition();
+ }
+
+ const Stmt *getLoopTarget() const { return LoopTarget; }
+
+ bool hasBinaryBranchTerminator() const;
+
+ Stmt* getLabel() { return Label; }
+ const Stmt* getLabel() const { return Label; }
+
+ unsigned getBlockID() const { return BlockID; }
+
+ void dump(const CFG *cfg, const LangOptions &LO) const;
+ void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
+ void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const;
+
+ void addSuccessor(CFGBlock* Block, BumpVectorContext &C) {
+ if (Block)
+ Block->Preds.push_back(this, C);
+ Succs.push_back(Block, C);
+ }
+
+ void appendStmt(Stmt* Statement, BumpVectorContext &C, bool asLValue) {
+ Stmts.push_back(CFGElement(Statement, asLValue), C);
+ }
+ void StartScope(Stmt* S, BumpVectorContext &C) {
+ Stmts.push_back(CFGElement(S, CFGElement::StartScope), C);
+ }
+ void EndScope(Stmt* S, BumpVectorContext &C) {
+ Stmts.push_back(CFGElement(S, CFGElement::EndScope), C);
+ }
+};
+
+
+/// 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.
+ //===--------------------------------------------------------------------===//
+
+ /// buildCFG - Builds a CFG from an AST. The responsibility to free the
+ /// constructed CFG belongs to the caller.
+ static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C,
+ bool AddEHEdges = false,
+ bool AddScopes = false /* NOT FULLY IMPLEMENTED.
+ NOT READY FOR GENERAL USE. */);
+
+ /// 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(); }
+
+ 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; }
+
+ //===--------------------------------------------------------------------===//
+ // 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)
+ O(*BI);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // CFG Introspection.
+ //===--------------------------------------------------------------------===//
+
+ struct BlkExprNumTy {
+ const signed Idx;
+ explicit BlkExprNumTy(signed idx) : Idx(idx) {}
+ explicit BlkExprNumTy() : Idx(-1) {}
+ operator bool() const { return Idx >= 0; }
+ operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
+ };
+
+ bool isBlkExpr(const Stmt* S) { return getBlkExprNum(S); }
+ BlkExprNumTy getBlkExprNum(const Stmt* S);
+ unsigned getNumBlkExprs();
+
+ /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which
+ /// start at 0).
+ unsigned getNumBlockIDs() const { return NumBlockIDs; }
+
+ //===--------------------------------------------------------------------===//
+ // CFG Debugging: Pretty-Printing and Visualization.
+ //===--------------------------------------------------------------------===//
+
+ void viewCFG(const LangOptions &LO) const;
+ void print(llvm::raw_ostream& OS, const LangOptions &LO) const;
+ void dump(const LangOptions &LO) const;
+
+ //===--------------------------------------------------------------------===//
+ // Internal: constructors and data.
+ //===--------------------------------------------------------------------===//
+
+ CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
+ BlkExprMap(NULL), Blocks(BlkBVC, 10) {}
+
+ ~CFG();
+
+ 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;
+
+ // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h.
+ // It represents a map from Expr* to integers to record the set of
+ // block-level expressions and their "statement number" in the CFG.
+ void* BlkExprMap;
+
+ BumpVectorContext BlkBVC;
+
+ CFGBlockListTy Blocks;
+
+};
+} // end namespace clang
+
+//===----------------------------------------------------------------------===//
+// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+/// Implement simplify_type for CFGElement, so that we can dyn_cast from
+/// CFGElement to a specific Stmt class.
+template <> struct simplify_type<const ::clang::CFGElement> {
+ typedef ::clang::Stmt* SimpleType;
+ static SimpleType getSimplifiedValue(const ::clang::CFGElement &Val) {
+ return Val.getStmt();
+ }
+};
+
+template <> struct simplify_type< ::clang::CFGElement>
+ : public simplify_type<const ::clang::CFGElement> {};
+
+// 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<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::iterator nodes_iterator;
+
+ static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
+ static nodes_iterator nodes_begin(::clang::CFG* F) { return F->begin(); }
+ static nodes_iterator nodes_end(::clang::CFG* F) { return F->end(); }
+};
+
+template <> struct GraphTraits<const ::clang::CFG* >
+ : public GraphTraits<const ::clang::CFGBlock* > {
+
+ typedef ::clang::CFG::const_iterator nodes_iterator;
+
+ static NodeType *getEntryNode( const ::clang::CFG* F) {
+ return &F->getEntry();
+ }
+ static nodes_iterator nodes_begin( const ::clang::CFG* F) {
+ return F->begin();
+ }
+ static nodes_iterator nodes_end( const ::clang::CFG* F) {
+ return F->end();
+ }
+};
+
+template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
+ : public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
+
+ typedef ::clang::CFG::const_iterator nodes_iterator;
+
+ static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
+ static nodes_iterator nodes_begin(const ::clang::CFG* F) { return F->begin();}
+ static nodes_iterator nodes_end(const ::clang::CFG* F) { return F->end(); }
+};
+} // end llvm namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h
new file mode 100644
index 0000000..3c76201
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -0,0 +1,320 @@
+//===--- DataflowSolver.h - Skeleton Dataflow Analysis Code -----*- 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 skeleton code for implementing dataflow analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
+#define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
+
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Analysis/FlowSensitive/DataflowValues.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "functional" // STL
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+/// DataflowWorkListTy - Data structure representing the worklist used for
+/// dataflow algorithms.
+//===----------------------------------------------------------------------===//
+
+class DataflowWorkListTy {
+ llvm::DenseMap<const CFGBlock*, unsigned char> BlockSet;
+ llvm::SmallVector<const CFGBlock *, 10> BlockQueue;
+public:
+ /// enqueue - Add a block to the worklist. Blocks already on the
+ /// worklist are not added a second time.
+ void enqueue(const CFGBlock* B) {
+ unsigned char &x = BlockSet[B];
+ if (x == 1)
+ return;
+ x = 1;
+ BlockQueue.push_back(B);
+ }
+
+ /// dequeue - Remove a block from the worklist.
+ const CFGBlock* dequeue() {
+ assert(!BlockQueue.empty());
+ const CFGBlock *B = BlockQueue.back();
+ BlockQueue.pop_back();
+ BlockSet[B] = 0;
+ return B;
+ }
+
+ /// isEmpty - Return true if the worklist is empty.
+ bool isEmpty() const { return BlockQueue.empty(); }
+};
+
+//===----------------------------------------------------------------------===//
+// BlockItrTraits - Traits classes that allow transparent iteration
+// over successors/predecessors of a block depending on the direction
+// of our dataflow analysis.
+//===----------------------------------------------------------------------===//
+
+namespace dataflow {
+template<typename Tag> struct ItrTraits {};
+
+template <> struct ItrTraits<forward_analysis_tag> {
+ typedef CFGBlock::const_pred_iterator PrevBItr;
+ typedef CFGBlock::const_succ_iterator NextBItr;
+ typedef CFGBlock::const_iterator StmtItr;
+
+ static PrevBItr PrevBegin(const CFGBlock* B) { return B->pred_begin(); }
+ static PrevBItr PrevEnd(const CFGBlock* B) { return B->pred_end(); }
+
+ static NextBItr NextBegin(const CFGBlock* B) { return B->succ_begin(); }
+ static NextBItr NextEnd(const CFGBlock* B) { return B->succ_end(); }
+
+ static StmtItr StmtBegin(const CFGBlock* B) { return B->begin(); }
+ static StmtItr StmtEnd(const CFGBlock* B) { return B->end(); }
+
+ static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) {
+ return BlockEdge(Prev, B, 0);
+ }
+
+ static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) {
+ return BlockEdge(B, Next, 0);
+ }
+};
+
+template <> struct ItrTraits<backward_analysis_tag> {
+ typedef CFGBlock::const_succ_iterator PrevBItr;
+ typedef CFGBlock::const_pred_iterator NextBItr;
+ typedef CFGBlock::const_reverse_iterator StmtItr;
+
+ static PrevBItr PrevBegin(const CFGBlock* B) { return B->succ_begin(); }
+ static PrevBItr PrevEnd(const CFGBlock* B) { return B->succ_end(); }
+
+ static NextBItr NextBegin(const CFGBlock* B) { return B->pred_begin(); }
+ static NextBItr NextEnd(const CFGBlock* B) { return B->pred_end(); }
+
+ static StmtItr StmtBegin(const CFGBlock* B) { return B->rbegin(); }
+ static StmtItr StmtEnd(const CFGBlock* B) { return B->rend(); }
+
+ static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) {
+ return BlockEdge(B, Prev, 0);
+ }
+
+ static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) {
+ return BlockEdge(Next, B, 0);
+ }
+};
+} // end namespace dataflow
+
+//===----------------------------------------------------------------------===//
+/// DataflowSolverTy - Generic dataflow solver.
+//===----------------------------------------------------------------------===//
+
+template <typename _DFValuesTy, // Usually a subclass of DataflowValues
+ typename _TransferFuncsTy,
+ typename _MergeOperatorTy,
+ typename _Equal = std::equal_to<typename _DFValuesTy::ValTy> >
+class DataflowSolver {
+
+ //===----------------------------------------------------===//
+ // Type declarations.
+ //===----------------------------------------------------===//
+
+public:
+ typedef _DFValuesTy DFValuesTy;
+ typedef _TransferFuncsTy TransferFuncsTy;
+ typedef _MergeOperatorTy MergeOperatorTy;
+
+ typedef typename _DFValuesTy::AnalysisDirTag AnalysisDirTag;
+ typedef typename _DFValuesTy::ValTy ValTy;
+ typedef typename _DFValuesTy::EdgeDataMapTy EdgeDataMapTy;
+ typedef typename _DFValuesTy::BlockDataMapTy BlockDataMapTy;
+
+ typedef dataflow::ItrTraits<AnalysisDirTag> ItrTraits;
+ typedef typename ItrTraits::NextBItr NextBItr;
+ typedef typename ItrTraits::PrevBItr PrevBItr;
+ typedef typename ItrTraits::StmtItr StmtItr;
+
+ //===----------------------------------------------------===//
+ // External interface: constructing and running the solver.
+ //===----------------------------------------------------===//
+
+public:
+ DataflowSolver(DFValuesTy& d) : D(d), TF(d.getAnalysisData()) {}
+ ~DataflowSolver() {}
+
+ /// runOnCFG - Computes dataflow values for all blocks in a CFG.
+ void runOnCFG(CFG& cfg, bool recordStmtValues = false) {
+ // Set initial dataflow values and boundary conditions.
+ D.InitializeValues(cfg);
+ // Solve the dataflow equations. This will populate D.EdgeDataMap
+ // with dataflow values.
+ SolveDataflowEquations(cfg, recordStmtValues);
+ }
+
+ /// runOnBlock - Computes dataflow values for a given block. This
+ /// should usually be invoked only after previously computing
+ /// dataflow values using runOnCFG, as runOnBlock is intended to
+ /// only be used for querying the dataflow values within a block
+ /// with and Observer object.
+ void runOnBlock(const CFGBlock* B, bool recordStmtValues) {
+ BlockDataMapTy& M = D.getBlockDataMap();
+ typename BlockDataMapTy::iterator I = M.find(B);
+
+ if (I != M.end()) {
+ TF.getVal().copyValues(I->second);
+ ProcessBlock(B, recordStmtValues, AnalysisDirTag());
+ }
+ }
+
+ void runOnBlock(const CFGBlock& B, bool recordStmtValues) {
+ runOnBlock(&B, recordStmtValues);
+ }
+ void runOnBlock(CFG::iterator& I, bool recordStmtValues) {
+ runOnBlock(*I, recordStmtValues);
+ }
+ void runOnBlock(CFG::const_iterator& I, bool recordStmtValues) {
+ runOnBlock(*I, recordStmtValues);
+ }
+
+ void runOnAllBlocks(const CFG& cfg, bool recordStmtValues = false) {
+ for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
+ runOnBlock(I, recordStmtValues);
+ }
+
+ //===----------------------------------------------------===//
+ // Internal solver logic.
+ //===----------------------------------------------------===//
+
+private:
+
+ /// SolveDataflowEquations - Perform the actual worklist algorithm
+ /// to compute dataflow values.
+ void SolveDataflowEquations(CFG& cfg, bool recordStmtValues) {
+ EnqueueBlocksOnWorklist(cfg, AnalysisDirTag());
+
+ while (!WorkList.isEmpty()) {
+ const CFGBlock* B = WorkList.dequeue();
+ ProcessMerge(cfg, B);
+ ProcessBlock(B, recordStmtValues, AnalysisDirTag());
+ UpdateEdges(cfg, B, TF.getVal());
+ }
+ }
+
+ void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::forward_analysis_tag) {
+ // Enqueue all blocks to ensure the dataflow values are computed
+ // for every block. Not all blocks are guaranteed to reach the exit block.
+ for (CFG::iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
+ WorkList.enqueue(&**I);
+ }
+
+ void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::backward_analysis_tag) {
+ // Enqueue all blocks to ensure the dataflow values are computed
+ // for every block. Not all blocks are guaranteed to reach the exit block.
+ // Enqueue in reverse order since that will more likely match with
+ // the order they should ideally processed by the dataflow algorithm.
+ for (CFG::reverse_iterator I=cfg.rbegin(), E=cfg.rend(); I!=E; ++I)
+ WorkList.enqueue(&**I);
+ }
+
+ void ProcessMerge(CFG& cfg, const CFGBlock* B) {
+ ValTy& V = TF.getVal();
+ TF.SetTopValue(V);
+
+ // Merge dataflow values from all predecessors of this block.
+ MergeOperatorTy Merge;
+
+ EdgeDataMapTy& M = D.getEdgeDataMap();
+ bool firstMerge = true;
+
+ for (PrevBItr I=ItrTraits::PrevBegin(B),E=ItrTraits::PrevEnd(B); I!=E; ++I){
+
+ CFGBlock *PrevBlk = *I;
+
+ if (!PrevBlk)
+ continue;
+
+ typename EdgeDataMapTy::iterator EI =
+ M.find(ItrTraits::PrevEdge(B, PrevBlk));
+
+ if (EI != M.end()) {
+ if (firstMerge) {
+ firstMerge = false;
+ V.copyValues(EI->second);
+ }
+ else
+ Merge(V, EI->second);
+ }
+ }
+
+ // Set the data for the block.
+ D.getBlockDataMap()[B].copyValues(V);
+ }
+
+ /// ProcessBlock - Process the transfer functions for a given block.
+ void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
+ dataflow::forward_analysis_tag) {
+
+ for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
+ ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
+
+ TF.VisitTerminator(const_cast<CFGBlock*>(B));
+ }
+
+ void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
+ dataflow::backward_analysis_tag) {
+
+ TF.VisitTerminator(const_cast<CFGBlock*>(B));
+
+ for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
+ ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
+ }
+
+ void ProcessStmt(const Stmt* S, bool record, dataflow::forward_analysis_tag) {
+ if (record) D.getStmtDataMap()[S] = TF.getVal();
+ TF.BlockStmt_Visit(const_cast<Stmt*>(S));
+ }
+
+ void ProcessStmt(const Stmt* S, bool record, dataflow::backward_analysis_tag){
+ TF.BlockStmt_Visit(const_cast<Stmt*>(S));
+ if (record) D.getStmtDataMap()[S] = TF.getVal();
+ }
+
+ /// UpdateEdges - After processing the transfer functions for a
+ /// block, update the dataflow value associated with the block's
+ /// outgoing/incoming edges (depending on whether we do a
+ // forward/backward analysis respectively)
+ void UpdateEdges(CFG& cfg, const CFGBlock* B, ValTy& V) {
+ for (NextBItr I=ItrTraits::NextBegin(B), E=ItrTraits::NextEnd(B); I!=E; ++I)
+ if (CFGBlock *NextBlk = *I)
+ UpdateEdgeValue(ItrTraits::NextEdge(B, NextBlk),V, NextBlk);
+ }
+
+ /// UpdateEdgeValue - Update the value associated with a given edge.
+ void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock* TargetBlock) {
+ EdgeDataMapTy& M = D.getEdgeDataMap();
+ typename EdgeDataMapTy::iterator I = M.find(E);
+
+ if (I == M.end()) { // First computed value for this edge?
+ M[E].copyValues(V);
+ WorkList.enqueue(TargetBlock);
+ }
+ else if (!_Equal()(V,I->second)) {
+ I->second.copyValues(V);
+ WorkList.enqueue(TargetBlock);
+ }
+ }
+
+private:
+ DFValuesTy& D;
+ DataflowWorkListTy WorkList;
+ TransferFuncsTy TF;
+};
+
+} // end namespace clang
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
new file mode 100644
index 0000000..7aa15c5
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
@@ -0,0 +1,172 @@
+//===--- 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/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h
new file mode 100644
index 0000000..075838d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h
@@ -0,0 +1,380 @@
+//==- 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_PROGRAM_POINT
+#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
+
+#include "clang/Analysis/CFG.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <utility>
+
+namespace clang {
+
+class LocationContext;
+class FunctionDecl;
+
+class ProgramPoint {
+public:
+ enum Kind { BlockEdgeKind,
+ BlockEntranceKind,
+ BlockExitKind,
+ PreStmtKind,
+ PostStmtKind,
+ PreLoadKind,
+ PostLoadKind,
+ PreStoreKind,
+ PostStoreKind,
+ PostPurgeDeadSymbolsKind,
+ PostStmtCustomKind,
+ PostLValueKind,
+ CallEnterKind,
+ CallExitKind,
+ MinPostStmtKind = PostStmtKind,
+ MaxPostStmtKind = PostLValueKind };
+
+private:
+ std::pair<const void *, const void *> Data;
+ Kind K;
+
+ // The LocationContext could be NULL to allow ProgramPoint to be used in
+ // context insensitive analysis.
+ const LocationContext *L;
+ const void *Tag;
+
+protected:
+ ProgramPoint(const void* P, Kind k, const LocationContext *l,
+ const void *tag = 0)
+ : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {}
+
+ ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l,
+ const void *tag = 0)
+ : Data(P1, P2), K(k), L(l), Tag(tag) {}
+
+protected:
+ const void* getData1() const { return Data.first; }
+ const void* getData2() const { return Data.second; }
+ const void *getTag() const { return Tag; }
+
+public:
+ Kind getKind() const { return K; }
+
+ const LocationContext *getLocationContext() const { return L; }
+
+ // For use with DenseMap. This hash is probably slow.
+ unsigned getHashValue() const {
+ llvm::FoldingSetNodeID ID;
+ Profile(ID);
+ return ID.ComputeHash();
+ }
+
+ static bool classof(const ProgramPoint*) { return true; }
+
+ bool operator==(const ProgramPoint & RHS) const {
+ return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag;
+ }
+
+ bool operator!=(const ProgramPoint& RHS) const {
+ return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag;
+ }
+
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ ID.AddInteger((unsigned) K);
+ ID.AddPointer(Data.first);
+ ID.AddPointer(Data.second);
+ ID.AddPointer(L);
+ ID.AddPointer(Tag);
+ }
+};
+
+class BlockEntrance : public ProgramPoint {
+public:
+ BlockEntrance(const CFGBlock* B, const LocationContext *L,
+ const void *tag = 0)
+ : ProgramPoint(B, BlockEntranceKind, L, tag) {}
+
+ CFGBlock* getBlock() const {
+ return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
+ }
+
+ CFGElement getFirstElement() const {
+ const CFGBlock* B = getBlock();
+ return B->empty() ? CFGElement() : B->front();
+ }
+
+ Stmt *getFirstStmt() const {
+ return getFirstElement().getStmt();
+ }
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == BlockEntranceKind;
+ }
+};
+
+class BlockExit : public ProgramPoint {
+public:
+ BlockExit(const CFGBlock* B, const LocationContext *L)
+ : ProgramPoint(B, BlockExitKind, L) {}
+
+ CFGBlock* getBlock() const {
+ return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
+ }
+
+ Stmt* getLastStmt() const {
+ const CFGBlock* B = getBlock();
+ return B->empty() ? CFGElement() : B->back();
+ }
+
+ Stmt* getTerminator() const {
+ return getBlock()->getTerminator();
+ }
+
+ static bool classof(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 void *tag)
+ : ProgramPoint(S, p2, k, L, tag) {}
+
+ const Stmt *getStmt() const { return (const Stmt*) getData1(); }
+
+ template <typename T>
+ const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
+
+ static bool classof(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 void *tag,
+ const Stmt *SubStmt = 0)
+ : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
+
+ const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == PreStmtKind;
+ }
+};
+
+class PostStmt : public StmtPoint {
+protected:
+ PostStmt(const Stmt* S, Kind k, const LocationContext *L, const void *tag = 0)
+ : StmtPoint(S, NULL, k, L, tag) {}
+
+ PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L,
+ const void *tag =0)
+ : StmtPoint(S, data, k, L, tag) {}
+
+public:
+ explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0)
+ : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
+
+ static bool classof(const ProgramPoint* Location) {
+ unsigned k = Location->getKind();
+ return k >= MinPostStmtKind && k <= MaxPostStmtKind;
+ }
+};
+
+class PostStmtCustom : public PostStmt {
+public:
+ PostStmtCustom(const Stmt* S,
+ const std::pair<const void*, const void*>* TaggedData,\
+ const LocationContext *L)
+ : PostStmt(S, TaggedData, PostStmtCustomKind, L) {}
+
+ const std::pair<const void*, const void*>& getTaggedPair() const {
+ return
+ *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2());
+ }
+
+ const void* getTag() const { return getTaggedPair().first; }
+
+ const void* getTaggedData() const { return getTaggedPair().second; }
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == PostStmtCustomKind;
+ }
+};
+
+
+class LocationCheck : public StmtPoint {
+protected:
+ LocationCheck(const Stmt *S, const LocationContext *L,
+ ProgramPoint::Kind K, const void *tag)
+ : StmtPoint(S, NULL, K, L, tag) {}
+
+ static bool classof(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 void *tag = 0)
+ : LocationCheck(S, L, PreLoadKind, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ return location->getKind() == PreLoadKind;
+ }
+};
+
+class PreStore : public LocationCheck {
+public:
+ PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0)
+ : LocationCheck(S, L, PreStoreKind, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ return location->getKind() == PreStoreKind;
+ }
+};
+
+class PostLoad : public PostStmt {
+public:
+ PostLoad(const Stmt* S, const LocationContext *L, const void *tag = 0)
+ : PostStmt(S, PostLoadKind, L, tag) {}
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == PostLoadKind;
+ }
+};
+
+class PostStore : public PostStmt {
+public:
+ PostStore(const Stmt* S, const LocationContext *L, const void *tag = 0)
+ : PostStmt(S, PostStoreKind, L, tag) {}
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == PostStoreKind;
+ }
+};
+
+class PostLValue : public PostStmt {
+public:
+ PostLValue(const Stmt* S, const LocationContext *L, const void *tag = 0)
+ : PostStmt(S, PostLValueKind, L, tag) {}
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == PostLValueKind;
+ }
+};
+
+class PostPurgeDeadSymbols : public PostStmt {
+public:
+ PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L,
+ const void *tag = 0)
+ : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {}
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == PostPurgeDeadSymbolsKind;
+ }
+};
+
+class BlockEdge : public ProgramPoint {
+public:
+ BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L)
+ : ProgramPoint(B1, B2, BlockEdgeKind, L) {}
+
+ CFGBlock* getSrc() const {
+ return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1()));
+ }
+
+ CFGBlock* getDst() const {
+ return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2()));
+ }
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == BlockEdgeKind;
+ }
+};
+
+class CallEnter : public StmtPoint {
+public:
+ // CallEnter uses the caller's location context.
+ CallEnter(const Stmt *S, const FunctionDecl *fd, const LocationContext *L)
+ : StmtPoint(S, fd, CallEnterKind, L, 0) {}
+
+ const Stmt *getCallExpr() const {
+ return static_cast<const Stmt *>(getData1());
+ }
+
+ const FunctionDecl *getCallee() const {
+ return static_cast<const FunctionDecl *>(getData2());
+ }
+
+ static bool classof(const ProgramPoint *Location) {
+ return Location->getKind() == CallEnterKind;
+ }
+};
+
+class CallExit : public StmtPoint {
+public:
+ // CallExit uses the callee's location context.
+ CallExit(const Stmt *S, const LocationContext *L)
+ : StmtPoint(S, 0, CallExitKind, L, 0) {}
+
+ static bool classof(const ProgramPoint *Location) {
+ return Location->getKind() == CallExitKind;
+ }
+};
+
+
+} // 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), 0);
+}
+
+static inline clang::ProgramPoint getTombstoneKey() {
+ uintptr_t x =
+ reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
+ return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
+}
+
+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/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h
new file mode 100644
index 0000000..27ecc66
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h
@@ -0,0 +1,307 @@
+// BlkExprDeclBitVector.h - Dataflow types for Bitvector 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 provides definition of dataflow types used by analyses such
+// as LiveVariables and UninitializedValues. The underlying dataflow values
+// are implemented as bitvectors, but the definitions in this file include
+// the necessary boilerplate to use with our dataflow framework.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STMTDECLBVDVAL_H
+#define LLVM_CLANG_STMTDECLBVDVAL_H
+
+#include "clang/Analysis/CFG.h"
+#include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+ class Stmt;
+ class ASTContext;
+
+struct DeclBitVector_Types {
+
+ class Idx {
+ unsigned I;
+ public:
+ explicit Idx(unsigned i) : I(i) {}
+ Idx() : I(~0U) {}
+
+ bool isValid() const {
+ return I != ~0U;
+ }
+ operator unsigned() const {
+ assert (isValid());
+ return I;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ // AnalysisDataTy - Whole-function meta data.
+ //===--------------------------------------------------------------------===//
+
+ class AnalysisDataTy {
+ public:
+ typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy;
+ typedef DMapTy::const_iterator decl_iterator;
+
+ protected:
+ DMapTy DMap;
+ unsigned NDecls;
+
+ public:
+
+ AnalysisDataTy() : NDecls(0) {}
+ virtual ~AnalysisDataTy() {}
+
+ bool isTracked(const NamedDecl* SD) { return DMap.find(SD) != DMap.end(); }
+
+ Idx getIdx(const NamedDecl* SD) const {
+ DMapTy::const_iterator I = DMap.find(SD);
+ return I == DMap.end() ? Idx() : Idx(I->second);
+ }
+
+ unsigned getNumDecls() const { return NDecls; }
+
+ void Register(const NamedDecl* SD) {
+ if (!isTracked(SD)) DMap[SD] = NDecls++;
+ }
+
+ decl_iterator begin_decl() const { return DMap.begin(); }
+ decl_iterator end_decl() const { return DMap.end(); }
+ };
+
+ //===--------------------------------------------------------------------===//
+ // ValTy - Dataflow value.
+ //===--------------------------------------------------------------------===//
+
+ class ValTy {
+ llvm::BitVector DeclBV;
+ public:
+
+ void resetDeclValues(AnalysisDataTy& AD) {
+ DeclBV.resize(AD.getNumDecls());
+ DeclBV.reset();
+ }
+
+ void setDeclValues(AnalysisDataTy& AD) {
+ DeclBV.resize(AD.getNumDecls());
+ DeclBV.set();
+ }
+
+ void resetValues(AnalysisDataTy& AD) {
+ resetDeclValues(AD);
+ }
+
+ bool operator==(const ValTy& RHS) const {
+ assert (sizesEqual(RHS));
+ return DeclBV == RHS.DeclBV;
+ }
+
+ void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; }
+
+ llvm::BitVector::reference getBit(unsigned i) {
+ return DeclBV[i];
+ }
+
+ bool getBit(unsigned i) const {
+ return DeclBV[i];
+ }
+
+ llvm::BitVector::reference
+ operator()(const NamedDecl* ND, const AnalysisDataTy& AD) {
+ return getBit(AD.getIdx(ND));
+ }
+
+ bool operator()(const NamedDecl* ND, const AnalysisDataTy& AD) const {
+ return getBit(AD.getIdx(ND));
+ }
+
+ llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; }
+ const llvm::BitVector::reference getDeclBit(unsigned i) const {
+ return const_cast<llvm::BitVector&>(DeclBV)[i];
+ }
+
+ ValTy& operator|=(const ValTy& RHS) {
+ assert (sizesEqual(RHS));
+ DeclBV |= RHS.DeclBV;
+ return *this;
+ }
+
+ ValTy& operator&=(const ValTy& RHS) {
+ assert (sizesEqual(RHS));
+ DeclBV &= RHS.DeclBV;
+ return *this;
+ }
+
+ ValTy& OrDeclBits(const ValTy& RHS) {
+ return operator|=(RHS);
+ }
+
+ ValTy& AndDeclBits(const ValTy& RHS) {
+ return operator&=(RHS);
+ }
+
+ bool sizesEqual(const ValTy& RHS) const {
+ return DeclBV.size() == RHS.DeclBV.size();
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ // Some useful merge operations.
+ //===--------------------------------------------------------------------===//
+
+ struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
+ struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
+};
+
+
+struct StmtDeclBitVector_Types {
+
+ //===--------------------------------------------------------------------===//
+ // AnalysisDataTy - Whole-function meta data.
+ //===--------------------------------------------------------------------===//
+
+ class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy {
+ ASTContext* ctx;
+ CFG* cfg;
+ public:
+ AnalysisDataTy() : ctx(0), cfg(0) {}
+ virtual ~AnalysisDataTy() {}
+
+ void setContext(ASTContext& c) { ctx = &c; }
+ ASTContext& getContext() {
+ assert(ctx && "ASTContext should not be NULL.");
+ return *ctx;
+ }
+
+ void setCFG(CFG& c) { cfg = &c; }
+ CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; }
+
+ bool isTracked(const Stmt* S) { return cfg->isBlkExpr(S); }
+ using DeclBitVector_Types::AnalysisDataTy::isTracked;
+
+ unsigned getIdx(const Stmt* S) const {
+ CFG::BlkExprNumTy I = cfg->getBlkExprNum(S);
+ assert(I && "Stmtession not tracked for bitvector.");
+ return I;
+ }
+ using DeclBitVector_Types::AnalysisDataTy::getIdx;
+
+ unsigned getNumBlkExprs() const { return cfg->getNumBlkExprs(); }
+ };
+
+ //===--------------------------------------------------------------------===//
+ // ValTy - Dataflow value.
+ //===--------------------------------------------------------------------===//
+
+ class ValTy : public DeclBitVector_Types::ValTy {
+ llvm::BitVector BlkExprBV;
+ typedef DeclBitVector_Types::ValTy ParentTy;
+
+ static inline ParentTy& ParentRef(ValTy& X) {
+ return static_cast<ParentTy&>(X);
+ }
+
+ static inline const ParentTy& ParentRef(const ValTy& X) {
+ return static_cast<const ParentTy&>(X);
+ }
+
+ public:
+
+ void resetBlkExprValues(AnalysisDataTy& AD) {
+ BlkExprBV.resize(AD.getNumBlkExprs());
+ BlkExprBV.reset();
+ }
+
+ void setBlkExprValues(AnalysisDataTy& AD) {
+ BlkExprBV.resize(AD.getNumBlkExprs());
+ BlkExprBV.set();
+ }
+
+ void resetValues(AnalysisDataTy& AD) {
+ resetDeclValues(AD);
+ resetBlkExprValues(AD);
+ }
+
+ void setValues(AnalysisDataTy& AD) {
+ setDeclValues(AD);
+ setBlkExprValues(AD);
+ }
+
+ bool operator==(const ValTy& RHS) const {
+ return ParentRef(*this) == ParentRef(RHS)
+ && BlkExprBV == RHS.BlkExprBV;
+ }
+
+ void copyValues(const ValTy& RHS) {
+ ParentRef(*this).copyValues(ParentRef(RHS));
+ BlkExprBV = RHS.BlkExprBV;
+ }
+
+ llvm::BitVector::reference
+ operator()(const Stmt* S, const AnalysisDataTy& AD) {
+ return BlkExprBV[AD.getIdx(S)];
+ }
+ const llvm::BitVector::reference
+ operator()(const Stmt* S, const AnalysisDataTy& AD) const {
+ return const_cast<ValTy&>(*this)(S,AD);
+ }
+
+ using DeclBitVector_Types::ValTy::operator();
+
+
+ llvm::BitVector::reference getStmtBit(unsigned i) { return BlkExprBV[i]; }
+ const llvm::BitVector::reference getStmtBit(unsigned i) const {
+ return const_cast<llvm::BitVector&>(BlkExprBV)[i];
+ }
+
+ ValTy& OrBlkExprBits(const ValTy& RHS) {
+ BlkExprBV |= RHS.BlkExprBV;
+ return *this;
+ }
+
+ ValTy& AndBlkExprBits(const ValTy& RHS) {
+ BlkExprBV &= RHS.BlkExprBV;
+ return *this;
+ }
+
+ ValTy& operator|=(const ValTy& RHS) {
+ assert (sizesEqual(RHS));
+ ParentRef(*this) |= ParentRef(RHS);
+ BlkExprBV |= RHS.BlkExprBV;
+ return *this;
+ }
+
+ ValTy& operator&=(const ValTy& RHS) {
+ assert (sizesEqual(RHS));
+ ParentRef(*this) &= ParentRef(RHS);
+ BlkExprBV &= RHS.BlkExprBV;
+ return *this;
+ }
+
+ bool sizesEqual(const ValTy& RHS) const {
+ return ParentRef(*this).sizesEqual(ParentRef(RHS))
+ && BlkExprBV.size() == RHS.BlkExprBV.size();
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ // Some useful merge operations.
+ //===--------------------------------------------------------------------===//
+
+ struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
+ struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
+
+};
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h
new file mode 100644
index 0000000..c6c9eed
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h
@@ -0,0 +1,216 @@
+//===-- 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_BUMP_VECTOR
+#define LLVM_CLANG_BUMP_VECTOR
+
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <algorithm>
+#include <cstring>
+
+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) {}
+
+ /// 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(NULL), End(NULL), Capacity(NULL) {
+ reserve(C, N);
+ }
+
+ ~BumpVector() {
+ if (llvm::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 (llvm::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;
+ }
+
+ 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();
+ }
+ }
+};
+
+// 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 (llvm::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 // end: LLVM_CLANG_BUMP_VECTOR
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Support/SaveAndRestore.h b/contrib/llvm/tools/clang/include/clang/Analysis/Support/SaveAndRestore.h
new file mode 100644
index 0000000..f720639
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Support/SaveAndRestore.h
@@ -0,0 +1,47 @@
+//===-- SaveAndRestore.h - Utility -------------------------------*- 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 utility classes that uses RAII to save and restore
+// values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SAVERESTORE
+#define LLVM_CLANG_ANALYSIS_SAVERESTORE
+
+namespace clang {
+
+// SaveAndRestore - A utility class that uses RAII to save and restore
+// the value of a variable.
+template<typename T>
+struct SaveAndRestore {
+ SaveAndRestore(T& x) : X(x), old_value(x) {}
+ SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) {
+ X = new_value;
+ }
+ ~SaveAndRestore() { X = old_value; }
+ T get() { return old_value; }
+private:
+ T& X;
+ T old_value;
+};
+
+// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
+// value of a variable is saved, and during the dstor the old value is
+// or'ed with the new value.
+struct SaveOr {
+ SaveOr(bool& x) : X(x), old_value(x) { x = false; }
+ ~SaveOr() { X |= old_value; }
+private:
+ bool& X;
+ const bool old_value;
+};
+
+}
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
new file mode 100644
index 0000000..d627b88
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
@@ -0,0 +1,92 @@
+//= CFGRecStmtDeclVisitor - Recursive visitor of CFG stmts/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 implements the template class CFGRecStmtDeclVisitor, which extends
+// CFGRecStmtVisitor by implementing (typed) visitation of decls.
+//
+// FIXME: This may not be fully complete. We currently explore only subtypes
+// of ScopedDecl.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
+#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
+
+#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+
+#define DISPATCH_CASE(CASE,CLASS) \
+case Decl::CASE: \
+static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<CLASS*>(D));\
+break;
+
+#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS(CLASS* D) {}
+#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS(CLASS* D)\
+ { static_cast<ImplClass*>(this)->VisitVarDecl(D); }
+
+
+namespace clang {
+template <typename ImplClass>
+class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor<ImplClass> {
+public:
+
+ void VisitDeclRefExpr(DeclRefExpr* DR) {
+ static_cast<ImplClass*>(this)->VisitDecl(DR->getDecl());
+ }
+
+ void VisitDeclStmt(DeclStmt* DS) {
+ for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
+ DI != DE; ++DI) {
+ Decl* D = *DI;
+ static_cast<ImplClass*>(this)->VisitDecl(D);
+ // Visit the initializer.
+ if (VarDecl* VD = dyn_cast<VarDecl>(D))
+ if (Expr* I = VD->getInit())
+ static_cast<ImplClass*>(this)->Visit(I);
+ }
+ }
+
+ void VisitDecl(Decl* D) {
+ switch (D->getKind()) {
+ DISPATCH_CASE(Function,FunctionDecl)
+ DISPATCH_CASE(CXXMethod,CXXMethodDecl)
+ DISPATCH_CASE(Var,VarDecl)
+ DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same)
+ DISPATCH_CASE(ImplicitParam,ImplicitParamDecl)
+ DISPATCH_CASE(EnumConstant,EnumConstantDecl)
+ DISPATCH_CASE(Typedef,TypedefDecl)
+ DISPATCH_CASE(Record,RecordDecl) // FIXME: Refine. VisitStructDecl?
+ DISPATCH_CASE(Enum,EnumDecl)
+ default:
+ assert(false && "Subtype of ScopedDecl not handled.");
+ }
+ }
+
+ DEFAULT_DISPATCH(VarDecl)
+ DEFAULT_DISPATCH(FunctionDecl)
+ DEFAULT_DISPATCH(CXXMethodDecl)
+ DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
+ DEFAULT_DISPATCH(ImplicitParamDecl)
+ DEFAULT_DISPATCH(EnumConstantDecl)
+ DEFAULT_DISPATCH(TypedefDecl)
+ DEFAULT_DISPATCH(RecordDecl)
+ DEFAULT_DISPATCH(EnumDecl)
+ DEFAULT_DISPATCH(ObjCInterfaceDecl)
+ DEFAULT_DISPATCH(ObjCClassDecl)
+ DEFAULT_DISPATCH(ObjCMethodDecl)
+ DEFAULT_DISPATCH(ObjCProtocolDecl)
+ DEFAULT_DISPATCH(ObjCCategoryDecl)
+};
+
+} // end namespace clang
+
+#undef DISPATCH_CASE
+#undef DEFAULT_DISPATCH
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
new file mode 100644
index 0000000..75a4ac6
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
@@ -0,0 +1,54 @@
+//==- CFGRecStmtVisitor - Recursive visitor of CFG 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 implements the template class CFGRecStmtVisitor, which extends
+// CFGStmtVisitor by implementing a default recursive visit of all statements.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H
+#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H
+
+#include "clang/Analysis/Visitors/CFGStmtVisitor.h"
+
+namespace clang {
+template <typename ImplClass>
+class CFGRecStmtVisitor : public CFGStmtVisitor<ImplClass,void> {
+public:
+
+ void VisitStmt(Stmt* S) {
+ static_cast< ImplClass* >(this)->VisitChildren(S);
+ }
+
+ void VisitConditionVariableInit(Stmt *S) {
+ assert(S == this->getCurrentBlkStmt());
+ VarDecl *CondVar = 0;
+ switch (S->getStmtClass()) {
+#define CONDVAR_CASE(CLASS) \
+case Stmt::CLASS ## Class:\
+CondVar = cast<CLASS>(S)->getConditionVariable();\
+break;
+ CONDVAR_CASE(IfStmt)
+ CONDVAR_CASE(ForStmt)
+ CONDVAR_CASE(SwitchStmt)
+ CONDVAR_CASE(WhileStmt)
+#undef CONDVAR_CASE
+ default:
+ assert(false && "Infeasible");
+ }
+ static_cast<ImplClass*>(this)->Visit(CondVar->getInit());
+ }
+
+ // Defining operator() allows the visitor to be used as a C++ style functor.
+ void operator()(Stmt* S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h
new file mode 100644
index 0000000..8a85ec1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h
@@ -0,0 +1,168 @@
+//===--- CFGStmtVisitor.h - Visitor for Stmts in a 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 defines the CFGStmtVisitor interface, which extends
+// StmtVisitor. This interface is useful for visiting statements in a CFG
+// where some statements have implicit control-flow and thus should
+// be treated specially.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H
+#define LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H
+
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Analysis/CFG.h"
+
+namespace clang {
+
+#define DISPATCH_CASE(CLASS) \
+case Stmt::CLASS ## Class: return \
+static_cast<ImplClass*>(this)->BlockStmt_Visit ## CLASS(static_cast<CLASS*>(S));
+
+#define DEFAULT_BLOCKSTMT_VISIT(CLASS) RetTy BlockStmt_Visit ## CLASS(CLASS *S)\
+{ return\
+ static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(\
+ cast<Expr>(S)); }
+
+template <typename ImplClass, typename RetTy=void>
+class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> {
+ Stmt* CurrentBlkStmt;
+
+ struct NullifyStmt {
+ Stmt*& S;
+
+ NullifyStmt(Stmt*& s) : S(s) {}
+ ~NullifyStmt() { S = NULL; }
+ };
+
+public:
+ CFGStmtVisitor() : CurrentBlkStmt(NULL) {}
+
+ Stmt* getCurrentBlkStmt() const { return CurrentBlkStmt; }
+
+ RetTy Visit(Stmt* S) {
+ if (S == CurrentBlkStmt ||
+ !static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S))
+ return StmtVisitor<ImplClass,RetTy>::Visit(S);
+ else
+ return RetTy();
+ }
+
+ /// VisitConditionVariableInit - Handle the initialization of condition
+ /// variables at branches. Valid statements include IfStmt, ForStmt,
+ /// WhileStmt, and SwitchStmt.
+ RetTy VisitConditionVariableInit(Stmt *S) {
+ return RetTy();
+ }
+
+ /// BlockVisit_XXX - Visitor methods for visiting the "root" statements in
+ /// CFGBlocks. Root statements are the statements that appear explicitly in
+ /// the list of statements in a CFGBlock. For substatements, or when there
+ /// is no implementation provided for a BlockStmt_XXX method, we default
+ /// to using StmtVisitor's Visit method.
+ RetTy BlockStmt_Visit(Stmt* S) {
+ CurrentBlkStmt = S;
+ NullifyStmt cleanup(CurrentBlkStmt);
+
+ switch (S->getStmtClass()) {
+ case Stmt::IfStmtClass:
+ case Stmt::ForStmtClass:
+ case Stmt::WhileStmtClass:
+ case Stmt::SwitchStmtClass:
+ return static_cast<ImplClass*>(this)->VisitConditionVariableInit(S);
+
+ DISPATCH_CASE(StmtExpr)
+ DISPATCH_CASE(ConditionalOperator)
+ DISPATCH_CASE(ObjCForCollectionStmt)
+
+ case Stmt::BinaryOperatorClass: {
+ BinaryOperator* B = cast<BinaryOperator>(S);
+ if (B->isLogicalOp())
+ return static_cast<ImplClass*>(this)->BlockStmt_VisitLogicalOp(B);
+ else if (B->getOpcode() == BinaryOperator::Comma)
+ return static_cast<ImplClass*>(this)->BlockStmt_VisitComma(B);
+ // Fall through.
+ }
+
+ default:
+ if (isa<Expr>(S))
+ return
+ static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(cast<Expr>(S));
+ else
+ return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
+ }
+ }
+
+ DEFAULT_BLOCKSTMT_VISIT(StmtExpr)
+ DEFAULT_BLOCKSTMT_VISIT(ConditionalOperator)
+
+ RetTy BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
+ return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
+ }
+
+ RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr* E) {
+ return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E);
+ }
+
+ RetTy BlockStmt_VisitExpr(Expr* E) {
+ return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(E);
+ }
+
+ RetTy BlockStmt_VisitStmt(Stmt* S) {
+ return static_cast<ImplClass*>(this)->Visit(S);
+ }
+
+ RetTy BlockStmt_VisitLogicalOp(BinaryOperator* B) {
+ return
+ static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B);
+ }
+
+ RetTy BlockStmt_VisitComma(BinaryOperator* B) {
+ return
+ static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Utility methods. Not called by default (but subclasses may use them).
+ //===--------------------------------------------------------------------===//
+
+ /// VisitChildren: Call "Visit" on each child of S.
+ void VisitChildren(Stmt* S) {
+
+ switch (S->getStmtClass()) {
+ default:
+ break;
+
+ case Stmt::StmtExprClass: {
+ CompoundStmt* CS = cast<StmtExpr>(S)->getSubStmt();
+ if (CS->body_empty()) return;
+ static_cast<ImplClass*>(this)->Visit(CS->body_back());
+ return;
+ }
+
+ case Stmt::BinaryOperatorClass: {
+ BinaryOperator* B = cast<BinaryOperator>(S);
+ if (B->getOpcode() != BinaryOperator::Comma) break;
+ static_cast<ImplClass*>(this)->Visit(B->getRHS());
+ return;
+ }
+ }
+
+ for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I != E;++I)
+ if (*I) static_cast<ImplClass*>(this)->Visit(*I);
+ }
+};
+
+#undef DEFAULT_BLOCKSTMT_VISIT
+#undef DISPATCH_CASE
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def
new file mode 100644
index 0000000..b306954
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def
@@ -0,0 +1,562 @@
+//===--- 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
+// f -> float
+// d -> double
+// z -> size_t
+// F -> constant CFString
+// a -> __builtin_va_list
+// A -> "reference" to __builtin_va_list
+// V -> Vector, following num elements and a base type.
+// X -> _Complex, followed by the base type.
+// P -> FILE
+// J -> jmp_buf
+// SJ -> sigjmp_buf
+// . -> "...". This may only occur at the end of the function list.
+//
+// Types maybe prefixed with the following modifiers:
+// L -> long (e.g. Li for 'long int')
+// LL -> long long
+// LLL -> __int128_t (e.g. LLLi)
+// S -> signed
+// U -> unsigned
+//
+// Types may be postfixed with the following modifiers:
+// * -> pointer (optionally followed by an address space number)
+// & -> 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
+// 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.
+// 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
+// e -> const, but only when -fmath-errno=0
+// FIXME: gcc has nonnull
+
+#if defined(BUILTIN) && !defined(LIBBUILTIN)
+# define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) 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*" , "Fnc")
+BUILTIN(__builtin_frexpf, "ffi*" , "Fnc")
+BUILTIN(__builtin_frexpl, "LdLdi*", "Fnc")
+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_ldexp , "ddi" , "Fnc")
+BUILTIN(__builtin_ldexpf, "ffi" , "Fnc")
+BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc")
+BUILTIN(__builtin_modf , "ddd*" , "Fnc")
+BUILTIN(__builtin_modff, "fff*" , "Fnc")
+BUILTIN(__builtin_modfl, "LdLdLd*", "Fnc")
+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_asin , "dd" , "Fnc")
+BUILTIN(__builtin_asinf, "ff" , "Fnc")
+BUILTIN(__builtin_asinl, "LdLd", "Fnc")
+BUILTIN(__builtin_atan , "dd" , "Fnc")
+BUILTIN(__builtin_atanf, "ff" , "Fnc")
+BUILTIN(__builtin_atanl, "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_exp , "dd" , "Fnc")
+BUILTIN(__builtin_expf, "ff" , "Fnc")
+BUILTIN(__builtin_expl, "LdLd", "Fnc")
+BUILTIN(__builtin_floor , "dd" , "Fnc")
+BUILTIN(__builtin_floorf, "ff" , "Fnc")
+BUILTIN(__builtin_floorl, "LdLd", "Fnc")
+BUILTIN(__builtin_hypot , "ddd" , "Fnc")
+BUILTIN(__builtin_hypotf, "fff" , "Fnc")
+BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_log , "dd" , "Fnc")
+BUILTIN(__builtin_log10 , "dd" , "Fnc")
+BUILTIN(__builtin_log10f, "ff" , "Fnc")
+BUILTIN(__builtin_log10l, "LdLd", "Fnc")
+BUILTIN(__builtin_logf, "ff" , "Fnc")
+BUILTIN(__builtin_logl, "LdLd", "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")
+
+// 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_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_casinl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_catan, "XdXd", "Fnc")
+BUILTIN(__builtin_catanf, "XfXf", "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, "dXd", "Fnc")
+BUILTIN(__builtin_conjf, "fXf", "Fnc")
+BUILTIN(__builtin_conjl, "LdXLd", "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.", "nc")
+BUILTIN(__builtin_isgreaterequal, "i.", "nc")
+BUILTIN(__builtin_isless , "i.", "nc")
+BUILTIN(__builtin_islessequal , "i.", "nc")
+BUILTIN(__builtin_islessgreater , "i.", "nc")
+BUILTIN(__builtin_isunordered , "i.", "nc")
+
+// Unary FP classification
+BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
+BUILTIN(__builtin_isfinite, "i.", "nc")
+BUILTIN(__builtin_isinf, "i.", "nc")
+BUILTIN(__builtin_isinf_sign, "i.", "nc")
+BUILTIN(__builtin_isnan, "i.", "nc")
+BUILTIN(__builtin_isnormal, "i.", "nc")
+
+// FP signbit builtins
+BUILTIN(__builtin_signbit, "id", "nc")
+BUILTIN(__builtin_signbitf, "if", "nc")
+BUILTIN(__builtin_signbitl, "iLd", "nc")
+
+// Builtins for arithmetic.
+BUILTIN(__builtin_clz , "iUi" , "nc")
+BUILTIN(__builtin_clzl , "iULi" , "nc")
+BUILTIN(__builtin_clzll, "iULLi", "nc")
+// TODO: int clzimax(uintmax_t)
+BUILTIN(__builtin_ctz , "iUi" , "nc")
+BUILTIN(__builtin_ctzl , "iULi" , "nc")
+BUILTIN(__builtin_ctzll, "iULLi", "nc")
+// TODO: int ctzimax(uintmax_t)
+BUILTIN(__builtin_ffs , "iUi" , "nc")
+BUILTIN(__builtin_ffsl , "iULi" , "nc")
+BUILTIN(__builtin_ffsll, "iULLi", "nc")
+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_bswap32, "UiUi", "nc")
+BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
+
+// Random GCC builtins
+BUILTIN(__builtin_constant_p, "Us.", "nc")
+BUILTIN(__builtin_classify_type, "i.", "nc")
+BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
+BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
+BUILTIN(__builtin_va_start, "vA.", "n")
+BUILTIN(__builtin_va_end, "vA", "n")
+BUILTIN(__builtin_va_copy, "vAA", "n")
+BUILTIN(__builtin_stdarg_start, "vA.", "n")
+BUILTIN(__builtin_bcmp, "iv*v*z", "n")
+BUILTIN(__builtin_bcopy, "vv*v*z", "n")
+BUILTIN(__builtin_bzero, "vv*z", "nF")
+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_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*Ui", "n")
+BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
+BUILTIN(__builtin_frame_address, "v*Ui", "n")
+BUILTIN(__builtin_flt_rounds, "i", "nc")
+BUILTIN(__builtin_setjmp, "iv**", "")
+BUILTIN(__builtin_longjmp, "vv**i", "r")
+BUILTIN(__builtin_unwind_init, "v", "")
+BUILTIN(__builtin_eh_return_data_regno, "ii", "nc")
+BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
+BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
+
+// GCC exception builtins
+BUILTIN(__builtin_eh_return, "vzv*", "") // 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, "zv*i", "n")
+BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "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___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_expect, "LiLiLi" , "nc")
+BUILTIN(__builtin_prefetch, "vvC*.", "nc")
+BUILTIN(__builtin_trap, "v", "nr")
+BUILTIN(__builtin_unreachable, "v", "nr")
+BUILTIN(__builtin_shufflevector, "v." , "nc")
+BUILTIN(__builtin_alloca, "v*z" , "n")
+
+// "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.", "")
+BUILTIN(__sync_fetch_and_add_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_add_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_add_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_add_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_add_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_fetch_and_sub, "v.", "")
+BUILTIN(__sync_fetch_and_sub_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_sub_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_sub_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_sub_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_sub_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_fetch_and_or, "v.", "")
+BUILTIN(__sync_fetch_and_or_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_or_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_or_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_or_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_or_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_fetch_and_and, "v.", "")
+BUILTIN(__sync_fetch_and_and_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_and_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_and_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_and_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_and_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_fetch_and_xor, "v.", "")
+BUILTIN(__sync_fetch_and_xor_1, "cc*c.", "n")
+BUILTIN(__sync_fetch_and_xor_2, "ss*s.", "n")
+BUILTIN(__sync_fetch_and_xor_4, "ii*i.", "n")
+BUILTIN(__sync_fetch_and_xor_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_fetch_and_xor_16, "LLLiLLLi*LLLi.", "n")
+
+
+BUILTIN(__sync_add_and_fetch, "v.", "")
+BUILTIN(__sync_add_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_add_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_add_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_add_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_add_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_sub_and_fetch, "v.", "")
+BUILTIN(__sync_sub_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_sub_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_sub_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_sub_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_sub_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_or_and_fetch, "v.", "")
+BUILTIN(__sync_or_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_or_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_or_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_or_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_or_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_and_and_fetch, "v.", "")
+BUILTIN(__sync_and_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_and_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_and_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_and_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_and_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_xor_and_fetch, "v.", "")
+BUILTIN(__sync_xor_and_fetch_1, "cc*c.", "n")
+BUILTIN(__sync_xor_and_fetch_2, "ss*s.", "n")
+BUILTIN(__sync_xor_and_fetch_4, "ii*i.", "n")
+BUILTIN(__sync_xor_and_fetch_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_xor_and_fetch_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_bool_compare_and_swap, "v.", "")
+BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "n")
+BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "n")
+BUILTIN(__sync_bool_compare_and_swap_4, "biD*ii.", "n")
+BUILTIN(__sync_bool_compare_and_swap_8, "bLLiD*LLiLLi.", "n")
+BUILTIN(__sync_bool_compare_and_swap_16, "bLLLiD*LLLiLLLi.", "n")
+
+BUILTIN(__sync_val_compare_and_swap, "v.", "")
+BUILTIN(__sync_val_compare_and_swap_1, "ccD*cc.", "n")
+BUILTIN(__sync_val_compare_and_swap_2, "ssD*ss.", "n")
+BUILTIN(__sync_val_compare_and_swap_4, "iiD*ii.", "n")
+BUILTIN(__sync_val_compare_and_swap_8, "LLiLLiD*LLiLLi.", "n")
+BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLiD*LLLiLLLi.", "n")
+
+BUILTIN(__sync_lock_test_and_set, "v.", "")
+BUILTIN(__sync_lock_test_and_set_1, "cc*c.", "n")
+BUILTIN(__sync_lock_test_and_set_2, "ss*s.", "n")
+BUILTIN(__sync_lock_test_and_set_4, "ii*i.", "n")
+BUILTIN(__sync_lock_test_and_set_8, "LLiLLi*LLi.", "n")
+BUILTIN(__sync_lock_test_and_set_16, "LLLiLLLi*LLLi.", "n")
+
+BUILTIN(__sync_lock_release, "v.", "")
+BUILTIN(__sync_lock_release_1, "vc*.", "n")
+BUILTIN(__sync_lock_release_2, "vs*.", "n")
+BUILTIN(__sync_lock_release_4, "vi*.", "n")
+BUILTIN(__sync_lock_release_8, "vLLi*.", "n")
+BUILTIN(__sync_lock_release_16, "vLLLi*.", "n")
+
+
+
+// Non-overloaded atomic builtins.
+BUILTIN(__sync_synchronize, "v.", "n")
+// LLVM instruction builtin [Clang extension].
+BUILTIN(__builtin_llvm_memory_barrier,"vbbbbb", "n")
+// GCC does not support these, they are a Clang extension.
+BUILTIN(__sync_fetch_and_min, "ii*i", "n")
+BUILTIN(__sync_fetch_and_max, "ii*i", "n")
+BUILTIN(__sync_fetch_and_umin, "UiUi*Ui", "n")
+BUILTIN(__sync_fetch_and_umax, "UiUi*Ui", "n")
+
+// Random libc builtins.
+BUILTIN(__builtin_abort, "v", "Fnr")
+BUILTIN(__builtin_index, "c*cC*i", "Fn")
+BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
+
+
+
+// C99 library functions
+// C99 stdlib.h
+LIBBUILTIN(abort, "v", "fr", "stdlib.h")
+LIBBUILTIN(calloc, "v*zz", "f", "stdlib.h")
+LIBBUILTIN(exit, "vi", "fr", "stdlib.h")
+LIBBUILTIN(_Exit, "vi", "fr", "stdlib.h")
+LIBBUILTIN(malloc, "v*z", "f", "stdlib.h")
+LIBBUILTIN(realloc, "v*v*z", "f", "stdlib.h")
+// C99 string.h
+LIBBUILTIN(memcpy, "v*v*vC*z", "f", "string.h")
+LIBBUILTIN(memmove, "v*v*vC*z", "f", "string.h")
+LIBBUILTIN(strcpy, "c*c*cC*", "f", "string.h")
+LIBBUILTIN(strncpy, "c*c*cC*z", "f", "string.h")
+LIBBUILTIN(strcat, "c*c*cC*", "f", "string.h")
+LIBBUILTIN(strncat, "c*c*cC*z", "f", "string.h")
+LIBBUILTIN(strxfrm, "zc*cC*z", "f", "string.h")
+LIBBUILTIN(memchr, "v*vC*iz", "f", "string.h")
+LIBBUILTIN(strchr, "c*cC*i", "f", "string.h")
+LIBBUILTIN(strcspn, "zcC*cC*", "f", "string.h")
+LIBBUILTIN(strpbrk, "c*cC*cC*", "f", "string.h")
+LIBBUILTIN(strrchr, "c*cC*i", "f", "string.h")
+LIBBUILTIN(strspn, "zcC*cC*", "f", "string.h")
+LIBBUILTIN(strstr, "c*cC*cC*", "f", "string.h")
+LIBBUILTIN(strtok, "c*c*cC*", "f", "string.h")
+LIBBUILTIN(memset, "v*v*iz", "f", "string.h")
+LIBBUILTIN(strerror, "c*i", "f", "string.h")
+LIBBUILTIN(strlen, "zcC*", "f", "string.h")
+// C99 stdio.h
+LIBBUILTIN(printf, "icC*.", "fp:0:", "stdio.h")
+LIBBUILTIN(fprintf, "iP*cC*.", "fp:1:", "stdio.h")
+LIBBUILTIN(snprintf, "ic*zcC*.", "fp:2:", "stdio.h")
+LIBBUILTIN(sprintf, "ic*cC*.", "fp:1:", "stdio.h")
+LIBBUILTIN(vprintf, "icC*a", "fP:0:", "stdio.h")
+LIBBUILTIN(vfprintf, "i.", "fP:1:", "stdio.h")
+LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h")
+LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", "stdio.h")
+// C99
+LIBBUILTIN(longjmp, "vJi", "fr", "setjmp.h")
+
+// Non-C library functions
+// FIXME: Non-C-standard stuff shouldn't be builtins in non-GNU mode!
+LIBBUILTIN(alloca, "v*z", "f", "stdlib.h")
+// POSIX string.h
+LIBBUILTIN(stpcpy, "c*c*cC*", "f", "string.h")
+LIBBUILTIN(stpncpy, "c*c*cC*z", "f", "string.h")
+LIBBUILTIN(strdup, "c*cC*", "f", "string.h")
+LIBBUILTIN(strndup, "c*cC*z", "f", "string.h")
+// POSIX strings.h
+LIBBUILTIN(index, "c*cC*i", "f", "strings.h")
+LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h")
+LIBBUILTIN(bzero, "vv*z", "f", "strings.h")
+// POSIX unistd.h
+LIBBUILTIN(_exit, "vi", "fr", "unistd.h")
+// POSIX setjmp.h
+LIBBUILTIN(_longjmp, "vJi", "fr", "setjmp.h")
+LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h")
+
+// FIXME: This type isn't very correct, it should be
+// id objc_msgSend(id, SEL)
+// but we need new type letters for that.
+LIBBUILTIN(objc_msgSend, "v*.", "f", "objc/message.h")
+
+// Builtin math library functions
+LIBBUILTIN(pow, "ddd", "fe", "math.h")
+LIBBUILTIN(powl, "LdLdLd", "fe", "math.h")
+LIBBUILTIN(powf, "fff", "fe", "math.h")
+
+LIBBUILTIN(sqrt, "dd", "fe", "math.h")
+LIBBUILTIN(sqrtl, "LdLd", "fe", "math.h")
+LIBBUILTIN(sqrtf, "ff", "fe", "math.h")
+
+LIBBUILTIN(sin, "dd", "fe", "math.h")
+LIBBUILTIN(sinl, "LdLd", "fe", "math.h")
+LIBBUILTIN(sinf, "ff", "fe", "math.h")
+
+LIBBUILTIN(cos, "dd", "fe", "math.h")
+LIBBUILTIN(cosl, "LdLd", "fe", "math.h")
+LIBBUILTIN(cosf, "ff", "fe", "math.h")
+
+#undef BUILTIN
+#undef LIBBUILTIN
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h
new file mode 100644
index 0000000..07f091a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h
@@ -0,0 +1,142 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines enum values for all the target-independent builtin
+// functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_BUILTINS_H
+#define LLVM_CLANG_BASIC_BUILTINS_H
+
+#include <cstring>
+
+// VC++ defines 'alloca' as an object-like macro, which interferes with our
+// builtins.
+#undef alloca
+
+namespace llvm {
+ template <typename T> class SmallVectorImpl;
+}
+
+namespace clang {
+ class TargetInfo;
+ class IdentifierTable;
+ class ASTContext;
+ class QualType;
+
+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;
+ bool Suppressed;
+
+ bool operator==(const Info &RHS) const {
+ return !strcmp(Name, RHS.Name) &&
+ !strcmp(Type, RHS.Type) &&
+ !strcmp(Attributes, RHS.Attributes);
+ }
+ bool operator!=(const Info &RHS) const { return !(*this == RHS); }
+};
+
+/// Builtin::Context - This holds information about target-independent and
+/// target-specific builtins, allowing easy queries by clients.
+class Context {
+ const Info *TSRecords;
+ unsigned NumTSRecords;
+public:
+ Context(const TargetInfo &Target);
+
+ /// InitializeBuiltins - 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, bool NoBuiltins = false);
+
+ /// \brief Popular the vector with the names of all of the builtins.
+ void GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names,
+ bool NoBuiltins);
+
+ /// Builtin::GetName - Return the identifier name for the specified builtin,
+ /// e.g. "__builtin_abs".
+ const char *GetName(unsigned ID) const {
+ return GetRecord(ID).Name;
+ }
+
+ /// GetTypeString - Get the type descriptor string for the specified builtin.
+ const char *GetTypeString(unsigned ID) const {
+ return GetRecord(ID).Type;
+ }
+
+ /// isConst - 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') != 0;
+ }
+
+ /// isNoThrow - Return true if we know this builtin never throws an exception.
+ bool isNoThrow(unsigned ID) const {
+ return strchr(GetRecord(ID).Attributes, 'n') != 0;
+ }
+
+ /// isNoReturn - Return true if we know this builtin never returns.
+ bool isNoReturn(unsigned ID) const {
+ return strchr(GetRecord(ID).Attributes, 'r') != 0;
+ }
+
+ /// isLibFunction - 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') != 0;
+ }
+
+ /// \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') != 0;
+ }
+
+ /// \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);
+
+ /// hasVAListUse - Return true of the specified builtin uses __builtin_va_list
+ /// as an operand or return type.
+ bool hasVAListUse(unsigned ID) const {
+ return strpbrk(GetRecord(ID).Type, "Aa") != 0;
+ }
+
+ /// isConstWithoutErrno - 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') != 0;
+ }
+
+private:
+ const Info &GetRecord(unsigned ID) const;
+};
+
+}
+} // end namespace clang
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def
new file mode 100644
index 0000000..4973076a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def
@@ -0,0 +1,20 @@
+//===--- 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.
+
+// FIXME: This is just a placeholder. NEON intrinsics should be listed here.
+BUILTIN(__builtin_thread_pointer, "v*", "")
+
+#undef BUILTIN
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsPPC.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsPPC.def
new file mode 100644
index 0000000..287bba9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsPPC.def
@@ -0,0 +1,114 @@
+//===--- 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.
+
+// This is just a placeholder, the types and attributes are wrong.
+BUILTIN(__builtin_altivec_abs_v16qi, "V16UcV16Sc", "")
+BUILTIN(__builtin_altivec_abs_v8hi, "V8UsV8Ss", "")
+BUILTIN(__builtin_altivec_abs_v4si, "V4UiV4Si", "")
+
+BUILTIN(__builtin_altivec_abss_v16qi, "V16UcV16Sc", "")
+BUILTIN(__builtin_altivec_abss_v8hi, "V8UsV8Ss", "")
+BUILTIN(__builtin_altivec_abss_v4si, "V4UiV4Si", "")
+
+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_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_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_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_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_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_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_vminfp, "V4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_mtvscr, "vV4i", "")
+
+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_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_vcmpgtfp_p, "iiV4fV4f", "")
+
+// FIXME: Obviously incomplete.
+
+#undef BUILTIN
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def
new file mode 100644
index 0000000..a878dd1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def
@@ -0,0 +1,328 @@
+//===--- 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: In GCC, these builtins are defined depending on whether support for
+// MMX/SSE/etc is turned on. We should do this too.
+
+// 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.
+
+BUILTIN(__builtin_ia32_emms , "v", "")
+
+// FIXME: Are these nothrow/const?
+
+// SSE intrinsics.
+BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comile, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comige, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fc", "")
+BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fc", "")
+BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dc", "")
+BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dc", "")
+BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pcmpeqb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pcmpeqw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pcmpeqd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pcmpgtb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pcmpgtw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pcmpgtd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_packsswb128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_packssdw128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_packuswb128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmaddubsw128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "")
+BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "")
+BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "")
+BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "")
+BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "")
+BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "")
+BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "")
+BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "")
+BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "")
+BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "")
+BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "")
+BUILTIN(__builtin_ia32_stmxcsr, "Ui", "")
+BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "")
+BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "")
+BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "")
+BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "")
+BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "")
+BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "")
+BUILTIN(__builtin_ia32_loadups, "V4ffC*", "")
+BUILTIN(__builtin_ia32_storeups, "vf*V4f", "")
+BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "")
+BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "")
+BUILTIN(__builtin_ia32_movmskps, "iV4f", "")
+BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "")
+BUILTIN(__builtin_ia32_movntps, "vf*V4f", "")
+BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "")
+BUILTIN(__builtin_ia32_sfence, "v", "")
+BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "")
+BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "")
+BUILTIN(__builtin_ia32_loadupd, "V2ddC*", "")
+BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "")
+BUILTIN(__builtin_ia32_movmskpd, "iV2d", "")
+BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "")
+BUILTIN(__builtin_ia32_movnti, "vi*i", "")
+BUILTIN(__builtin_ia32_movntpd, "vd*V2d", "")
+BUILTIN(__builtin_ia32_movntdq, "vV2LLi*V2LLi", "")
+BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "")
+BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "")
+BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "")
+BUILTIN(__builtin_ia32_cvtdq2pd, "V2dV4i", "")
+BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "")
+BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "")
+BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "")
+BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "")
+BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "")
+BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "")
+BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "")
+BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "")
+BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "")
+BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "")
+BUILTIN(__builtin_ia32_cvtps2pd, "V2dV4f", "")
+BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "")
+BUILTIN(__builtin_ia32_clflush, "vvC*", "")
+BUILTIN(__builtin_ia32_lfence, "v", "")
+BUILTIN(__builtin_ia32_mfence, "v", "")
+BUILTIN(__builtin_ia32_loaddqu, "V16ccC*", "")
+BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "")
+BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "")
+BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "")
+BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "")
+BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "")
+BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pslldqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrldqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_pmaddwd128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "")
+BUILTIN(__builtin_ia32_mwait, "vUiUi", "")
+BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "")
+BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cc", "")
+BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cc", "")
+BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "")
+
+BUILTIN(__builtin_ia32_storelv4si, "vV2i*V2LLi", "")
+
+BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pblendw128, "V8sV8sV8si", "")
+BUILTIN(__builtin_ia32_blendpd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_blendps, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "")
+
+BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmovsxbd128, "V4iV16c", "")
+BUILTIN(__builtin_ia32_pmovsxbq128, "V2LLiV16c", "")
+BUILTIN(__builtin_ia32_pmovsxbw128, "V8sV16c", "")
+BUILTIN(__builtin_ia32_pmovsxdq128, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_pmovsxwd128, "V4iV8s", "")
+BUILTIN(__builtin_ia32_pmovsxwq128, "V2LLiV8s", "")
+BUILTIN(__builtin_ia32_pmovzxbd128, "V4iV16c", "")
+BUILTIN(__builtin_ia32_pmovzxbq128, "V2LLiV16c", "")
+BUILTIN(__builtin_ia32_pmovzxbw128, "V8sV16c", "")
+BUILTIN(__builtin_ia32_pmovzxdq128, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_pmovzxwd128, "V4iV8s", "")
+BUILTIN(__builtin_ia32_pmovzxwq128, "V2LLiV8s", "")
+BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "")
+BUILTIN(__builtin_ia32_pmulld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_roundps, "V4fV4fi", "")
+BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "")
+BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_dppd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLi*", "")
+BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_pcmpeqq, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16ci", "")
+
+// SSE 4.2
+BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cc", "")
+BUILTIN(__builtin_ia32_pcmpistri128, "iV16cV16cc", "")
+BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16cic", "")
+BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16cic","")
+
+BUILTIN(__builtin_ia32_pcmpistria128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpistric128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpistrio128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpistris128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpistriz128, "iV16ciV16cic","")
+
+BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16cic","")
+BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16cic","")
+
+BUILTIN(__builtin_ia32_pcmpgtq, "V2LLiV2LLiV2LLi", "")
+
+BUILTIN(__builtin_ia32_crc32qi, "iic", "")
+BUILTIN(__builtin_ia32_crc32hi, "iis", "")
+BUILTIN(__builtin_ia32_crc32si, "iii", "")
+BUILTIN(__builtin_ia32_crc32di, "LLiLLiLLi", "")
+
+// AES
+BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLii", "")
+#undef BUILTIN
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/Basic/CMakeLists.txt
new file mode 100644
index 0000000..c2a4e13
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/CMakeLists.txt
@@ -0,0 +1,20 @@
+macro(clang_diag_gen component)
+ tablegen(Diagnostic${component}Kinds.inc
+ -gen-clang-diags-defs -clang-component=${component})
+ add_custom_target(ClangDiagnostic${component}
+ DEPENDS Diagnostic${component}Kinds.inc)
+endmacro(clang_diag_gen)
+
+set(LLVM_TARGET_DEFINITIONS Diagnostic.td)
+clang_diag_gen(Analysis)
+clang_diag_gen(AST)
+clang_diag_gen(Common)
+clang_diag_gen(Driver)
+clang_diag_gen(Frontend)
+clang_diag_gen(Lex)
+clang_diag_gen(Parse)
+clang_diag_gen(Sema)
+tablegen(DiagnosticGroups.inc
+ -gen-clang-diag-groups)
+add_custom_target(ClangDiagnosticGroups
+ DEPENDS DiagnosticGroups.inc)
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h b/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h
new file mode 100644
index 0000000..4da2ad75
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h
@@ -0,0 +1,159 @@
+/*===--- ConvertUTF.h - Universal Character Names conversions ---------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *==------------------------------------------------------------------------==*/
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+ Conversions between UTF32, UTF-16, and UTF-8. Header file.
+
+ Several funtions are included here, forming a complete set of
+ conversions between the three formats. UTF-7 is not included
+ here, but is handled in a separate source file.
+
+ Each of these routines takes pointers to input buffers and output
+ buffers. The input buffers are const.
+
+ Each routine converts the text between *sourceStart and sourceEnd,
+ putting the result into the buffer between *targetStart and
+ targetEnd. Note: the end pointers are *after* the last item: e.g.
+ *(sourceEnd - 1) is the last item.
+
+ The return result indicates whether the conversion was successful,
+ and if not, whether the problem was in the source or target buffers.
+ (Only the first encountered problem is indicated.)
+
+ After the conversion, *sourceStart and *targetStart are both
+ updated to point to the end of last text successfully converted in
+ the respective buffers.
+
+ Input parameters:
+ sourceStart - pointer to a pointer to the source buffer.
+ The contents of this are modified on return so that
+ it points at the next thing to be converted.
+ targetStart - similarly, pointer to pointer to the target buffer.
+ sourceEnd, targetEnd - respectively pointers to the ends of the
+ two buffers, for overflow checking only.
+
+ These conversion functions take a ConversionFlags argument. When this
+ flag is set to strict, both irregular sequences and isolated surrogates
+ will cause an error. When the flag is set to lenient, both irregular
+ sequences and isolated surrogates are converted.
+
+ Whether the flag is strict or lenient, all illegal sequences will cause
+ an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
+ or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
+ must check for illegal sequences.
+
+ When the flag is set to lenient, characters over 0x10FFFF are converted
+ to the replacement character; otherwise (when the flag is set to strict)
+ they constitute an error.
+
+ Output parameters:
+ The value "sourceIllegal" is returned from some routines if the input
+ sequence is malformed. When "sourceIllegal" is returned, the source
+ value will point to the illegal value that caused the problem. E.g.,
+ in UTF-8 when a sequence is malformed, it points to the start of the
+ malformed sequence.
+
+ Author: Mark E. Davis, 1994.
+ Rev History: Rick McGowan, fixes & updates May 2001.
+ Fixes & updates, Sept 2001.
+
+------------------------------------------------------------------------ */
+
+/* ---------------------------------------------------------------------
+ The following 4 definitions are compiler-specific.
+ The C standard does not guarantee that wchar_t has at least
+ 16 bits, so wchar_t is no less portable than unsigned short!
+ All should be unsigned values to avoid sign extension during
+ bit mask & shift operations.
+------------------------------------------------------------------------ */
+
+typedef unsigned long UTF32; /* at least 32 bits */
+typedef unsigned short UTF16; /* at least 16 bits */
+typedef unsigned char UTF8; /* typically 8 bits */
+typedef unsigned char Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+typedef enum {
+ conversionOK, /* conversion successful */
+ sourceExhausted, /* partial character in source, but hit end */
+ targetExhausted, /* insuff. room in target for conversion */
+ sourceIllegal /* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+ strictConversion = 0,
+ lenientConversion
+} ConversionFlags;
+
+/* This is for C++ and does no harm in C */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ConversionResult ConvertUTF8toUTF16 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+#ifdef CLANG_NEEDS_THESE_ONE_DAY
+ConversionResult ConvertUTF16toUTF8 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF8toUTF32 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF8 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF32 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF16 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+#endif
+
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* --------------------------------------------------------------------- */
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h
new file mode 100644
index 0000000..62f06ed
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h
@@ -0,0 +1,968 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Diagnostic-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTIC_H
+#define LLVM_CLANG_DIAGNOSTIC_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/type_traits.h"
+#include <string>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ template <typename T> class SmallVectorImpl;
+ class raw_ostream;
+}
+
+namespace clang {
+ class DeclContext;
+ class DiagnosticBuilder;
+ class DiagnosticClient;
+ class FileManager;
+ class IdentifierInfo;
+ class LangOptions;
+ class PartialDiagnostic;
+ class Preprocessor;
+ class SourceManager;
+ class SourceRange;
+
+ // Import the diagnostic enums themselves.
+ namespace diag {
+ // Start position for diagnostics.
+ enum {
+ DIAG_START_DRIVER = 300,
+ DIAG_START_FRONTEND = DIAG_START_DRIVER + 100,
+ DIAG_START_LEX = DIAG_START_FRONTEND + 100,
+ DIAG_START_PARSE = DIAG_START_LEX + 300,
+ DIAG_START_AST = DIAG_START_PARSE + 300,
+ DIAG_START_SEMA = DIAG_START_AST + 100,
+ DIAG_START_ANALYSIS = DIAG_START_SEMA + 1500,
+ DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100
+ };
+
+ class CustomDiagInfo;
+
+ /// diag::kind - 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) ENUM,
+#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 MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
+ /// (emit as an error). It allows clients to map errors to
+ /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
+ /// one).
+ enum Mapping {
+ // NOTE: 0 means "uncomputed".
+ MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it.
+ MAP_WARNING = 2, //< Map this diagnostic to a warning.
+ MAP_ERROR = 3, //< Map this diagnostic to an error.
+ MAP_FATAL = 4, //< Map this diagnostic to a fatal error.
+
+ /// Map this diagnostic to "warning", but make it immune to -Werror. This
+ /// happens when you specify -Wno-error=foo.
+ MAP_WARNING_NO_WERROR = 5,
+ /// Map this diagnostic to "error", but make it immune to -Wfatal-errors.
+ /// This happens for -Wno-fatal-errors=foo.
+ MAP_ERROR_NO_WFATAL = 6
+ };
+ }
+
+/// \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 Tokens that should be removed to correct the error.
+ SourceRange RemoveRange;
+
+ /// \brief The location at which we should insert code to correct
+ /// the error.
+ SourceLocation InsertionLoc;
+
+ /// \brief The actual code to insert at the insertion location, as a
+ /// string.
+ std::string CodeToInsert;
+
+ /// \brief Empty code modification hint, indicating that no code
+ /// modification is known.
+ FixItHint() : RemoveRange(), InsertionLoc() { }
+
+ bool isNull() const {
+ return !RemoveRange.isValid() && !InsertionLoc.isValid();
+ }
+
+ /// \brief Create a code modification hint that inserts the given
+ /// code string at a specific location.
+ static FixItHint CreateInsertion(SourceLocation InsertionLoc,
+ llvm::StringRef Code) {
+ FixItHint Hint;
+ Hint.InsertionLoc = InsertionLoc;
+ Hint.CodeToInsert = Code;
+ return Hint;
+ }
+
+ /// \brief Create a code modification hint that removes the given
+ /// source range.
+ static FixItHint CreateRemoval(SourceRange RemoveRange) {
+ FixItHint Hint;
+ Hint.RemoveRange = RemoveRange;
+ return Hint;
+ }
+
+ /// \brief Create a code modification hint that replaces the given
+ /// source range with the given code string.
+ static FixItHint CreateReplacement(SourceRange RemoveRange,
+ llvm::StringRef Code) {
+ FixItHint Hint;
+ Hint.RemoveRange = RemoveRange;
+ Hint.InsertionLoc = RemoveRange.getBegin();
+ Hint.CodeToInsert = Code;
+ return Hint;
+ }
+};
+
+/// Diagnostic - This concrete class is used by the front-end to report
+/// problems and issues. It massages the diagnostics (e.g. handling things like
+/// "report warnings as errors" and passes them off to the DiagnosticClient for
+/// reporting to the user.
+class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
+public:
+ /// Level - The level of the diagnostic, after it has been through mapping.
+ enum Level {
+ Ignored, Note, Warning, Error, Fatal
+ };
+
+ /// ExtensionHandling - How do we handle otherwise-unmapped extension? This
+ /// is controlled by -pedantic and -pedantic-errors.
+ enum ExtensionHandling {
+ Ext_Ignore, Ext_Warn, Ext_Error
+ };
+
+ enum ArgumentKind {
+ ak_std_string, // std::string
+ ak_c_string, // const char *
+ ak_sint, // int
+ ak_uint, // unsigned
+ ak_identifierinfo, // IdentifierInfo
+ ak_qualtype, // QualType
+ ak_declarationname, // DeclarationName
+ ak_nameddecl, // NamedDecl *
+ ak_nestednamespec, // NestedNameSpecifier *
+ ak_declcontext // DeclContext *
+ };
+
+ /// ArgumentValue - This typedef 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 ErrorsAsFatal; // Treat errors like fatal errors.
+ bool SuppressSystemWarnings; // Suppress warnings in system headers.
+ bool SuppressAllDiagnostics; // Suppress all diagnostics.
+ unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit.
+ unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
+ // 0 -> no limit.
+ ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
+ DiagnosticClient *Client;
+
+ /// DiagMappings - Mapping information for diagnostics. Mapping info is
+ /// packed into four bits per diagnostic. The low three bits are the mapping
+ /// (an instance of diag::Mapping), 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.
+
+ typedef std::vector<unsigned char> DiagMappings;
+ mutable std::vector<DiagMappings> DiagMappingsStack;
+
+ /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or
+ /// fatal error is emitted, and is sticky.
+ bool ErrorOccurred;
+ bool FatalErrorOccurred;
+
+ /// LastDiagLevel - This is the level of the last diagnostic emitted. This is
+ /// used to emit continuation diagnostics with the same level as the
+ /// diagnostic that they follow.
+ Diagnostic::Level LastDiagLevel;
+
+ unsigned NumWarnings; // Number of warnings reported
+ unsigned NumErrors; // Number of errors reported
+ unsigned NumErrorsSuppressed; // Number of errors suppressed
+
+ /// CustomDiagInfo - Information for uniquing and looking up custom diags.
+ diag::CustomDiagInfo *CustomDiagInfo;
+
+ /// ArgToStringFn - 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 (whose length is NumPrevArgs) 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,
+ const char *Modifier, unsigned ModifierLen,
+ const char *Argument, unsigned ArgumentLen,
+ const ArgumentValue *PrevArgs,
+ unsigned NumPrevArgs,
+ llvm::SmallVectorImpl<char> &Output,
+ void *Cookie);
+ 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;
+
+public:
+ explicit Diagnostic(DiagnosticClient *client = 0);
+ ~Diagnostic();
+
+ //===--------------------------------------------------------------------===//
+ // Diagnostic characterization methods, used by a client to customize how
+ //
+
+ DiagnosticClient *getClient() { return Client; }
+ const DiagnosticClient *getClient() const { return Client; }
+
+ /// pushMappings - Copies the current DiagMappings and pushes the new copy
+ /// onto the top of the stack.
+ void pushMappings();
+
+ /// popMappings - Pops the current DiagMappings off the top of the stack
+ /// causing the new top of the stack to be the active mappings. Returns
+ /// true if the pop happens, false if there is only one DiagMapping on the
+ /// stack.
+ bool popMappings();
+
+ void setClient(DiagnosticClient* client) { Client = client; }
+
+ /// setErrorLimit - 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
+ /// nodes to emit along with a given diagnostic.
+ unsigned getTemplateBacktraceLimit() const {
+ return TemplateBacktraceLimit;
+ }
+
+ /// setIgnoreAllWarnings - 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; }
+
+ /// setWarningsAsErrors - When set to true, any warnings reported are issued
+ /// as errors.
+ void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
+ bool getWarningsAsErrors() const { return WarningsAsErrors; }
+
+ /// setErrorsAsFatal - When set to true, any error reported is made a
+ /// fatal error.
+ void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
+ bool getErrorsAsFatal() const { return ErrorsAsFatal; }
+
+ /// setSuppressSystemWarnings - 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 Pretend that the last diagnostic issued was ignored. This can
+ /// be used by clients who suppress diagnostics themselves.
+ void setLastDiagnosticIgnored() {
+ LastDiagLevel = Ignored;
+ }
+
+ /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
+ /// extension diagnostics are mapped onto ignore/warning/error. This
+ /// corresponds to the GCC -pedantic and -pedantic-errors option.
+ void setExtensionHandlingBehavior(ExtensionHandling H) {
+ ExtBehavior = H;
+ }
+
+ /// AllExtensionsSilenced - This is a 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; }
+
+ /// setDiagnosticMapping - 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.
+ void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
+ assert(Diag < diag::DIAG_UPPER_LIMIT &&
+ "Can only map builtin diagnostics");
+ assert((isBuiltinWarningOrExtension(Diag) ||
+ (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
+ "Cannot map errors into warnings!");
+ setDiagnosticMappingInternal(Diag, Map, true);
+ }
+
+ /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
+ /// "unknown-pragmas" to have the specified mapping. This returns true and
+ /// ignores the request if "Group" was unknown, false otherwise.
+ bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map);
+
+ bool hasErrorOccurred() const { return ErrorOccurred; }
+ bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
+
+ unsigned getNumErrors() const { return NumErrors; }
+ unsigned getNumErrorsSuppressed() const { return NumErrorsSuppressed; }
+ unsigned getNumWarnings() const { return NumWarnings; }
+
+ /// getCustomDiagID - Return an ID for a diagnostic with the specified message
+ /// and level. If this is the first request for this diagnosic, it is
+ /// registered and created, otherwise the existing ID is returned.
+ unsigned getCustomDiagID(Level L, llvm::StringRef Message);
+
+
+ /// ConvertArgToString - This method converts a diagnostic argument (as an
+ /// intptr_t) into the string that represents it.
+ void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
+ const char *Modifier, unsigned ModLen,
+ const char *Argument, unsigned ArgLen,
+ const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
+ llvm::SmallVectorImpl<char> &Output) const {
+ ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
+ PrevArgs, NumPrevArgs, Output, ArgToStringCookie);
+ }
+
+ void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
+ ArgToStringFn = Fn;
+ ArgToStringCookie = Cookie;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Diagnostic classification and reporting interfaces.
+ //
+
+ /// getDescription - Given a diagnostic ID, return a description of the
+ /// issue.
+ const char *getDescription(unsigned DiagID) const;
+
+ /// isNoteWarningOrExtension - Return true if the unmapped diagnostic
+ /// level of 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 Determine whether the given built-in diagnostic ID is a
+ /// Note.
+ static bool isBuiltinNote(unsigned DiagID);
+
+ /// isBuiltinExtensionDiag - 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);
+ }
+
+ /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
+ /// ID is for an extension of some sort. 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);
+
+
+ /// getWarningOptionForDiag - 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 const char *getWarningOptionForDiag(unsigned DiagID);
+
+ /// getWarningOptionForDiag - Return the category number that a specified
+ /// DiagID belongs to, or 0 if no category.
+ static unsigned getCategoryNumberForDiag(unsigned DiagID);
+
+ /// getCategoryNameFromID - Given a category ID, return the name of the
+ /// category.
+ static const char *getCategoryNameFromID(unsigned CategoryID);
+
+ /// \brief Enumeration describing how the 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 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);
+
+ /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+ /// object, classify the specified diagnostic ID into a Level, consumable by
+ /// the DiagnosticClient.
+ Level getDiagnosticLevel(unsigned DiagID) const;
+
+ /// Report - Issue the message to the client. @c DiagID is a member of the
+ /// @c diag::kind enum. This actually returns aninstance of DiagnosticBuilder
+ /// which emits the diagnostics (through @c ProcessDiag) when it is destroyed.
+ /// @c Pos represents the source location associated with the diagnostic,
+ /// which can be an invalid location if no position information is available.
+ inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID);
+ inline DiagnosticBuilder Report(unsigned DiagID);
+
+ /// \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
+ /// Diagnostic object itself.
+ ///
+ /// \param Arg2 A string argument that will be provided to the
+ /// diagnostic. A copy of this string will be stored in the
+ /// Diagnostic object itself.
+ void SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1 = "",
+ llvm::StringRef Arg2 = "");
+
+ /// \brief Clear out the current diagnostic.
+ void Clear() { CurDiagID = ~0U; }
+
+private:
+ /// \brief Report the delayed diagnostic.
+ void ReportDelayed();
+
+
+ /// getDiagnosticMappingInfo - Return the mapping info currently set for the
+ /// specified builtin diagnostic. This returns the high bit encoding, or zero
+ /// if the field is completely uninitialized.
+ diag::Mapping getDiagnosticMappingInfo(diag::kind Diag) const {
+ const DiagMappings &currentMappings = DiagMappingsStack.back();
+ return (diag::Mapping)((currentMappings[Diag/2] >> (Diag & 1)*4) & 15);
+ }
+
+ void setDiagnosticMappingInternal(unsigned DiagId, unsigned Map,
+ bool isUser) const {
+ if (isUser) Map |= 8; // Set the high bit for user mappings.
+ unsigned char &Slot = DiagMappingsStack.back()[DiagId/2];
+ unsigned Shift = (DiagId & 1)*4;
+ Slot &= ~(15 << Shift);
+ Slot |= Map << Shift;
+ }
+
+ /// getDiagnosticLevel - This is an internal implementation helper used when
+ /// DiagClass is already known.
+ Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const;
+
+ // 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 DiagnosticBuilder;
+ friend class DiagnosticInfo;
+
+ /// CurDiagLoc - This is the location of the current diagnostic that is in
+ /// flight.
+ FullSourceLoc CurDiagLoc;
+
+ /// CurDiagID - This is 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 {
+ /// MaxArguments - 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
+ };
+
+ /// NumDiagArgs - This contains the number of entries in Arguments.
+ signed char NumDiagArgs;
+ /// NumRanges - This is the number of ranges in the DiagRanges array.
+ unsigned char NumDiagRanges;
+ /// \brief The number of code modifications hints in the
+ /// FixItHints array.
+ unsigned char NumFixItHints;
+
+ /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
+ /// values, with one for each argument. This specifies whether the argument
+ /// is in DiagArgumentsStr or in DiagArguments.
+ unsigned char DiagArgumentsKind[MaxArguments];
+
+ /// DiagArgumentsStr - This holds the values of each string argument for the
+ /// current diagnostic. This value is only used when the corresponding
+ /// ArgumentKind is ak_std_string.
+ std::string DiagArgumentsStr[MaxArguments];
+
+ /// DiagArgumentsVal - 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 intepretation depends on exactly what
+ /// sort of argument kind it is.
+ intptr_t DiagArgumentsVal[MaxArguments];
+
+ /// DiagRanges - The list of ranges added to this diagnostic. It currently
+ /// only support 10 ranges, could easily be extended if needed.
+ SourceRange DiagRanges[10];
+
+ enum { MaxFixItHints = 3 };
+
+ /// FixItHints - If valid, provides a hint with some code
+ /// to insert, remove, or modify at a particular position.
+ FixItHint FixItHints[MaxFixItHints];
+
+ /// ProcessDiag - This is the method used to report a diagnostic that is
+ /// finally fully formed.
+ ///
+ /// \returns true if the diagnostic was emitted, false if it was
+ /// suppressed.
+ bool ProcessDiag();
+};
+
+//===----------------------------------------------------------------------===//
+// DiagnosticBuilder
+//===----------------------------------------------------------------------===//
+
+/// DiagnosticBuilder - This is a little helper class used to produce
+/// diagnostics. This is constructed by the Diagnostic::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 Diagnostic *DiagObj;
+ mutable unsigned NumArgs, NumRanges, NumFixItHints;
+
+ void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
+ friend class Diagnostic;
+ explicit DiagnosticBuilder(Diagnostic *diagObj)
+ : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixItHints(0) {}
+
+public:
+ /// Copy constructor. When copied, this "takes" the diagnostic info from the
+ /// input and neuters it.
+ DiagnosticBuilder(const DiagnosticBuilder &D) {
+ DiagObj = D.DiagObj;
+ D.DiagObj = 0;
+ NumArgs = D.NumArgs;
+ NumRanges = D.NumRanges;
+ NumFixItHints = D.NumFixItHints;
+ }
+
+ /// \brief Simple enumeration value used to give a name to the
+ /// suppress-diagnostic constructor.
+ enum SuppressKind { Suppress };
+
+ /// \brief Create an empty DiagnosticBuilder object that represents
+ /// no actual diagnostic.
+ explicit DiagnosticBuilder(SuppressKind)
+ : DiagObj(0), NumArgs(0), NumRanges(0), NumFixItHints(0) { }
+
+ /// \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();
+
+ /// Destructor - The dtor emits the diagnostic if it hasn't already
+ /// been emitted.
+ ~DiagnosticBuilder() { Emit(); }
+
+ /// isActive - Determine whether this diagnostic is still active.
+ bool isActive() const { return DiagObj != 0; }
+
+ /// Operator bool: conversion of DiagnosticBuilder to bool always returns
+ /// true. This allows is to be used in boolean error contexts like:
+ /// return Diag(...);
+ operator bool() const { return true; }
+
+ void AddString(llvm::StringRef S) const {
+ assert(NumArgs < Diagnostic::MaxArguments &&
+ "Too many arguments to diagnostic!");
+ if (DiagObj) {
+ DiagObj->DiagArgumentsKind[NumArgs] = Diagnostic::ak_std_string;
+ DiagObj->DiagArgumentsStr[NumArgs++] = S;
+ }
+ }
+
+ void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
+ assert(NumArgs < Diagnostic::MaxArguments &&
+ "Too many arguments to diagnostic!");
+ if (DiagObj) {
+ DiagObj->DiagArgumentsKind[NumArgs] = Kind;
+ DiagObj->DiagArgumentsVal[NumArgs++] = V;
+ }
+ }
+
+ void AddSourceRange(const SourceRange &R) const {
+ assert(NumRanges <
+ sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
+ "Too many arguments to diagnostic!");
+ if (DiagObj)
+ DiagObj->DiagRanges[NumRanges++] = R;
+ }
+
+ void AddFixItHint(const FixItHint &Hint) const {
+ if (Hint.isNull())
+ return;
+
+ assert(NumFixItHints < Diagnostic::MaxFixItHints &&
+ "Too many fix-it hints!");
+ if (DiagObj)
+ DiagObj->FixItHints[NumFixItHints++] = Hint;
+ }
+};
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ llvm::StringRef S) {
+ DB.AddString(S);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const char *Str) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
+ Diagnostic::ak_c_string);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
+ DB.AddTaggedVal(I, Diagnostic::ak_sint);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) {
+ DB.AddTaggedVal(I, Diagnostic::ak_sint);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ unsigned I) {
+ DB.AddTaggedVal(I, Diagnostic::ak_uint);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const IdentifierInfo *II) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
+ Diagnostic::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 llvm::enable_if<llvm::is_same<T, DeclContext>,
+ const DiagnosticBuilder &>::type
+operator<<(const DiagnosticBuilder &DB, T *DC) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
+ Diagnostic::ak_declcontext);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const SourceRange &R) {
+ DB.AddSourceRange(R);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const FixItHint &Hint) {
+ DB.AddFixItHint(Hint);
+ return DB;
+}
+
+/// Report - Issue the message to the client. DiagID is a member of the
+/// diag::kind enum. This actually returns a new instance of DiagnosticBuilder
+/// which emits the diagnostics (through ProcessDiag) when it is destroyed.
+inline DiagnosticBuilder Diagnostic::Report(FullSourceLoc Loc, unsigned DiagID){
+ assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
+ CurDiagLoc = Loc;
+ CurDiagID = DiagID;
+ return DiagnosticBuilder(this);
+}
+inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) {
+ return Report(FullSourceLoc(), DiagID);
+}
+
+//===----------------------------------------------------------------------===//
+// DiagnosticInfo
+//===----------------------------------------------------------------------===//
+
+/// DiagnosticInfo - This is a little helper class (which is basically a smart
+/// pointer that forward info from Diagnostic) that allows clients to enquire
+/// about the currently in-flight diagnostic.
+class DiagnosticInfo {
+ const Diagnostic *DiagObj;
+public:
+ explicit DiagnosticInfo(const Diagnostic *DO) : DiagObj(DO) {}
+
+ const Diagnostic *getDiags() const { return DiagObj; }
+ unsigned getID() const { return DiagObj->CurDiagID; }
+ const FullSourceLoc &getLocation() const { return DiagObj->CurDiagLoc; }
+
+ unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
+
+ /// getArgKind - Return the kind of the specified index. Based on the kind
+ /// of argument, the accessors below can be used to get the value.
+ Diagnostic::ArgumentKind getArgKind(unsigned Idx) const {
+ assert(Idx < getNumArgs() && "Argument index out of range!");
+ return (Diagnostic::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
+ }
+
+ /// getArgStdStr - Return the provided argument string specified by Idx.
+ const std::string &getArgStdStr(unsigned Idx) const {
+ assert(getArgKind(Idx) == Diagnostic::ak_std_string &&
+ "invalid argument accessor!");
+ return DiagObj->DiagArgumentsStr[Idx];
+ }
+
+ /// getArgCStr - Return the specified C string argument.
+ const char *getArgCStr(unsigned Idx) const {
+ assert(getArgKind(Idx) == Diagnostic::ak_c_string &&
+ "invalid argument accessor!");
+ return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
+ }
+
+ /// getArgSInt - Return the specified signed integer argument.
+ int getArgSInt(unsigned Idx) const {
+ assert(getArgKind(Idx) == Diagnostic::ak_sint &&
+ "invalid argument accessor!");
+ return (int)DiagObj->DiagArgumentsVal[Idx];
+ }
+
+ /// getArgUInt - Return the specified unsigned integer argument.
+ unsigned getArgUInt(unsigned Idx) const {
+ assert(getArgKind(Idx) == Diagnostic::ak_uint &&
+ "invalid argument accessor!");
+ return (unsigned)DiagObj->DiagArgumentsVal[Idx];
+ }
+
+ /// getArgIdentifier - Return the specified IdentifierInfo argument.
+ const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
+ assert(getArgKind(Idx) == Diagnostic::ak_identifierinfo &&
+ "invalid argument accessor!");
+ return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
+ }
+
+ /// getRawArg - Return the specified non-string argument in an opaque form.
+ intptr_t getRawArg(unsigned Idx) const {
+ assert(getArgKind(Idx) != Diagnostic::ak_std_string &&
+ "invalid argument accessor!");
+ return DiagObj->DiagArgumentsVal[Idx];
+ }
+
+
+ /// getNumRanges - Return the number of source ranges associated with this
+ /// diagnostic.
+ unsigned getNumRanges() const {
+ return DiagObj->NumDiagRanges;
+ }
+
+ SourceRange getRange(unsigned Idx) const {
+ assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
+ return DiagObj->DiagRanges[Idx];
+ }
+
+ unsigned getNumFixItHints() const {
+ return DiagObj->NumFixItHints;
+ }
+
+ const FixItHint &getFixItHint(unsigned Idx) const {
+ return DiagObj->FixItHints[Idx];
+ }
+
+ const FixItHint *getFixItHints() const {
+ return DiagObj->NumFixItHints?
+ &DiagObj->FixItHints[0] : 0;
+ }
+
+ /// FormatDiagnostic - Format this diagnostic into a string, substituting the
+ /// formal arguments into the %0 slots. The result is appended onto the Str
+ /// array.
+ void FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const;
+
+ /// FormatDiagnostic - Format the given format-string into the
+ /// output buffer using the arguments stored in this diagnostic.
+ void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
+ llvm::SmallVectorImpl<char> &OutStr) const;
+};
+
+/**
+ * \brief Represents a diagnostic in a form that can be serialized and
+ * deserialized.
+ */
+class StoredDiagnostic {
+ Diagnostic::Level Level;
+ FullSourceLoc Loc;
+ std::string Message;
+ std::vector<SourceRange> Ranges;
+ std::vector<FixItHint> FixIts;
+
+public:
+ StoredDiagnostic();
+ StoredDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info);
+ StoredDiagnostic(Diagnostic::Level Level, llvm::StringRef Message);
+ ~StoredDiagnostic();
+
+ /// \brief Evaluates true when this object stores a diagnostic.
+ operator bool() const { return Message.size() > 0; }
+
+ Diagnostic::Level getLevel() const { return Level; }
+ const FullSourceLoc &getLocation() const { return Loc; }
+ llvm::StringRef getMessage() const { return Message; }
+
+ typedef std::vector<SourceRange>::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(); }
+
+ 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(); }
+
+ /// Serialize - Serialize the given diagnostic (with its diagnostic
+ /// level) to the given stream. Serialization is a lossy operation,
+ /// since the specific diagnostic ID and any macro-instantiation
+ /// information is lost.
+ void Serialize(llvm::raw_ostream &OS) const;
+
+ /// Deserialize - Deserialize the first diagnostic within the memory
+ /// [Memory, MemoryEnd), producing a new diagnostic builder describing the
+ /// deserialized diagnostic. If the memory does not contain a
+ /// diagnostic, returns a diagnostic builder with no diagnostic ID.
+ static StoredDiagnostic Deserialize(FileManager &FM, SourceManager &SM,
+ const char *&Memory, const char *MemoryEnd);
+};
+
+/// DiagnosticClient - This is an abstract interface implemented by clients of
+/// the front-end, which formats and prints fully processed diagnostics.
+class DiagnosticClient {
+public:
+ virtual ~DiagnosticClient();
+
+ /// BeginSourceFile - 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().
+ ///
+ /// \arg LO - The language options for the source file being processed.
+ /// \arg PP - The preprocessor object being used for the source; this optional
+ /// and may not be present, for example when processing AST source files.
+ virtual void BeginSourceFile(const LangOptions &LangOpts,
+ const Preprocessor *PP = 0) {}
+
+ /// EndSourceFile - 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 \see BeginSourceFile() are inaccessible.
+ virtual void EndSourceFile() {}
+
+ /// IncludeInDiagnosticCounts - This method (whose default implementation
+ /// returns true) indicates whether the diagnostics handled by this
+ /// DiagnosticClient should be included in the number of diagnostics reported
+ /// by Diagnostic.
+ virtual bool IncludeInDiagnosticCounts() const;
+
+ /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
+ /// capturing it to a log as needed.
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info) = 0;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td
new file mode 100644
index 0000000..fabf9eb
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td
@@ -0,0 +1,87 @@
+//===--- 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 mappings.
+class DiagMapping;
+def MAP_IGNORE : DiagMapping;
+def MAP_WARNING : DiagMapping;
+def MAP_ERROR : DiagMapping;
+def MAP_FATAL : DiagMapping;
+
+// Define the diagnostic classes.
+class DiagClass;
+def CLASS_NOTE : DiagClass;
+def CLASS_WARNING : DiagClass;
+def CLASS_EXTENSION : DiagClass;
+def CLASS_ERROR : DiagClass;
+
+// 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, DiagMapping defaultmapping> {
+ /// Component is specified by the file with a big let directive.
+ string Component = ?;
+ string Text = text;
+ DiagClass Class = DC;
+ bit SFINAE = 1;
+ DiagMapping DefaultMapping = defaultmapping;
+ DiagGroup Group;
+ string CategoryName = "";
+}
+
+class Error<string str> : Diagnostic<str, CLASS_ERROR, MAP_ERROR>;
+class Warning<string str> : Diagnostic<str, CLASS_WARNING, MAP_WARNING>;
+class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_IGNORE>;
+class ExtWarn<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_WARNING>;
+class Note<string str> : Diagnostic<str, CLASS_NOTE, MAP_FATAL/*ignored*/>;
+
+
+class DefaultIgnore { DiagMapping DefaultMapping = MAP_IGNORE; }
+class DefaultWarn { DiagMapping DefaultMapping = MAP_WARNING; }
+class DefaultError { DiagMapping DefaultMapping = MAP_ERROR; }
+class DefaultFatal { DiagMapping DefaultMapping = MAP_FATAL; }
+
+class NoSFINAE { bit SFINAE = 0; }
+
+// Definitions for Diagnostics.
+include "DiagnosticASTKinds.td"
+include "DiagnosticAnalysisKinds.td"
+include "DiagnosticCommonKinds.td"
+include "DiagnosticDriverKinds.td"
+include "DiagnosticFrontendKinds.td"
+include "DiagnosticLexKinds.td"
+include "DiagnosticParseKinds.td"
+include "DiagnosticSemaKinds.td"
+
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td
new file mode 100644
index 0000000..d755d99
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -0,0 +1,84 @@
+//==--- 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 {
+
+//def note_comma_in_ice : Note<
+// "C does not permit evaluated commas in an integer constant expression">;
+def note_expr_divide_by_zero : Note<"division by zero">;
+
+// 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">;
+}
+
+
+// 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">;
+def note_odr_tag_kind_here: Note<
+ "%0 is a %select{struct|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_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_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
+}
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticAnalysisKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticAnalysisKinds.td
new file mode 100644
index 0000000..46dc0e6
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticAnalysisKinds.td
@@ -0,0 +1,15 @@
+//==--- 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 {
+
+// CHECK: use of uninitialized values
+def warn_uninit_val : Warning<"use of uninitialized variable">;
+
+}
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCategories.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCategories.td
new file mode 100644
index 0000000..a02fbdf
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCategories.td
@@ -0,0 +1,10 @@
+//==--- 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">;
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td
new file mode 100644
index 0000000..88e7dc1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -0,0 +1,77 @@
+//==--- 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_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_also_found : Note<"also found">;
+
+// Parse && Lex
+def err_expected_colon : Error<"expected ':'">;
+def err_expected_colon_after_setter_name : Error<
+ "method name referenced in property setter attribute "
+ "must end with ':'">;
+
+// Parse && Sema
+def ext_no_declarators : ExtWarn<"declaration does not declare anything">;
+def err_param_redefinition : Error<"redefinition of parameter %0">;
+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">;
+
+// Sema && Lex
+def ext_longlong : Extension<
+ "'long long' is an extension when C99 mode is not enabled">,
+ InGroup<LongLong>;
+def warn_integer_too_large : Warning<
+ "integer constant is too large for its type">;
+def warn_integer_too_large_for_signed : Warning<
+ "integer constant is so large that it is unsigned">;
+
+// Sema && AST
+def note_invalid_subexpr_in_ice : Note<
+ "subexpression not valid in an integer 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_invalid_feature : Error<"invalid target feature '%0'">;
+
+// 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;
+}
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
new file mode 100644
index 0000000..f4a31cc
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -0,0 +1,102 @@
+//==--- 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_unknown_stdin_type : Error<
+ "-E or -x required when input is from 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_opt_with_multiple_archs : Error<
+ "option '%0' cannot be used with multiple -arch options">;
+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_unable_to_make_temp : Error<
+ "unable to make temporary file: %0">;
+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 %plural{1:value|:values}1)">;
+def err_drv_invalid_Xarch_argument : Error<
+ "invalid Xarch argument: '%0'">;
+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_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 %1 (use -v to see invocation)">;
+def err_drv_invalid_mfloat_abi : Error<
+ "invalid float ABI '%0'">;
+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 warn_drv_input_file_unused : Warning<
+ "%0: '%1' input unused when '%2' is present">;
+def warn_drv_preprocessed_input_file_unused : Warning<
+ "%0: previously preprocessed input unused when '%1' is present">;
+def warn_drv_unused_argument : Warning<
+ "argument unused during compilation: '%0'">;
+def warn_drv_pipe_ignored_with_save_temps : Warning<
+ "-pipe ignored because -save-temps specified">;
+def warn_drv_not_using_clang_cpp : Warning<
+ "not using the clang preprocessor due to user override">;
+def warn_drv_not_using_clang_cxx : Warning<
+ "not using the clang compiler for C++ inputs">;
+def warn_drv_not_using_clang_arch : Warning<
+ "not using the clang compiler for the '%0' architecture">;
+def warn_drv_clang_unsupported : Warning<
+ "the clang compiler does not support '%0'">;
+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_missing_resource_library : Warning<
+ "missing resource library '%0', link may fail">;
+def warn_drv_conflicting_deployment_targets : Warning<
+ "conflicting deployment targets, both MACOSX_DEPLOYMENT_TARGET '%0' and IPHONEOS_DEPLOYMENT_TARGET '%1' are present in environment">;
+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'">;
+
+}
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td
new file mode 100644
index 0000000..c7cad73
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -0,0 +1,253 @@
+//==--- 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.
+//
+//===----------------------------------------------------------------------===//
+
+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">;
+def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
+def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
+def err_fe_invalid_ast_action : Error<"invalid action for AST input">,
+ DefaultFatal;
+// Error generated by the backend.
+def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
+def note_fe_inline_asm_here : Note<"generated from here">;
+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_stderr_binary : Error<"unable to change standard error to binary">,
+ DefaultFatal;
+def err_fe_dependency_file_requires_MT : Error<
+ "-dependency-file requires at least one -MT or -MQ option">;
+def err_fe_incompatible_options : Error<
+ "'%0' cannot be used with '%1'">, DefaultFatal;
+def err_fe_no_fixit_and_codegen : Error<
+ "FIX-ITs cannot be applied when generating code">;
+def err_fe_unable_to_find_fixit_file : Error<
+ "FIX-IT could not find file '%0'">;
+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_read_pch_file : Error<
+ "unable to read PCH file: '%0'">;
+def err_fe_not_a_pch_file : Error<
+ "input is not a PCH file: '%0'">;
+def err_fe_pch_malformed : Error<
+ "malformed or corrupted PCH file: '%0'">, DefaultFatal;
+def err_fe_pch_malformed_block : Error<
+ "malformed block record in PCH file: '%0'">, DefaultFatal;
+def err_fe_pch_error_at_end_block : Error<
+ "error at end of module block in PCH file: '%0'">, DefaultFatal;
+def err_fe_pch_file_modified : Error<
+ "file '%0' has been modified since the precompiled header was built">,
+ DefaultFatal;
+def err_fe_unable_to_open_output : Error<
+ "unable to open output file '%0': '%1'">;
+def err_fe_unable_to_open_logfile : Error<
+ "unable to open logfile 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 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_inconsistent_diags : Error<
+ "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: %2">;
+
+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 note_fixit_main_file_unchanged : Note<
+ "main file unchanged">;
+def warn_fixit_no_changes : Note<
+ "FIX-IT detected errors it could not fix; no output will be generated">;
+
+def err_fe_invoking : Error<"error invoking%0: %1">, DefaultFatal;
+
+// PCH reader
+def err_relocatable_without_without_isysroot : Error<
+ "must specify system root with -isysroot when building a relocatable "
+ "PCH file">;
+def warn_pch_target_triple : Error<
+ "PCH file was compiled for the target '%0' but the current translation "
+ "unit is being compiled for target '%1'">;
+def warn_pch_c99 : Error<
+ "C99 support was %select{disabled|enabled}0 in PCH file but is "
+ "currently %select{disabled|enabled}1">;
+def warn_pch_cplusplus : Error<
+ "C++ support was %select{disabled|enabled}0 in PCH file but is "
+ "currently %select{disabled|enabled}1">;
+def warn_pch_cplusplus0x : Error<
+ "C++0x support was %select{disabled|enabled}0 in PCH file but is "
+ "currently %select{disabled|enabled}1">;
+def warn_pch_objective_c : Error<
+ "Objective-C support was %select{disabled|enabled}0 in PCH file but is "
+ "currently %select{disabled|enabled}1">;
+def warn_pch_objective_c2 : Error<
+ "Objective-C 2.0 support was %select{disabled|enabled}0 in PCH file but "
+ "is currently %select{disabled|enabled}1">;
+def warn_pch_nonfragile_abi : Error<
+ "PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C "
+ "ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">;
+def warn_pch_nonfragile_abi2 : Error<
+ "PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 "
+ "Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 "
+ "Objective-C ABI is selected">;
+def warn_pch_no_constant_cfstrings : Error<
+ "Objctive-C NSstring generation support was %select{disabled|enabled}0 "
+ "in PCH file but currently %select{disabled|enabled}1">;
+def warn_pch_extensions : Error<
+ "extensions were %select{enabled|disabled}0 in PCH file but are "
+ "currently %select{enabled|disabled}1">;
+def warn_pch_gnu_extensions : Error<
+ "GNU extensions were %select{disabled|enabled}0 in PCH file but are "
+ "currently %select{disabled|enabled}1">;
+def warn_pch_gnu_keywords : Error<
+ "GNU keywords were %select{disabled|enabled}0 in PCH file but are "
+ "currently %select{disabled|enabled}1">;
+def warn_pch_microsoft_extensions : Error<
+ "Microsoft extensions were %select{disabled|enabled}0 in PCH file but are "
+ "currently %select{disabled|enabled}1">;
+def warn_pch_heinous_extensions : Error<
+ "heinous extensions were %select{disabled|enabled}0 in PCH file but are "
+ "currently %select{disabled|enabled}1">;
+def warn_pch_lax_vector_conversions : Error<
+ "lax vector conversions were %select{disabled|enabled}0 in PCH file but "
+ "are currently %select{disabled|enabled}1">;
+def warn_pch_altivec : Error<
+ "AltiVec initializers were %select{disabled|enabled}0 in PCH file but "
+ "are currently %select{disabled|enabled}1">;
+def warn_pch_opencl : Error<
+ "OpenCL language extensions were %select{disabled|enabled}0 in PCH file "
+ "but are currently %select{disabled|enabled}1">;
+def warn_pch_elide_constructors : Error<
+ "Elidable copy constructors were %select{disabled|enabled}0 in PCH file "
+ "but are currently %select{disabled|enabled}1">;
+def warn_pch_exceptions : Error<
+ "exceptions were %select{disabled|enabled}0 in PCH file but "
+ "are currently %select{disabled|enabled}1">;
+def warn_pch_sjlj_exceptions : Error<
+ "sjlj-exceptions were %select{disabled|enabled}0 in PCH file but "
+ "are currently %select{disabled|enabled}1">;
+def warn_pch_objc_runtime : Error<
+ "PCH file was compiled with the %select{NeXT|GNU}0 runtime but the "
+ "%select{NeXT|GNU}1 runtime is selected">;
+def warn_pch_freestanding : Error<
+ "PCH file was compiled with a %select{hosted|freestanding}0 "
+ "implementation but a %select{hosted|freestanding}1 implementation "
+ "is selected">;
+def warn_pch_builtins : Error<
+ "PCH file was compiled with builtins %select{enabled|disabled}0 but "
+ "builtins are currently %select{enabled|disabled}1">;
+def warn_pch_thread_safe_statics : Error<
+ "PCH file was compiled %select{without|with}0 thread-safe statics but "
+ "thread-safe statics are currently %select{disabled|enabled}1">;
+def warn_pch_posix_threads : Error<
+ "PCH file was compiled %select{without|with}0 POSIX thread support but "
+ "POSIX threads are currently %select{disabled|enabled}1">;
+def warn_pch_stack_protector : Error<
+ "stack protector was %select{off|on|required}0 in PCH file but "
+ "is currently %select{off|on|required}1">;
+def warn_pch_blocks : Error<
+ "blocks were %select{disabled|enabled}0 in PCH file but "
+ "are currently %select{disabled|enabled}1">;
+def warn_pch_math_errno : Error<
+ "math functions %select{do not respect|respect}0 'errno' in PCH "
+ "file but they are currently set to %select{not respect|respect}1 "
+ "'errno'">;
+def warn_pch_overflow_checking : Error<
+ "signed integer overflow checking was %select{disabled|enabled}0 in PCH "
+ "file but is currently %select{disabled|enabled}1">;
+def warn_pch_optimize : Error<
+ "the macro '__OPTIMIZE__' was %select{not defined|defined}0 in "
+ "the PCH file but is currently %select{undefined|defined}1">;
+def warn_pch_optimize_size : Error<
+ "the macro '__OPTIMIZE_SIZE__' was %select{not defined|defined}0 in "
+ "the PCH file but is currently %select{undefined|defined}1">;
+def warn_pch_static : Error<
+ "the PCH file was compiled %select{dynamic|static}0 but the "
+ "current translation unit is being compiled as %select{dynamic|static}1">;
+def warn_pch_pic_level : Error<
+ "PCH file was compiled with PIC level %0, but the current translation "
+ "unit will be compiled with PIC level %1">;
+def warn_pch_gnu_inline : Error<
+ "PCH file was compiled with %select{C99|GNU|}0 inline semantics but "
+ "%select{C99|GNU}1 inline semantics are currently selected">;
+def warn_pch_no_inline : Error<
+ "the macro '__NO_INLINE__' was %select{not defined|defined}0 in "
+ "the PCH file but is currently %select{undefined|defined}1">;
+def warn_pch_gc_mode : Error<
+ "the PCH file was built with %select{no||hybrid}0 garbage collection but "
+ "the current translation unit will compiled with %select{no||hybrid}1 "
+ "garbage collection">;
+def warn_pch_version_too_old : Error<
+ "PCH file uses an older PCH format that is no longer supported">;
+def warn_pch_version_too_new : Error<
+ "PCH file uses a newer PCH format that cannot be read">;
+def warn_pch_different_branch : Error<
+ "PCH file built from a different branch (%0) than the compiler (%1)">;
+def warn_cmdline_conflicting_macro_def : Error<
+ "definition of the macro '%0' conflicts with the definition used to "
+ "build the precompiled header">;
+def note_pch_macro_defined_as : Note<
+ "definition of macro '%0' in the precompiled header">;
+def warn_cmdline_missing_macro_defs : Warning<
+ "macro definitions used to build the precompiled header are missing">;
+def note_using_macro_def_from_pch : Note<
+ "using this macro definition from precompiled header">;
+def warn_macro_name_used_in_pch : Error<
+ "definition of macro %0 conflicts with an identifier used in the "
+ "precompiled header">;
+def warn_pch_compiler_options_mismatch : Error<
+ "compiler options used when building the precompiled header differ from "
+ "the options used when using the precompiled header">;
+def warn_pch_access_control : Error<
+ "C++ access control was %select{disabled|enabled}0 in the PCH file but "
+ "is currently %select{disabled|enabled}1">;
+def warn_pch_char_signed : Error<
+ "char was %select{unsigned|signed}0 in the PCH file but "
+ "is currently %select{unsigned|signed}1">;
+def warn_pch_short_wchar : Error<
+ "-fshort-wchar was %select{disabled|enabled}0 in the PCH file but "
+ "is currently %select{disabled|enabled}1">;
+
+def err_not_a_pch_file : Error<
+ "'%0' does not appear to be a precompiled header file">, DefaultFatal;
+def warn_unknown_warning_option : Warning<
+ "unknown warning option '%0'">,
+ InGroup<DiagGroup<"unknown-warning-option"> >;
+def warn_unknown_warning_specifier : Warning<
+ "unknown %0 warning specifier: '%1'">,
+ InGroup<DiagGroup<"unknown-warning-option"> >;
+}
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
new file mode 100644
index 0000000..b79bf8e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
@@ -0,0 +1,198 @@
+//==--- 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<"address">;
+def AddressOfTemporary : DiagGroup<"address-of-temporary">;
+def : DiagGroup<"aggregate-return">;
+def : DiagGroup<"attributes">;
+def : DiagGroup<"bad-function-cast">;
+def : DiagGroup<"c++-compat">;
+def : DiagGroup<"cast-align">;
+def : DiagGroup<"cast-qual">;
+def : DiagGroup<"char-align">;
+def Comment : DiagGroup<"comment">;
+def : DiagGroup<"ctor-dtor-privacy">;
+def : DiagGroup<"declaration-after-statement">;
+def GNUDesignator : DiagGroup<"gnu-designator">;
+def Deprecated : DiagGroup<"deprecated">;
+def : DiagGroup<"disabled-optimization">;
+def : DiagGroup<"discard-qual">;
+def : DiagGroup<"div-by-zero">;
+def EmptyBody : DiagGroup<"empty-body">;
+def ExtraTokens : DiagGroup<"extra-tokens">;
+
+def FormatExtraArgs : DiagGroup<"format-extra-args">;
+def FormatZeroLength : DiagGroup<"format-zero-length">;
+
+def CXXHexFloats : DiagGroup<"c++-hex-floats">;
+
+def : DiagGroup<"c++0x-compat", [CXXHexFloats]>;
+def FourByteMultiChar : DiagGroup<"four-char-constants">;
+def : DiagGroup<"idiomatic-parentheses">;
+def : DiagGroup<"import">;
+def : DiagGroup<"init-self">;
+def : DiagGroup<"inline">;
+def : DiagGroup<"int-to-pointer-cast">;
+def : DiagGroup<"invalid-pch">;
+def LiteralRange : DiagGroup<"literal-range">;
+def MissingBraces : DiagGroup<"missing-braces">;
+def : DiagGroup<"missing-declarations">;
+def : DiagGroup<"missing-format-attribute">;
+def : DiagGroup<"missing-include-dirs">;
+def : DiagGroup<"missing-noreturn">;
+def MultiChar : DiagGroup<"multichar">;
+def : DiagGroup<"nested-externs">;
+def : DiagGroup<"newline-eof">;
+def LongLong : DiagGroup<"long-long">;
+def MismatchedTags : DiagGroup<"mismatched-tags">;
+def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
+def NonNull : DiagGroup<"nonnull">;
+def : DiagGroup<"nonportable-cfstrings">;
+def : DiagGroup<"non-virtual-dtor">;
+def : DiagGroup<"old-style-definition">;
+def : DiagGroup<"overflow">;
+def : DiagGroup<"overloaded-virtual">;
+def : DiagGroup<"packed">;
+def PointerArith : DiagGroup<"pointer-arith">;
+def : DiagGroup<"pointer-to-int-cast">;
+def : DiagGroup<"redundant-decls">;
+def ReturnType : DiagGroup<"return-type">;
+def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
+def : DiagGroup<"sequence-point">;
+def Shadow : DiagGroup<"shadow">;
+def : DiagGroup<"shorten-64-to-32">;
+def SignCompare : DiagGroup<"sign-compare">;
+def : DiagGroup<"synth">;
+
+// Preprocessor warnings.
+def : DiagGroup<"builtin-macro-redefined">;
+
+// 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 : DiagGroup<"strict-selector-match">;
+def SwitchEnum : DiagGroup<"switch-enum">;
+def Switch : DiagGroup<"switch", [SwitchEnum]>;
+def Trigraphs : DiagGroup<"trigraphs">;
+
+def : DiagGroup<"type-limits">;
+def Uninitialized : DiagGroup<"uninitialized">;
+def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def UnusedArgument : DiagGroup<"unused-argument">;
+def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
+def UnusedFunction : DiagGroup<"unused-function">;
+def UnusedLabel : DiagGroup<"unused-label">;
+def UnusedParameter : DiagGroup<"unused-parameter">;
+def UnusedValue : DiagGroup<"unused-value">;
+def UnusedVariable : DiagGroup<"unused-variable">;
+def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
+def Reorder : DiagGroup<"reorder">;
+def UndeclaredSelector : DiagGroup<"undeclared-selector">;
+def Protocol : DiagGroup<"protocol">;
+def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
+def : DiagGroup<"variadic-macros">;
+def VariadicMacros : DiagGroup<"variadic-macros">;
+def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
+def VLA : DiagGroup<"vla">;
+def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
+def : DiagGroup<"write-strings">;
+def CharSubscript : DiagGroup<"char-subscripts">;
+
+// Aggregation warning settings.
+
+// -Widiomatic-parentheses contains warnings about 'idiomatic'
+// missing parentheses; it is off by default.
+def Parentheses : DiagGroup<"parentheses", [DiagGroup<"idiomatic-parentheses">]>;
+
+// -Wconversion has its own warnings, but we split this one out for
+// legacy reasons.
+def Conversion : DiagGroup<"conversion",
+ [DiagGroup<"shorten-64-to-32">]>,
+ DiagCategory<"Value Conversion Issue">;
+
+def Unused : DiagGroup<"unused",
+ [UnusedArgument, UnusedFunction, UnusedLabel,
+ // UnusedParameter, (matches GCC's behavior)
+ UnusedValue, UnusedVariable]>,
+ DiagCategory<"Unused Entity Issue">;
+
+// Format settings.
+def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>,
+ DiagCategory<"Format String Issue">;
+def FormatSecurity : DiagGroup<"format-security", [Format]>;
+def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
+def FormatY2K : DiagGroup<"format-y2k", [Format]>;
+def Format2 : DiagGroup<"format=2",
+ [FormatNonLiteral, FormatSecurity, FormatY2K]>;
+
+def Extra : DiagGroup<"extra", [
+ MissingFieldInitializers,
+ SemiBeforeMethodBody,
+ SignCompare,
+ UnusedParameter
+ ]>;
+
+def Most : DiagGroup<"most", [
+ CharSubscript,
+ Comment,
+ Format,
+ Implicit,
+ MismatchedTags,
+ MissingBraces,
+ MultiChar,
+ Reorder,
+ ReturnType,
+ Switch,
+ Trigraphs,
+ Uninitialized,
+ UnknownPragmas,
+ Unused,
+ VectorConversions,
+ VolatileRegisterVar
+ ]>;
+
+// -Wall is -Wmost -Wparentheses
+def : DiagGroup<"all", [Most, Parentheses]>;
+
+// Aliases.
+def : DiagGroup<"", [Extra]>; // -W = -Wextra
+def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wendif-tokens
+def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
+
+// 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 GCC extensions.
+def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td
new file mode 100644
index 0000000..848e85c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -0,0 +1,300 @@
+//==--- 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_string : Warning<"null character(s) preserved in string literal">;
+def null_in_char : Warning<"null character(s) preserved in character literal">;
+def null_in_file : Warning<"null character ignored">;
+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">;
+
+// 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_bcpl_comment : Extension<"multi-line // comment">,
+ InGroup<Comment>;
+def ext_bcpl_comment : Extension<
+ "// comments are not allowed in this language">,
+ InGroup<Comment>;
+def ext_no_newline_eof : Extension<"no newline at end of file">;
+def ext_backslash_newline_eof : Extension<"backslash-newline at end of file">;
+def ext_dollar_in_identifier : Extension<"'$' in identifier">;
+def charize_microsoft_ext : Extension<"@# is a microsoft extension">;
+
+def ext_token_used : Extension<"extension used">;
+
+def err_unterminated_string : Error<"missing terminating '\"' character">;
+def err_unterminated_char : Error<"missing terminating ' character">;
+def err_empty_character : Error<"empty character constant">;
+def err_unterminated_block_comment : Error<"unterminated /* comment">;
+def err_invalid_character_to_charify : Error<
+ "invalid argument to convert to character">;
+
+def err_conflict_marker : Error<"version control conflict marker in file">;
+
+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>;
+
+
+// Literal
+def ext_nonstandard_escape : Extension<
+ "use of non-standard escape character '\\%0'">;
+def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">;
+def err_hex_escape_no_digits : Error<"\\x used with no following hex digits">;
+def err_ucn_escape_no_digits : Error<"\\u used with no following hex digits">;
+def err_ucn_escape_invalid : Error<"invalid universal character">;
+def err_ucn_escape_incomplete : Error<"incomplete universal character name">;
+def err_ucn_escape_too_big : Error<"universal character name is too long">;
+def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">;
+def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">;
+def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">;
+def err_invalid_suffix_integer_constant : Error<
+ "invalid suffix '%0' on integer constant">;
+def err_invalid_suffix_float_constant : Error<
+ "invalid suffix '%0' on floating constant">;
+def warn_extraneous_wide_char_constant : Warning<
+ "extraneous characters in wide character constant ignored">;
+def warn_char_constant_too_large : Warning<
+ "character constant too long for its type">;
+def err_exponent_has_no_digits : Error<"exponent has no digits">;
+def ext_imaginary_constant : Extension<"imaginary constants are an extension">;
+def err_hexconstant_requires_exponent : Error<
+ "hexadecimal floating constants require an exponent">;
+def ext_hexconstant_cplusplus : Extension<
+ "hexadecimal floating constants are a C99 feature that is incompatible with "
+ "C++0x">, InGroup<CXXHexFloats>;
+def ext_hexconstant_invalid : Extension<
+ "hexadecimal floating constants are a C99 feature">;
+def ext_binary_literal : Extension<
+ "binary integer literals are an extension">;
+def err_pascal_string_too_long : Error<"Pascal string is too long">;
+def warn_octal_escape_too_large : ExtWarn<"octal escape sequence out of range">;
+def warn_hex_escape_too_large : ExtWarn<"hex escape sequence out of range">;
+
+//===----------------------------------------------------------------------===//
+// PTH Diagnostics
+//===----------------------------------------------------------------------===//
+def err_pth_cannot_read : Error<
+ "PTH file '%0' could not be read">;
+def err_invalid_pth_file : Error<
+ "invalid or corrupt PTH file '%0'">;
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Diagnostics
+//===----------------------------------------------------------------------===//
+def pp_hash_warning : Warning<"#warning%0">, InGroup<DiagGroup<"#warnings">>;
+def pp_include_next_in_primary : Warning<
+ "#include_next in primary source file">;
+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">;
+def ext_c99_whitespace_required_after_macro_name : ExtWarn<
+ "ISO C99 requires whitespace after the macro name">;
+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">;
+def pp_pragma_sysheader_in_main_file : Warning<
+ "#pragma system_header ignored in main file">;
+def pp_poisoning_existing_macro : Warning<"poisoning existing macro">;
+def pp_out_of_date_dependency : Warning<
+ "current file is older than dependency %0">;
+def pp_undef_builtin_macro : Warning<"undefining builtin macro">;
+def pp_redef_builtin_macro : Warning<"redefining builtin macro">,
+ InGroup<DiagGroup<"builtin-macro-redefined">>;
+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 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_lhs_to_positive : Warning<
+ "left side of operator converted from negative value to unsigned: %0">;
+def warn_pp_convert_rhs_to_positive : Warning<
+ "right side of operator converted from negative value to unsigned: %0">;
+
+def ext_pp_import_directive : Extension<"#import is a language extension">;
+def ext_pp_ident_directive : Extension<"#ident is a language extension">;
+def ext_pp_include_next_directive : Extension<
+ "#include_next is a language extension">;
+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">;
+def ext_variadic_macro : Extension<"variadic macros were introduced in C99">,
+ InGroup<VariadicMacros>;
+def ext_named_variadic_macro : Extension<
+ "named variadic macros are a GNU extension">, InGroup<VariadicMacros>;
+def ext_embedded_directive : Extension<
+ "embedding a directive within macro arguments is not portable">;
+def ext_missing_varargs_arg : Extension<
+ "varargs argument missing, but tolerated as an extension">;
+def ext_empty_fnmacro_arg : Extension<
+ "empty macro arguments were standardized in C99">;
+
+def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
+def err_pp_hash_error : Error<"#error%0">;
+def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
+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 names must be identifiers">;
+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_missing_val_before_operator : Error<"missing value before operator">;
+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_defined_requires_identifier : Error<
+ "operator 'defined' requires an identifier">;
+def err_pp_missing_lparen : Error<"missing '(' after '%0'">;
+def err_pp_missing_rparen : Error<"missing ')' 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__Pragma_malformed : Error<
+ "_Pragma takes a parenthesized string literal">;
+def err_pragma_comment_malformed : Error<
+ "pragma comment requires parenthesized identifier and optional string">;
+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_stdc_pragma_syntax :
+ ExtWarn<"expected 'ON' or 'OFF' or 'DEFAULT' in pragma">,
+ InGroup<UnknownPragmas>;
+def ext_stdc_pragma_syntax_eom :
+ ExtWarn<"expected end of macro in STDC 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_gcc_invalid :
+ ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', or"
+ " 'fatal'">,
+ InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_clang_invalid :
+ ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal'"
+ " 'push', or 'pop'">,
+ InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_clang_cannot_ppp :
+ 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>;
+
+def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">;
+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<
+ "Use of comma pasting extension is non-portable">;
+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 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 err_pp_operator_used_as_macro_name : Error<
+ "C++ operator '%0' cannot be used as a macro name">;
+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 err_pp_line_invalid_filename : Error<
+ "invalid filename for #line directive">;
+def warn_pp_line_decimal : Warning<
+ "#line directive interprets number as decimal, not octal">;
+def err_pp_line_digit_sequence : Error<
+ "#line 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">;
+
+}
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td
new file mode 100644
index 0000000..934bd0d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -0,0 +1,387 @@
+//==--- 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 = "Parse Issue" in {
+
+def ext_empty_source_file : Extension<"ISO C forbids an empty source file">;
+def ext_top_level_semi : Extension<
+ "extra ';' outside of a function">;
+def ext_extra_struct_semi : Extension<
+ "extra ';' inside a struct or union">;
+
+def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
+def ext_plain_complex : ExtWarn<
+ "plain '_Complex' requires a type specifier; assuming '_Complex double'">;
+def ext_integer_complex : Extension<
+ "complex integer types are an extension">;
+def ext_thread_before : Extension<"'__thread' before 'static'">;
+
+def ext_empty_struct_union_enum : Extension<"use of empty %0 extension">;
+
+def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">;
+def err_invalid_short_spec : Error<"'short %0' is invalid">;
+def err_invalid_long_spec : Error<"'long %0' is invalid">;
+def err_invalid_longlong_spec : Error<"'long long %0' is invalid">;
+def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">;
+def err_friend_storage_spec : Error<"'%0' is invalid in friend declarations">;
+
+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">;
+def ext_c99_compound_literal : Extension<
+ "compound literals are a C99-specific feature">;
+def ext_enumerator_list_comma : Extension<
+ "commas at the end of enumerator lists are a %select{C99|C++0x}0-specific "
+ "feature">;
+
+def ext_gnu_indirect_goto : Extension<
+ "use of GNU indirect-goto extension">, InGroup<GNU>;
+def ext_gnu_address_of_label : Extension<
+ "use of GNU address-of-label extension">, InGroup<GNU>;
+def ext_gnu_statement_expr : Extension<
+ "use of GNU statement expression extension">, InGroup<GNU>;
+def ext_gnu_conditional_expr : Extension<
+ "use of GNU ?: expression extension, eliding middle term">, InGroup<GNU>;
+def ext_gnu_empty_initializer : Extension<
+ "use of GNU empty initializer extension">, InGroup<GNU>;
+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<GNU>;
+
+// Generic errors.
+def err_parse_error : Error<"parse error">;
+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_expected_ident : Error<"expected identifier">;
+def err_expected_ident_lparen : Error<"expected identifier or '('">;
+def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
+def err_expected_lbrace : Error<"expected '{'">;
+def err_expected_lparen : Error<"expected '('">;
+def err_expected_rparen : Error<"expected ')'">;
+def err_expected_lsquare : Error<"expected '['">;
+def err_expected_rsquare : Error<"expected ']'">;
+def err_expected_rbrace : Error<"expected '}'">;
+def err_expected_greater : Error<"expected '>'">;
+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 : Extension<
+ "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_expected_fn_body : Error<
+ "expected function body after function declarator">;
+def err_expected_method_body : Error<"expected method body">;
+def err_invalid_token_after_toplevel_declarator : Error<
+ "invalid token after top level declarator">;
+def err_expected_statement : Error<"expected statement">;
+def err_expected_lparen_after : Error<"expected '(' after '%0'">;
+def err_expected_lparen_after_id : Error<"expected '(' after %0">;
+def err_expected_less_after : Error<"expected '<' after '%0'">;
+def err_expected_comma : Error<"expected ','">;
+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 : Error<"expected ';' after %0">;
+def err_expected_semi_after_stmt : Error<"expected ';' after %0 statement">;
+def err_expected_semi_after_expr : Error<"expected ';' after expression">;
+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 can not be specified on namespace alias">;
+def err_namespace_nonnamespace_scope : Error<
+ "namespaces can only be defined in global or namespace scope">;
+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_expected_colon_after : Error<"expected ':' after %0">;
+def err_label_end_of_compound_statement : Error<
+ "label at end of compound statement: expected statement">;
+def err_expected_string_literal : Error<"expected string literal">;
+def err_expected_asm_operand : Error<
+ "expected string literal or '[' for asm operand">, CatInlineAsm;
+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_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 err_rvalue_reference : Error<
+ "rvalue references are only allowed in C++0x">;
+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 err_expected_class_name : Error<"expected class name">;
+def err_unspecified_vla_size_with_static : Error<
+ "'static' may not be used with an unspecified variable length array size">;
+
+// 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_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_double_decl_spec_combination : Error<
+ "cannot use 'double' with '__vector'">;
+def warn_vector_long_decl_spec_combination : Warning<
+ "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
+def err_friend_invalid_in_context : Error<
+ "'friend' used outside of class">;
+def err_unknown_typename : Error<
+ "unknown type name %0">;
+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_expected_ident_in_using : Error<
+ "expected an identifier in using directive">;
+def err_unexected_colon_in_nested_name_spec : Error<
+ "unexpected ':' in nested name specifier">;
+
+/// 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 warn_objc_protocol_qualifier_missing_id : Warning<
+ "protocol qualifiers without 'id' is archaic">;
+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_objc_illegal_visibility_spec : Error<
+ "illegal visibility specification">;
+def err_objc_illegal_interface_qual : Error<"illegal interface qualifier">;
+def err_objc_expected_equal : Error<
+ "setter/getter expects '=' followed by name">;
+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_propertoes_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_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_missing_sel_definition : Error<"cannot find definition of 'SEL'">;
+def err_missing_id_definition : Error<"cannot find definition of 'id'">;
+def err_missing_proto_definition : Error<
+ "cannot find definition of 'Protocol'">;
+def err_missing_class_definition : Error<"cannot find definition of 'Class'">;
+def warn_expected_implementation : Warning<
+ "@end must appear in an @implementation context">;
+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 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_expected_unqualified_id : Error<
+ "expected %select{identifier|unqualified-id}0">;
+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_equal_after_declarator : Error<
+ "expected '=' after declarator">;
+def warn_parens_disambiguated_as_function_decl : Warning<
+ "parentheses were disambiguated as a function declarator">;
+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 ext_ellipsis_exception_spec : Extension<
+ "exception specification of '...' is a Microsoft extension">;
+def err_expected_catch : Error<"expected catch">;
+def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
+def err_using_namespace_in_class : Error<
+ "'using namespace' is not allowed in classes">;
+def err_destructor_tilde_identifier : Error<
+ "expected a class name after '~' to name a destructor">;
+def err_destructor_template_id : Error<
+ "destructor name %0 does not refer to a template">;
+
+// C++ derived classes
+def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
+
+// C++ operator overloading
+def err_operator_missing_type_specifier : Error<
+ "missing type specifier after 'operator'">;
+def err_operator_string_not_empty : Error<
+ "string literal after 'operator' must be '\"\"'">;
+
+// Classes.
+def err_anon_type_definition : Error<
+ "declaration of anonymous %0 must be a definition">;
+
+def err_cxx0x_attribute_forbids_arguments : Error<
+ "C++0x attribute '%0' cannot have an argument list">;
+def err_cxx0x_attribute_requires_arguments : Error<
+ "C++0x attribute '%0' must have an argument list">;
+def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
+
+/// 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_expected_type_id_after : Error<"expected type-id after '%0'">;
+def err_expected_class_before : Error<"expected 'class' before '%0'">;
+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 template template parameter}1">;
+def err_id_after_template_in_nested_name_spec : Error<
+ "expected template name after 'template' keyword in nested name specifier">;
+def err_id_after_template_in_typename_spec : Error<
+ "expected template name after 'template' keyword in typename specifier">;
+def err_less_after_template_name_in_nested_name_spec : Error<
+ "expected '<' after 'template %0' in nested name specifier">;
+def err_two_right_angle_brackets_need_space : Error<
+ "a space is required between consecutive right angle brackets (use '> >')">;
+def warn_cxx0x_right_shift_in_template_arg : Warning<
+ "use of right-shift operator ('>>') in template argument will require "
+ "parentheses in C++0x">;
+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_enum_template : Error<"enumeration cannot be a template">;
+
+def err_missing_dependent_template_keyword : Error<
+ "use 'template' keyword to treat '%0' as a dependent template name">;
+
+// 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_names_constructor : Error<
+ "qualified reference to %0 is a constructor name rather than a "
+ "template name wherever a constructor can be declared">;
+def err_out_of_line_type_names_constructor : Error<
+ "qualified reference to %0 is a constructor name rather than a "
+ "type wherever a constructor can be declared">;
+
+def err_expected_qualified_after_typename : Error<
+ "expected a qualified name after 'typename'">;
+def err_expected_semi_after_tagdecl : Error<
+ "expected ';' after %0">;
+
+def err_typename_refers_to_non_type_template : Error<
+ "typename specifier refers to a non-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 "
+ "%select{class|struct|union}1 %2">;
+
+def err_variadic_templates : Error<
+ "variadic templates are only allowed in C++0x">;
+
+def err_default_template_template_parameter_not_template : Error<
+ "default template argument for a template template parameter must be a class "
+ "template">;
+
+// C++ declarations
+def err_friend_decl_defines_class : Error<
+ "cannot define a type in a friend declaration">;
+
+// Language specific pragmas
+// - Generic warnings
+def warn_pragma_expected_lparen : Warning<
+ "missing '(' after '#pragma %0' - ignoring">;
+def warn_pragma_expected_rparen : Warning<
+ "missing ')' after '#pragma %0' - ignoring">;
+def warn_pragma_expected_identifier : Warning<
+ "expected identifier in '#pragma %0' - ignored">;
+def warn_pragma_extra_tokens_at_eol : Warning<
+ "extra tokens at end of '#pragma %0' - ignored">;
+// - #pragma options
+def warn_pragma_options_expected_align : Warning<
+ "expected 'align' following '#pragma options' - ignored">;
+def warn_pragma_options_expected_equal : Warning<
+ "expected '=' following '#pragma options align' - ignored">;
+def warn_pragma_options_invalid_option : Warning<
+ "invalid alignment option in '#pragma options align' - ignored">;
+// - #pragma pack
+def warn_pragma_pack_invalid_action : Warning<
+ "unknown action for '#pragma pack' - ignored">;
+def warn_pragma_pack_invalid_constant : Warning<
+ "invalid constant for '#pragma pack', expected %0 - ignored">;
+def warn_pragma_pack_malformed : Warning<
+ "expected integer or identifier in '#pragma pack' - ignored">;
+// - #pragma unused
+def warn_pragma_unused_expected_var : Warning<
+ "expected '#pragma unused' argument to be a variable name">;
+def warn_pragma_unused_expected_punc : Warning<
+ "expected ')' or ',' in '#pragma unused'">;
+
+} // end of Parse Issue category.
+} // end of Parser diagnostics
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
new file mode 100644
index 0000000..0ba31ae
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -0,0 +1,3100 @@
+//==--- 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 {
+
+// Constant expressions
+def err_expr_not_ice : Error<
+ "expression is not an integer constant expression">;
+def ext_expr_not_ice : Extension<
+ "expression is not integer constant expression "
+ "(but is allowed as an extension)">;
+
+def ext_null_pointer_expr_not_ice : Extension<
+ "null pointer expression is not an integer constant expression "
+ "(but is allowed as an extension)">;
+
+
+
+// Semantic analysis of constant literals.
+def ext_predef_outside_function : Warning<
+ "predefined identifier is only valid inside 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>;
+
+// C99 variable-length arrays
+def ext_vla : Extension<
+ "variable length arrays are a C99 feature, accepted as an extension">,
+ InGroup<VLA>;
+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 can not have 'static' storage duration">;
+def err_vla_decl_has_extern_linkage : Error<
+ "variable length array declaration can not have 'extern' linkage">;
+
+// 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">;
+
+// C99 Designated Initializers
+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">;
+def warn_initializer_overrides : Warning<
+ "initializer overrides prior initialization of this subobject">;
+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<GNU>;
+
+// Declarations.
+def ext_anon_param_requires_type_specifier : Extension<
+ "type specifier required for unnamed parameter, defaults to int">;
+def err_bad_variable_name : Error<
+ "'%0' cannot be the name of a variable or data member">;
+def err_parameter_name_omitted : Error<"parameter name omitted">;
+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_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">;
+def warn_unused_function : Warning<"unused function %0">,
+ InGroup<UnusedFunction>, DefaultIgnore;
+
+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 err_ellipsis_first_arg : Error<
+ "ISO C requires a named argument before '...'">;
+def err_declarator_need_ident : Error<"declarator requires an identifier">;
+def err_bad_language : Error<"unknown linkage language">;
+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 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_can_not_refer_to_class_member : Error<
+ "using declaration can not refer to class member">;
+def err_using_decl_can_not_refer_to_namespace : Error<
+ "using declaration can not refer to namespace">;
+def err_using_decl_constructor : Error<
+ "using declaration can not refer to a constructor">;
+def err_using_decl_destructor : Error<
+ "using declaration can not refer to a destructor">;
+def err_using_decl_template_id : Error<
+ "using declaration can not 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_invalid_thread : Error<
+ "'__thread' is only allowed on variable declarations">;
+def err_thread_non_global : Error<
+ "'__thread' variables must have global storage">;
+def err_thread_unsupported : Error<
+ "thread-local storage is unsupported 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<
+ "function could be attribute 'noreturn'">,
+ InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore;
+def warn_suggest_noreturn_block : Warning<
+ "block could be attribute 'noreturn'">,
+ InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore;
+def warn_unreachable : Warning<"will never be executed">,
+ InGroup<DiagGroup<"unreachable-code">>, DefaultIgnore;
+
+/// Built-in functions.
+def ext_implicit_lib_function_decl : ExtWarn<
+ "implicitly declaring C library function '%0' with type %1">;
+def note_please_include_header : Note<
+ "please 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 err_implicit_decl_requires_stdio : Error<
+ "implicit declaration of '%0' requires inclusion of the header <stdio.h>">;
+def err_implicit_decl_requires_setjmp : Error<
+ "implicit declaration of '%0' requires inclusion of the header <setjmp.h>">;
+def warn_redecl_library_builtin : Warning<
+ "incompatible redeclaration of library function %0">;
+def err_builtin_definition : Error<"definition of builtin function %0">;
+def err_types_compatible_p_in_cplusplus : Error<
+ "__builtin_types_compatible_p is not valid in C++">;
+def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError;
+
+/// main()
+// static/inline main() are not errors in C, just in C++.
+def warn_unusual_main_decl : Warning<"'main' should not be declared "
+ "%select{static|inline|static or inline}0">;
+def err_unusual_main_decl : Error<"'main' is not allowed to be declared "
+ "%select{static|inline|static or inline}0">;
+def err_main_returns_nonint : Error<"'main' must return '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">;
+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">;
+
+/// parser diagnostics
+def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">;
+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 warn_enum_value_overflow : Warning<"overflow in enumeration value">;
+def warn_pragma_options_align_unsupported_option : Warning<
+ "unsupported alignment option in '#pragma options align'">;
+def warn_pragma_options_align_reset_failed : Warning<
+ "#pragma options align=reset failed: %0">;
+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'">;
+// Follow the MSVC 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_pack_pop_failed : Warning<"#pragma pack(pop, ...) failed: %0">;
+
+def warn_pragma_unused_undeclared_var : Warning<
+ "undeclared variable %0 used as an argument for '#pragma unused'">;
+def warn_pragma_unused_expected_localvar : Warning<
+ "only local variables can be arguments to '#pragma unused'">;
+def err_unsupported_pragma_weak : Error<
+ "using '#pragma weak' to refer to an undeclared identifier is not yet supported">;
+
+/// 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_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 warn_previous_alias_decl : Warning<"previously declared alias is ignored">;
+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_readonly_property : Warning<
+ "attribute 'readonly' of property %0 restricts attribute "
+ "'readwrite' of property inherited from %1">;
+
+def warn_property_attribute : Warning<
+ "property %0 '%1' attribute does not match the property inherited from %2">;
+def warn_property_types_are_incompatible : Warning<
+ "property type %0 is incompatible with type %1 inherited from %2">;
+def err_undef_interface : Error<"cannot find interface declaration for %0">;
+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 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: %1 vs %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_inconsistant_ivar_count : Error<
+ "inconsistent number of instance variables specified">;
+def warn_incomplete_impl : Warning<"incomplete implementation">;
+def note_undef_method_impl : Note<"method definition for %0 not found">;
+def note_required_for_protocol_at :
+ Note<"required for direct or indirect protocol %0">;
+
+def warn_conflicting_ret_types : Warning<
+ "conflicting return type in implementation of %0: %1 vs %2">;
+
+def warn_conflicting_param_types : Warning<
+ "conflicting parameter types in implementation of %0: %1 vs %2">;
+def warn_conflicting_variadic :Warning<
+ "conflicting variadic declaration of method and its implementation">;
+
+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">;
+def warn_accessor_property_type_mismatch : Warning<
+ "type of property %0 does not match type of accessor %1">;
+def note_declared_at : Note<"declared 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_missing_atend : Warning<"'@end' is missing in implementation context">;
+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">;
+def warn_objc_property_default_assign_on_object : Warning<
+ "default property attribute 'assign' not appropriate for non-gc object">;
+def warn_property_attr_mismatch : Warning<
+ "property attribute in continuation class does not match the primary class">;
+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_atomic_property_rule : Warning<
+ "writable atomic property %0 cannot pair a synthesized setter/getter "
+ "with a user defined setter/getter">;
+def err_use_continuation_class : Error<
+ "illegal declaration of property in continuation class %0"
+ ": attribute must be readwrite, while its primary must be readonly">;
+def err_continuation_class : Error<"continuation class 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">;
+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 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"
+ " ivar or must explicitly name an ivar">;
+
+def error_synthesized_ivar_yet_not_supported : Error<
+ "instance variable synthesis not yet supported"
+ " (need to declare %0 explicitly)">;
+
+def error_property_ivar_type : Error<
+ "type of property %0 (%1) does not match type of ivar %2 (%3)">;
+def error_ivar_in_superclass_use : Error<
+ "property %0 attempting to use ivar %1 declared in super class %2">;
+def error_weak_property : Error<
+ "existing ivar %1 for __weak property %0 must be __weak">;
+def error_strong_property : Error<
+ "existing ivar %1 for a __strong property %0 must be garbage collectable">;
+def error_dynamic_property_ivar_decl : Error<
+ "dynamic property can not have ivar specification">;
+def error_duplicate_ivar_use : Error<
+ "synthesized properties %0 and %1 both claim ivar %2">;
+def error_property_implemented : Error<"property %0 is already implemented">;
+def warn_objc_property_attr_mutually_exclusive : Warning<
+ "property attributes '%0' and '%1' are mutually exclusive">,
+ InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
+def warn_undeclared_selector : Warning<
+ "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
+def warn_unimplemented_protocol_method : Warning<
+ "method in protocol not implemented">, InGroup<Protocol>;
+
+// 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 \"%0\"">;
+
+def err_unexpected_friend : Error<
+ "friends can only be classes or functions">;
+def ext_enum_friend : ExtWarn<
+ "enumeration type %0 cannot be a friend">;
+def ext_nonclass_type_friend : ExtWarn<
+ "non-class type %0 cannot be a friend">;
+def err_friend_is_member : Error<
+ "friends cannot be members of the declaring class">;
+def ext_unelaborated_friend_type : ExtWarn<
+ "must specify '%select{struct|union|class|enum}0' to befriend %1">;
+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_abstract_type_in_decl : Error<
+ "%select{return|parameter|variable|field}0 type %1 is an abstract class">;
+def err_allocation_of_abstract_type : Error<
+ "allocation of an object of abstract 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_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 can not be defined in a type specifier">;
+def err_type_defined_in_result_type : Error<
+ "%0 can not be defined in the result type of a function">;
+def err_type_defined_in_param_type : Error<
+ "%0 can not be defined in a parameter type">;
+
+def note_pure_virtual_function : Note<
+ "pure virtual function %0">;
+
+def err_deleted_non_function : Error<
+ "only functions can have deleted definitions">;
+def err_deleted_decl_not_first : Error<
+ "deleted definition must be first declaration">;
+
+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;
+
+// C++ exception specifications
+def err_exception_spec_in_typedef : Error<
+ "exception specifications are not allowed in typedefs">;
+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_mismatched_exception_spec : Error<
+ "exception specification in declaration does not match previous declaration">;
+def err_override_exception_spec : Error<
+ "exception specification of overriding function is more lax than "
+ "base version">;
+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 warn_missing_exception_specification : Warning<
+ "%0 is missing exception specification '%1'">;
+
+// 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">, NoSFINAE;
+def err_access_ctor : Error<
+ "calling a %select{private|protected}0 constructor of class %2">, NoSFINAE;
+def err_access_base : Error<
+ "%select{base class|inherited virtual base class}0 %1 has %select{private|"
+ "protected}3 %select{constructor|copy constructor|copy assignment operator|"
+ "destructor}2">, NoSFINAE;
+def err_access_field: Error<
+ "field of type %0 has %select{private|protected}2 %select{constructor|copy "
+ "constructor|copy assignment operator|destructor}1">, NoSFINAE;
+
+def err_access_ctor_field :
+ Error<"field of type %1 has %select{private|protected}2 constructor">,
+ NoSFINAE;
+def err_access_dtor_base :
+ Error<"base class %0 has %select{private|protected}1 destructor">,
+ NoSFINAE;
+def err_access_dtor_vbase :
+ Error<"inherited virtual base class %0 has "
+ "%select{private|protected}1 destructor">,
+ NoSFINAE;
+def err_access_dtor_temp :
+ Error<"temporary of type %0 has %select{private|protected}1 destructor">,
+ NoSFINAE;
+def err_access_dtor_field :
+ Error<"field of type %1 has %select{private|protected}2 destructor">,
+ NoSFINAE;
+def err_access_dtor_var :
+ Error<"variable of type %1 has %select{private|protected}2 destructor">,
+ NoSFINAE;
+def err_access_assign_field :
+ Error<"field of type %1 has %select{private|protected}2 copy assignment"
+ " operator">,
+ NoSFINAE;
+def err_access_assign_base :
+ Error<"base class %0 has %select{private|protected}1 copy assignment"
+ " operator">,
+ NoSFINAE;
+def err_access_copy_field :
+ Error<"field of type %1 has %select{private|protected}2 copy constructor">,
+ NoSFINAE;
+def err_access_copy_base :
+ Error<"base class %0 has %select{private|protected}1 copy constructor">,
+ NoSFINAE;
+def err_access_dtor_ivar :
+ Error<"instance variable of type %0 has %select{private|protected}1 "
+ "destructor">,
+ NoSFINAE;
+def note_previous_access_declaration : Note<
+ "previously declared '%1' here">;
+def err_access_outside_class : Error<
+ "access to %select{private|protected}0 member outside any class context">;
+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">;
+
+// 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 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">;
+
+// 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 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_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_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_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_initialization : Error<
+ "%0 can only be initialized if it is a static const integral data member">;
+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 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 note_field_decl : Note<"member is declared here">;
+def note_ivar_decl : Note<"ivar is declared here">;
+def note_bitfield_decl : Note<"bit-field is declared here">;
+def note_previous_decl : Note<"%0 declared here">;
+def note_member_synthesized_at : Note<
+ "implicit default %select{constructor|copy constructor|"
+ "copy assignment operator|destructor}0 for %1 first required here">;
+def err_missing_default_ctor : Error<
+ "%select{|implicit default }0constructor for %1 must explicitly initialize "
+ "the %select{base class|member}2 %3 which does not have a default "
+ "constructor">;
+def err_illegal_union_member : Error<
+ "union member %0 has a non-trivial %select{constructor|"
+ "copy constructor|copy assignment operator|destructor}1">;
+def note_nontrivial_has_virtual : Note<
+ "because type %0 has a virtual %select{member function|base class}1">;
+def note_nontrivial_has_nontrivial : Note<
+ "because type %0 has a %select{member|base class}1 with a non-trivial "
+ "%select{constructor|copy constructor|copy assignment operator|destructor}2">;
+def note_nontrivial_user_defined : Note<
+ "because type %0 has a user-declared %select{constructor|copy constructor|"
+ "copy assignment operator|destructor}1">;
+
+def err_different_return_type_for_overriding_virtual_function : Error<
+ "virtual function %0 has a different return type (%1) than the "
+ "function it overrides (which has return type %2)">;
+def note_overridden_virtual_function : Note<
+ "overridden virtual function is here">;
+
+def err_covariant_return_inaccessible_base : Error<
+ "invalid covariant return for virtual function: %1 is a "
+ "%select{private|protected}2 base class of %0">, NoSFINAE;
+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_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|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">;
+
+// 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_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 typedef %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_pseudo_dtor_not_a_type : Error<
+ "identifier %0 in pseudo-destructor expression does not name a type">;
+
+// 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 vector element}0 of type %1 with an %select{rvalue|lvalue}2 of "
+ "type %3">;
+
+def err_lvalue_to_rvalue_ref : Error<"rvalue reference cannot bind to lvalue">;
+def err_invalid_initialization : Error<
+"invalid initialization of reference of type %0 from expression of type %1">;
+def err_lvalue_to_rvalue_ambig_ref : Error<"rvalue reference cannot bind to lvalue "
+ "due to multiple conversion functions">;
+def err_not_reference_to_const_init : Error<
+ "%select{non-const|volatile}0 lvalue reference to type %1 cannot be "
+ "initialized with a %select{value|temporary}2 of type %3">;
+def err_lvalue_reference_bind_to_temporary : Error<
+ "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
+ "temporary of type %2">;
+def err_lvalue_reference_bind_to_unrelated : Error<
+ "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
+ "value of unrelated type %2">;
+def err_reference_bind_drops_quals : Error<
+ "binding of reference to type %0 to a value of type %1 drops qualifiers">;
+def err_reference_bind_failed : Error<
+ "reference to type %0 could not bind to an %select{rvalue|lvalue}1 of type "
+ "%2">;
+def err_reference_bind_init_list : Error<
+ "reference to type %0 cannot bind to an initializer list">;
+def err_init_list_bad_dest_type : Error<
+ "%select{|non-aggregate }0type %1 cannot be initialized with an initializer "
+ "list">;
+
+def err_reference_init_drops_quals : Error<
+ "initialization of reference to type %0 with a %select{value|temporary}1 of type %2 drops "
+ "qualifiers">;
+def err_reference_bind_to_bitfield : Error<
+ "%select{non-const|volatile}0 reference cannot bind to bit-field %1">;
+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_const_var_requires_init : Error<
+ "declaration of const variable '%0' requires an initializer">;
+def err_reference_without_init : Error<
+ "reference to type %0 requires an initializer">;
+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 is uninitialized when used here">,
+ InGroup<DiagGroup<"uninitialized">>;
+def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
+
+def err_temp_copy_no_viable : Error<
+ "no viable constructor %select{copying variable|copying parameter|"
+ "returning object|throwing object|copying member subobject|copying array "
+ "element|allocating object|copying temporary|initializing base subobject|"
+ "initializing vector element}0 of type %1">;
+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}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}0 "
+ "of type %1 invokes deleted constructor">;
+def err_temp_copy_incomplete : Error<
+ "copying a temporary object of incomplete type %0">;
+
+// C++0x decltype
+def err_cannot_determine_declared_type_of_overloaded_function : Error<
+ "cannot determine the %select{type|declared type}0 of an overloaded "
+ "function">;
+
+// C++0x auto
+def err_auto_variable_cannot_appear_in_own_initializer : Error<
+ "variable %0 declared with 'auto' type cannot appear in its own initializer">;
+def err_illegal_decl_array_of_auto : Error<
+ "'%0' declared as array of 'auto'">;
+def err_auto_not_allowed : Error<
+ "'auto' not allowed in %select{function prototype|struct member|union member"
+ "|class member|exception declaration|template parameter|block literal}0">;
+def err_auto_var_requires_init : Error<
+ "declaration of variable %0 with type %1 requires an initializer">;
+
+// C++0x attributes
+def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
+
+// C++0x [[final]]
+def err_final_function_overridden : Error<
+ "declaration of %0 overrides a 'final' function">;
+def err_final_base : Error<
+ "derivation from 'final' %0">;
+
+// Objective-C++
+def err_objc_decls_may_only_appear_in_global_scope : Error<
+ "Objective-C declarations may only appear in global scope">;
+def err_nsobject_attribute : Error<
+ "__attribute ((NSObject)) is for pointer types only">;
+
+// Attributes
+def err_attribute_can_be_applied_only_to_symbol_declaration : Error<
+ "%0 attribute can be applied only to symbol declaration">;
+def err_attributes_are_not_compatible : Error<
+ "%0 and %1 attributes are not compatible">;
+def err_attribute_wrong_number_arguments : Error<
+ "attribute requires %0 argument(s)">;
+def err_attribute_missing_parameter_name : Error<
+ "attribute requires unquoted parameter">;
+def err_attribute_invalid_vector_type : Error<"invalid vector type %0">;
+def err_attribute_argument_not_int : Error<
+ "'%0' attribute requires integer constant">;
+def err_attribute_argument_n_not_int : Error<
+ "'%0' attribute requires parameter %1 to be an integer constant">;
+def err_attribute_argument_n_not_string : Error<
+ "'%0' attribute requires parameter %1 to be a string">;
+def err_attribute_argument_out_of_bounds : Error<
+ "'%0' attribute parameter %1 is out of bounds">;
+def err_attribute_requires_objc_interface : Error<
+ "attribute may only be applied to an Objective-C interface">;
+def err_nonnull_pointers_only : Error<
+ "nonnull attribute only applies to pointer arguments">;
+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_attribute_invalid_size : Error<
+ "vector size not an integral multiple of component size">;
+def err_attribute_zero_size : Error<"zero vector size">;
+def err_typecheck_vector_not_convertable : Error<
+ "can't convert between vector values of different size (%0 and %1)">;
+def err_typecheck_ext_vector_not_typedef : Error<
+ "ext_vector_type only applies to types, not variables">;
+def err_unsupported_vector_size : Error<
+ "unsupported type %0 for vector_size attribute, please use on typedef">;
+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_not_int : Error<
+ "address space attribute requires an integer constant">;
+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_implicit_pointer_address_space_cast : Error<
+ "illegal implicit cast between two pointers with different address spaces">;
+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_attribute_not_string : Error<
+ "argument to %0 attribute was not a string literal">;
+def err_attribute_section_invalid_for_target : Error<
+ "argument to 'section' attribute is not valid for this target: %0">;
+def err_attribute_section_local_variable : Error<
+ "'section' attribute is not valid on local variables">;
+def err_attribute_aligned_not_power_of_two : Error<
+ "requested alignment is not a power of 2">;
+def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
+ "'%0' redeclared without %1 attribute: previous %1 ignored">;
+def warn_attribute_ignored : Warning<"%0 attribute ignored">;
+def warn_attribute_precede_definition : Warning<
+ "attribute declaration must precede definition">;
+def warn_attribute_void_function_method : Warning<
+ "attribute %0 cannot be applied to "
+ "%select{functions|Objective-C method}1 without return value">;
+def warn_attribute_weak_on_field : Warning<
+ "__weak attribute cannot be specified on a field declaration">;
+def warn_attribute_weak_on_local : Warning<
+ "__weak attribute cannot be specified on an automatic variable">;
+def warn_weak_identifier_undeclared : Warning<
+ "weak identifier %0 never declared">;
+def err_attribute_weak_static : Error<
+ "weak declaration of '%0' must be public">;
+def warn_attribute_weak_import_invalid_on_definition : Warning<
+ "'weak_import' attribute cannot be specified on a definition">;
+def err_attribute_weakref_not_static : Error<
+ "weakref declaration of '%0' must be static">;
+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 warn_attribute_wrong_decl_type : Warning<
+ "%0 attribute only applies to %select{function|union|"
+ "variable and function|function or method|parameter|"
+ "parameter or Objective-C method |function, method or block|"
+ "virtual method or class|function, method, or parameter|class|virtual method"
+ "|member}1 types">;
+def err_attribute_wrong_decl_type : Error<
+ "%0 attribute only applies to %select{function|union|"
+ "variable and function|function or method|parameter|"
+ "parameter or Objective-C method |function, method or block|"
+ "virtual method or class|function, method, or parameter|class|virtual method"
+ "|member}1 types">;
+def warn_function_attribute_wrong_type : Warning<
+ "%0 only applies to function types; type here is %1">;
+def warn_gnu_inline_attribute_requires_inline : Warning<
+ "'gnu_inline' attribute requires function to be marked 'inline',"
+ " attribute ignored">;
+def err_cconv_change : Error<
+ "function declared '%0' here was previously declared "
+ "%select{'%2'|without calling convention}1">;
+def err_cconv_knr : Error<
+ "function with no prototype cannot use %0 calling convention">;
+def err_cconv_varargs : Error<
+ "variadic function cannot use %0 calling convention">;
+
+def warn_impcast_vector_scalar : Warning<
+ "implicit cast turns vector to scalar: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_complex_scalar : Warning<
+ "implicit cast discards imaginary component: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_float_precision : Warning<
+ "implicit cast loses floating-point precision: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_float_integer : Warning<
+ "implicit cast turns floating-point number into integer: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_sign : Warning<
+ "implicit cast changes signedness: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_sign_conditional : Warning<
+ "operand of ? changes signedness: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_precision : Warning<
+ "implicit cast loses integer precision: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_64_32 : Warning<
+ "implicit cast loses integer precision: %0 to %1">,
+ InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore;
+
+def warn_attribute_ignored_for_field_of_type : Warning<
+ "%0 attribute ignored for field of type %1">;
+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">;
+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">;
+def warn_transparent_union_attribute_floating : Warning<
+ "first field of a transparent union cannot have floating point or vector "
+ "type; transparent_union attribute ignored">;
+def warn_transparent_union_attribute_zero_fields : Warning<
+ "transparent union definition must contain at least one field; "
+ "transparent_union attribute ignored">;
+def warn_attribute_type_not_supported : Warning<
+ "'%0' attribute argument not supported: %1">;
+def warn_attribute_unknown_visibility : Warning<"unknown visibility '%1'">;
+def err_unknown_machine_mode : Error<"unknown machine mode %0">;
+def err_unsupported_machine_mode : Error<"unsupported machine mode %0">;
+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 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">;
+def warn_attribute_malloc_pointer_only : Warning<
+ "'malloc' attribute only applies to functions returning a pointer type">;
+def warn_transparent_union_nonpointer : Warning<
+ "'transparent_union' attribute support incomplete; only supported for "
+ "pointer unions">;
+
+def warn_attribute_sentinel_named_arguments : Warning<
+ "'sentinel' attribute requires named arguments">;
+def warn_attribute_sentinel_not_variadic : Warning<
+ "'sentinel' attribute only supported for variadic %select{functions|blocks}0">;
+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 err_attribute_cleanup_arg_not_found : Error<
+ "'cleanup' argument %0 not found">;
+def err_attribute_cleanup_arg_not_function : Error<
+ "'cleanup' argument %0 is not a function">;
+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 type %1 which is incompatible with "
+ "type %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">;
+
+
+// Clang-Specific Attributes
+def err_attribute_iboutlet : Error<
+ "%0 attribute can only be applied to instance variables or properties">;
+def err_attribute_ibaction: Error<
+ "ibaction attribute can only be applied to Objective-C instance methods">;
+def err_attribute_overloadable_not_function : Error<
+ "'overloadable' attribute can only be applied to a function">;
+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 functions or methods that "
+ "return a pointer or Objective-C object">;
+
+// 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_typedef_of_void : Error<
+ "empty parameter list defined with a typedef of 'void' not allowed in C++">;
+def err_param_default_argument : Error<
+ "C does not support default arguments">;
+def err_param_default_argument_redefinition : Error<
+ "redefinition of default argument">;
+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_uninitialized_member_for_assign : Error<
+ "cannot define the implicit default assignment operator for %0, because "
+ "non-static %select{reference|const}1 member %2 can't use default "
+ "assignment operator">;
+def note_first_required_here : Note<
+ "synthesized method is first required here">;
+def err_uninitialized_member_in_ctor : Error<
+ "%select{|implicit default }0constructor for %1 must explicitly initialize "
+ "the %select{reference|const}2 member %3">;
+
+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<
+ "promoted type %0 of K&R function parameter is not compatible with the "
+ "parameter type %1 declared in a previous prototype">;
+
+
+// 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">;
+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">;
+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 copy assignment operator}0%1">;
+
+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 (%2 vs. %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_substitution_failure : Note<
+ "candidate template ignored: substitution failure %0">;
+
+// 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)|"
+ "function (the implicit copy assignment operator)}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_deleted : Note<
+ "candidate %select{function|function|constructor|"
+ "function |function |constructor |||}0%1 "
+ "has been explicitly %select{made unavailable|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)|"
+ "function (the implicit copy assignment operator)}0%1 "
+ "not viable: cannot convert argument of incomplete type %2 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)|"
+ "function (the implicit copy assignment operator)}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)|"
+ "function (the implicit copy assignment operator)}0%1"
+ " not viable: no known conversion from %2 to %3 for "
+ "%select{%ordinal5 argument|object argument}4">;
+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)|"
+ "function (the implicit copy assignment operator)}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_cvr_this : Note<"candidate "
+ "%select{|function|||function||||"
+ "function (the implicit copy assignment operator)}0 not viable: "
+ "'this' argument has type %2, but method is not marked "
+ "%select{const|volatile|const or volatile|restrict|const or restrict|"
+ "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)|"
+ "function (the implicit copy assignment operator)}0%1 not viable: "
+ "%ordinal4 argument (%2) would lose "
+ "%select{const|volatile|const and volatile|restrict|const and restrict|"
+ "volatile and restrict|const, volatile, and restrict}3 qualifier"
+ "%select{||s||s|s|s}3">;
+def note_ambiguous_type_conversion: Note<
+ "because of ambiguity in conversion of %0 to %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_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_ambiguous_oper : Error<
+ "use of overloaded operator '%0' is ambiguous">;
+def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
+def err_ovl_deleted_oper : Error<
+ "overload resolution selected %select{unavailable|deleted}0 operator '%1'">;
+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_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">;
+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">;
+
+// 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_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 err_template_parameter_default_in_function_template : Error<
+ "a template parameter of a function template cannot have a default argument "
+ "in C++98">;
+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_variable : Error<"variable %0 declared as a template">;
+def err_template_variable_noparams : Error<
+ "extraneous 'template<>' in declaration of variable %0">;
+def err_template_tag_noparams : Error<
+ "extraneous 'template<>' in declaration of %0 %1">;
+def err_template_decl_ref : Error<
+ "cannot refer to class template %0 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 note_member_of_template_here : Note<"member 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_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 type %0">;
+def err_template_arg_must_be_template : Error<
+ "template argument for template template parameter must be a class template">;
+def err_template_arg_local_type : Error<"template argument uses local type %0">;
+def err_template_arg_unnamed_type : Error<
+ "template argument uses unnamed type">;
+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_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 (%0 vs %1)">;
+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">;
+def warn_template_arg_too_large : Warning<
+ "non-type template argument value '%0' truncated to '%1' for "
+ "template parameter of type %2">;
+def err_template_arg_no_ref_bind : Error<
+ "non-type template parameter of reference type %0 cannot bind to template "
+ "argument of type %1">;
+def err_template_arg_ref_bind_ignores_quals : Error<
+ "reference binding of non-type template parameter of type %0 to template "
+ "argument of type %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_object_or_func_form : Error<
+ "non-type template argument does not directly refer to an object or "
+ "function">;
+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_function_not_extern : Error<
+ "non-template argument refers to function %0 with internal linkage">;
+def err_template_arg_object_not_extern : Error<
+ "non-template argument refers to object %0 that does not have external "
+ "linkage">;
+def note_template_arg_internal_object : Note<
+ "non-template argument refers to %select{function|object}0 here">;
+def note_template_arg_refers_here : Note<"non-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_extra_parens : Error<
+ "non-type template argument cannot be surrounded by parentheses">;
+def err_pointer_to_member_type : Error<
+ "invalid use of pointer to member type after %select{.*|->*}0">;
+
+// C++ template specialization
+def err_template_spec_unknown_kind : Error<
+ "can only provide an explicit specialization for a class template, function "
+ "template, or a member function, static data member, or member class 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|function template|member "
+ "function|static data member|member class}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|function template|member "
+ "function|static data member|member class}0 specialization of %1 must "
+ "originally be declared in namespace %2">;
+def err_template_spec_redecl_out_of_scope : Error<
+ "%select{class template|class template partial|function template|member "
+ "function|static data member|member class}0 specialization of %1 not in a "
+ "namespace enclosing %2">;
+def err_template_spec_redecl_global_scope : Error<
+ "%select{class template|class template partial|function template|member "
+ "function|static data member|member class}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">;
+
+// 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_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">;
+
+// 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 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<
+ "class template partial specialization does not specialize any template "
+ "argument; to %select{declare|define}0 the primary template, remove the "
+ "template argument list">;
+def warn_partial_specs_not_deducible : Warning<
+ "class template partial specialization contains "
+ "%select{a template parameter|template parameters}0 that can not 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++ 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">;
+
+// 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_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_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_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_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 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++0x extension)">;
+def note_previous_template_specialization : Note<
+ "previous template specialization is here">;
+def err_explicit_instantiation_enum : Error<
+ "explicit instantiation of enumeration type %0">;
+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_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<DiagGroup<"-Wc++0x-compat"> >;
+def warn_explicit_instantiation_must_be_global_0x : Warning<
+ "explicit instantiation of %0 must occur at global scope">,
+ InGroup<DiagGroup<"-Wc++0x-compat"> >;
+
+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_not_known : Error<
+ "explicit instantiation of %0 does not refer to a function 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 err_explicit_instantiation_without_qualified_id : Error<
+ "qualifier in explicit instantiation of %q0 requires a template-id">;
+def err_explicit_instantiation_without_qualified_id_quals : Error<
+ "qualifier in explicit instantiation of '%0%1' requires a template-id">;
+def err_explicit_instantiation_unqualified_wrong_namespace : Error<
+ "explicit instantiation of %q0 must occur in %1">;
+def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning<
+ "explicit instantiation of %q0 must occur in %1">,
+ InGroup<DiagGroup<"c++0x-compat"> >;
+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_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">;
+
+// C++ typename-specifiers
+def err_typename_nested_not_found : Error<"no type named %0 in %1">;
+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 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_function_template : Error<
+ "%0 following the 'template' keyword refers to a function 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'">;
+
+// C++0x 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_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 note_dependent_var_use : Note<"must qualify identifier to find this "
+ "declaration in dependent base class">;
+def err_undeclared_use : Error<"use of undeclared %0">;
+def warn_deprecated : Warning<"%0 is deprecated">,
+ InGroup<DiagGroup<"deprecated-declarations">>;
+def warn_unavailable : Warning<"%0 is unavailable">,
+ InGroup<DiagGroup<"unavailable-declarations">>;
+def note_unavailable_here : Note<
+ "function has been explicitly marked %select{unavailable|deleted}0 here">;
+def warn_not_enough_argument : Warning<
+ "not enough variable arguments in %0 declaration to fit a sentinel">;
+def warn_missing_sentinel : Warning <
+ "missing sentinel in %select{function call|method dispatch|block call}0">;
+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 err_redefinition : Error<"redefinition of %0">;
+def err_definition_of_implicitly_declared_member : Error<
+ "definition of implicitly declared %select{constructor|copy constructor|"
+ "copy assignment operator|destructor}1">;
+
+def warn_redefinition_of_typedef : Warning<
+ "redefinition of typedef %0 is invalid in C">,
+ InGroup<DiagGroup<"typedef-redefinition"> >, DefaultError;
+
+def err_static_non_static : Error<
+ "static declaration of %0 follows non-static declaration">;
+def err_non_static_static : Error<
+ "non-static declaration of %0 follows static 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_redefinition_different_type : Error<
+ "redefinition of %0 with a different type">;
+def err_redefinition_different_kind : Error<
+ "redefinition of %0 as different kind of symbol">;
+def err_redefinition_different_typedef : Error<
+ "typedef redefinition with different types (%0 vs %1)">;
+def err_tag_reference_non_tag : Error<
+ "elaborated type refers to %select{a non-tag type|a typedef|a template}0">;
+def err_tag_reference_conflict : Error<
+ "implicit declaration introduced by elaborated type conflicts with "
+ "%select{a declaration|a typedef|a template}0 of the same name">;
+def err_dependent_tag_decl : Error<
+ "%select{declaration|definition}0 of %select{struct|union|class|enum}1 "
+ "in a dependent scope">;
+def err_tag_definition_of_typedef : Error<
+ "definition of type %0 conflicts with typedef of the same name">;
+def err_conflicting_types : Error<"conflicting types for %0">;
+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|class}0 %select{|template}1 %2 was previously declared "
+ "as a %select{class|struct}0 %select{|template}1">,
+ InGroup<MismatchedTags>, DefaultIgnore;
+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 err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
+def err_duplicate_member : Error<"duplicate member %0">;
+def err_misplaced_ivar : Error<
+ "ivars may not be placed in %select{categories|class extension}0">;
+def ext_enum_value_not_int : Extension<
+ "ISO C restricts enumerator values to range of 'int' (%0 is too "
+ "%select{small|large}1)">;
+def warn_enum_too_large : Warning<
+ "enumeration values exceed range of largest integer">;
+def warn_enumerator_too_large : Warning<
+ "enumerator value %0 is not representable in the largest integer type">;
+
+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 can not 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_typecheck_negative_array_size : Error<"array size is negative">;
+def warn_typecheck_function_qualifiers : Warning<
+ "qualifier on function type %0 has unspecified behavior">;
+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">;
+def err_typecheck_zero_array_size : Error<
+ "zero-length arrays are not permitted in C++">;
+def err_at_least_one_initializer_needed_to_size_array : Error<
+ "at least one initializer value required to size array">;
+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 err_block_extern_cant_init : Error<
+ "'extern' variable cannot have an initializer">;
+def warn_extern_init : Warning<"'extern' variable has an initializer">;
+def err_variable_object_no_init : Error<
+ "variable-sized object may not be initialized">;
+def err_array_init_list_required : Error<
+ "initialization with '{...}' expected for array">;
+def err_excess_initializers : Error<
+ "excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
+def warn_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 warn_excess_initializers_in_char_array_initializer : ExtWarn<
+ "excess elements in char array initializer">;
+def warn_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">;
+def err_many_braces_around_scalar_init : Error<
+ "too many braces around scalar initializer">;
+def err_empty_scalar_initializer : Error<"scalar initializer cannot be empty">;
+def err_illegal_initializer : Error<
+ "illegal initializer (only variables can be initialized)">;
+def err_illegal_initializer_type : Error<"illegal initializer type %0">;
+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_size : Error<
+ "size of bit-field %0 (%1 bits) exceeds size of its type (%2 bits)">;
+def err_anon_bitfield_width_exceeds_type_size : Error<
+ "size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)">;
+
+// Used by C++ which allows bit-fields that are wider than the type.
+def warn_bitfield_width_exceeds_type_size: Warning<
+ "size of bit-field %0 (%1 bits) exceeds the size of its type; value will be "
+ "truncated to %2 bits">;
+def warn_anon_bitfield_width_exceeds_type_size : Warning<
+ "size of anonymous bit-field (%0 bits) exceeds size of its type; value will "
+ "be truncated to %1 bits">;
+
+def warn_missing_braces : Warning<
+ "suggest braces around initialization of subobject">,
+ InGroup<DiagGroup<"missing-braces">>, 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_into_protected_scope : Error<"illegal goto into protected scope">;
+def err_switch_into_protected_scope : Error<
+ "illegal switch case into protected scope">;
+def err_indirect_goto_without_addrlabel : Error<
+ "indirect goto in function with no address-of-label expressions">;
+def warn_indirect_goto_in_protected_scope : Warning<
+ "indirect goto might cross protected scopes">,
+ InGroup<DiagGroup<"label-address-scope">>;
+def note_indirect_goto_target : Note<"possible target of indirect goto">;
+def note_protected_by_variable_init : Note<
+ "jump bypasses variable initialization">;
+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 : 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_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___block : Note<
+ "jump bypasses setup of __block 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___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 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<GNU>;
+
+def err_flexible_array_empty_struct : Error<
+ "flexible array %0 not allowed in otherwise empty struct">;
+def err_flexible_array_has_nonpod_type : Error<
+ "flexible array member %0 of non-POD element type %1">;
+def ext_flexible_array_in_struct : Extension<
+ "%0 may not be nested in a struct due to flexible array member">;
+def ext_flexible_array_in_array : Extension<
+ "%0 may not be used as an array element due to flexible array member">;
+def err_flexible_array_init_nonempty : Error<
+ "non-empty initialization of flexible array member inside subobject">;
+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_decl_array_of_references : Error<
+ "'%0' declared as array of references of type %1">;
+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_qualified_block_pointer_type : Error<
+ "qualifier specification on block pointer type not allowed">;
+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_block_with_return_type_requires_args : Error<
+ "block with explicit return type requires argument list">;
+def err_func_def_incomplete_result : Error<
+ "incomplete result type %0 in function definition">;
+
+// Expressions.
+def ext_sizeof_function_type : Extension<
+ "invalid application of 'sizeof' to a function type">, InGroup<PointerArith>;
+def err_sizeof_alignof_overloaded_function_type : Error<
+ "invalid application of '%select{sizeof|__alignof}0' to an overloaded "
+ "function">;
+def ext_sizeof_void_type : Extension<
+ "invalid application of '%0' to a void type">, InGroup<PointerArith>;
+def err_sizeof_alignof_incomplete_type : Error<
+ "invalid application of '%select{sizeof|__alignof}0' to an incomplete type %1">;
+def err_sizeof_alignof_bitfield : Error<
+ "invalid application of '%select{sizeof|__alignof}0' to bit-field">;
+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">;
+def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
+ InGroup<InvalidOffsetof>;
+def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
+
+def warn_floatingpoint_eq : Warning<
+ "comparing floating point with == or != is unsafe">,
+ InGroup<DiagGroup<"float-equal">>, DefaultIgnore;
+
+def warn_division_by_zero : Warning<"division by zero is undefined">;
+def warn_remainder_by_zero : Warning<"remainder by zero is undefined">;
+def warn_shift_negative : Warning<"shift count is negative">;
+def warn_shift_gt_typewidth : Warning<"shift count >= width of type">;
+
+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_bitwise_silence : Note<
+ "place parentheses around the %0 expression to silence this warning">;
+
+def err_sizeof_nonfragile_interface : Error<
+ "invalid application of '%select{alignof|sizeof}1' to interface %0 in "
+ "non-fragile ABI">;
+def err_atdef_nonfragile_interface : Error<
+ "invalid application of @defs in non-fragile ABI">;
+def err_subscript_nonfragile_interface : Error<
+ "subscript requires size of interface %0, which is not constant in "
+ "non-fragile ABI">;
+
+def err_arithmetic_nonfragile_interface : Error<
+ "arithmetic on pointer to interface %0, which is not a constant size in "
+ "non-fragile ABI">;
+
+
+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_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 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; maybe you meant to use '%select{->|.}1'?">;
+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 has function type %0; perhaps you meant to call "
+ "this function with '()'?">;
+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_member_redeclared : Error<"class member cannot be redeclared">;
+def err_member_def_undefined_record : Error<
+ "out-of-line definition of %0 from class %1 without definition">;
+def err_member_def_does_not_match : Error<
+ "out-of-line definition of %0 does not match any declaration in %1">;
+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 err_out_of_line_declaration : Error<
+ "out-of-line declaration of a member must be a definition">;
+def note_member_def_close_match : Note<"member declaration nearly matches">;
+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_arithmetic_incomplete_type : Error<
+ "arithmetic on pointer to incomplete type %0">;
+def err_typecheck_pointer_arith_function_type : Error<
+ "arithmetic on pointer to function type %0">;
+def err_typecheck_pointer_arith_void_type : Error<
+ "arithmetic on pointer to void type">;
+def err_typecheck_decl_incomplete_type : Error<
+ "variable has incomplete type %0">;
+def ext_typecheck_decl_incomplete_type : ExtWarn<
+ "tentative definition of variable with internal linkage has incomplete non-array type %0">;
+def err_tentative_def_incomplete_type : Error<
+ "tentative definition has type %0 that is never completed">;
+def err_tentative_def_incomplete_type_arr : Error<
+ "tentative definition has array of 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}0">;
+def warn_deprecated_string_literal_conversion : Warning<
+ "conversion from string literal to %0 is deprecated">, InGroup<Deprecated>;
+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 err_unsupported_global_register : Error<
+ "global register variables are not supported">;
+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 %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 member function %0 when taking its address">;
+def err_typecheck_invalid_lvalue_addrof : Error<
+ "address expression must be an lvalue or a function designator">;
+def ext_typecheck_addrof_class_temporary : ExtWarn<
+ "taking the address of a temporary object of type %0">,
+ InGroup<DiagGroup<"address-of-temporary">>, DefaultError;
+def err_typecheck_addrof_class_temporary : Error<
+ "taking the address of a temporary object of type %0">;
+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 err_indirection_requires_nonfragile_object : Error<
+ "indirection cannot be to an interface in non-fragile ABI (%0 invalid)">;
+def err_direct_interface_unsupported : Error<
+ "indirection to an interface is not supported (%0 invalid)">;
+def err_typecheck_invalid_operands : Error<
+ "invalid operands to binary expression (%0 and %1)">;
+def err_typecheck_sub_ptr_object : Error<
+ "subtraction of pointer %0 requires pointee to be a complete object type">;
+def err_typecheck_sub_ptr_compatible : Error<
+ "%0 and %1 are not pointers to compatible types">;
+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 ext_typecheck_comparison_of_pointer_integer : ExtWarn<
+ "comparison between pointer and integer (%0 and %1)">;
+def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
+ "comparison of distinct pointer types (%0 and %1)">;
+def ext_typecheck_cond_incompatible_operands : ExtWarn<
+ "incompatible operand types (%0 and %1)">;
+def err_typecheck_comparison_of_distinct_pointers : Error<
+ "comparison of distinct pointer types (%0 and %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">;
+def err_typecheck_vector_comparison : Error<
+ "comparison of vector types (%0 and %1) not supported yet">;
+def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
+def err_stmtexpr_file_scope : Error<
+ "statement expression not allowed at file scope">;
+def warn_mixed_sign_comparison : Warning<
+ "comparison of integers of different signs: %0 and %1">,
+ InGroup<SignCompare>, DefaultIgnore;
+def warn_mixed_sign_conditional : Warning<
+ "operands of ? are integers of different signs: %0 and %1">,
+ InGroup<SignCompare>, DefaultIgnore;
+def warn_lunsigned_always_true_comparison : Warning<
+ "comparison of unsigned expression %0 is always %1">,
+ InGroup<SignCompare>, DefaultIgnore;
+def warn_runsigned_always_true_comparison : Warning<
+ "comparison of %0 unsigned expression is always %1">,
+ InGroup<SignCompare>, DefaultIgnore;
+
+def err_invalid_this_use : Error<
+ "invalid use of 'this' outside of a nonstatic member function">;
+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<
+ "type qualifier is not allowed on this function">;
+def err_invalid_qualified_typedef_function_type_use : Error<
+ "a qualified function type cannot be used to declare a nonmember function "
+ "or a static member function">;
+
+def err_invalid_non_static_member_use : Error<
+ "invalid use of nonstatic data member %0">;
+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_builtin_direct_init_more_than_one_arg : Error<
+ "initializer of a builtin type can only take one argument">;
+def err_value_init_for_array_type : Error<
+ "array types cannot be value-initialized">;
+def warn_printf_nonliteral_noargs : Warning<
+ "format string is not a string literal (potentially insecure)">,
+ InGroup<FormatSecurity>;
+def warn_printf_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_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_duplicate_property : Error<
+ "property has a previous declaration">;
+def ext_gnu_void_ptr : Extension<
+ "use of GNU void* extension">, InGroup<PointerArith>;
+def ext_gnu_ptr_func_arith : Extension<
+ "arithmetic on pointer to function type %0 is a GNU extension">,
+ InGroup<PointerArith>;
+def error_readonly_property_assignment : Error<
+ "assigning to property with 'readonly' attribute 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 error_nosetter_property_assignment : Error<
+ "setter method is needed to assign to object using property" " assignment syntax">;
+def error_no_subobject_property_setting : Error<
+ "expression is not assignable using property assignment syntax">;
+
+def ext_freestanding_complex : Extension<
+ "complex numbers are an extension in a freestanding C99 implementation">;
+
+
+// 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">;
+def warn_class_method_not_found : Warning<
+ "method %objcclass0 not found (return type defaults to 'id')">;
+def warn_inst_method_not_found : Warning<
+ "method %objcinstance0 not found (return type defaults to 'id')">;
+def error_no_super_class_message : Error<
+ "no @interface declaration found in class messaging of %0">;
+def error_no_super_class : Error<
+ "no super class declared in @interface for %0">;
+def err_invalid_receiver_to_message : Error<
+ "invalid receiver to message expression">;
+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 warn_bad_receiver_type : Warning<
+ "receiver type %0 is not 'id' or interface pointer, consider "
+ "casting it to 'id'">;
+def err_bad_receiver_type : Error<"bad 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 %select{|'typedef'|'extern'|"
+ "'static'|'auto'|'register'|'__private_extern__'|'mutable'}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_setter_getter_impl_required : Warning<
+ "property %0 requires method %1 to be defined - "
+ "use @synthesize, @dynamic or provide a method implementation">;
+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 category">;
+def note_property_impl_required : Note<
+ "implementation is here">;
+def note_parameter_named_here : Note<
+ "passing argument to parameter %0 here">;
+def note_parameter_here : Note<
+ "passing argument to parameter here">;
+
+// 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_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_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_const_away : Error<
+ "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+ "functional-style cast}0 from %1 to %2 casts away constness">;
+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 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_static_cast_incomplete : Error<"%0 is an incomplete type">;
+
+// 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_incomplete_typeid : Error<"'typeid' of incomplete 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 err_new_paren_array_nonconst : Error<
+ "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 enumerated type, not %0">;
+def err_default_init_const : Error<
+ "default initialization of an object of const type %0"
+ "%select{| requires a user-provided default constructor}1">;
+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">;
+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 behaviour">;
+def err_no_suitable_delete_member_function_found : Error<
+ "no suitable member %0 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">, InGroup<Deprecated>;
+def ext_catch_incomplete_ptr : ExtWarn<
+ "ISO C++ forbids catching a pointer to incomplete type %0">;
+def ext_catch_incomplete_ref : ExtWarn<
+ "ISO C++ forbids catching a 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_memptr_rhs_to_incomplete : Error<
+ "cannot dereference pointer into incomplete class type %0">;
+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">;
+def note_previous_exception_handler : Note<"for type %0">;
+
+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; %0 can be converted to %1 "
+ "and vice versa">;
+def err_conditional_ambiguous_ovl : Error<
+ "conditional expression is ambiguous; %0 and %1 can be converted to several "
+ "common types">;
+
+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 err_operator_arrow_circular : Error<
+ "circular pointer delegation detected">;
+def err_pseudo_dtor_base_not_scalar : Error<
+ "object expression of non-scalar type %0 cannot be used in a "
+ "pseudo-destructor expression">;
+def err_pseudo_dtor_type_mismatch : Error<
+ "the type of object expression (%0) does not match the type being destroyed "
+ "(%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<
+ "%select{destructor reference|pseudo-destructor expression}0 must be "
+ "called immediately with '()'">;
+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_pseudo_dtor_template : Error<
+ "specialization of template %0 does not refer to a scalar type in pseudo-"
+ "destructor expression">;
+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_type_defined_in_condition : Error<
+ "types may not be defined in conditions">;
+def err_typecheck_bool_condition : Error<
+ "value of type %0 is not contextually convertible to 'bool'">;
+def err_typecheck_ambiguous_condition : Error<
+ "conversion from %0 to %1 is ambiguous">;
+def err_typecheck_nonviable_condition : Error<
+ "no viable conversion from %0 to %1">;
+def err_typecheck_deleted_function : Error<
+ "conversion function from %0 to %1 invokes a deleted function">;
+
+def err_expected_class_or_namespace : Error<"expected a class or namespace">;
+def err_missing_qualified_for_redecl : Error<
+ "must qualify the name %0 to declare %q1 in this scope">;
+def err_invalid_declarator_scope : Error<
+ "definition or redeclaration of %0 not in a namespace enclosing %1">;
+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_not_tag_in_scope : Error<
+ "no %select{struct|union|class|enum}0 named %1 in %2">;
+
+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 err_incomplete_pointer_to_member_return : Error<
+ "incomplete return type %0 of pointer-to-member constant">;
+
+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_assign_silence : Note<
+ "place parentheses around the assignment to silence this warning">;
+
+def warn_value_always_zero : Warning<
+ "%0 is always %select{zero|false|NULL}1 in this context">;
+
+// 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{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from incompatible type|to parameter of incompatible type|"
+ "from a function with incompatible result type|to incompatible type|"
+ "with an expression of incompatible type|to parameter of incompatible type|"
+ "to incompatible type}2 %1">;
+def warn_incompatible_qualified_id : Warning<
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from incompatible type|to parameter of incompatible type|"
+ "from a function with incompatible result type|to incompatible type|"
+ "with an expression of incompatible type|to parameter of incompatible type|"
+ "to incompatible type}2 %1">;
+def ext_typecheck_convert_pointer_int : ExtWarn<
+ "incompatible pointer to integer conversion "
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1">;
+def ext_typecheck_convert_int_pointer : ExtWarn<
+ "incompatible integer to pointer conversion "
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1">;
+def ext_typecheck_convert_pointer_void_func : Extension<
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1 "
+ "converts between void pointer and function pointer">;
+def ext_typecheck_convert_incompatible_pointer_sign : ExtWarn<
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1 "
+ "converts between pointers to integer types with different sign">,
+ InGroup<DiagGroup<"pointer-sign">>;
+def ext_typecheck_convert_incompatible_pointer : ExtWarn<
+ "incompatible pointer types "
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1">;
+def ext_typecheck_convert_discards_qualifiers : ExtWarn<
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1 discards "
+ "qualifiers">;
+def ext_nested_pointer_qualifier_mismatch : ExtWarn<
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1 discards "
+ "qualifiers in nested pointer types">;
+def warn_incompatible_vectors : Warning<
+ "incompatible vector types "
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1">,
+ InGroup<VectorConversions>, DefaultIgnore;
+def err_int_to_block_pointer : Error<
+ "invalid block pointer conversion "
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1">;
+def err_typecheck_convert_incompatible_block_pointer : Error<
+ "incompatible block pointer types "
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%select{from|to parameter of type|from a function with result type|to type|"
+ "with an expression of type|to parameter of type|to type}2 %1">;
+
+def err_typecheck_convert_ambiguous : Error<
+ "ambiguity in initializing value of type %0 with initializer of type %1">;
+def err_cannot_initialize_decl_noname : Error<
+ "cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 "
+ "of type %2">;
+def err_cannot_initialize_decl : Error<
+ "cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2">;
+def err_typecheck_comparison_of_distinct_blocks : Error<
+ "comparison of distinct block types (%0 and %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_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 note_function_with_incomplete_return_type_declared_here : Note<
+ "%0 declared here">;
+def err_call_incomplete_argument : Error<
+ "argument type %0 is incomplete">;
+def err_typecheck_call_too_few_args : Error<
+ "too few arguments to %select{function|block|method}0 call, "
+ "expected %1, have %2">;
+def err_typecheck_call_too_few_args_at_least : Error<
+ "too few arguments to %select{function|block|method}0 call, "
+ "expected at least %1, have %2">;
+def err_typecheck_call_too_many_args : Error<
+ "too many arguments to %select{function|block|method}0 call, "
+ "expected %1, have %2">;
+def err_typecheck_call_too_many_args_at_most : Error<
+ "too many arguments to %select{function|block|method}0 call, "
+ "expected at most %1, have %2">;
+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<
+ "first argument to atomic builtin must be a pointer (%0 invalid)">;
+def err_atomic_builtin_must_be_pointer_intptr : Error<
+ "first argument to atomic builtin must be a pointer to integer or pointer"
+ " (%0 invalid)">;
+def err_atomic_builtin_pointer_size : Error<
+ "first argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte "
+ "type (%0 invalid)">;
+
+
+def err_deleted_function_use : Error<"attempt to use a deleted function">;
+
+def err_cannot_pass_objc_interface_to_vararg : Error<
+ "cannot pass object with interface type %0 by-value through variadic "
+ "%select{function|block|method}1">;
+
+def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
+ "cannot pass object of non-POD type %0 through variadic "
+ "%select{function|block|method|constructor}1; call will abort at runtime">,
+ InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
+
+def err_typecheck_call_invalid_ordered_compare : Error<
+ "ordered compare requires two args of floating point type (%0 and %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_scalar : Error<
+ "used type %0 where arithmetic or pointer type is required">;
+def ext_typecheck_cond_one_void : Extension<
+ "C99 forbids conditional expressions with only one void side">;
+def ext_typecheck_cast_nonscalar : Extension<
+ "C99 forbids casting nonscalar type %0 to the same type">;
+def ext_typecheck_cast_to_union : Extension<"C99 forbids casts to union type">;
+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 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 (%0 and %1)">;
+def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn<
+ "incompatible operand types (%0 and %1) use non-standard composite pointer "
+ "type %2">;
+def err_cast_selector_expr : Error<
+ "cannot type cast @selector expression">;
+def warn_typecheck_cond_incompatible_pointers : ExtWarn<
+ "pointer type mismatch (%0 and %1)">;
+def warn_typecheck_cond_pointer_integer_mismatch : ExtWarn<
+ "pointer/integer type mismatch in conditional expression (%0 and %1)">;
+def err_typecheck_choose_expr_requires_constant : Error<
+ "'__builtin_choose_expr' requires a constant expression">;
+def ext_typecheck_expression_not_constant_but_accepted : Extension<
+ "expression is not a constant, but is accepted as one by GNU extensions">,
+ InGroup<GNU>;
+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<UnusedValue>;
+def warn_unused_call : Warning<
+ "ignoring return value of function declared with %0 attribute">,
+ InGroup<UnusedValue>;
+
+def err_incomplete_type_used_in_type_trait_expr : Error<
+ "incomplete type %0 used in type trait expression">;
+def err_expected_ident_or_lparen : Error<"expected identifier or '('">;
+
+} // End of general sema category.
+
+// inline asm.
+let CategoryName = "Inline Assembly Issue" in {
+ def err_asm_wide_character : Error<"wide string is invalid in 'asm'">;
+ 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_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 %0 matching output with type %1">;
+ def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
+ 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 warn_invalid_asm_cast_lvalue : Warning<
+ "invalid use of a cast in a inline asm context requiring an l-value: "
+ "accepted due to -fheinous-gnu-extensions, but clang may remove support "
+ "for this in the future">;
+}
+
+let CategoryName = "Semantic Issue" in {
+
+def err_invalid_conversion_between_vectors : Error<
+ "invalid conversion between vector type %0 and %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_invalid_conversion_between_vector_and_scalar : Error<
+ "invalid conversion between vector type %0 and scalar type %1">;
+def err_overload_expr_requires_non_zero_constant : Error<
+ "overload requires a non-zero constant expression as first argument">;
+def err_overload_incorrect_fntype : Error<
+ "argument is not a function, or has wrong number of parameters">;
+
+// 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 anonymous 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 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_integral_type : Error<
+ "in-class initializer has non-integral, non-enumeration type %0">;
+def err_in_class_initializer_non_constant : Error<
+ "in-class initializer is not an integral constant expression">;
+
+// C++ anonymous unions and GNU anonymous structs/unions
+def ext_anonymous_union : Extension<
+ "anonymous unions are a GNU extension in C">, InGroup<GNU>;
+def ext_anonymous_struct : Extension<
+ "anonymous structs are a GNU extension">, InGroup<GNU>;
+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_union_member_redecl : Error<
+ "member of anonymous union redeclares %0">;
+def err_anonymous_struct_member_redecl : Error<
+ "member of anonymous struct redeclares %0">;
+def err_anonymous_record_with_type : Error<
+ "types cannot be declared in an anonymous %select{struct|union}0">;
+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">;
+
+// C++ local classes
+def err_reference_to_local_var_in_enclosing_function : Error<
+ "reference to local variable %0 declared in enclosed function %1">;
+def note_local_variable_declared_here : Note<
+ "%0 declared here">;
+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_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">;
+// 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++ access control
+def err_conv_to_inaccessible_base : Error<
+ "conversion from %0 to inaccessible base class %1">, NoSFINAE;
+def note_inheritance_specifier_here : Note<
+ "'%0' inheritance specifier here">;
+def note_inheritance_implicitly_private_here : Note<
+ "inheritance is implicitly 'private'">;
+
+// 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 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 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<
+ "%0 takes type %1 as first parameter">;
+
+// C++ literal operators
+def err_literal_operator_outside_namespace : Error<
+ "literal operator %0 must be in a namespace or global scope">;
+// FIXME: This diagnostic sucks
+def err_literal_operator_params : Error<
+ "parameter declaration for literal operator %0 is not valid">;
+
+// 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<
+ "must use a typedef to declare a conversion to %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++0x explicit conversion operators
+def warn_explicit_conversion_functions : Warning<
+ "explicit conversion functions are a C++0x extension">;
+
+def warn_printf_write_back : Warning<
+ "use of '%%n' in format string discouraged (potentially insecure)">,
+ InGroup<FormatSecurity>;
+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_printf_invalid_conversion : Warning<
+ "invalid conversion specifier '%0'">, InGroup<Format>;
+def warn_printf_incomplete_specifier : Warning<
+ "incomplete format specifier">, InGroup<Format>;
+def warn_printf_missing_format_string : Warning<
+ "format string missing">, InGroup<Format>;
+def warn_printf_conversion_argument_type_mismatch : Warning<
+ "conversion specifies type %0 but the argument has type %1">,
+ 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_printf_zero_positional_specifier : Warning<
+ "position arguments in format strings start counting at 1 (not 0)">,
+ InGroup<Format>;
+def warn_printf_invalid_positional_specifier : Warning<
+ "invalid position specified for %select{field width|field precision}0">,
+ InGroup<Format>;
+def warn_printf_mix_positional_nonpositional_args : Warning<
+ "cannot mix positional and non-positional arguments in format string">,
+ InGroup<Format>;
+def warn_null_arg : Warning<
+ "null passed to a callee which requires a non-null argument">,
+ InGroup<NonNull>;
+def warn_printf_empty_format_string : Warning<
+ "format string is empty">, InGroup<FormatZeroLength>;
+def warn_printf_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_asterisk_missing_arg : Warning<
+ "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">;
+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_precision: Warning<
+ "precision used in '%0' conversion specifier (where it has no meaning)">,
+ InGroup<Format>;
+def warn_printf_nonsensical_flag: Warning<
+ "flag '%0' results in undefined behavior in '%1' conversion specifier">,
+ InGroup<Format>;
+
+// CHECK: returning address/reference of stack memory
+def warn_ret_stack_addr : Warning<
+ "address of stack memory associated with local variable %0 returned">;
+def warn_ret_stack_ref : Warning<
+ "reference to stack memory associated with local variable %0 returned">;
+def warn_ret_addr_label : Warning<
+ "returning address of label, which is local">;
+def err_ret_local_block : Error<
+ "returning block that lives on the local stack">;
+
+
+// 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.
+def warn_selfcomparison : Warning<
+ "self-comparison always results in a constant value">;
+def warn_stringcompare : Warning<
+ "result of comparison against %select{a string literal|@encode}0 is "
+ "unspecified (use strncmp instead)">;
+
+
+
+// Blocks
+def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks"
+ " or pick a deployment target that supports them">;
+def err_expected_block_lbrace : Error<"expected '{' in block literal">;
+def err_return_in_block_expression : Error<
+ "return not allowed in block expression literal">;
+def err_block_returns_array : Error<
+ "block declared as returning an array">;
+
+
+// CFString checking
+def err_cfstring_literal_not_string_constant : Error<
+ "CFString literal is not a string constant">;
+def warn_cfstring_literal_contains_nul_character : Warning<
+ "CFString literal contains NUL character">;
+
+// 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 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">;
+def warn_case_value_overflow : Warning<
+ "overflow converting case value to switch condition type (%0 to %1)">,
+ InGroup<DiagGroup<"switch">>;
+def err_duplicate_case : Error<"duplicate case value '%0'">;
+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_missing_cases : Warning<"enumeration value %0 not handled in switch">,
+ InGroup<DiagGroup<"switch-enum"> >;
+def warn_not_in_enum : Warning<"case value not in enumerated type %0">,
+ InGroup<DiagGroup<"switch-enum"> >;
+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 err_va_start_used_in_non_variadic_function : Error<
+ "'va_start' used in function with fixed args">;
+def warn_second_parameter_of_va_start_not_last_named_argument : Warning<
+ "second parameter of 'va_start' not last named argument">;
+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 warn_return_missing_expr : Warning<
+ "non-void %select{function|method}1 %0 should return a value">,
+ InGroup<ReturnType>;
+def ext_return_missing_expr : ExtWarn<
+ "non-void %select{function|method}1 %0 should return a value">,
+ InGroup<ReturnType>;
+def ext_return_has_expr : ExtWarn<
+ "void %select{function|method}1 %0 should not return a value">,
+ InGroup<ReturnType>;
+def ext_return_has_void_expr : Extension<
+ "void %select{function|method}1 %0 should not return void expression">;
+def warn_noreturn_function_has_return_expr : Warning<
+ "function %0 declared 'noreturn' should not return">,
+ InGroup<DiagGroup<"invalid-noreturn">>;
+def warn_falloff_noreturn_function : Warning<
+ "function declared 'noreturn' should not return">,
+ InGroup<DiagGroup<"invalid-noreturn">>;
+def err_noreturn_block_has_return_expr : Error<
+ "block declared 'noreturn' should not return">;
+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_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_argument_invalid_range : Error<
+ "argument should be a value from %0 to %1">;
+
+def err_builtin_longjmp_invalid_val : Error<
+ "argument to __builtin_longjmp must be a constant 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">;
+def err_non_variable_decl_in_for : Error<
+ "declaration of non-local variable 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_collection_expr_type : Error<
+ "collection expression type %0 is not a valid object">;
+
+def err_invalid_conversion_between_ext_vectors : Error<
+ "invalid conversion between ext-vector type %0 and %1">;
+
+// 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">;
+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_missing_param_declspec : Error<
+ "parameter requires a declaration specifier">;
+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<
+ "use of C99-specific array features, accepted as an extension">;
+def err_c99_array_usage_cxx : Error<
+ "C99-specific array features are not permitted in C++">;
+
+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">;
+def error_ivar_use_in_class_method : Error<
+ "instance variable %0 accessed in class method">;
+def error_private_ivar_access : Error<"instance variable %0 is private">,
+ NoSFINAE;
+def error_protected_ivar_access : Error<"instance variable %0 is protected">,
+ NoSFINAE;
+def warn_maynot_respond : Warning<"%0 may not respond to %1">;
+def warn_attribute_method_def : Warning<
+ "method attribute can only be specified on method declarations">;
+def ext_typecheck_base_super : Warning<
+ "method parameter type %0 does not match "
+ "super class method parameter type %1">, InGroup<SuperSubClassMismatch>, DefaultIgnore;
+
+// Spell-checking diagnostics
+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 %2?">;
+def err_no_member_suggest : Error<"no member named %0 in %1; did you mean %2?">;
+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 %2?">;
+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_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">;
+
+} // end of sema category
+} // end of sema component.
+
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h
new file mode 100644
index 0000000..d0e0118
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h
@@ -0,0 +1,216 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the FileManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FILEMANAGER_H
+#define LLVM_CLANG_FILEMANAGER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Config/config.h" // for mode_t
+// FIXME: Enhance libsystem to support inode and other fields in stat.
+#include <sys/types.h>
+#include <sys/stat.h>
+
+namespace clang {
+class FileManager;
+
+/// DirectoryEntry - Cached information about one directory on the disk.
+///
+class DirectoryEntry {
+ const char *Name; // Name of the directory.
+ friend class FileManager;
+public:
+ DirectoryEntry() : Name(0) {}
+ const char *getName() const { return Name; }
+};
+
+/// FileEntry - Cached information about one file on the disk.
+///
+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.
+ dev_t Device; // ID for the device containing the file.
+ ino_t Inode; // Inode number for the file.
+ mode_t FileMode; // The file mode as returned by 'stat'.
+ friend class FileManager;
+public:
+ FileEntry(dev_t device, ino_t inode, mode_t m)
+ : Name(0), Device(device), Inode(inode), FileMode(m) {}
+ // Add a default constructor for use with llvm::StringMap
+ FileEntry() : Name(0), Device(0), Inode(0), FileMode(0) {}
+
+ const char *getName() const { return Name; }
+ off_t getSize() const { return Size; }
+ unsigned getUID() const { return UID; }
+ ino_t getInode() const { return Inode; }
+ dev_t getDevice() const { return Device; }
+ time_t getModificationTime() const { return ModTime; }
+ mode_t getFileMode() const { return FileMode; }
+
+ /// getDir - Return the directory the file lives in.
+ ///
+ const DirectoryEntry *getDir() const { return Dir; }
+
+ bool operator<(const FileEntry& RHS) const {
+ return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode);
+ }
+};
+
+/// \brief Abstract interface for introducing a FileManager cache for 'stat'
+/// system calls, which is used by precompiled and pretokenized headers to
+/// improve performance.
+class StatSysCallCache {
+protected:
+ llvm::OwningPtr<StatSysCallCache> NextStatCache;
+
+public:
+ virtual ~StatSysCallCache() {}
+ virtual int stat(const char *path, struct stat *buf) {
+ if (getNextStatCache())
+ return getNextStatCache()->stat(path, buf);
+
+ return ::stat(path, buf);
+ }
+
+ /// \brief Sets the next stat call cache in the chain of stat caches.
+ /// Takes ownership of the given stat cache.
+ void setNextStatCache(StatSysCallCache *Cache) {
+ NextStatCache.reset(Cache);
+ }
+
+ /// \brief Retrieve the next stat call cache in the chain.
+ StatSysCallCache *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.
+ StatSysCallCache *takeNextStatCache() { return NextStatCache.take(); }
+};
+
+/// \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 StatSysCallCache {
+public:
+ /// \brief The result of a stat() call.
+ ///
+ /// The first member is the result of calling stat(). If stat()
+ /// found something, the second member is a copy of the stat
+ /// structure.
+ typedef std::pair<int, struct stat> StatResult;
+
+ /// \brief The set of stat() calls that have been
+ llvm::StringMap<StatResult, llvm::BumpPtrAllocator> StatCalls;
+
+ typedef llvm::StringMap<StatResult, llvm::BumpPtrAllocator>::const_iterator
+ iterator;
+
+ iterator begin() const { return StatCalls.begin(); }
+ iterator end() const { return StatCalls.end(); }
+
+ virtual int stat(const char *path, struct stat *buf);
+};
+
+/// FileManager - 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 {
+
+ class UniqueDirContainer;
+ class UniqueFileContainer;
+
+ /// UniqueDirs/UniqueFiles - Cache for existing directories/files.
+ ///
+ UniqueDirContainer &UniqueDirs;
+ UniqueFileContainer &UniqueFiles;
+
+ /// DirEntries/FileEntries - This is a cache of directory/file entries we have
+ /// looked up. The actual Entry is owned by UniqueFiles/UniqueDirs above.
+ ///
+ llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> DirEntries;
+ llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> FileEntries;
+
+ /// NextFileUID - Each FileEntry we create is assigned a unique ID #.
+ ///
+ unsigned NextFileUID;
+
+ /// \brief The virtual files that we have allocated.
+ llvm::SmallVector<FileEntry *, 4> VirtualFileEntries;
+
+ // Statistics.
+ unsigned NumDirLookups, NumFileLookups;
+ unsigned NumDirCacheMisses, NumFileCacheMisses;
+
+ // Caching.
+ llvm::OwningPtr<StatSysCallCache> StatCache;
+
+ int stat_cached(const char* path, struct stat* buf) {
+ return StatCache.get() ? StatCache->stat(path, buf) : stat(path, buf);
+ }
+
+public:
+ FileManager();
+ ~FileManager();
+
+ /// \brief Installs the provided StatSysCallCache 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(StatSysCallCache *statCache, bool AtBeginning = false);
+
+ /// \brief Removes the provided StatSysCallCache object from the file manager.
+ void removeStatCache(StatSysCallCache *statCache);
+
+ /// getDirectory - Lookup, cache, and verify the specified directory. This
+ /// returns null if the directory doesn't exist.
+ ///
+ const DirectoryEntry *getDirectory(const llvm::StringRef &Filename) {
+ return getDirectory(Filename.begin(), Filename.end());
+ }
+ const DirectoryEntry *getDirectory(const char *FileStart,const char *FileEnd);
+
+ /// getFile - Lookup, cache, and verify the specified file. This returns null
+ /// if the file doesn't exist.
+ ///
+ const FileEntry *getFile(const llvm::StringRef &Filename) {
+ return getFile(Filename.begin(), Filename.end());
+ }
+ const FileEntry *getFile(const char *FilenameStart,
+ const char *FilenameEnd);
+
+ /// \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(const llvm::StringRef &Filename,
+ off_t Size, time_t ModificationTime);
+ void PrintStats() const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h
new file mode 100644
index 0000000..582d59c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h
@@ -0,0 +1,569 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the IdentifierInfo, IdentifierTable, and Selector
+// interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
+#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
+
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <string>
+#include <cassert>
+
+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
+
+ /// IdentifierLocPair - A simple pair of identifier info and location.
+ typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
+
+
+/// IdentifierInfo - 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 {
+ // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a
+ // signed char and TokenKinds > 127 won't be handled correctly.
+ unsigned TokenID : 8; // 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 :10;
+ bool HasMacro : 1; // True if there is a #define for this.
+ bool IsExtension : 1; // True if identifier is a lang extension.
+ bool IsPoisoned : 1; // True if identifier is poisoned.
+ bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
+ bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier".
+ // 9 bits left in 32-bit word.
+ void *FETokenInfo; // Managed by the language front-end.
+ llvm::StringMapEntry<IdentifierInfo*> *Entry;
+
+ IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE.
+ void operator=(const IdentifierInfo&); // NONASSIGNABLE.
+
+ friend class IdentifierTable;
+
+public:
+ IdentifierInfo();
+
+
+ /// isStr - 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);
+ }
+
+ /// getNameStart - Return the beginning of the actual string for this
+ /// identifier. The returned string is properly null terminated.
+ ///
+ 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.
+ return ((std::pair<IdentifierInfo, const char*>*) this)->second;
+ }
+
+ /// getLength - 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.
+ const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second-2;
+ return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
+ }
+
+ /// getName - Return the actual identifier string.
+ llvm::StringRef getName() const {
+ return llvm::StringRef(getNameStart(), getLength());
+ }
+
+ /// hasMacroDefinition - Return true if this identifier is #defined to some
+ /// other value.
+ bool hasMacroDefinition() const {
+ return HasMacro;
+ }
+ void setHasMacroDefinition(bool Val) {
+ if (HasMacro == Val) return;
+
+ HasMacro = Val;
+ if (Val)
+ NeedsHandleIdentifier = 1;
+ else
+ RecomputeNeedsHandleIdentifier();
+ }
+
+ /// get/setTokenID - 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; }
+ void setTokenID(tok::TokenKind ID) { TokenID = ID; }
+
+ /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
+ /// For example, "define" will return tok::pp_define.
+ tok::PPKeywordKind getPPKeywordID() const;
+
+ /// getObjCKeywordID - 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; }
+
+ /// getBuiltinID - 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();
+ }
+
+ /// 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();
+ }
+
+ /// isPoisoned - 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; }
+
+ /// 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; }
+
+ /// isHandleIdentifierCase - 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; }
+
+private:
+ /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
+ /// several special (but rare) things to identifiers of various sorts. For
+ /// example, it changes the "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());
+ }
+};
+
+/// IdentifierInfoLookup - An abstract class used by IdentifierTable that
+/// provides an interface for performing lookups from strings
+/// (const char *) to IdentiferInfo objects.
+class IdentifierInfoLookup {
+public:
+ virtual ~IdentifierInfoLookup();
+
+ /// 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.
+ virtual IdentifierInfo* get(llvm::StringRef Name) = 0;
+};
+
+/// \brief An abstract class used to resolve numerical identifier
+/// references (meaningful only to some external source) into
+/// IdentifierInfo pointers.
+class ExternalIdentifierLookup {
+public:
+ virtual ~ExternalIdentifierLookup();
+
+ /// \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;
+};
+
+/// IdentifierTable - This table implements an efficient mapping from strings to
+/// IdentifierInfo nodes. It has no other purpose, but this is an
+/// extremely performance-critical piece of the code, as each occurrance 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:
+ /// IdentifierTable ctor - Create the identifier table, populating it with
+ /// info about the language keywords for the language specified by LangOpts.
+ IdentifierTable(const LangOptions &LangOpts,
+ IdentifierInfoLookup* externalLookup = 0);
+
+ /// \brief Set the external identifier lookup mechanism.
+ void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
+ ExternalLookup = IILookup;
+ }
+
+ llvm::BumpPtrAllocator& getAllocator() {
+ return HashTable.getAllocator();
+ }
+
+ /// get - Return the identifier token info for the specified named identifier.
+ ///
+ IdentifierInfo &get(llvm::StringRef Name) {
+ llvm::StringMapEntry<IdentifierInfo*> &Entry =
+ HashTable.GetOrCreateValue(Name);
+
+ IdentifierInfo *II = Entry.getValue();
+ if (II) return *II;
+
+ // No entry; if we have an external lookup, look there first.
+ if (ExternalLookup) {
+ II = ExternalLookup->get(Name);
+ if (II) {
+ // Cache in the StringMap for subsequent lookups.
+ Entry.setValue(II);
+ return *II;
+ }
+ }
+
+ // Lookups failed, make a new IdentifierInfo.
+ void *Mem = getAllocator().Allocate<IdentifierInfo>();
+ II = new (Mem) IdentifierInfo();
+ Entry.setValue(II);
+
+ // Make sure getName() knows how to find the IdentifierInfo
+ // contents.
+ II->Entry = &Entry;
+
+ return *II;
+ }
+
+ IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
+ return get(llvm::StringRef(NameStart, NameEnd-NameStart));
+ }
+
+ IdentifierInfo &get(const char *Name, size_t NameLen) {
+ return get(llvm::StringRef(Name, NameLen));
+ }
+
+ /// \brief Creates a new IdentifierInfo from the given string.
+ ///
+ /// This is a lower-level version of get() that requires that this
+ /// identifier not be known previously and that does not consult an
+ /// external source for identifiers. In particular, external
+ /// identifier sources can use this routine to build IdentifierInfo
+ /// nodes and then introduce additional information about those
+ /// identifiers.
+ IdentifierInfo &CreateIdentifierInfo(const char *NameStart,
+ const char *NameEnd) {
+ llvm::StringMapEntry<IdentifierInfo*> &Entry =
+ HashTable.GetOrCreateValue(NameStart, NameEnd);
+
+ IdentifierInfo *II = Entry.getValue();
+ assert(!II && "IdentifierInfo already exists");
+
+ // Lookups failed, make a new IdentifierInfo.
+ void *Mem = getAllocator().Allocate<IdentifierInfo>();
+ II = new (Mem) IdentifierInfo();
+ Entry.setValue(II);
+
+ // Make sure getName() knows how to find the IdentifierInfo
+ // contents.
+ II->Entry = &Entry;
+
+ return *II;
+ }
+ IdentifierInfo &CreateIdentifierInfo(llvm::StringRef Name) {
+ return CreateIdentifierInfo(Name.begin(), Name.end());
+ }
+
+ 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(); }
+
+ /// PrintStats - Print some statistics to stderr that indicate how well the
+ /// hashing is doing.
+ void PrintStats() const;
+
+ void AddKeywords(const LangOptions &LangOpts);
+};
+
+/// Selector - This smart pointer class 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 DiagnosticInfo;
+
+ enum IdentifierInfoFlag {
+ // MultiKeywordSelector = 0.
+ ZeroArg = 0x1,
+ OneArg = 0x2,
+ 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");
+ }
+
+ IdentifierInfo *getAsIdentifierInfo() const {
+ if (getIdentifierInfoFlag())
+ return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
+ return 0;
+ }
+ unsigned getIdentifierInfoFlag() const {
+ return InfoPtr & ArgFlags;
+ }
+
+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;
+ IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
+
+ /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return
+ /// it as an std::string.
+ std::string getAsString() const;
+
+ static Selector getEmptyMarker() {
+ return Selector(uintptr_t(-1));
+ }
+ static Selector getTombstoneMarker() {
+ return Selector(uintptr_t(-2));
+ }
+};
+
+/// SelectorTable - This table allows us to fully hide how we implement
+/// multi-keyword caching.
+class SelectorTable {
+ void *Impl; // Actually a SelectorTableImpl
+ SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
+ void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
+public:
+ SelectorTable();
+ ~SelectorTable();
+
+ /// getSelector - This can create any sort of selector. 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);
+ }
+
+ /// constructSetterName - Return the setter name for the given
+ /// identifier, i.e. "set" + Name where the initial character of Name
+ /// has been capitalized.
+ static Selector constructSetterName(IdentifierTable &Idents,
+ SelectorTable &SelTable,
+ const IdentifierInfo *Name) {
+ llvm::SmallString<100> SelectorName;
+ SelectorName = "set";
+ SelectorName += Name->getName();
+ SelectorName[3] = toupper(SelectorName[3]);
+ IdentifierInfo *SetterName = &Idents.get(SelectorName);
+ return SelTable.getUnarySelector(SetterName);
+ }
+};
+
+/// 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; };
+
+
+// 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/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h
new file mode 100644
index 0000000..1ed86f1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h
@@ -0,0 +1,202 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LangOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LANGOPTIONS_H
+#define LLVM_CLANG_LANGOPTIONS_H
+
+#include <string>
+
+namespace clang {
+
+/// LangOptions - This class keeps track of the various options that can be
+/// enabled, which controls the dialect of C that is accepted.
+class LangOptions {
+public:
+ unsigned Trigraphs : 1; // Trigraphs in source files.
+ unsigned BCPLComment : 1; // BCPL-style '//' comments.
+ unsigned Bool : 1; // 'bool', 'true', 'false' keywords.
+ unsigned DollarIdents : 1; // '$' allowed in identifiers.
+ unsigned AsmPreprocessor : 1; // Preprocessor in asm mode.
+ unsigned GNUMode : 1; // True in gnu99 mode false in c99 mode (etc)
+ unsigned GNUKeywords : 1; // True if GNU-only keywords are allowed
+ unsigned ImplicitInt : 1; // C89 implicit 'int'.
+ unsigned Digraphs : 1; // C94, C99 and C++
+ unsigned HexFloats : 1; // C99 Hexadecimal float constants.
+ unsigned C99 : 1; // C99 Support
+ unsigned Microsoft : 1; // Microsoft extensions.
+ unsigned CPlusPlus : 1; // C++ Support
+ unsigned CPlusPlus0x : 1; // C++0x Support
+ unsigned CXXOperatorNames : 1; // Treat C++ operator names as keywords.
+
+ unsigned ObjC1 : 1; // Objective-C 1 support enabled.
+ unsigned ObjC2 : 1; // Objective-C 2 support enabled.
+ unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled
+ unsigned ObjCNonFragileABI2 : 1; // Objective-C enhanced modern abi enabled
+
+ unsigned PascalStrings : 1; // Allow Pascal strings
+ unsigned WritableStrings : 1; // Allow writable strings
+ unsigned ConstStrings : 1; // Add const qualifier to strings (-Wwrite-strings)
+ unsigned LaxVectorConversions : 1;
+ unsigned AltiVec : 1; // Support AltiVec-style vector initializers.
+ unsigned Exceptions : 1; // Support exception handling.
+ unsigned SjLjExceptions : 1; // Use setjmp-longjump exception handling.
+ unsigned RTTI : 1; // Support RTTI information.
+
+ unsigned NeXTRuntime : 1; // Use NeXT runtime.
+ unsigned Freestanding : 1; // Freestanding implementation
+ unsigned NoBuiltin : 1; // Do not use builtin functions (-fno-builtin)
+
+ unsigned ThreadsafeStatics : 1; // Whether static initializers are protected
+ // by locks.
+ unsigned POSIXThreads : 1; // Compiling with POSIX thread support
+ // (-pthread)
+ unsigned Blocks : 1; // block extension to C
+ unsigned EmitAllDecls : 1; // Emit all declarations, even if
+ // they are unused.
+ unsigned MathErrno : 1; // Math functions must respect errno
+ // (modulo the platform support).
+
+ unsigned OverflowChecking : 1; // Extension to call a handler function when
+ // signed integer arithmetic overflows.
+
+ unsigned HeinousExtensions : 1; // Extensions that we really don't like and
+ // may be ripped out at any time.
+
+ unsigned Optimize : 1; // Whether __OPTIMIZE__ should be defined.
+ unsigned OptimizeSize : 1; // Whether __OPTIMIZE_SIZE__ should be
+ // defined.
+ unsigned Static : 1; // Should __STATIC__ be defined (as
+ // opposed to __DYNAMIC__).
+ unsigned PICLevel : 2; // The value for __PIC__, if non-zero.
+
+ unsigned GNUInline : 1; // Should GNU inline semantics be
+ // used (instead of C99 semantics).
+ unsigned NoInline : 1; // Should __NO_INLINE__ be defined.
+
+ unsigned ObjCGCBitmapPrint : 1; // Enable printing of gc's bitmap layout
+ // for __weak/__strong ivars.
+
+ unsigned AccessControl : 1; // Whether C++ access control should
+ // be enabled.
+ unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type
+ unsigned ShortWChar : 1; // Force wchar_t to be unsigned short int.
+
+ unsigned OpenCL : 1; // OpenCL C99 language extensions.
+
+ unsigned AssumeSaneOperatorNew : 1; // Whether to add __attribute__((malloc))
+ // to the declaration of C++'s new
+ // operators
+ unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
+ // elided if possible.
+ unsigned CatchUndefined : 1; // Generate code to check for undefined ops.
+ unsigned DumpRecordLayouts : 1; /// Dump the layout of IRgen'd records.
+ unsigned DumpVTableLayouts : 1; /// Dump the layouts of emitted vtables.
+ unsigned NoConstantCFStrings : 1; // Do not do CF strings
+
+ // FIXME: This is just a temporary option, for testing purposes.
+ unsigned NoBitFieldTypeAlign : 1;
+
+private:
+ unsigned GC : 2; // Objective-C Garbage Collection modes. We
+ // declare this enum as unsigned because MSVC
+ // insists on making enums signed. Set/Query
+ // this value using accessors.
+ unsigned SymbolVisibility : 3; // Symbol's visibility.
+ unsigned StackProtector : 2; // Whether stack protectors are on. We declare
+ // this enum as unsigned because MSVC insists
+ // on making enums signed. Set/Query this
+ // value using accessors.
+
+public:
+ unsigned InstantiationDepth; // Maximum template instantiation depth.
+
+ std::string ObjCConstantStringClass;
+
+ enum GCMode { NonGC, GCOnly, HybridGC };
+ enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
+ enum VisibilityMode {
+ Default,
+ Protected,
+ Hidden
+ };
+
+ LangOptions() {
+ Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
+ GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0;
+ HexFloats = 0;
+ GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
+ NoConstantCFStrings = 0;
+ C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
+ CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
+ Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
+ NeXTRuntime = 1;
+ RTTI = 1;
+ LaxVectorConversions = 1;
+ HeinousExtensions = 0;
+ AltiVec = OpenCL = StackProtector = 0;
+
+ SymbolVisibility = (unsigned) Default;
+
+ ThreadsafeStatics = 1;
+ POSIXThreads = 0;
+ Blocks = 0;
+ EmitAllDecls = 0;
+ MathErrno = 1;
+
+ AssumeSaneOperatorNew = 1;
+
+ // FIXME: The default should be 1.
+ AccessControl = 0;
+ ElideConstructors = 1;
+
+ OverflowChecking = 0;
+ ObjCGCBitmapPrint = 0;
+
+ InstantiationDepth = 1024;
+
+ Optimize = 0;
+ OptimizeSize = 0;
+
+ Static = 0;
+ PICLevel = 0;
+
+ GNUInline = 0;
+ NoInline = 0;
+
+ CharIsSigned = 1;
+ ShortWChar = 0;
+ CatchUndefined = 0;
+ DumpRecordLayouts = 0;
+ DumpVTableLayouts = 0;
+ NoBitFieldTypeAlign = 0;
+ }
+
+ GCMode getGCMode() const { return (GCMode) GC; }
+ void setGCMode(GCMode m) { GC = (unsigned) m; }
+
+ StackProtectorMode getStackProtectorMode() const {
+ return static_cast<StackProtectorMode>(StackProtector);
+ }
+ void setStackProtectorMode(StackProtectorMode m) {
+ StackProtector = static_cast<unsigned>(m);
+ }
+
+ VisibilityMode getVisibilityMode() const {
+ return (VisibilityMode) SymbolVisibility;
+ }
+ void setVisibilityMode(VisibilityMode v) { SymbolVisibility = (unsigned) v; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Linkage.h b/contrib/llvm/tools/clang/include/clang/Basic/Linkage.h
new file mode 100644
index 0000000..de0de34
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Linkage.h
@@ -0,0 +1,57 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Linkage enumeration and various utility
+// functions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_LINKAGE_H
+#define LLVM_CLANG_BASIC_LINKAGE_H
+
+namespace clang {
+
+/// \brief Describes the different kinds of linkage
+/// (C++ [basic.link], C99 6.2.2) that an entity may have.
+enum Linkage {
+ /// \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
+ /// langauge 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 External linkage, which indicates that the entity can
+ /// be referred to from other translation units.
+ ExternalLinkage
+};
+
+/// \brief Determine whether the given linkage is semantically
+/// external.
+inline bool isExternalLinkage(Linkage L) {
+ return L == UniqueExternalLinkage || L == ExternalLinkage;
+}
+
+/// \brief Compute the minimum linkage given two linages.
+static inline Linkage minLinkage(Linkage L1, Linkage L2) {
+ return L1 < L2? L1 : L2;
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_LINKAGE_H
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/MacroBuilder.h b/contrib/llvm/tools/clang/include/clang/Basic/MacroBuilder.h
new file mode 100644
index 0000000..3287b30
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/MacroBuilder.h
@@ -0,0 +1,46 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MacroBuilder utility class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_MACROBUILDER_H
+#define LLVM_CLANG_BASIC_MACROBUILDER_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+class MacroBuilder {
+ llvm::raw_ostream &Out;
+public:
+ MacroBuilder(llvm::raw_ostream &Output) : Out(Output) {}
+
+ /// Append a #define line for macro of the form "#define Name Value\n".
+ void defineMacro(const llvm::Twine &Name, const llvm::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 llvm::Twine &Name) {
+ Out << "#undef " << Name << '\n';
+ }
+
+ /// Directly append Str and a newline to the underlying buffer.
+ void append(const llvm::Twine &Str) {
+ Out << Str << '\n';
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Makefile b/contrib/llvm/tools/clang/include/clang/Basic/Makefile
new file mode 100644
index 0000000..48f7f9d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Makefile
@@ -0,0 +1,22 @@
+LEVEL = ../../../../..
+BUILT_SOURCES = DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \
+ DiagnosticCommonKinds.inc DiagnosticDriverKinds.inc \
+ DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
+ DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
+ DiagnosticGroups.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(LEVEL)/Makefile.common
+
+INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td)
+
+$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
+ $(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang diagnostic groups with tblgen"
+ $(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<
+
+
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h b/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h
new file mode 100644
index 0000000..2019e27
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h
@@ -0,0 +1,347 @@
+//===--- OnDiskHashTable.h - On-Disk Hash Table Implementation --*- 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 facilities for reading and writing on-disk hash
+// tables.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
+#define LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Host.h"
+#include <cassert>
+#include <cstdlib>
+
+namespace clang {
+
+namespace io {
+
+typedef uint32_t Offset;
+
+inline void Emit8(llvm::raw_ostream& Out, uint32_t V) {
+ Out << (unsigned char)(V);
+}
+
+inline void Emit16(llvm::raw_ostream& Out, uint32_t V) {
+ Out << (unsigned char)(V);
+ Out << (unsigned char)(V >> 8);
+ assert((V >> 16) == 0);
+}
+
+inline void Emit24(llvm::raw_ostream& Out, uint32_t V) {
+ Out << (unsigned char)(V);
+ Out << (unsigned char)(V >> 8);
+ Out << (unsigned char)(V >> 16);
+ assert((V >> 24) == 0);
+}
+
+inline void Emit32(llvm::raw_ostream& Out, uint32_t V) {
+ Out << (unsigned char)(V);
+ Out << (unsigned char)(V >> 8);
+ Out << (unsigned char)(V >> 16);
+ Out << (unsigned char)(V >> 24);
+}
+
+inline void Emit64(llvm::raw_ostream& Out, uint64_t V) {
+ Out << (unsigned char)(V);
+ Out << (unsigned char)(V >> 8);
+ Out << (unsigned char)(V >> 16);
+ Out << (unsigned char)(V >> 24);
+ Out << (unsigned char)(V >> 32);
+ Out << (unsigned char)(V >> 40);
+ Out << (unsigned char)(V >> 48);
+ Out << (unsigned char)(V >> 56);
+}
+
+inline void Pad(llvm::raw_ostream& Out, unsigned A) {
+ Offset off = (Offset) Out.tell();
+ uint32_t n = ((uintptr_t)(off+A-1) & ~(uintptr_t)(A-1)) - off;
+ for (; n ; --n)
+ Emit8(Out, 0);
+}
+
+inline uint16_t ReadUnalignedLE16(const unsigned char *&Data) {
+ uint16_t V = ((uint16_t)Data[0]) |
+ ((uint16_t)Data[1] << 8);
+ Data += 2;
+ return V;
+}
+
+inline uint32_t ReadUnalignedLE32(const unsigned char *&Data) {
+ uint32_t V = ((uint32_t)Data[0]) |
+ ((uint32_t)Data[1] << 8) |
+ ((uint32_t)Data[2] << 16) |
+ ((uint32_t)Data[3] << 24);
+ Data += 4;
+ return V;
+}
+
+inline uint64_t ReadUnalignedLE64(const unsigned char *&Data) {
+ uint64_t V = ((uint64_t)Data[0]) |
+ ((uint64_t)Data[1] << 8) |
+ ((uint64_t)Data[2] << 16) |
+ ((uint64_t)Data[3] << 24) |
+ ((uint64_t)Data[4] << 32) |
+ ((uint64_t)Data[5] << 40) |
+ ((uint64_t)Data[6] << 48) |
+ ((uint64_t)Data[7] << 56);
+ Data += 8;
+ return V;
+}
+
+inline uint32_t ReadLE32(const unsigned char *&Data) {
+ // Hosts that directly support little-endian 32-bit loads can just
+ // use them. Big-endian hosts need a bswap.
+ uint32_t V = *((uint32_t*)Data);
+ if (llvm::sys::isBigEndianHost())
+ V = llvm::ByteSwap_32(V);
+ Data += 4;
+ return V;
+}
+
+} // end namespace io
+
+template<typename Info>
+class OnDiskChainedHashTableGenerator {
+ unsigned NumBuckets;
+ unsigned NumEntries;
+ llvm::BumpPtrAllocator BA;
+
+ class Item {
+ public:
+ typename Info::key_type key;
+ typename Info::data_type data;
+ Item *next;
+ const uint32_t hash;
+
+ Item(typename Info::key_type_ref k, typename Info::data_type_ref d)
+ : key(k), data(d), next(0), hash(Info::ComputeHash(k)) {}
+ };
+
+ class Bucket {
+ public:
+ io::Offset off;
+ Item* head;
+ unsigned length;
+
+ Bucket() {}
+ };
+
+ Bucket* Buckets;
+
+private:
+ void insert(Bucket* b, size_t size, Item* E) {
+ unsigned idx = E->hash & (size - 1);
+ Bucket& B = b[idx];
+ E->next = B.head;
+ ++B.length;
+ B.head = E;
+ }
+
+ void resize(size_t newsize) {
+ Bucket* newBuckets = (Bucket*) std::calloc(newsize, sizeof(Bucket));
+ // Populate newBuckets with the old entries.
+ for (unsigned i = 0; i < NumBuckets; ++i)
+ for (Item* E = Buckets[i].head; E ; ) {
+ Item* N = E->next;
+ E->next = 0;
+ insert(newBuckets, newsize, E);
+ E = N;
+ }
+
+ free(Buckets);
+ NumBuckets = newsize;
+ Buckets = newBuckets;
+ }
+
+public:
+
+ void insert(typename Info::key_type_ref key,
+ typename Info::data_type_ref data) {
+
+ ++NumEntries;
+ if (4*NumEntries >= 3*NumBuckets) resize(NumBuckets*2);
+ insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data));
+ }
+
+ io::Offset Emit(llvm::raw_ostream &out) {
+ Info InfoObj;
+ return Emit(out, InfoObj);
+ }
+
+ io::Offset Emit(llvm::raw_ostream &out, Info &InfoObj) {
+ using namespace clang::io;
+
+ // Emit the payload of the table.
+ for (unsigned i = 0; i < NumBuckets; ++i) {
+ Bucket& B = Buckets[i];
+ if (!B.head) continue;
+
+ // Store the offset for the data of this bucket.
+ B.off = out.tell();
+ assert(B.off && "Cannot write a bucket at offset 0. Please add padding.");
+
+ // Write out the number of items in the bucket.
+ Emit16(out, B.length);
+
+ // Write out the entries in the bucket.
+ for (Item *I = B.head; I ; I = I->next) {
+ Emit32(out, I->hash);
+ const std::pair<unsigned, unsigned>& Len =
+ InfoObj.EmitKeyDataLength(out, I->key, I->data);
+ InfoObj.EmitKey(out, I->key, Len.first);
+ InfoObj.EmitData(out, I->key, I->data, Len.second);
+ }
+ }
+
+ // Emit the hashtable itself.
+ Pad(out, 4);
+ io::Offset TableOff = out.tell();
+ Emit32(out, NumBuckets);
+ Emit32(out, NumEntries);
+ for (unsigned i = 0; i < NumBuckets; ++i) Emit32(out, Buckets[i].off);
+
+ return TableOff;
+ }
+
+ OnDiskChainedHashTableGenerator() {
+ NumEntries = 0;
+ NumBuckets = 64;
+ // Note that we do not need to run the constructors of the individual
+ // Bucket objects since 'calloc' returns bytes that are all 0.
+ Buckets = (Bucket*) std::calloc(NumBuckets, sizeof(Bucket));
+ }
+
+ ~OnDiskChainedHashTableGenerator() {
+ std::free(Buckets);
+ }
+};
+
+template<typename Info>
+class OnDiskChainedHashTable {
+ const unsigned NumBuckets;
+ const unsigned NumEntries;
+ const unsigned char* const Buckets;
+ const unsigned char* const Base;
+ Info InfoObj;
+
+public:
+ typedef typename Info::internal_key_type internal_key_type;
+ typedef typename Info::external_key_type external_key_type;
+ typedef typename Info::data_type data_type;
+
+ OnDiskChainedHashTable(unsigned numBuckets, unsigned numEntries,
+ const unsigned char* buckets,
+ const unsigned char* base,
+ const Info &InfoObj = Info())
+ : NumBuckets(numBuckets), NumEntries(numEntries),
+ Buckets(buckets), Base(base), InfoObj(InfoObj) {
+ assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
+ "'buckets' must have a 4-byte alignment");
+ }
+
+ unsigned getNumBuckets() const { return NumBuckets; }
+ unsigned getNumEntries() const { return NumEntries; }
+ const unsigned char* getBase() const { return Base; }
+ const unsigned char* getBuckets() const { return Buckets; }
+
+ bool isEmpty() const { return NumEntries == 0; }
+
+ class iterator {
+ internal_key_type key;
+ const unsigned char* const data;
+ const unsigned len;
+ Info *InfoObj;
+ public:
+ iterator() : data(0), len(0) {}
+ iterator(const internal_key_type k, const unsigned char* d, unsigned l,
+ Info *InfoObj)
+ : key(k), data(d), len(l), InfoObj(InfoObj) {}
+
+ data_type operator*() const { return InfoObj->ReadData(key, data, len); }
+ bool operator==(const iterator& X) const { return X.data == data; }
+ bool operator!=(const iterator& X) const { return X.data != data; }
+ };
+
+ iterator find(const external_key_type& eKey, Info *InfoPtr = 0) {
+ if (!InfoPtr)
+ InfoPtr = &InfoObj;
+
+ using namespace io;
+ const internal_key_type& iKey = Info::GetInternalKey(eKey);
+ unsigned key_hash = Info::ComputeHash(iKey);
+
+ // Each bucket is just a 32-bit offset into the hash table file.
+ unsigned idx = key_hash & (NumBuckets - 1);
+ const unsigned char* Bucket = Buckets + sizeof(uint32_t)*idx;
+
+ unsigned offset = ReadLE32(Bucket);
+ if (offset == 0) return iterator(); // Empty bucket.
+ const unsigned char* Items = Base + offset;
+
+ // 'Items' starts with a 16-bit unsigned integer representing the
+ // number of items in this bucket.
+ unsigned len = ReadUnalignedLE16(Items);
+
+ for (unsigned i = 0; i < len; ++i) {
+ // Read the hash.
+ uint32_t item_hash = ReadUnalignedLE32(Items);
+
+ // Determine the length of the key and the data.
+ const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Items);
+ unsigned item_len = L.first + L.second;
+
+ // Compare the hashes. If they are not the same, skip the entry entirely.
+ if (item_hash != key_hash) {
+ Items += item_len;
+ continue;
+ }
+
+ // Read the key.
+ const internal_key_type& X =
+ InfoPtr->ReadKey((const unsigned char* const) Items, L.first);
+
+ // If the key doesn't match just skip reading the value.
+ if (!Info::EqualKey(X, iKey)) {
+ Items += item_len;
+ continue;
+ }
+
+ // The key matches!
+ return iterator(X, Items + L.first, L.second, InfoPtr);
+ }
+
+ return iterator();
+ }
+
+ iterator end() const { return iterator(); }
+
+
+ static OnDiskChainedHashTable* Create(const unsigned char* buckets,
+ const unsigned char* const base,
+ const Info &InfoObj = Info()) {
+ using namespace io;
+ assert(buckets > base);
+ assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
+ "buckets should be 4-byte aligned.");
+
+ unsigned numBuckets = ReadLE32(buckets);
+ unsigned numEntries = ReadLE32(buckets);
+ return new OnDiskChainedHashTable<Info>(numBuckets, numEntries, buckets,
+ base, InfoObj);
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.def
new file mode 100644
index 0000000..d011e9d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.def
@@ -0,0 +1,106 @@
+//===--- 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)
+
+#undef OVERLOADED_OPERATOR_MULTI
+#undef OVERLOADED_OPERATOR
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.h
new file mode 100644
index 0000000..c0a9505
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.h
@@ -0,0 +1,35 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C++ overloaded operators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPERATOR_KINDS_H
+#define LLVM_CLANG_BASIC_OPERATOR_KINDS_H
+
+namespace clang {
+
+/// OverloadedOperatorKind - Enumeration specifying the different kinds of
+/// C++ overloaded operators.
+enum OverloadedOperatorKind {
+ 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/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h
new file mode 100644
index 0000000..89fae87
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h
@@ -0,0 +1,287 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a partial diagnostic that can be emitted anwyhere
+// in a DiagnosticBuilder stream.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARTIALDIAGNOSTIC_H
+#define LLVM_CLANG_PARTIALDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/System/DataTypes.h"
+#include <cassert>
+
+namespace clang {
+
+class PartialDiagnostic {
+public:
+ struct Storage {
+ Storage() : NumDiagArgs(0), NumDiagRanges(0), NumFixItHints(0) { }
+
+ enum {
+ /// MaxArguments - 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
+ };
+
+ /// NumDiagArgs - This contains the number of entries in Arguments.
+ unsigned char NumDiagArgs;
+
+ /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
+ unsigned char NumDiagRanges;
+
+ /// \brief The number of code modifications hints in the
+ /// FixItHints array.
+ unsigned char NumFixItHints;
+
+ /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
+ /// values, with one for each argument. This specifies whether the argument
+ /// is in DiagArgumentsStr or in DiagArguments.
+ unsigned char DiagArgumentsKind[MaxArguments];
+
+ /// DiagArgumentsVal - 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 intepretation depends on exactly
+ /// what sort of argument kind it is.
+ intptr_t DiagArgumentsVal[MaxArguments];
+
+ /// DiagRanges - The list of ranges added to this diagnostic. It currently
+ /// only support 10 ranges, could easily be extended if needed.
+ SourceRange DiagRanges[10];
+
+ enum { MaxFixItHints = 3 };
+
+ /// FixItHints - If valid, provides a hint with some code
+ /// to insert, remove, or modify at a particular position.
+ FixItHint FixItHints[MaxFixItHints];
+ };
+
+ /// \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 = 4;
+ 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->NumDiagRanges = 0;
+ Result->NumFixItHints = 0;
+ 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.
+
+ /// DiagID - The diagnostic ID.
+ mutable unsigned DiagID;
+
+ /// DiagStorage - 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;
+
+ if (Allocator)
+ Allocator->Deallocate(DiagStorage);
+ else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
+ delete DiagStorage;
+ DiagStorage = 0;
+ }
+
+ void AddSourceRange(const SourceRange &R) const {
+ if (!DiagStorage)
+ DiagStorage = getStorage();
+
+ assert(DiagStorage->NumDiagRanges <
+ llvm::array_lengthof(DiagStorage->DiagRanges) &&
+ "Too many arguments to diagnostic!");
+ DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R;
+ }
+
+ void AddFixItHint(const FixItHint &Hint) const {
+ if (Hint.isNull())
+ return;
+
+ if (!DiagStorage)
+ DiagStorage = getStorage();
+
+ assert(DiagStorage->NumFixItHints < Storage::MaxFixItHints &&
+ "Too many code modification hints!");
+ DiagStorage->FixItHints[DiagStorage->NumFixItHints++]
+ = Hint;
+ }
+
+public:
+ PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
+ : DiagID(DiagID), DiagStorage(0), Allocator(&Allocator) { }
+
+ PartialDiagnostic(const PartialDiagnostic &Other)
+ : DiagID(Other.DiagID), DiagStorage(0), Allocator(Other.Allocator)
+ {
+ if (Other.DiagStorage) {
+ DiagStorage = getStorage();
+ *DiagStorage = *Other.DiagStorage;
+ }
+ }
+
+ 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 &operator=(const PartialDiagnostic &Other) {
+ DiagID = Other.DiagID;
+ if (Other.DiagStorage) {
+ if (!DiagStorage)
+ DiagStorage = getStorage();
+
+ *DiagStorage = *Other.DiagStorage;
+ } else {
+ freeStorage();
+ }
+
+ return *this;
+ }
+
+ ~PartialDiagnostic() {
+ freeStorage();
+ }
+
+ unsigned getDiagID() const { return DiagID; }
+
+ void AddTaggedVal(intptr_t V, Diagnostic::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 Emit(const DiagnosticBuilder &DB) const {
+ if (!DiagStorage)
+ return;
+
+ // Add all arguments.
+ for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) {
+ DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i],
+ (Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
+ }
+
+ // Add all ranges.
+ for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i)
+ DB.AddSourceRange(DiagStorage->DiagRanges[i]);
+
+ // Add all code modification hints
+ for (unsigned i = 0, e = DiagStorage->NumFixItHints; i != e; ++i)
+ DB.AddFixItHint(DiagStorage->FixItHints[i]);
+ }
+
+ /// \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 != 0; }
+
+ friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ unsigned I) {
+ PD.AddTaggedVal(I, Diagnostic::ak_uint);
+ return PD;
+ }
+
+ friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ int I) {
+ PD.AddTaggedVal(I, Diagnostic::ak_sint);
+ return PD;
+ }
+
+ friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const char *S) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), Diagnostic::ak_c_string);
+ return PD;
+ }
+
+ friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const SourceRange &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;
+}
+
+
+} // end namespace clang
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/PrettyStackTrace.h b/contrib/llvm/tools/clang/include/clang/Basic/PrettyStackTrace.h
new file mode 100644
index 0000000..5a5d551
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/PrettyStackTrace.h
@@ -0,0 +1,37 @@
+//===- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PrettyStackTraceEntry class, which is used to make
+// crashes give more contextual information about what the program was doing
+// when it crashed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_PRETTYSTACKTRACE_H
+#define CLANG_BASIC_PRETTYSTACKTRACE_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace clang {
+
+ /// PrettyStackTraceLoc - 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) {}
+ virtual void print(llvm::raw_ostream &OS) const;
+ };
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h
new file mode 100644
index 0000000..0bbeffe
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h
@@ -0,0 +1,305 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SourceLocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCELOCATION_H
+#define LLVM_CLANG_SOURCELOCATION_H
+
+#include <utility>
+#include <cassert>
+
+namespace llvm {
+ class MemoryBuffer;
+ class raw_ostream;
+ class StringRef;
+ template <typename T> struct DenseMapInfo;
+ template <typename T> struct isPodLike;
+}
+
+namespace clang {
+
+class SourceManager;
+
+/// FileID - This is an opaque identifier used by SourceManager which refers to
+/// a source file (MemoryBuffer) along with its #include path and #line data.
+///
+class FileID {
+ /// ID - Opaque identifier, 0 is "invalid".
+ unsigned ID;
+public:
+ FileID() : 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(~0U); }
+ unsigned getHashValue() const { return ID; }
+
+private:
+ friend class SourceManager;
+ static FileID get(unsigned V) {
+ FileID F;
+ F.ID = V;
+ return F;
+ }
+ unsigned getOpaqueValue() const { return ID; }
+};
+
+
+/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
+/// a full include stack, line and column number information for a position in
+/// an input translation unit.
+class SourceLocation {
+ unsigned ID;
+ friend class SourceManager;
+ enum {
+ MacroIDBit = 1U << 31
+ };
+public:
+
+ SourceLocation() : ID(0) {} // 0 is an invalid FileID.
+
+ bool isFileID() const { return (ID & MacroIDBit) == 0; }
+ bool isMacroID() const { return (ID & MacroIDBit) != 0; }
+
+ /// isValid - 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:
+ /// getOffset - Return the index for SourceManager's SLocEntryTable table,
+ /// note that this is not an index *into* it though.
+ 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:
+
+ /// getFileLocWithOffset - Return a source location with the specified offset
+ /// from this file SourceLocation.
+ SourceLocation getFileLocWithOffset(int Offset) const {
+ assert(((getOffset()+Offset) & MacroIDBit) == 0 && "invalid location");
+ SourceLocation L;
+ L.ID = ID+Offset;
+ return L;
+ }
+
+ /// getRawEncoding - 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; }
+
+
+ /// getFromRawEncoding - Turn a raw encoding of a SourceLocation object into
+ /// a real SourceLocation.
+ static SourceLocation getFromRawEncoding(unsigned Encoding) {
+ SourceLocation X;
+ X.ID = Encoding;
+ return X;
+ }
+
+ void print(llvm::raw_ostream &OS, 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();
+}
+
+/// SourceRange - a trival 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;
+ }
+};
+
+/// FullSourceLoc - A SourceLocation and its associated SourceManager. Useful
+/// for argument passing to functions that expect both objects.
+class FullSourceLoc : public SourceLocation {
+ const SourceManager *SrcMgr;
+public:
+ /// Creates a FullSourceLoc where isValid() returns false.
+ explicit FullSourceLoc() : SrcMgr(0) {}
+
+ explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
+ : SourceLocation(Loc), SrcMgr(&SM) {}
+
+ const SourceManager &getManager() const {
+ assert(SrcMgr && "SourceManager is NULL.");
+ return *SrcMgr;
+ }
+
+ FileID getFileID() const;
+
+ FullSourceLoc getInstantiationLoc() const;
+ FullSourceLoc getSpellingLoc() const;
+
+ unsigned getInstantiationLineNumber(bool *Invalid = 0) const;
+ unsigned getInstantiationColumnNumber(bool *Invalid = 0) const;
+
+ unsigned getSpellingLineNumber(bool *Invalid = 0) const;
+ unsigned getSpellingColumnNumber(bool *Invalid = 0) const;
+
+ const char *getCharacterData(bool *Invalid = 0) const;
+
+ const llvm::MemoryBuffer* getBuffer(bool *Invalid = 0) const;
+
+ /// getBufferData - Return a StringRef to the source buffer data for the
+ /// specified FileID.
+ llvm::StringRef getBufferData(bool *Invalid = 0) const;
+
+ /// getDecomposedLoc - 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;
+
+ /// Prints information about this FullSourceLoc to stderr. Useful for
+ /// debugging.
+ void dump() const { SourceLocation::dump(*SrcMgr); }
+
+ 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);
+ }
+
+};
+
+/// PresumedLoc - This class 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 instantiation 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(0) {}
+ PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
+ : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
+ }
+
+ /// isInvalid - 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 == 0; }
+ bool isValid() const { return Filename != 0; }
+
+ /// getFilename - Return the presumed filename of this location. This can be
+ /// affected by #line etc.
+ const char *getFilename() const { return Filename; }
+
+ /// getLine - Return the presumed line number of this location. This can be
+ /// affected by #line etc.
+ unsigned getLine() const { return Line; }
+
+ /// getColumn - Return the presumed column number of this location. This can
+ /// not be affected by #line, but is packaged here for convenience.
+ unsigned getColumn() const { return Col; }
+
+ /// getIncludeLoc - 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; };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h
new file mode 100644
index 0000000..6a4be46
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h
@@ -0,0 +1,848 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SourceManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMANAGER_H
+#define LLVM_CLANG_SOURCEMANAGER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+class MemoryBuffer;
+class StringRef;
+}
+
+namespace clang {
+
+class Diagnostic;
+class SourceManager;
+class FileManager;
+class FileEntry;
+class LineTableInfo;
+
+/// SrcMgr - Public enums and private classes that are part of the
+/// SourceManager implementation.
+///
+namespace SrcMgr {
+ /// CharacteristicKind - This is used to represent 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
+ /// FileIDInfos when a #pragma system_header is seen or various other cases.
+ ///
+ enum CharacteristicKind {
+ C_User, C_System, C_ExternCSystem
+ };
+
+ /// ContentCache - Once instance of this struct is kept for every file
+ /// loaded or used. This object owns the MemoryBuffer object.
+ class ContentCache {
+ /// Buffer - The actual buffer containing the characters from the input
+ /// file. This is owned by the ContentCache object.
+ /// The bit indicates whether the buffer is invalid.
+ mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 1, bool> Buffer;
+
+ public:
+ /// Reference to the file entry. 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 *Entry;
+
+ /// SourceLineCache - 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;
+
+ /// NumLines - The number of lines in this ContentCache. This is only valid
+ /// if SourceLineCache is non-null.
+ unsigned NumLines;
+
+ /// getBuffer - Returns the memory buffer for the associated content.
+ ///
+ /// \param Diag Object through which diagnostics will be emitted it 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.
+ const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag,
+ const SourceManager &SM,
+ SourceLocation Loc = SourceLocation(),
+ bool *Invalid = 0) const;
+
+ /// getSize - 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;
+
+ /// getSizeBytesMapped - Returns the number of bytes actually mapped for
+ /// this ContentCache. This can be 0 if the MemBuffer was not actually
+ /// instantiated.
+ unsigned getSizeBytesMapped() const;
+
+ void setBuffer(const llvm::MemoryBuffer *B) {
+ assert(!Buffer.getPointer() && "MemoryBuffer already set.");
+ Buffer.setPointer(B);
+ Buffer.setInt(false);
+ }
+
+ /// \brief Replace the existing buffer (which will be deleted)
+ /// with the given buffer.
+ void replaceBuffer(const llvm::MemoryBuffer *B);
+
+ ContentCache(const FileEntry *Ent = 0)
+ : Buffer(0, false), Entry(Ent), SourceLineCache(0), NumLines(0) {}
+
+ ~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 transfered, so this is a logical error.
+ ContentCache(const ContentCache &RHS)
+ : Buffer(0, false), SourceLineCache(0)
+ {
+ Entry = RHS.Entry;
+
+ assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0
+ && "Passed ContentCache object cannot own a buffer.");
+
+ NumLines = RHS.NumLines;
+ }
+
+ private:
+ // Disable assignments.
+ ContentCache &operator=(const ContentCache& RHS);
+ };
+
+ /// FileInfo - 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
+ /// instantiated from. The main include file has an invalid IncludeLoc.
+ ///
+ /// FileInfos contain a "ContentCache *", with the contents of the file.
+ ///
+ class FileInfo {
+ /// IncludeLoc - 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
+
+ /// Data - This contains the ContentCache* and the bits indicating the
+ /// characteristic of the file and whether it has #line info, all bitmangled
+ /// together.
+ uintptr_t Data;
+ public:
+ /// get - Return a FileInfo object.
+ static FileInfo get(SourceLocation IL, const ContentCache *Con,
+ CharacteristicKind FileCharacter) {
+ FileInfo X;
+ X.IncludeLoc = IL.getRawEncoding();
+ 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 & ~7UL);
+ }
+
+ /// getCharacteristic - Return whether this is a system header or not.
+ CharacteristicKind getFileCharacteristic() const {
+ return (CharacteristicKind)(Data & 3);
+ }
+
+ /// hasLineDirectives - Return true if this FileID has #line directives in
+ /// it.
+ bool hasLineDirectives() const { return (Data & 4) != 0; }
+
+ /// setHasLineDirectives - Set the flag that indicates that this FileID has
+ /// line table entries associated with it.
+ void setHasLineDirectives() {
+ Data |= 4;
+ }
+ };
+
+ /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation
+ /// location - where the token was ultimately instantiated, and the
+ /// SpellingLoc - where the actual character data for the token came from.
+ class InstantiationInfo {
+ // Really these are all SourceLocations.
+
+ /// SpellingLoc - Where the spelling for the token can be found.
+ unsigned SpellingLoc;
+
+ /// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these
+ /// indicate the start and end of the instantiation. In object-like macros,
+ /// these will be the same. In a function-like macro instantiation, the
+ /// start will be the identifier and the end will be the ')'.
+ unsigned InstantiationLocStart, InstantiationLocEnd;
+ public:
+ SourceLocation getSpellingLoc() const {
+ return SourceLocation::getFromRawEncoding(SpellingLoc);
+ }
+ SourceLocation getInstantiationLocStart() const {
+ return SourceLocation::getFromRawEncoding(InstantiationLocStart);
+ }
+ SourceLocation getInstantiationLocEnd() const {
+ return SourceLocation::getFromRawEncoding(InstantiationLocEnd);
+ }
+
+ std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const {
+ return std::make_pair(getInstantiationLocStart(),
+ getInstantiationLocEnd());
+ }
+
+ /// get - Return a InstantiationInfo for an expansion. IL specifies
+ /// the instantiation location (where the macro is expanded), and SL
+ /// specifies the spelling location (where the characters from the token
+ /// come from). IL and PL can both refer to normal File SLocs or
+ /// instantiation locations.
+ static InstantiationInfo get(SourceLocation ILStart, SourceLocation ILEnd,
+ SourceLocation SL) {
+ InstantiationInfo X;
+ X.SpellingLoc = SL.getRawEncoding();
+ X.InstantiationLocStart = ILStart.getRawEncoding();
+ X.InstantiationLocEnd = ILEnd.getRawEncoding();
+ return X;
+ }
+ };
+
+ /// SLocEntry - This is a discriminated union of FileInfo and
+ /// InstantiationInfo. SourceManager keeps an array of these objects, and
+ /// they are uniquely identified by the FileID datatype.
+ class SLocEntry {
+ unsigned Offset; // low bit is set for instantiation info.
+ union {
+ FileInfo File;
+ InstantiationInfo Instantiation;
+ };
+ public:
+ unsigned getOffset() const { return Offset >> 1; }
+
+ bool isInstantiation() const { return Offset & 1; }
+ bool isFile() const { return !isInstantiation(); }
+
+ const FileInfo &getFile() const {
+ assert(isFile() && "Not a file SLocEntry!");
+ return File;
+ }
+
+ const InstantiationInfo &getInstantiation() const {
+ assert(isInstantiation() && "Not an instantiation SLocEntry!");
+ return Instantiation;
+ }
+
+ static SLocEntry get(unsigned Offset, const FileInfo &FI) {
+ SLocEntry E;
+ E.Offset = Offset << 1;
+ E.File = FI;
+ return E;
+ }
+
+ static SLocEntry get(unsigned Offset, const InstantiationInfo &II) {
+ SLocEntry E;
+ E.Offset = (Offset << 1) | 1;
+ E.Instantiation = II;
+ 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.
+ virtual void ReadSLocEntry(unsigned ID) = 0;
+};
+
+
+/// IsBeforeInTranslationUnitCache - This class holds the cache used by
+/// isBeforeInTranslationUnit. The cache structure is complex enough to be
+/// worth breaking out of SourceManager.
+class IsBeforeInTranslationUnitCache {
+ /// L/R QueryFID - These are the FID's of the cached query. If these match up
+ /// with a subsequent query, the result can be reused.
+ FileID LQueryFID, RQueryFID;
+
+ /// CommonFID - This is the file found in common between the two #include
+ /// traces. It is the nearest common ancestor of the #include tree.
+ FileID CommonFID;
+
+ /// L/R CommonOffset - This is 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 vise versa) then these can be a
+ /// random token in the parent.
+ unsigned LCommonOffset, RCommonOffset;
+public:
+
+ /// isCacheValid - 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;
+ }
+
+ /// getCachedResult - If the cache is valid, compute the result given the
+ /// specified offsets in the LHS/RHS FID'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;
+ return LOffset < ROffset;
+ }
+
+ // Set up a new query.
+ void setQueryFIDs(FileID LHS, FileID RHS) {
+ LQueryFID = LHS;
+ RQueryFID = RHS;
+ }
+
+ void setCommonLoc(FileID commonFID, unsigned lCommonOffset,
+ unsigned rCommonOffset) {
+ CommonFID = commonFID;
+ LCommonOffset = lCommonOffset;
+ RCommonOffset = rCommonOffset;
+ }
+
+};
+
+/// SourceManager - This file 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 instantiation locations.
+/// Spelling locations represent where the bytes corresponding to a token came
+/// from and instantiation 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 instantiation
+/// location specifies where it was expanded.
+class SourceManager {
+ /// \brief Diagnostic object.
+ Diagnostic &Diag;
+
+ mutable llvm::BumpPtrAllocator ContentCacheAlloc;
+
+ /// FileInfos - Memoized information about all of the files tracked by this
+ /// SourceManager. This set 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;
+
+ /// MemBufferInfos - 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;
+
+ /// SLocEntryTable - This is an array of SLocEntry's that we have created.
+ /// FileID is an index into this vector. This array is sorted by the offset.
+ std::vector<SrcMgr::SLocEntry> SLocEntryTable;
+ /// NextOffset - This is the next available offset that a new SLocEntry can
+ /// start at. It is SLocEntryTable.back().getOffset()+size of back() entry.
+ unsigned NextOffset;
+
+ /// \brief If source location entries are being lazily loaded from
+ /// an external source, this vector indicates whether the Ith source
+ /// location entry has already been loaded from the external storage.
+ std::vector<bool> SLocEntryLoaded;
+
+ /// \brief An external source for source location entries.
+ ExternalSLocEntrySource *ExternalSLocEntries;
+
+ /// LastFileIDLookup - This is 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;
+
+ /// LineTable - This holds information for #line directives. It is referenced
+ /// by indices from SLocEntryTable.
+ LineTableInfo *LineTable;
+
+ /// LastLineNo - 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;
+
+ /// MainFileID - The file ID for the main source file of the translation unit.
+ FileID MainFileID;
+
+ // Statistics for -print-stats.
+ mutable unsigned NumLinearScans, NumBinaryProbes;
+
+ // Cache results for the isBeforeInTranslationUnit method.
+ mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache;
+
+ // SourceManager doesn't support copy construction.
+ explicit SourceManager(const SourceManager&);
+ void operator=(const SourceManager&);
+public:
+ SourceManager(Diagnostic &Diag)
+ : Diag(Diag), ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
+ NumBinaryProbes(0) {
+ clearIDTables();
+ }
+ ~SourceManager();
+
+ void clearIDTables();
+
+ //===--------------------------------------------------------------------===//
+ // MainFileID creation and querying methods.
+ //===--------------------------------------------------------------------===//
+
+ /// getMainFileID - Returns the FileID of the main source file.
+ FileID getMainFileID() const { return MainFileID; }
+
+ /// createMainFileID - Create the FileID for the main source file.
+ FileID createMainFileID(const FileEntry *SourceFile,
+ SourceLocation IncludePos) {
+ assert(MainFileID.isInvalid() && "MainFileID already set!");
+ MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
+ return MainFileID;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Methods to create new FileID's and instantiations.
+ //===--------------------------------------------------------------------===//
+
+ /// createFileID - Create a new FileID that represents the specified file
+ /// being #included from the specified IncludePosition. This returns 0 on
+ /// error and translates NULL into standard input.
+ /// PreallocateID should be non-zero to specify which a pre-allocated,
+ /// lazily computed source location is being filled in by this operation.
+ FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
+ SrcMgr::CharacteristicKind FileCharacter,
+ unsigned PreallocatedID = 0,
+ unsigned Offset = 0) {
+ const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
+ if (IR == 0) return FileID(); // Error opening file?
+ return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset);
+ }
+
+ /// createFileIDForMemBuffer - 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 createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
+ unsigned PreallocatedID = 0,
+ unsigned Offset = 0) {
+ return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
+ SrcMgr::C_User, PreallocatedID, Offset);
+ }
+
+ /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
+ /// that will represent the FileID for the main source. One example
+ /// of when this would be used is when the main source is read from STDIN.
+ FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
+ assert(MainFileID.isInvalid() && "MainFileID already set!");
+ MainFileID = createFileIDForMemBuffer(Buffer);
+ return MainFileID;
+ }
+
+ /// createInstantiationLoc - Return a new SourceLocation that encodes the fact
+ /// that a token at Loc should actually be referenced from InstantiationLoc.
+ /// TokLength is the length of the token being instantiated.
+ SourceLocation createInstantiationLoc(SourceLocation Loc,
+ SourceLocation InstantiationLocStart,
+ SourceLocation InstantiationLocEnd,
+ unsigned TokLength,
+ unsigned PreallocatedID = 0,
+ unsigned Offset = 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.
+ const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
+ bool *Invalid = 0);
+
+ /// \brief Override the contents of the given source file by providing an
+ /// already-allocated buffer.
+ ///
+ /// \param SourceFile the source file whose contents will be override.
+ ///
+ /// \param Buffer the memory buffer whose contents will be used as the
+ /// data in the given source file.
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool overrideFileContents(const FileEntry *SourceFile,
+ const llvm::MemoryBuffer *Buffer);
+
+ //===--------------------------------------------------------------------===//
+ // FileID manipulation methods.
+ //===--------------------------------------------------------------------===//
+
+ /// getBuffer - 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.
+ const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+ bool *Invalid = 0) const {
+ return getSLocEntry(FID).getFile().getContentCache()
+ ->getBuffer(Diag, *this, Loc, Invalid);
+ }
+
+ const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
+ return getSLocEntry(FID).getFile().getContentCache()
+ ->getBuffer(Diag, *this, SourceLocation(), Invalid);
+ }
+
+ /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
+ const FileEntry *getFileEntryForID(FileID FID) const {
+ return getSLocEntry(FID).getFile().getContentCache()->Entry;
+ }
+
+ /// getBufferData - 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.
+ llvm::StringRef getBufferData(FileID FID, bool *Invalid = 0) const;
+
+
+ //===--------------------------------------------------------------------===//
+ // SourceLocation manipulation methods.
+ //===--------------------------------------------------------------------===//
+
+ /// getFileID - 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);
+ }
+
+ /// getLocForStartOfFile - Return the source location corresponding to the
+ /// first byte of the specified file.
+ SourceLocation getLocForStartOfFile(FileID FID) const {
+ assert(FID.ID < SLocEntryTable.size() && "FileID out of range");
+ assert(getSLocEntry(FID).isFile() && "FileID is not a file");
+ unsigned FileOffset = getSLocEntry(FID).getOffset();
+ return SourceLocation::getFileLoc(FileOffset);
+ }
+
+ /// getInstantiationLoc - Given a SourceLocation object, return the
+ /// instantiation location referenced by the ID.
+ SourceLocation getInstantiationLoc(SourceLocation Loc) const {
+ // Handle the non-mapped case inline, defer to out of line code to handle
+ // instantiations.
+ if (Loc.isFileID()) return Loc;
+ return getInstantiationLocSlowCase(Loc);
+ }
+
+ /// getImmediateInstantiationRange - Loc is required to be an instantiation
+ /// location. Return the start/end of the instantiation information.
+ std::pair<SourceLocation,SourceLocation>
+ getImmediateInstantiationRange(SourceLocation Loc) const;
+
+ /// getInstantiationRange - Given a SourceLocation object, return the
+ /// range of tokens covered by the instantiation in the ultimate file.
+ std::pair<SourceLocation,SourceLocation>
+ getInstantiationRange(SourceLocation Loc) const;
+
+
+ /// getSpellingLoc - 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
+ // instantiations.
+ if (Loc.isFileID()) return Loc;
+ return getSpellingLocSlowCase(Loc);
+ }
+
+ /// getImmediateSpellingLoc - 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;
+
+ /// getDecomposedLoc - 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);
+ return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset());
+ }
+
+ /// getDecomposedInstantiationLoc - Decompose the specified location into a
+ /// raw FileID + Offset pair. If the location is an instantiation record,
+ /// walk through it until we find the final location instantiated.
+ std::pair<FileID, unsigned>
+ getDecomposedInstantiationLoc(SourceLocation Loc) const {
+ FileID FID = getFileID(Loc);
+ const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
+
+ unsigned Offset = Loc.getOffset()-E->getOffset();
+ if (Loc.isFileID())
+ return std::make_pair(FID, Offset);
+
+ return getDecomposedInstantiationLocSlowCase(E, Offset);
+ }
+
+ /// getDecomposedSpellingLoc - Decompose the specified location into a raw
+ /// FileID + Offset pair. If the location is an instantiation record, walk
+ /// through it until we find its spelling record.
+ std::pair<FileID, unsigned>
+ getDecomposedSpellingLoc(SourceLocation Loc) const {
+ FileID FID = getFileID(Loc);
+ const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
+
+ unsigned Offset = Loc.getOffset()-E->getOffset();
+ if (Loc.isFileID())
+ return std::make_pair(FID, Offset);
+ return getDecomposedSpellingLocSlowCase(E, Offset);
+ }
+
+ /// getFileOffset - This method 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;
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Queries about the code at a SourceLocation.
+ //===--------------------------------------------------------------------===//
+
+ /// getCharacterData - 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 = 0) const;
+
+ /// getColumnNumber - 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 instantiation location
+ /// before calling this method.
+ unsigned getColumnNumber(FileID FID, unsigned FilePos,
+ bool *Invalid = 0) const;
+ unsigned getSpellingColumnNumber(SourceLocation Loc,
+ bool *Invalid = 0) const;
+ unsigned getInstantiationColumnNumber(SourceLocation Loc,
+ bool *Invalid = 0) const;
+
+
+ /// getLineNumber - 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 = 0) const;
+
+ unsigned getInstantiationLineNumber(SourceLocation Loc,
+ bool *Invalid = 0) const;
+ unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
+
+ /// 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 = 0) const;
+
+ /// getFileCharacteristic - 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:
+ /// # 4 "foo.h" 3
+ /// 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;
+
+ /// getPresumedLoc - This method 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 instantiation point
+ /// of an instantiation location, not at the spelling location.
+ PresumedLoc getPresumedLoc(SourceLocation Loc) const;
+
+ /// isFromSameFile - Returns true if both SourceLocations correspond to
+ /// the same file.
+ bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
+ return getFileID(Loc1) == getFileID(Loc2);
+ }
+
+ /// isFromMainFile - Returns true if the file of provided SourceLocation is
+ /// the main file.
+ bool isFromMainFile(SourceLocation Loc) const {
+ return getFileID(Loc) == getMainFileID();
+ }
+
+ /// isInSystemHeader - Returns if a SourceLocation is in a system header.
+ bool isInSystemHeader(SourceLocation Loc) const {
+ return getFileCharacteristic(Loc) != SrcMgr::C_User;
+ }
+
+ /// isInExternCSystemHeader - Returns if a SourceLocation is in an "extern C"
+ /// system header.
+ bool isInExternCSystemHeader(SourceLocation Loc) const {
+ return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Line Table Manipulation Routines
+ //===--------------------------------------------------------------------===//
+
+ /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
+ ///
+ unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
+
+ /// AddLineNote - 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 != 0; }
+
+ /// \brief Retrieve the stored line table.
+ LineTableInfo &getLineTable();
+
+ //===--------------------------------------------------------------------===//
+ // 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 getLocation(const FileEntry *SourceFile,
+ unsigned Line, unsigned Col) 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;
+
+ // 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();
+ }
+
+ /// PrintStats - Print statistics to stderr.
+ ///
+ void PrintStats() const;
+
+ unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
+
+ // FIXME: Exposing this is a little gross; what we want is a good way
+ // to iterate the entries that were not defined in a PCH file (or
+ // any other external source).
+ unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
+
+ const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
+ assert(ID < SLocEntryTable.size() && "Invalid id");
+ if (ExternalSLocEntries &&
+ ID < SLocEntryLoaded.size() &&
+ !SLocEntryLoaded[ID])
+ ExternalSLocEntries->ReadSLocEntry(ID);
+ return SLocEntryTable[ID];
+ }
+
+ const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
+ return getSLocEntry(FID.ID);
+ }
+
+ unsigned getNextOffset() const { return NextOffset; }
+
+ /// \brief Preallocate some number of source location entries, which
+ /// will be loaded as needed from the given external source.
+ void PreallocateSLocEntries(ExternalSLocEntrySource *Source,
+ unsigned NumSLocEntries,
+ unsigned NextOffset);
+
+ /// \brief Clear out any preallocated source location entries that
+ /// haven't already been loaded.
+ void ClearPreallocatedSLocEntries();
+
+private:
+ /// isOffsetInFileID - 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 last entry than it does. Otherwise, the entry after it
+ // has to not include it.
+ if (FID.ID+1 == SLocEntryTable.size()) return true;
+
+ return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
+ }
+
+ /// createFileID - 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,
+ unsigned PreallocatedID = 0,
+ unsigned Offset = 0);
+
+ const SrcMgr::ContentCache *
+ getOrCreateContentCache(const FileEntry *SourceFile);
+
+ /// createMemBufferContentCache - Create a new ContentCache for the specified
+ /// memory buffer.
+ const SrcMgr::ContentCache*
+ createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
+
+ FileID getFileIDSlow(unsigned SLocOffset) const;
+
+ SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const;
+ SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
+
+ std::pair<FileID, unsigned>
+ getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
+ unsigned Offset) const;
+ std::pair<FileID, unsigned>
+ getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
+ unsigned Offset) const;
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceManagerInternals.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceManagerInternals.h
new file mode 100644
index 0000000..258989c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceManagerInternals.h
@@ -0,0 +1,130 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the implementation details of the SourceManager
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
+#define LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
+
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringMap.h"
+#include <map>
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// Line Table Implementation
+//===----------------------------------------------------------------------===//
+
+struct LineEntry {
+ /// FileOffset - The offset in this file that the line entry occurs at.
+ unsigned FileOffset;
+
+ /// LineNo - The presumed line number of this line entry: #line 4.
+ unsigned LineNo;
+
+ /// FilenameID - The ID of the filename identified by this line entry:
+ /// #line 4 "foo.c". This is -1 if not specified.
+ int FilenameID;
+
+ /// Flags - Set the 0 if no flags, 1 if a system header,
+ SrcMgr::CharacteristicKind FileKind;
+
+ /// IncludeOffset - This is 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;
+}
+
+/// LineTableInfo - This class is used to hold and unique data used to
+/// represent #line information.
+class LineTableInfo {
+ /// FilenameIDs - This map is 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;
+
+ /// LineEntries - This is a map from FileIDs to a list of line entries (sorted
+ /// by the offset they occur in the file.
+ std::map<unsigned, std::vector<LineEntry> > LineEntries;
+public:
+ LineTableInfo() {
+ }
+
+ void clear() {
+ FilenameIDs.clear();
+ FilenamesByID.clear();
+ LineEntries.clear();
+ }
+
+ ~LineTableInfo() {}
+
+ unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
+ const char *getFilename(unsigned ID) const {
+ assert(ID < FilenamesByID.size() && "Invalid FilenameID");
+ return FilenamesByID[ID]->getKeyData();
+ }
+ unsigned getNumFilenames() const { return FilenamesByID.size(); }
+
+ void AddLineNote(unsigned FID, unsigned Offset,
+ unsigned LineNo, int FilenameID);
+ void AddLineNote(unsigned FID, unsigned Offset,
+ unsigned LineNo, int FilenameID,
+ unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
+
+
+ /// FindNearestLineEntry - Find the line entry nearest to FID that is before
+ /// it. If there is no line entry before Offset in FID, return null.
+ const LineEntry *FindNearestLineEntry(unsigned FID, unsigned Offset);
+
+ // Low-level access
+ typedef std::map<unsigned, 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(unsigned FID, const std::vector<LineEntry> &Entries);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h
new file mode 100644
index 0000000..9e54762a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h
@@ -0,0 +1,83 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various enumerations that describe declaration and
+// type specifiers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
+#define LLVM_CLANG_BASIC_SPECIFIERS_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++0x char16_t
+ TST_char32, // C++0x char32_t
+ TST_int,
+ 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_typename, // Typedef, C++ class-name or enum name, etc.
+ TST_typeofType,
+ TST_typeofExpr,
+ TST_decltype, // C++0x decltype
+ TST_auto, // C++0x auto
+ TST_error // erroneous type
+ };
+
+ /// WrittenBuiltinSpecs - 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;
+ };
+
+ /// AccessSpecifier - 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
+ };
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h
new file mode 100644
index 0000000..f1edd1d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h
@@ -0,0 +1,50 @@
+//===--- TargetBuiltins.h - Target specific builtin IDs -------------------===//
+//
+// 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_TARGET_BUILTINS_H
+#define LLVM_CLANG_BASIC_TARGET_BUILTINS_H
+
+#include "clang/Basic/Builtins.h"
+#undef PPC
+
+namespace clang {
+
+ /// ARM builtins
+ namespace ARM {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsARM.def"
+ LastTSBuiltin
+ };
+ }
+
+ /// PPC builtins
+ namespace PPC {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsPPC.def"
+ LastTSBuiltin
+ };
+ }
+
+ /// X86 builtins
+ namespace X86 {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsX86.def"
+ LastTSBuiltin
+ };
+ }
+
+} // end namespace clang.
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h
new file mode 100644
index 0000000..00fd9b9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h
@@ -0,0 +1,474 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TargetInfo interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
+#define LLVM_CLANG_BASIC_TARGETINFO_H
+
+// FIXME: Daniel isn't smart enough to use a prototype for this.
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/System/DataTypes.h"
+#include <cassert>
+#include <vector>
+#include <string>
+
+namespace llvm {
+struct fltSemantics;
+class StringRef;
+}
+
+namespace clang {
+class Diagnostic;
+class LangOptions;
+class MacroBuilder;
+class SourceLocation;
+class SourceManager;
+class TargetOptions;
+
+namespace Builtin { struct Info; }
+
+/// TargetInfo - This class exposes information about the current target.
+///
+class TargetInfo {
+ llvm::Triple Triple;
+protected:
+ // Target values set by the ctor of the actual target implementation. Default
+ // values are specified by the TargetInfo constructor.
+ bool TLSSupported;
+ bool NoAsmVariants; // True if {|} are normal characters.
+ unsigned char PointerWidth, PointerAlign;
+ unsigned char IntWidth, IntAlign;
+ unsigned char FloatWidth, FloatAlign;
+ unsigned char DoubleWidth, DoubleAlign;
+ unsigned char LongDoubleWidth, LongDoubleAlign;
+ unsigned char LongWidth, LongAlign;
+ unsigned char LongLongWidth, LongLongAlign;
+ const char *DescriptionString;
+ const char *UserLabelPrefix;
+ const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
+ unsigned char RegParmMax, SSERegParmMax;
+
+ unsigned HasAlignMac68kSupport : 1;
+
+ // TargetInfo Constructor. Default initializes all fields.
+ TargetInfo(const std::string &T);
+
+public:
+ /// CreateTargetInfo - 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(Diagnostic &Diags, TargetOptions &Opts);
+
+ virtual ~TargetInfo();
+
+ ///===---- Target Data Type Query Methods -------------------------------===//
+ enum IntType {
+ NoInt = 0,
+ SignedShort,
+ UnsignedShort,
+ SignedInt,
+ UnsignedInt,
+ SignedLong,
+ UnsignedLong,
+ SignedLongLong,
+ UnsignedLongLong
+ };
+protected:
+ IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
+ WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType;
+
+ /// 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;
+
+public:
+ IntType getSizeType() const { return SizeType; }
+ IntType getIntMaxType() const { return IntMaxType; }
+ IntType getUIntMaxType() const { return UIntMaxType; }
+ IntType getPtrDiffType(unsigned AddrSpace) const {
+ return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
+ }
+ IntType getIntPtrType() const { return 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 getSigAtomicType() const { return SigAtomicType; }
+
+
+ /// getTypeWidth - Return the width (in bits) of the specified integer type
+ /// enum. For example, SignedInt -> getIntWidth().
+ unsigned getTypeWidth(IntType T) const;
+
+ /// getTypeAlign - Return the alignment (in bits) of the specified integer
+ /// type enum. For example, SignedInt -> getIntAlign().
+ unsigned getTypeAlign(IntType T) const;
+
+ /// isTypeSigned - Return whether an integer types is signed. Returns true if
+ /// the type is signed; false otherwise.
+ bool isTypeSigned(IntType T) const;
+
+ /// getPointerWidth - 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);
+ }
+
+ /// getBoolWidth/Align - Return the size of '_Bool' and C++ 'bool' for this
+ /// target, in bits.
+ unsigned getBoolWidth(bool isWide = false) const { return 8; } // FIXME
+ unsigned getBoolAlign(bool isWide = false) const { return 8; } // FIXME
+
+ unsigned getCharWidth() const { return 8; } // FIXME
+ unsigned getCharAlign() const { return 8; } // FIXME
+
+ /// getShortWidth/Align - Return the size of 'signed short' and
+ /// 'unsigned short' for this target, in bits.
+ unsigned getShortWidth() const { return 16; } // FIXME
+ 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; }
+
+ /// 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); }
+
+ /// 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;
+ }
+
+ /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
+ /// target, in bits.
+ unsigned getIntMaxTWidth() const {
+ return getTypeWidth(IntMaxType);
+ }
+
+ /// getUserLabelPrefix - This 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;
+ }
+
+ bool useBitFieldTypeAlignment() const {
+ return UseBitFieldTypeAlignment;
+ }
+
+ /// hasAlignMac68kSupport - Check whether this target support '#pragma options
+ /// align=mac68k'.
+ bool hasAlignMac68kSupport() const {
+ return HasAlignMac68kSupport;
+ }
+
+ /// getTypeName - Return the user string for the specified integer type enum.
+ /// For example, SignedShort -> "short".
+ static const char *getTypeName(IntType T);
+
+ /// getTypeConstantSuffix - Return the constant suffix for the specified
+ /// integer type enum. For example, SignedLong -> "L".
+ static const char *getTypeConstantSuffix(IntType T);
+
+ ///===---- Other target property query methods --------------------------===//
+
+ /// getTargetDefines - Appends the target-specific #define values for this
+ /// target set to the specified buffer.
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const = 0;
+
+
+ /// getTargetBuiltins - 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 void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const = 0;
+
+ /// getVAListDeclaration - Return the declaration to use for
+ /// __builtin_va_list, which is target-specific.
+ virtual const char *getVAListDeclaration() const = 0;
+
+ /// isValidGCCRegisterName - 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(llvm::StringRef Name) const;
+
+ // getNormalizedGCCRegisterName - Returns the "normalized" GCC register name.
+ // For example, on x86 it will return "ax" when "eax" is passed in.
+ llvm::StringRef getNormalizedGCCRegisterName(llvm::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.
+ };
+ unsigned Flags;
+ int TiedOperand;
+
+ std::string ConstraintStr; // constraint: "=rm"
+ std::string Name; // Operand name: [foo] with no []'s.
+ public:
+ ConstraintInfo(llvm::StringRef ConstraintStr, llvm::StringRef Name)
+ : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
+ Name(Name.str()) {}
+
+ const std::string &getConstraintStr() const { return ConstraintStr; }
+ const std::string &getName() const { return Name; }
+ bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
+ bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
+ bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
+
+ /// hasMatchingInput - Return true if this output operand has a matching
+ /// (tied) input operand.
+ bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
+
+ /// hasTiedOperand() - 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;
+ }
+
+ void setIsReadWrite() { Flags |= CI_ReadWrite; }
+ void setAllowsMemory() { Flags |= CI_AllowsMemory; }
+ void setAllowsRegister() { Flags |= CI_AllowsRegister; }
+ void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
+
+ /// setTiedOperand - 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.
+ }
+ };
+
+ // 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(ConstraintInfo *OutputConstraints,
+ unsigned NumOutputs,
+ ConstraintInfo &info) const;
+ bool resolveSymbolicName(const char *&Name,
+ ConstraintInfo *OutputConstraints,
+ unsigned NumOutputs, unsigned &Index) const;
+
+ virtual std::string convertConstraint(const char Constraint) const {
+ return std::string(1, Constraint);
+ }
+
+ // Returns a string of target-specific clobbers, in LLVM format.
+ virtual const char *getClobbers() const = 0;
+
+
+ /// getTriple - Return the target triple of the primary target.
+ const llvm::Triple &getTriple() const {
+ return Triple;
+ }
+
+ const char *getTargetDescription() const {
+ return DescriptionString;
+ }
+
+ struct GCCRegAlias {
+ const char * const Aliases[5];
+ const char * const Register;
+ };
+
+ virtual bool useGlobalsForAutomaticVariables() const { return false; }
+
+ /// getCFStringSection - Return the section to use for CFString
+ /// literals, or 0 if no special section is used.
+ virtual const char *getCFStringSection() const {
+ return "__DATA,__cfstring";
+ }
+
+ /// getNSStringSection - Return the section to use for NSString
+ /// literals, or 0 if no special section is used.
+ virtual const char *getNSStringSection() const {
+ return "__OBJC,__cstring_object,regular,no_dead_strip";
+ }
+
+ /// getNSStringNonFragileABISection - Return the section to use for
+ /// NSString literals, or 0 if no special section is used (NonFragile ABI).
+ virtual const char *getNSStringNonFragileABISection() const {
+ return "__DATA, __objc_stringobj, regular, no_dead_strip";
+ }
+
+ /// isValidSectionSpecifier - This is 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(llvm::StringRef SR) const {
+ return "";
+ }
+
+ /// setForcedLangOptions - Set forced language options.
+ /// Apply changes to the target information with respect to certain
+ /// language options which change the target configuration.
+ virtual void setForcedLangOptions(LangOptions &Opts);
+
+ /// getDefaultFeatures - Get the default set of target features for
+ /// the \args CPU; this should include all legal feature strings on
+ /// the target.
+ virtual void getDefaultFeatures(const std::string &CPU,
+ llvm::StringMap<bool> &Features) const {
+ }
+
+ /// getABI - Get the ABI in use.
+ virtual const char *getABI() const {
+ return "";
+ }
+
+ /// setCPU - Target the specific CPU.
+ ///
+ /// \return - False on error (invalid CPU name).
+ //
+ // FIXME: Remove this.
+ virtual bool setCPU(const std::string &Name) {
+ return true;
+ }
+
+ /// setABI - Use the specific ABI.
+ ///
+ /// \return - False on error (invalid ABI name).
+ virtual bool setABI(const std::string &Name) {
+ return false;
+ }
+
+ /// setFeatureEnabled - Enable or disable a specific target feature,
+ /// the feature name must be valid.
+ ///
+ /// \return - False on error (invalid feature name).
+ virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+ const std::string &Name,
+ bool Enabled) const {
+ return false;
+ }
+
+ /// HandleTargetOptions - 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.
+ virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+ }
+
+ // getRegParmMax - Returns maximal number of args passed in registers.
+ unsigned getRegParmMax() const {
+ return RegParmMax;
+ }
+
+ /// isTLSSupported - Whether the target supports thread-local storage.
+ bool isTLSSupported() const {
+ return TLSSupported;
+ }
+
+ /// hasNoAsmVariants - 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;
+ }
+
+ /// getEHDataRegisterNumber - Return the register number that
+ /// __builtin_eh_return_regno would return with the specified argument.
+ virtual int getEHDataRegisterNumber(unsigned RegNo) const {
+ return -1;
+ }
+
+
+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 void getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const = 0;
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const = 0;
+ virtual bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &info) const= 0;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h
new file mode 100644
index 0000000..eeaab15
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h
@@ -0,0 +1,39 @@
+//===--- TargetOptions.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_TARGETOPTIONS_H
+#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// TargetOptions - 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 name of the target ABI to use.
+ std::string ABI;
+
+ /// 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;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TemplateKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/TemplateKinds.h
new file mode 100644
index 0000000..c6ea05b
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TemplateKinds.h
@@ -0,0 +1,39 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TemplateNameKind enum.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_TEMPLATEKINDS_H
+#define LLVM_CLANG_TEMPLATEKINDS_H
+
+namespace clang {
+
+/// \brief Specifies the kind of template name that an identifier refers to.
+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 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/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def
new file mode 100644
index 0000000..b16b828
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def
@@ -0,0 +1,429 @@
+//===--- 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,
+// 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 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 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)
+
+//===----------------------------------------------------------------------===//
+// Language keywords.
+//===----------------------------------------------------------------------===//
+
+// These define members of the tok::* namespace.
+
+TOK(unknown) // Not a token.
+TOK(eof) // End of file.
+TOK(eom) // End of macro (end of line inside a macro).
+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
+
+// 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' L'b'
+
+// C99 6.4.5: String Literals.
+TOK(string_literal) // "foo"
+TOK(wide_string_literal) // L"foo"
+TOK(angle_string_literal)// <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, "@")
+
+// 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
+// KEYCXX - This is a C++ keyword, or a C++-specific keyword in the
+// implementation namespace
+// KEYCXX0X - This is a C++ keyword introduced to C++ in C++0x
+// KEYGNU - This is a keyword if GNU extensions are enabled
+// KEYMS - This is a keyword if Microsoft extensions are enabled
+//
+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(_Bool , KEYNOMS)
+KEYWORD(_Complex , KEYALL)
+KEYWORD(_Imaginary , KEYALL)
+KEYWORD(__func__ , KEYALL)
+
+// C++ 2.11p1: Keywords.
+KEYWORD(asm , KEYCXX|KEYGNU)
+KEYWORD(bool , BOOLSUPPORT|KEYALTIVEC)
+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|KEYALTIVEC)
+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|KEYALTIVEC)
+KEYWORD(try , KEYCXX)
+KEYWORD(typename , KEYCXX)
+KEYWORD(typeid , KEYCXX)
+KEYWORD(using , KEYCXX)
+KEYWORD(virtual , KEYCXX)
+KEYWORD(wchar_t , KEYCXX)
+
+// 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++0x keywords
+KEYWORD(alignof , KEYCXX0X)
+KEYWORD(axiom , KEYCXX0X)
+KEYWORD(char16_t , KEYCXX0X)
+KEYWORD(char32_t , KEYCXX0X)
+KEYWORD(concept , KEYCXX0X)
+KEYWORD(concept_map , KEYCXX0X)
+KEYWORD(constexpr , KEYCXX0X)
+KEYWORD(decltype , KEYCXX0X)
+KEYWORD(late_check , KEYCXX0X)
+KEYWORD(nullptr , KEYCXX0X)
+KEYWORD(requires , KEYCXX0X)
+KEYWORD(static_assert , KEYCXX0X)
+KEYWORD(thread_local , KEYCXX0X)
+
+// 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)
+KEYWORD(__builtin_types_compatible_p, KEYALL)
+KEYWORD(__builtin_va_arg , KEYALL)
+KEYWORD(__extension__ , KEYALL)
+KEYWORD(__imag , KEYALL)
+KEYWORD(__label__ , KEYALL)
+KEYWORD(__real , KEYALL)
+KEYWORD(__thread , KEYALL)
+KEYWORD(__FUNCTION__ , KEYALL)
+KEYWORD(__PRETTY_FUNCTION__ , KEYALL)
+
+// GNU Extensions (outside impl-reserved namespace)
+KEYWORD(typeof , KEYGNU)
+
+// GNU and MS Type Traits
+KEYWORD(__has_nothrow_assign , KEYCXX)
+KEYWORD(__has_nothrow_copy , KEYCXX)
+KEYWORD(__has_nothrow_constructor , KEYCXX)
+KEYWORD(__has_trivial_assign , KEYCXX)
+KEYWORD(__has_trivial_copy , KEYCXX)
+KEYWORD(__has_trivial_constructor , KEYCXX)
+KEYWORD(__has_trivial_destructor , KEYCXX)
+KEYWORD(__has_virtual_destructor , KEYCXX)
+KEYWORD(__is_abstract , KEYCXX)
+KEYWORD(__is_base_of , KEYCXX)
+KEYWORD(__is_class , KEYCXX)
+KEYWORD(__is_empty , KEYCXX)
+KEYWORD(__is_enum , KEYCXX)
+KEYWORD(__is_pod , KEYCXX)
+KEYWORD(__is_polymorphic , KEYCXX)
+KEYWORD(__is_union , KEYCXX)
+// Tentative name - there's no implementation of std::is_literal_type yet.
+KEYWORD(__is_literal , KEYCXX)
+// FIXME: Add MS's traits, too.
+
+// Apple Extension.
+KEYWORD(__private_extern__ , KEYALL)
+
+// Microsoft Extension.
+KEYWORD(__declspec , KEYALL)
+KEYWORD(__cdecl , KEYALL)
+KEYWORD(__stdcall , KEYALL)
+KEYWORD(__fastcall , KEYALL)
+KEYWORD(__thiscall , KEYALL)
+KEYWORD(__forceinline , KEYALL)
+
+// Altivec Extension.
+KEYWORD(__vector , KEYALTIVEC)
+KEYWORD(__pixel , KEYALTIVEC)
+
+// Alternate spelling for various tokens. There are GCC extensions in all
+// languages, but should not be disabled in strict conformance mode.
+ALIAS("__attribute__", __attribute, KEYALL)
+ALIAS("__const" , const , KEYALL)
+ALIAS("__const__" , const , KEYALL)
+ALIAS("__alignof__" , __alignof , KEYALL)
+ALIAS("__asm" , asm , KEYALL)
+ALIAS("__asm__" , asm , KEYALL)
+ALIAS("__complex" , _Complex , KEYALL)
+ALIAS("__complex__" , _Complex , KEYALL)
+ALIAS("__imag__" , __imag , KEYALL)
+ALIAS("__inline" , inline , KEYALL)
+ALIAS("__inline__" , inline , KEYALL)
+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)
+
+// Microsoft extensions which should be disabled in strict conformance mode
+KEYWORD(__ptr64 , KEYMS)
+KEYWORD(__w64 , KEYMS)
+ALIAS("_asm" , asm , KEYMS)
+ALIAS("_cdecl" , __cdecl , KEYMS)
+ALIAS("_fastcall" , __fastcall , KEYMS)
+ALIAS("_stdcall" , __stdcall , KEYMS)
+ALIAS("_thiscall" , __thiscall , KEYMS)
+
+//===----------------------------------------------------------------------===//
+// Objective-C @-preceeded 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)
+
+OBJC2_AT_KEYWORD(property)
+OBJC2_AT_KEYWORD(package)
+OBJC2_AT_KEYWORD(required)
+OBJC2_AT_KEYWORD(optional)
+OBJC2_AT_KEYWORD(synthesize)
+OBJC2_AT_KEYWORD(dynamic)
+
+// 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>"
+#undef ANNOTATION
+#undef OBJC2_AT_KEYWORD
+#undef OBJC1_AT_KEYWORD
+#undef CXX_KEYWORD_OPERATOR
+#undef PPKEYWORD
+#undef ALIAS
+#undef KEYWORD
+#undef PUNCTUATOR
+#undef TOK
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.h
new file mode 100644
index 0000000..85dc067
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.h
@@ -0,0 +1,64 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TokenKind enum and support functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKENKINDS_H
+#define LLVM_CLANG_TOKENKINDS_H
+
+namespace clang {
+
+namespace tok {
+
+/// TokenKind - This provides a simple uniform namespace for tokens from all C
+/// languages.
+enum TokenKind {
+#define TOK(X) X,
+#include "clang/Basic/TokenKinds.def"
+ NUM_TOKENS
+};
+
+/// PPKeywordKind - This 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
+};
+
+/// ObjCKeywordKind - This 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 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(enum TokenKind Kind);
+
+/// \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 *getTokenSimpleSpelling(enum TokenKind Kind);
+
+} // end namespace tok
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h b/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h
new file mode 100644
index 0000000..36b8300
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h
@@ -0,0 +1,41 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines enumerations for the type traits support.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TYPETRAITS_H
+#define LLVM_CLANG_TYPETRAITS_H
+
+namespace clang {
+
+ /// UnaryTypeTrait - Names for the unary type traits.
+ enum UnaryTypeTrait {
+ UTT_HasNothrowAssign,
+ UTT_HasNothrowCopy,
+ UTT_HasNothrowConstructor,
+ UTT_HasTrivialAssign,
+ UTT_HasTrivialCopy,
+ UTT_HasTrivialConstructor,
+ UTT_HasTrivialDestructor,
+ UTT_HasVirtualDestructor,
+ UTT_IsAbstract,
+ UTT_IsClass,
+ UTT_IsEmpty,
+ UTT_IsEnum,
+ UTT_IsPOD,
+ UTT_IsPolymorphic,
+ UTT_IsUnion,
+ UTT_IsLiteral
+ };
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Version.h b/contrib/llvm/tools/clang/include/clang/Basic/Version.h
new file mode 100644
index 0000000..b3b6184
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Version.h
@@ -0,0 +1,71 @@
+//===- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines version macros and version-related utility functions
+// for Clang.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_VERSION_H
+#define LLVM_CLANG_BASIC_VERSION_H
+
+#include "llvm/ADT/StringRef.h"
+
+/// \brief Clang major version
+#define CLANG_VERSION_MAJOR 2
+
+// FIXME: Updates to this file must also update CMakeLists.txt and VER.
+/// \brief Clang minor version
+#define CLANG_VERSION_MINOR 0
+
+/// \brief Clang patchlevel version
+// #define CLANG_VERSION_PATCHLEVEL 1
+
+/// \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.
+ llvm::StringRef getClangRepositoryPath();
+
+ /// \brief Retrieves the repository revision number (or identifer) from which
+ /// this Clang was built.
+ std::string getClangRevision();
+
+ /// \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();
+}
+
+#endif // LLVM_CLANG_BASIC_VERSION_H
diff --git a/contrib/llvm/tools/clang/include/clang/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/CMakeLists.txt
new file mode 100644
index 0000000..c288048
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(AST)
+add_subdirectory(Basic)
+add_subdirectory(Driver)
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/BugReporter.h b/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/BugReporter.h
new file mode 100644
index 0000000..5b65d52
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/BugReporter.h
@@ -0,0 +1,479 @@
+//===--- 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 GRState.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
+#define LLVM_CLANG_ANALYSIS_BUGREPORTER
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/ImmutableSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include <list>
+
+namespace clang {
+
+class PathDiagnostic;
+class PathDiagnosticPiece;
+class PathDiagnosticClient;
+class ASTContext;
+class Diagnostic;
+class ExplodedNode;
+class ExplodedGraph;
+class BugReporter;
+class BugReporterContext;
+class GRExprEngine;
+class GRState;
+class Stmt;
+class BugType;
+class ParentMap;
+
+//===----------------------------------------------------------------------===//
+// Interface for individual bug reports.
+//===----------------------------------------------------------------------===//
+
+class BugReporterVisitor : public llvm::FoldingSetNode {
+public:
+ virtual ~BugReporterVisitor();
+ virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
+ const ExplodedNode* PrevN,
+ BugReporterContext& BRC) = 0;
+
+ virtual bool isOwnedByReporterContext() { return true; }
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
+};
+
+// FIXME: Combine this with RangedBugReport and remove RangedBugReport.
+class BugReport : public BugReporterVisitor {
+protected:
+ BugType& BT;
+ std::string ShortDescription;
+ std::string Description;
+ const ExplodedNode *EndNode;
+ SourceRange R;
+
+protected:
+ friend class BugReporter;
+ friend class BugReportEquivClass;
+
+ virtual void Profile(llvm::FoldingSetNodeID& hash) const {
+ hash.AddInteger(getLocation().getRawEncoding());
+ }
+
+public:
+ class NodeResolver {
+ public:
+ virtual ~NodeResolver() {}
+ virtual const ExplodedNode*
+ getOriginalNode(const ExplodedNode* N) = 0;
+ };
+
+ BugReport(BugType& bt, llvm::StringRef desc, const ExplodedNode *n)
+ : BT(bt), Description(desc), EndNode(n) {}
+
+ BugReport(BugType& bt, llvm::StringRef shortDesc, llvm::StringRef desc,
+ const ExplodedNode *n)
+ : BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
+
+ virtual ~BugReport();
+
+ virtual bool isOwnedByReporterContext() { return false; }
+
+ const BugType& getBugType() const { return BT; }
+ BugType& getBugType() { return BT; }
+
+ // FIXME: Perhaps this should be moved into a subclass?
+ const ExplodedNode* getEndNode() const { return EndNode; }
+
+ // FIXME: Do we need this? Maybe getLocation() should return a ProgramPoint
+ // object.
+ // FIXME: If we do need it, we can probably just make it private to
+ // BugReporter.
+ const Stmt* getStmt() const;
+
+ const llvm::StringRef getDescription() const { return Description; }
+
+ const llvm::StringRef getShortDescription() const {
+ return ShortDescription.empty() ? Description : ShortDescription;
+ }
+
+ // FIXME: Is this needed?
+ virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
+ return std::make_pair((const char**)0,(const char**)0);
+ }
+
+ // FIXME: Perhaps move this into a subclass.
+ virtual PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
+ const ExplodedNode* N);
+
+ /// getLocation - 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 occured.
+ /// This location is used by clients rendering diagnostics.
+ virtual SourceLocation getLocation() const;
+
+ /// getRanges - Returns the source ranges associated with this bug.
+ virtual void getRanges(const SourceRange*& beg, const SourceRange*& end);
+
+ virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
+ const ExplodedNode* PrevN,
+ BugReporterContext& BR);
+
+ virtual void registerInitialVisitors(BugReporterContext& BRC,
+ const ExplodedNode* N) {}
+};
+
+//===----------------------------------------------------------------------===//
+// BugTypes (collections of related reports).
+//===----------------------------------------------------------------------===//
+
+class BugReportEquivClass : public llvm::FoldingSetNode {
+ // List of *owned* BugReport objects.
+ std::list<BugReport*> Reports;
+
+ friend class BugReporter;
+ void AddReport(BugReport* R) { Reports.push_back(R); }
+public:
+ BugReportEquivClass(BugReport* R) { Reports.push_back(R); }
+ ~BugReportEquivClass();
+
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ assert(!Reports.empty());
+ (*Reports.begin())->Profile(ID);
+ }
+
+ class iterator {
+ std::list<BugReport*>::iterator impl;
+ public:
+ iterator(std::list<BugReport*>::iterator i) : impl(i) {}
+ iterator& operator++() { ++impl; return *this; }
+ bool operator==(const iterator& I) const { return I.impl == impl; }
+ bool operator!=(const iterator& I) const { return I.impl != impl; }
+ BugReport* operator*() const { return *impl; }
+ BugReport* operator->() const { return *impl; }
+ };
+
+ class const_iterator {
+ std::list<BugReport*>::const_iterator impl;
+ public:
+ const_iterator(std::list<BugReport*>::const_iterator i) : impl(i) {}
+ const_iterator& operator++() { ++impl; return *this; }
+ bool operator==(const const_iterator& I) const { return I.impl == impl; }
+ bool operator!=(const const_iterator& I) const { return I.impl != impl; }
+ const BugReport* operator*() const { return *impl; }
+ const BugReport* operator->() const { return *impl; }
+ };
+
+ iterator begin() { return iterator(Reports.begin()); }
+ iterator end() { return iterator(Reports.end()); }
+
+ const_iterator begin() const { return const_iterator(Reports.begin()); }
+ const_iterator end() const { return const_iterator(Reports.end()); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Specialized subclasses of BugReport.
+//===----------------------------------------------------------------------===//
+
+// FIXME: Collapse this with the default BugReport class.
+class RangedBugReport : public BugReport {
+ std::vector<SourceRange> Ranges;
+public:
+ RangedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
+ : BugReport(D, description, n) {}
+
+ RangedBugReport(BugType& D, llvm::StringRef shortDescription,
+ llvm::StringRef description, ExplodedNode *n)
+ : BugReport(D, shortDescription, description, n) {}
+
+ ~RangedBugReport();
+
+ // FIXME: Move this out of line.
+ void addRange(SourceRange R) {
+ assert(R.isValid());
+ Ranges.push_back(R);
+ }
+
+ // FIXME: Move this out of line.
+ void getRanges(const SourceRange*& beg, const SourceRange*& end) {
+
+ if (Ranges.empty()) {
+ beg = NULL;
+ end = NULL;
+ }
+ else {
+ beg = &Ranges[0];
+ end = beg + Ranges.size();
+ }
+ }
+};
+
+class EnhancedBugReport : public RangedBugReport {
+public:
+ typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data,
+ const ExplodedNode *N);
+
+private:
+ typedef std::vector<std::pair<VisitorCreator, const void*> > Creators;
+ Creators creators;
+
+public:
+ EnhancedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
+ : RangedBugReport(D, description, n) {}
+
+ EnhancedBugReport(BugType& D, llvm::StringRef shortDescription,
+ llvm::StringRef description, ExplodedNode *n)
+ : RangedBugReport(D, shortDescription, description, n) {}
+
+ ~EnhancedBugReport() {}
+
+ void registerInitialVisitors(BugReporterContext& BRC, const ExplodedNode* N) {
+ for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I)
+ I->first(BRC, I->second, N);
+ }
+
+ void addVisitorCreator(VisitorCreator creator, const void *data) {
+ creators.push_back(std::make_pair(creator, data));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// BugReporter and friends.
+//===----------------------------------------------------------------------===//
+
+class BugReporterData {
+public:
+ virtual ~BugReporterData();
+ virtual Diagnostic& getDiagnostic() = 0;
+ virtual PathDiagnosticClient* getPathDiagnosticClient() = 0;
+ virtual ASTContext& getASTContext() = 0;
+ virtual SourceManager& getSourceManager() = 0;
+};
+
+class BugReporter {
+public:
+ enum Kind { BaseBRKind, GRBugReporterKind };
+
+private:
+ typedef llvm::ImmutableSet<BugType*> BugTypesTy;
+ BugTypesTy::Factory F;
+ BugTypesTy BugTypes;
+
+ const Kind kind;
+ BugReporterData& D;
+
+ void FlushReport(BugReportEquivClass& EQ);
+
+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();
+
+ void FlushReports();
+
+ Kind getKind() const { return kind; }
+
+ Diagnostic& getDiagnostic() {
+ return D.getDiagnostic();
+ }
+
+ PathDiagnosticClient* getPathDiagnosticClient() {
+ return D.getPathDiagnosticClient();
+ }
+
+ typedef BugTypesTy::iterator iterator;
+ iterator begin() { return BugTypes.begin(); }
+ iterator end() { return BugTypes.end(); }
+
+ ASTContext& getContext() { return D.getASTContext(); }
+
+ SourceManager& getSourceManager() { return D.getSourceManager(); }
+
+ virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
+ BugReportEquivClass& EQ) {}
+
+ void Register(BugType *BT);
+
+ void EmitReport(BugReport *R);
+
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
+ SourceLocation Loc,
+ SourceRange* RangeBeg, unsigned NumRanges);
+
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory,
+ llvm::StringRef BugStr, SourceLocation Loc,
+ SourceRange* RangeBeg, unsigned NumRanges);
+
+
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
+ SourceLocation Loc) {
+ EmitBasicReport(BugName, BugStr, Loc, 0, 0);
+ }
+
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory,
+ llvm::StringRef BugStr, SourceLocation Loc) {
+ EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0);
+ }
+
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
+ SourceLocation Loc, SourceRange R) {
+ EmitBasicReport(BugName, BugStr, Loc, &R, 1);
+ }
+
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef Category,
+ llvm::StringRef BugStr, SourceLocation Loc,
+ SourceRange R) {
+ EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1);
+ }
+
+ static bool classof(const BugReporter* R) { return true; }
+};
+
+// FIXME: Get rid of GRBugReporter. It's the wrong abstraction.
+class GRBugReporter : public BugReporter {
+ GRExprEngine& Eng;
+ llvm::SmallSet<SymbolRef, 10> NotableSymbols;
+public:
+ GRBugReporter(BugReporterData& d, GRExprEngine& eng)
+ : BugReporter(d, GRBugReporterKind), Eng(eng) {}
+
+ virtual ~GRBugReporter();
+
+ /// getEngine - Return the analysis engine used to analyze a given
+ /// function or method.
+ GRExprEngine &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.
+ GRStateManager &getStateManager();
+
+ virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
+ BugReportEquivClass& R);
+
+ void addNotableSymbol(SymbolRef Sym) {
+ NotableSymbols.insert(Sym);
+ }
+
+ bool isNotable(SymbolRef Sym) const {
+ return (bool) NotableSymbols.count(Sym);
+ }
+
+ /// classof - Used by isa<>, cast<>, and dyn_cast<>.
+ static bool classof(const BugReporter* R) {
+ return R->getKind() == GRBugReporterKind;
+ }
+};
+
+class BugReporterContext {
+ GRBugReporter &BR;
+ // Not the most efficient data structure, but we use an ImmutableList for the
+ // Callbacks because it is safe to make additions to list during iteration.
+ llvm::ImmutableList<BugReporterVisitor*>::Factory F;
+ llvm::ImmutableList<BugReporterVisitor*> Callbacks;
+ llvm::FoldingSet<BugReporterVisitor> CallbacksSet;
+public:
+ BugReporterContext(GRBugReporter& br) : BR(br), Callbacks(F.GetEmptyList()) {}
+ virtual ~BugReporterContext();
+
+ void addVisitor(BugReporterVisitor* visitor);
+
+ typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator;
+ visitor_iterator visitor_begin() { return Callbacks.begin(); }
+ visitor_iterator visitor_end() { return Callbacks.end(); }
+
+ GRBugReporter& getBugReporter() { return BR; }
+
+ ExplodedGraph &getGraph() { return BR.getGraph(); }
+
+ void addNotableSymbol(SymbolRef Sym) {
+ // FIXME: For now forward to GRBugReporter.
+ BR.addNotableSymbol(Sym);
+ }
+
+ bool isNotable(SymbolRef Sym) const {
+ // FIXME: For now forward to GRBugReporter.
+ return BR.isNotable(Sym);
+ }
+
+ GRStateManager& getStateManager() {
+ return BR.getStateManager();
+ }
+
+ ValueManager& getValueManager() {
+ return getStateManager().getValueManager();
+ }
+
+ ASTContext& getASTContext() {
+ return BR.getContext();
+ }
+
+ SourceManager& getSourceManager() {
+ return BR.getSourceManager();
+ }
+
+ virtual BugReport::NodeResolver& getNodeResolver() = 0;
+};
+
+class DiagBugReport : public RangedBugReport {
+ std::list<std::string> Strs;
+ FullSourceLoc L;
+public:
+ DiagBugReport(BugType& D, llvm::StringRef desc, FullSourceLoc l) :
+ RangedBugReport(D, desc, 0), L(l) {}
+
+ virtual ~DiagBugReport() {}
+
+ // FIXME: Move out-of-line (virtual function).
+ SourceLocation getLocation() const { return L; }
+
+ void addString(llvm::StringRef s) { Strs.push_back(s); }
+
+ typedef std::list<std::string>::const_iterator str_iterator;
+ str_iterator str_begin() const { return Strs.begin(); }
+ str_iterator str_end() const { return Strs.end(); }
+};
+
+//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+
+namespace bugreporter {
+
+const Stmt *GetDerefExpr(const ExplodedNode *N);
+const Stmt *GetDenomExpr(const ExplodedNode *N);
+const Stmt *GetCalleeExpr(const ExplodedNode *N);
+const Stmt *GetRetValExpr(const ExplodedNode *N);
+
+void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt,
+ const ExplodedNode* N);
+
+void registerFindLastStore(BugReporterContext& BRC, const void *memregion,
+ const ExplodedNode *N);
+
+void registerNilReceiverVisitor(BugReporterContext &BRC);
+
+} // end namespace clang::bugreporter
+
+//===----------------------------------------------------------------------===//
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/BugType.h b/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/BugType.h
new file mode 100644
index 0000000..afc07c8
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/BugType.h
@@ -0,0 +1,72 @@
+//===--- 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_ANALYSIS_BUGTYPE
+#define LLVM_CLANG_ANALYSIS_BUGTYPE
+
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <string>
+
+namespace clang {
+
+class ExplodedNode;
+class GRExprEngine;
+
+class BugType {
+private:
+ const std::string Name;
+ const std::string Category;
+ llvm::FoldingSet<BugReportEquivClass> EQClasses;
+ friend class BugReporter;
+ bool SuppressonSink;
+public:
+ BugType(llvm::StringRef name, llvm::StringRef cat)
+ : Name(name), Category(cat), SuppressonSink(false) {}
+ virtual ~BugType();
+
+ // FIXME: Should these be made strings as well?
+ llvm::StringRef getName() const { return Name; }
+ llvm::StringRef getCategory() const { return Category; }
+
+ /// 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);
+
+ typedef llvm::FoldingSet<BugReportEquivClass>::iterator iterator;
+ iterator begin() { return EQClasses.begin(); }
+ iterator end() { return EQClasses.end(); }
+
+ typedef llvm::FoldingSet<BugReportEquivClass>::const_iterator const_iterator;
+ const_iterator begin() const { return EQClasses.begin(); }
+ const_iterator end() const { return EQClasses.end(); }
+};
+
+class BuiltinBug : public BugType {
+ const std::string desc;
+public:
+ BuiltinBug(const char *name, const char *description)
+ : BugType(name, "Logic error"), desc(description) {}
+
+ BuiltinBug(const char *name)
+ : BugType(name, "Logic error"), desc(name) {}
+
+ llvm::StringRef getDescription() const { return desc; }
+};
+
+} // end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/PathDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/PathDiagnostic.h
new file mode 100644
index 0000000..24c75ce
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/BugReporter/PathDiagnostic.h
@@ -0,0 +1,494 @@
+//===--- 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_PATH_DIAGNOSTIC_H
+#define LLVM_CLANG_PATH_DIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <deque>
+#include <iterator>
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class Decl;
+class SourceManager;
+class Stmt;
+
+//===----------------------------------------------------------------------===//
+// High-level interface for handlers of path-sensitive diagnostics.
+//===----------------------------------------------------------------------===//
+
+class PathDiagnostic;
+
+class PathDiagnosticClient : public DiagnosticClient {
+public:
+ PathDiagnosticClient() {}
+
+ virtual ~PathDiagnosticClient() {}
+
+ virtual void
+ FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade = 0) = 0;
+
+ void FlushDiagnostics(llvm::SmallVectorImpl<std::string> &FilesMade) {
+ FlushDiagnostics(&FilesMade);
+ }
+
+ virtual llvm::StringRef getName() const = 0;
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info);
+ virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0;
+
+ enum PathGenerationScheme { Minimal, Extensive };
+ virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
+ virtual bool supportsLogicalOpControlFlow() const { return false; }
+ virtual bool supportsAllBlockEdges() const { return false; }
+ virtual bool useVerboseDescription() const { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Path-sensitive diagnostics.
+//===----------------------------------------------------------------------===//
+
+class PathDiagnosticRange : public SourceRange {
+public:
+ const bool isPoint;
+
+ PathDiagnosticRange(const SourceRange &R, bool isP = false)
+ : SourceRange(R), isPoint(isP) {}
+};
+
+class PathDiagnosticLocation {
+private:
+ enum Kind { RangeK, SingleLocK, StmtK, DeclK } K;
+ SourceRange R;
+ const Stmt *S;
+ const Decl *D;
+ const SourceManager *SM;
+public:
+ PathDiagnosticLocation()
+ : K(SingleLocK), S(0), D(0), SM(0) {}
+
+ PathDiagnosticLocation(FullSourceLoc L)
+ : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()) {}
+
+ PathDiagnosticLocation(const Stmt *s, const SourceManager &sm)
+ : K(StmtK), S(s), D(0), SM(&sm) {}
+
+ PathDiagnosticLocation(SourceRange r, const SourceManager &sm)
+ : K(RangeK), R(r), S(0), D(0), SM(&sm) {}
+
+ PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
+ : K(DeclK), S(0), D(d), SM(&sm) {}
+
+ bool operator==(const PathDiagnosticLocation &X) const {
+ return K == X.K && R == X.R && S == X.S && D == X.D;
+ }
+
+ bool operator!=(const PathDiagnosticLocation &X) const {
+ return K != X.K || R != X.R || S != X.S || D != X.D;;
+ }
+
+ PathDiagnosticLocation& operator=(const PathDiagnosticLocation &X) {
+ K = X.K;
+ R = X.R;
+ S = X.S;
+ D = X.D;
+ SM = X.SM;
+ return *this;
+ }
+
+ bool isValid() const {
+ return SM != 0;
+ }
+
+ const SourceManager& getSourceManager() const { assert(isValid());return *SM;}
+
+ FullSourceLoc asLocation() const;
+ PathDiagnosticRange asRange() const;
+ 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;
+};
+
+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 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:
+ enum Kind { ControlFlow, Event, Macro };
+ enum DisplayHint { Above, Below };
+
+private:
+ const std::string str;
+ std::vector<FixItHint> FixItHints;
+ const Kind kind;
+ const DisplayHint Hint;
+ std::vector<SourceRange> ranges;
+
+ // Do not implement:
+ PathDiagnosticPiece();
+ PathDiagnosticPiece(const PathDiagnosticPiece &P);
+ PathDiagnosticPiece& operator=(const PathDiagnosticPiece &P);
+
+protected:
+ PathDiagnosticPiece(llvm::StringRef s, Kind k, DisplayHint hint = Below);
+
+ PathDiagnosticPiece(Kind k, DisplayHint hint = Below);
+
+public:
+ virtual ~PathDiagnosticPiece();
+
+ const std::string& getString() const { return str; }
+
+ /// getDisplayHint - Return a hint indicating where the diagnostic should
+ /// be displayed by the PathDiagnosticClient.
+ DisplayHint getDisplayHint() const { return Hint; }
+
+ virtual PathDiagnosticLocation getLocation() const = 0;
+ virtual void flattenLocations() = 0;
+
+ Kind getKind() const { return kind; }
+
+ void addRange(SourceRange R) { ranges.push_back(R); }
+
+ void addRange(SourceLocation B, SourceLocation E) {
+ ranges.push_back(SourceRange(B,E));
+ }
+
+ void addFixItHint(const FixItHint& Hint) {
+ FixItHints.push_back(Hint);
+ }
+
+ typedef const SourceRange* range_iterator;
+
+ range_iterator ranges_begin() const {
+ return ranges.empty() ? NULL : &ranges[0];
+ }
+
+ range_iterator ranges_end() const {
+ return ranges_begin() + ranges.size();
+ }
+
+ typedef const FixItHint *fixit_iterator;
+
+ fixit_iterator fixit_begin() const {
+ return FixItHints.empty()? 0 : &FixItHints[0];
+ }
+
+ fixit_iterator fixit_end() const {
+ return FixItHints.empty()? 0
+ : &FixItHints[0] + FixItHints.size();
+ }
+
+ static inline bool classof(const PathDiagnosticPiece* P) {
+ return true;
+ }
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
+private:
+ PathDiagnosticLocation Pos;
+public:
+ PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos,
+ llvm::StringRef s,
+ PathDiagnosticPiece::Kind k,
+ bool addPosRange = true)
+ : PathDiagnosticPiece(s, k), Pos(pos) {
+ assert(Pos.asLocation().isValid() &&
+ "PathDiagnosticSpotPiece's must have a valid location.");
+ if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
+ }
+
+ PathDiagnosticLocation getLocation() const { return Pos; }
+ virtual void flattenLocations() { Pos.flatten(); }
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
+
+public:
+ PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
+ llvm::StringRef s, bool addPosRange = true)
+ : PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {}
+
+ ~PathDiagnosticEventPiece();
+
+ static inline bool classof(const PathDiagnosticPiece* P) {
+ return P->getKind() == Event;
+ }
+};
+
+class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece {
+ std::vector<PathDiagnosticLocationPair> LPairs;
+public:
+ PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
+ const PathDiagnosticLocation &endPos,
+ llvm::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();
+
+ 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 push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
+
+ virtual PathDiagnosticLocation getLocation() const {
+ return getStartLocation();
+ }
+
+ typedef std::vector<PathDiagnosticLocationPair>::iterator iterator;
+ iterator begin() { return LPairs.begin(); }
+ iterator end() { return LPairs.end(); }
+
+ virtual void flattenLocations() {
+ 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;
+ }
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
+ std::vector<PathDiagnosticPiece*> SubPieces;
+public:
+ PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
+ : PathDiagnosticSpotPiece(pos, "", Macro) {}
+
+ ~PathDiagnosticMacroPiece();
+
+ bool containsEvent() const;
+
+ void push_back(PathDiagnosticPiece* P) { SubPieces.push_back(P); }
+
+ typedef std::vector<PathDiagnosticPiece*>::iterator iterator;
+ iterator begin() { return SubPieces.begin(); }
+ iterator end() { return SubPieces.end(); }
+
+ virtual void flattenLocations() {
+ PathDiagnosticSpotPiece::flattenLocations();
+ for (iterator I=begin(), E=end(); I!=E; ++I) (*I)->flattenLocations();
+ }
+
+ typedef std::vector<PathDiagnosticPiece*>::const_iterator const_iterator;
+ const_iterator begin() const { return SubPieces.begin(); }
+ const_iterator end() const { return SubPieces.end(); }
+
+ static inline bool classof(const PathDiagnosticPiece* P) {
+ return P->getKind() == Macro;
+ }
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+
+/// 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::deque<PathDiagnosticPiece*> path;
+ unsigned Size;
+ std::string BugType;
+ std::string Desc;
+ std::string Category;
+ std::deque<std::string> OtherDesc;
+
+public:
+ PathDiagnostic();
+
+ PathDiagnostic(llvm::StringRef bugtype, llvm::StringRef desc,
+ llvm::StringRef category);
+
+ ~PathDiagnostic();
+
+ llvm::StringRef getDescription() const { return Desc; }
+ llvm::StringRef getBugType() const { return BugType; }
+ llvm::StringRef getCategory() const { return Category; }
+
+ 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(llvm::StringRef s) { OtherDesc.push_back(s); }
+
+ PathDiagnosticLocation getLocation() const {
+ assert(Size > 0 && "getLocation() requires a non-empty PathDiagnostic.");
+ return rbegin()->getLocation();
+ }
+
+ void push_front(PathDiagnosticPiece* piece) {
+ assert(piece);
+ path.push_front(piece);
+ ++Size;
+ }
+
+ void push_back(PathDiagnosticPiece* piece) {
+ assert(piece);
+ path.push_back(piece);
+ ++Size;
+ }
+
+ PathDiagnosticPiece* back() {
+ return path.back();
+ }
+
+ const PathDiagnosticPiece* back() const {
+ return path.back();
+ }
+
+ unsigned size() const { return Size; }
+ bool empty() const { return Size == 0; }
+
+ void resetPath(bool deletePieces = true);
+
+ class iterator {
+ public:
+ typedef std::deque<PathDiagnosticPiece*>::iterator ImplTy;
+
+ typedef PathDiagnosticPiece value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
+ typedef ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ private:
+ ImplTy I;
+
+ public:
+ iterator(const ImplTy& i) : I(i) {}
+
+ bool operator==(const iterator& X) const { return I == X.I; }
+ bool operator!=(const iterator& X) const { return I != X.I; }
+
+ PathDiagnosticPiece& operator*() const { return **I; }
+ PathDiagnosticPiece* operator->() const { return *I; }
+
+ iterator& operator++() { ++I; return *this; }
+ iterator& operator--() { --I; return *this; }
+ };
+
+ class const_iterator {
+ public:
+ typedef std::deque<PathDiagnosticPiece*>::const_iterator ImplTy;
+
+ typedef const PathDiagnosticPiece value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
+ typedef ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ private:
+ ImplTy I;
+
+ public:
+ const_iterator(const ImplTy& i) : I(i) {}
+
+ bool operator==(const const_iterator& X) const { return I == X.I; }
+ bool operator!=(const const_iterator& X) const { return I != X.I; }
+
+ reference operator*() const { return **I; }
+ pointer operator->() const { return *I; }
+
+ const_iterator& operator++() { ++I; return *this; }
+ const_iterator& operator--() { --I; return *this; }
+ };
+
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ // forward iterator creation methods.
+
+ iterator begin() { return path.begin(); }
+ iterator end() { return path.end(); }
+
+ const_iterator begin() const { return path.begin(); }
+ const_iterator end() const { return path.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());}
+
+ void flattenLocations() {
+ for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations();
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+};
+} //end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/Checkers/DereferenceChecker.h b/contrib/llvm/tools/clang/include/clang/Checker/Checkers/DereferenceChecker.h
new file mode 100644
index 0000000..a84183e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/Checkers/DereferenceChecker.h
@@ -0,0 +1,31 @@
+//== NullDerefChecker.h - Null dereference checker --------------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines NullDerefChecker and UndefDerefChecker, two builtin checks
+// in GRExprEngine that check for null and undefined pointers at loads
+// and stores.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DEREFCHECKER
+#define LLVM_CLANG_DEREFCHECKER
+
+#include <utility>
+
+namespace clang {
+
+class GRExprEngine;
+class ExplodedNode;
+
+std::pair<ExplodedNode * const *, ExplodedNode * const *>
+GetImplicitNullDereferences(GRExprEngine &Eng);
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/Checkers/LocalCheckers.h b/contrib/llvm/tools/clang/include/clang/Checker/Checkers/LocalCheckers.h
new file mode 100644
index 0000000..4a9e381
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/Checkers/LocalCheckers.h
@@ -0,0 +1,61 @@
+//==- 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_ANALYSIS_LOCALCHECKERS_H
+#define LLVM_CLANG_ANALYSIS_LOCALCHECKERS_H
+
+namespace clang {
+
+class CFG;
+class Decl;
+class Diagnostic;
+class ASTContext;
+class PathDiagnosticClient;
+class GRTransferFuncs;
+class BugType;
+class LangOptions;
+class ParentMap;
+class LiveVariables;
+class BugReporter;
+class ObjCImplementationDecl;
+class LangOptions;
+class GRExprEngine;
+class TranslationUnitDecl;
+
+void CheckDeadStores(CFG &cfg, LiveVariables &L, ParentMap &map,
+ BugReporter& BR);
+
+GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
+ const LangOptions& lopts);
+
+void CheckObjCDealloc(const ObjCImplementationDecl* D, const LangOptions& L,
+ BugReporter& BR);
+
+void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID,
+ BugReporter& BR);
+
+void CheckObjCUnusedIvar(const ObjCImplementationDecl *D, BugReporter& BR);
+
+void RegisterAppleChecks(GRExprEngine& Eng, const Decl &D);
+void RegisterExperimentalChecks(GRExprEngine &Eng);
+void RegisterExperimentalInternalChecks(GRExprEngine &Eng);
+
+void CheckLLVMConventions(TranslationUnitDecl &TU, BugReporter &BR);
+void CheckSecuritySyntaxOnly(const Decl *D, BugReporter &BR);
+void CheckSizeofPointer(const Decl *D, BugReporter &BR);
+
+void RegisterCallInliner(GRExprEngine &Eng);
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/DomainSpecific/CocoaConventions.h b/contrib/llvm/tools/clang/include/clang/Checker/DomainSpecific/CocoaConventions.h
new file mode 100644
index 0000000..4bbdab0
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/DomainSpecific/CocoaConventions.h
@@ -0,0 +1,39 @@
+//===- 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 defines
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_DS_COCOA
+#define LLVM_CLANG_CHECKER_DS_COCOA
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+namespace cocoa {
+
+ enum NamingConvention { NoConvention, CreateRule, InitRule };
+
+ NamingConvention deriveNamingConvention(Selector S);
+
+ static inline bool followsFundamentalRule(Selector S) {
+ return deriveNamingConvention(S) == CreateRule;
+ }
+
+ bool isRefType(QualType RetTy, llvm::StringRef Prefix,
+ llvm::StringRef Name = llvm::StringRef());
+
+ bool isCFObjectRef(QualType T);
+
+ bool isCocoaObjectRef(QualType T);
+
+}}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/ManagerRegistry.h b/contrib/llvm/tools/clang/include/clang/Checker/ManagerRegistry.h
new file mode 100644
index 0000000..ebfd28e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/ManagerRegistry.h
@@ -0,0 +1,53 @@
+//===-- ManagerRegistry.h - Pluggable analyzer module registry --*- 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 ManagerRegistry and Register* classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
+#define LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
+
+#include "clang/Checker/PathSensitive/GRState.h"
+
+namespace clang {
+
+/// ManagerRegistry - This class records manager creators registered at
+/// runtime. The information is communicated to AnalysisManager through static
+/// members. Better design is expected.
+
+class ManagerRegistry {
+public:
+ static StoreManagerCreator StoreMgrCreator;
+ static ConstraintManagerCreator ConstraintMgrCreator;
+};
+
+/// RegisterConstraintManager - This class is used to setup the constraint
+/// manager of the static analyzer. The constructor takes a creator function
+/// pointer for creating the constraint manager.
+///
+/// It is used like this:
+///
+/// class MyConstraintManager {};
+/// ConstraintManager* CreateMyConstraintManager(GRStateManager& statemgr) {
+/// return new MyConstraintManager(statemgr);
+/// }
+/// RegisterConstraintManager X(CreateMyConstraintManager);
+
+class RegisterConstraintManager {
+public:
+ RegisterConstraintManager(ConstraintManagerCreator CMC) {
+ assert(ManagerRegistry::ConstraintMgrCreator == 0
+ && "ConstraintMgrCreator already set!");
+ ManagerRegistry::ConstraintMgrCreator = CMC;
+ }
+};
+
+}
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/AnalysisManager.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/AnalysisManager.h
new file mode 100644
index 0000000..3c7cb68
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/AnalysisManager.h
@@ -0,0 +1,164 @@
+//== 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_ANALYSIS_ANALYSISMANAGER_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+
+namespace clang {
+
+class AnalysisManager : public BugReporterData {
+ AnalysisContextManager AnaCtxMgr;
+ LocationContextManager LocCtxMgr;
+
+ ASTContext &Ctx;
+ Diagnostic &Diags;
+ const LangOptions &LangInfo;
+
+ llvm::OwningPtr<PathDiagnosticClient> PD;
+
+ // Configurable components creators.
+ StoreManagerCreator CreateStoreMgr;
+ ConstraintManagerCreator CreateConstraintMgr;
+
+ enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
+
+ // The maximum number of exploded nodes the analyzer will generate.
+ unsigned MaxNodes;
+
+ // The maximum number of times the analyzer will go through a loop.
+ unsigned MaxLoop;
+
+ bool VisualizeEGDot;
+ bool VisualizeEGUbi;
+ bool PurgeDead;
+
+ /// EargerlyAssume - A flag indicating 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.
+ bool EagerlyAssume;
+ bool TrimGraph;
+ bool InlineCall;
+
+public:
+ AnalysisManager(ASTContext &ctx, Diagnostic &diags,
+ const LangOptions &lang, PathDiagnosticClient *pd,
+ StoreManagerCreator storemgr,
+ ConstraintManagerCreator constraintmgr, unsigned maxnodes,
+ unsigned maxloop,
+ bool vizdot, bool vizubi, bool purge, bool eager, bool trim,
+ bool inlinecall)
+
+ : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
+ CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
+ AScope(ScopeDecl), MaxNodes(maxnodes), MaxLoop(maxloop),
+ VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
+ EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {}
+
+ ~AnalysisManager() { FlushDiagnostics(); }
+
+ void ClearContexts() {
+ LocCtxMgr.clear();
+ AnaCtxMgr.clear();
+ }
+
+ StoreManagerCreator getStoreManagerCreator() {
+ return CreateStoreMgr;
+ }
+
+ ConstraintManagerCreator getConstraintManagerCreator() {
+ return CreateConstraintMgr;
+ }
+
+ virtual ASTContext &getASTContext() {
+ return Ctx;
+ }
+
+ virtual SourceManager &getSourceManager() {
+ return getASTContext().getSourceManager();
+ }
+
+ virtual Diagnostic &getDiagnostic() {
+ return Diags;
+ }
+
+ const LangOptions &getLangOptions() const {
+ return LangInfo;
+ }
+
+ virtual PathDiagnosticClient *getPathDiagnosticClient() {
+ return PD.get();
+ }
+
+ void FlushDiagnostics() {
+ if (PD.get())
+ PD->FlushDiagnostics();
+ }
+
+ unsigned getMaxNodes() const { return MaxNodes; }
+
+ unsigned getMaxLoop() const { return MaxLoop; }
+
+ bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
+
+ bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
+
+ bool shouldVisualize() const {
+ return VisualizeEGDot || VisualizeEGUbi;
+ }
+
+ bool shouldTrimGraph() const { return TrimGraph; }
+
+ bool shouldPurgeDead() const { return PurgeDead; }
+
+ bool shouldEagerlyAssume() const { return EagerlyAssume; }
+
+ bool shouldInlineCall() const { return InlineCall; }
+
+ CFG *getCFG(Decl const *D) {
+ return AnaCtxMgr.getContext(D)->getCFG();
+ }
+
+ LiveVariables *getLiveVariables(Decl const *D) {
+ return AnaCtxMgr.getContext(D)->getLiveVariables();
+ }
+
+ ParentMap &getParentMap(Decl const *D) {
+ return AnaCtxMgr.getContext(D)->getParentMap();
+ }
+
+ // Get the top level stack frame.
+ const StackFrameContext *getStackFrame(Decl const *D) {
+ return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0, 0, 0);
+ }
+
+ // Get a stack frame with parent.
+ StackFrameContext const *getStackFrame(Decl const *D,
+ LocationContext const *Parent,
+ Stmt const *S, const CFGBlock *Blk,
+ unsigned Idx) {
+ return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S, Blk,Idx);
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/BasicValueFactory.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/BasicValueFactory.h
new file mode 100644
index 0000000..59dd919
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/BasicValueFactory.h
@@ -0,0 +1,197 @@
+//=== 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 GRExprEngine
+// and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
+#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
+
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/AST/ASTContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ImmutableList.h"
+
+namespace clang {
+
+ class GRState;
+
+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 {
+ const void *store;
+ const TypedRegion *region;
+public:
+ LazyCompoundValData(const void *st, const TypedRegion *r)
+ : store(st), region(r) {}
+
+ const void *getStore() const { return store; }
+ const TypedRegion *getRegion() const { return region; }
+
+ static void Profile(llvm::FoldingSetNodeID& ID, const void *store,
+ const TypedRegion *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;
+
+public:
+ BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
+ : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0),
+ 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, unsigned BitWidth, bool isUnsigned);
+ const llvm::APSInt& getValue(uint64_t X, QualType T);
+
+ /// 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) {
+
+ if (To.isUnsigned() == From.isUnsigned() &&
+ To.getBitWidth() == From.getBitWidth())
+ return From;
+
+ return getValue(From.getSExtValue(), To.getBitWidth(), To.isUnsigned());
+ }
+
+ const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
+ assert(T->isIntegerType() || Loc::IsLocType(T));
+ unsigned bitwidth = Ctx.getTypeSize(T);
+ bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+
+ if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth())
+ return From;
+
+ return getValue(From.getSExtValue(), bitwidth, isUnsigned);
+ }
+
+ const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) {
+ QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
+ return getValue(X, T);
+ }
+
+ inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) {
+ return getValue(llvm::APSInt::getMaxValue(v.getBitWidth(), v.isUnsigned()));
+ }
+
+ inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) {
+ return getValue(llvm::APSInt::getMinValue(v.getBitWidth(), v.isUnsigned()));
+ }
+
+ inline const llvm::APSInt& getMaxValue(QualType T) {
+ assert(T->isIntegerType() || Loc::IsLocType(T));
+ bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+ return getValue(llvm::APSInt::getMaxValue(Ctx.getTypeSize(T), isUnsigned));
+ }
+
+ inline const llvm::APSInt& getMinValue(QualType T) {
+ assert(T->isIntegerType() || Loc::IsLocType(T));
+ bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+ return getValue(llvm::APSInt::getMinValue(Ctx.getTypeSize(T), isUnsigned));
+ }
+
+ 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.IntTy);
+ }
+
+ const CompoundValData *getCompoundValData(QualType T,
+ llvm::ImmutableList<SVal> Vals);
+
+ const LazyCompoundValData *getLazyCompoundValData(const void *store,
+ const TypedRegion *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* EvaluateAPSInt(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 clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Checker.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Checker.h
new file mode 100644
index 0000000..8cb9cc8
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Checker.h
@@ -0,0 +1,285 @@
+//== Checker.h - Abstract interface 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 and CheckerVisitor, classes used for creating
+// domain-specific checks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CHECKER
+#define LLVM_CLANG_ANALYSIS_CHECKER
+
+#include "clang/Analysis/Support/SaveAndRestore.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+
+//===----------------------------------------------------------------------===//
+// Checker interface.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+
+class CheckerContext {
+ ExplodedNodeSet &Dst;
+ GRStmtNodeBuilder &B;
+ GRExprEngine &Eng;
+ ExplodedNode *Pred;
+ SaveAndRestore<bool> OldSink;
+ SaveAndRestore<const void*> OldTag;
+ SaveAndRestore<ProgramPoint::Kind> OldPointKind;
+ SaveOr OldHasGen;
+ const GRState *ST;
+ const Stmt *statement;
+ const unsigned size;
+ bool DoneEvaluating; // FIXME: This is not a permanent API change.
+public:
+ CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
+ GRExprEngine &eng, ExplodedNode *pred,
+ const void *tag, ProgramPoint::Kind K,
+ const Stmt *stmt = 0, const GRState *st = 0)
+ : Dst(dst), B(builder), Eng(eng), Pred(pred),
+ OldSink(B.BuildSinks),
+ OldTag(B.Tag, tag),
+ OldPointKind(B.PointKind, K),
+ OldHasGen(B.HasGeneratedNode),
+ ST(st), statement(stmt), size(Dst.size()) {}
+
+ ~CheckerContext();
+
+ GRExprEngine &getEngine() {
+ return Eng;
+ }
+
+ AnalysisManager &getAnalysisManager() {
+ return Eng.getAnalysisManager();
+ }
+
+ ConstraintManager &getConstraintManager() {
+ return Eng.getConstraintManager();
+ }
+
+ StoreManager &getStoreManager() {
+ return Eng.getStoreManager();
+ }
+
+ ExplodedNodeSet &getNodeSet() { return Dst; }
+ GRStmtNodeBuilder &getNodeBuilder() { return B; }
+ ExplodedNode *&getPredecessor() { return Pred; }
+ const GRState *getState() { return ST ? ST : B.GetState(Pred); }
+
+ ASTContext &getASTContext() {
+ return Eng.getContext();
+ }
+
+ BugReporter &getBugReporter() {
+ return Eng.getBugReporter();
+ }
+
+ SourceManager &getSourceManager() {
+ return getBugReporter().getSourceManager();
+ }
+
+ ValueManager &getValueManager() {
+ return Eng.getValueManager();
+ }
+
+ SValuator &getSValuator() {
+ return Eng.getSValuator();
+ }
+
+ ExplodedNode *GenerateNode(bool autoTransition = true) {
+ assert(statement && "Only transitions with statements currently supported");
+ ExplodedNode *N = GenerateNodeImpl(statement, getState(), false);
+ if (N && autoTransition)
+ Dst.Add(N);
+ return N;
+ }
+
+ ExplodedNode *GenerateNode(const Stmt *stmt, const GRState *state,
+ bool autoTransition = true) {
+ assert(state);
+ ExplodedNode *N = GenerateNodeImpl(stmt, state, false);
+ if (N && autoTransition)
+ addTransition(N);
+ return N;
+ }
+
+ ExplodedNode *GenerateNode(const GRState *state, ExplodedNode *pred,
+ bool autoTransition = true) {
+ assert(statement && "Only transitions with statements currently supported");
+ ExplodedNode *N = GenerateNodeImpl(statement, state, pred, false);
+ if (N && autoTransition)
+ addTransition(N);
+ return N;
+ }
+
+ ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) {
+ assert(statement && "Only transitions with statements currently supported");
+ ExplodedNode *N = GenerateNodeImpl(statement, state, false);
+ if (N && autoTransition)
+ addTransition(N);
+ return N;
+ }
+
+ ExplodedNode *GenerateSink(const Stmt *stmt, const GRState *state = 0) {
+ return GenerateNodeImpl(stmt, state ? state : getState(), true);
+ }
+
+ ExplodedNode *GenerateSink(const GRState *state = 0) {
+ assert(statement && "Only transitions with statements currently supported");
+ return GenerateNodeImpl(statement, state ? state : getState(), true);
+ }
+
+ void addTransition(ExplodedNode *node) {
+ Dst.Add(node);
+ }
+
+ void addTransition(const GRState *state) {
+ assert(state);
+ // If the 'state' is not new, we need to check if the cached state 'ST'
+ // is new.
+ if (state != getState() || (ST && ST != B.GetState(Pred)))
+ GenerateNode(state, true);
+ else
+ Dst.Add(Pred);
+ }
+
+ // Generate a node with a new program point different from the one that will
+ // be created by the GRStmtNodeBuilder.
+ void addTransition(const GRState *state, ProgramPoint Loc) {
+ ExplodedNode *N = B.generateNode(Loc, state, Pred);
+ if (N)
+ addTransition(N);
+ }
+
+ void EmitReport(BugReport *R) {
+ Eng.getBugReporter().EmitReport(R);
+ }
+
+private:
+ ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
+ bool markAsSink) {
+ ExplodedNode *node = B.generateNode(stmt, state, Pred);
+ if (markAsSink && node)
+ node->markAsSink();
+ return node;
+ }
+
+ ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
+ ExplodedNode *pred, bool markAsSink) {
+ ExplodedNode *node = B.generateNode(stmt, state, pred);
+ if (markAsSink && node)
+ node->markAsSink();
+ return node;
+ }
+};
+
+class Checker {
+private:
+ friend class GRExprEngine;
+
+ // FIXME: Remove the 'tag' option.
+ void GR_Visit(ExplodedNodeSet &Dst,
+ GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng,
+ const Stmt *S,
+ ExplodedNode *Pred, void *tag, bool isPrevisit) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind, S);
+ if (isPrevisit)
+ _PreVisit(C, S);
+ else
+ _PostVisit(C, S);
+ }
+
+ bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const ObjCMessageExpr *ME,
+ ExplodedNode *Pred, const GRState *state, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
+ ME, state);
+ return EvalNilReceiver(C, ME);
+ }
+
+ bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const CallExpr *CE,
+ ExplodedNode *Pred, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
+ CE);
+ return EvalCallExpr(C, CE);
+ }
+
+ // FIXME: Remove the 'tag' option.
+ void GR_VisitBind(ExplodedNodeSet &Dst,
+ GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
+ const Stmt *AssignE,
+ const Stmt *StoreE, ExplodedNode *Pred, void *tag,
+ SVal location, SVal val,
+ bool isPrevisit) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind, StoreE);
+ assert(isPrevisit && "Only previsit supported for now.");
+ PreVisitBind(C, AssignE, StoreE, location, val);
+ }
+
+ // FIXME: Remove the 'tag' option.
+ void GR_VisitLocation(ExplodedNodeSet &Dst,
+ GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng,
+ const Stmt *S,
+ ExplodedNode *Pred, const GRState *state,
+ SVal location,
+ void *tag, bool isLoad) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isLoad ? ProgramPoint::PreLoadKind :
+ ProgramPoint::PreStoreKind, S, state);
+ VisitLocation(C, S, location);
+ }
+
+ void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
+ SymbolReaper &SymReaper, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ ProgramPoint::PostPurgeDeadSymbolsKind, S);
+ EvalDeadSymbols(C, S, SymReaper);
+ }
+
+public:
+ virtual ~Checker();
+ virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
+ virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
+ virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
+ virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
+ const Stmt *StoreE, SVal location, SVal val) {}
+ virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
+ SymbolReaper &SymReaper) {}
+ virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
+ GRExprEngine &Eng) {}
+
+ virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
+ GRExprEngine &Eng,
+ Stmt *Condition, void *tag) {}
+
+ virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
+ return false;
+ }
+
+ virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
+ return false;
+ }
+
+ virtual const GRState *EvalAssume(const GRState *state, SVal Cond,
+ bool Assumption) {
+ return state;
+ }
+};
+} // end clang namespace
+
+#endif
+
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/CheckerVisitor.def b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/CheckerVisitor.def
new file mode 100644
index 0000000..2edc4a3
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/CheckerVisitor.def
@@ -0,0 +1,37 @@
+//===-- CheckerVisitor.def - Metadata for CheckerVisitor ----------------*-===//
+//
+// 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 nodes accepted by the CheckerVisitor class.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef PREVISIT
+#define PREVISIT(NODE, FALLBACK)
+#endif
+
+#ifndef POSTVISIT
+#define POSTVISIT(NODE, FALLBACK)
+#endif
+
+PREVISIT(ArraySubscriptExpr, Stmt)
+PREVISIT(BinaryOperator, Stmt)
+PREVISIT(CallExpr, Stmt)
+PREVISIT(CXXOperatorCallExpr, CallExpr)
+PREVISIT(DeclStmt, Stmt)
+PREVISIT(ObjCMessageExpr, Stmt)
+PREVISIT(ReturnStmt, Stmt)
+
+POSTVISIT(BlockExpr, Stmt)
+POSTVISIT(BinaryOperator, Stmt)
+POSTVISIT(CallExpr, Stmt)
+POSTVISIT(CXXOperatorCallExpr, CallExpr)
+POSTVISIT(ObjCMessageExpr, Stmt)
+
+#undef PREVISIT
+#undef POSTVISIT
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/CheckerVisitor.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/CheckerVisitor.h
new file mode 100644
index 0000000..72f0ae1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/CheckerVisitor.h
@@ -0,0 +1,102 @@
+//== CheckerVisitor.h - Abstract visitor 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_ANALYSIS_CHECKERVISITOR
+#define LLVM_CLANG_ANALYSIS_CHECKERVISITOR
+#include "clang/Checker/PathSensitive/Checker.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// Checker visitor interface. Used by subclasses of Checker to specify their
+// own checker visitor logic.
+//===----------------------------------------------------------------------===//
+
+/// CheckerVisitor - This class implements a simple visitor for Stmt subclasses.
+/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
+template<typename ImplClass>
+class CheckerVisitor : public Checker {
+public:
+ virtual void _PreVisit(CheckerContext &C, const Stmt *S) {
+ PreVisit(C, S);
+ }
+
+ virtual void _PostVisit(CheckerContext &C, const Stmt *S) {
+ PostVisit(C, S);
+ }
+
+ void PreVisit(CheckerContext &C, const Stmt *S) {
+ switch (S->getStmtClass()) {
+ default:
+ assert(false && "Unsupport statement.");
+ return;
+
+ case Stmt::ImplicitCastExprClass:
+ case Stmt::CStyleCastExprClass:
+ static_cast<ImplClass*>(this)->PreVisitCastExpr(C,
+ static_cast<const CastExpr*>(S));
+ break;
+
+ case Stmt::CompoundAssignOperatorClass:
+ static_cast<ImplClass*>(this)->PreVisitBinaryOperator(C,
+ static_cast<const BinaryOperator*>(S));
+ break;
+
+#define PREVISIT(NAME, FALLBACK) \
+case Stmt::NAME ## Class:\
+static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
+break;
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
+ }
+ }
+
+ void PostVisit(CheckerContext &C, const Stmt *S) {
+ switch (S->getStmtClass()) {
+ default:
+ assert(false && "Unsupport statement.");
+ return;
+ case Stmt::CompoundAssignOperatorClass:
+ static_cast<ImplClass*>(this)->PostVisitBinaryOperator(C,
+ static_cast<const BinaryOperator*>(S));
+ break;
+
+#define POSTVISIT(NAME, FALLBACK) \
+case Stmt::NAME ## Class:\
+static_cast<ImplClass*>(this)->\
+PostVisit ## NAME(C,static_cast<const NAME*>(S));\
+break;
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
+ }
+ }
+
+ void PreVisitStmt(CheckerContext &C, const Stmt *S) {}
+ void PostVisitStmt(CheckerContext &C, const Stmt *S) {}
+
+ void PreVisitCastExpr(CheckerContext &C, const CastExpr *E) {
+ static_cast<ImplClass*>(this)->PreVisitStmt(C, E);
+ }
+
+#define PREVISIT(NAME, FALLBACK) \
+void PreVisit ## NAME(CheckerContext &C, const NAME* S) {\
+ static_cast<ImplClass*>(this)->PreVisit ## FALLBACK(C, S);\
+}
+#define POSTVISIT(NAME, FALLBACK) \
+void PostVisit ## NAME(CheckerContext &C, const NAME* S) {\
+ static_cast<ImplClass*>(this)->PostVisit ## FALLBACK(C, S);\
+}
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
+};
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ConstraintManager.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ConstraintManager.h
new file mode 100644
index 0000000..ce7d1b3
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ConstraintManager.h
@@ -0,0 +1,75 @@
+//== 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_ANALYSIS_CONSTRAINT_MANAGER_H
+#define LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
+
+// FIXME: Typedef LiveSymbolsTy/DeadSymbolsTy at a more appropriate place.
+#include "clang/Checker/PathSensitive/Store.h"
+
+namespace llvm {
+class APSInt;
+}
+
+namespace clang {
+
+class GRState;
+class GRStateManager;
+class GRSubEngine;
+class SVal;
+
+class ConstraintManager {
+public:
+ virtual ~ConstraintManager();
+ virtual const GRState *Assume(const GRState *state, DefinedSVal Cond,
+ bool Assumption) = 0;
+
+ virtual const GRState *AssumeInBound(const GRState *state, DefinedSVal Idx,
+ DefinedSVal UpperBound, bool Assumption) = 0;
+
+ std::pair<const GRState*, const GRState*> AssumeDual(const GRState *state,
+ DefinedSVal Cond) {
+ return std::make_pair(Assume(state, Cond, true),
+ Assume(state, Cond, false));
+ }
+
+ virtual const llvm::APSInt* getSymVal(const GRState *state,
+ SymbolRef sym) const = 0;
+
+ virtual bool isEqual(const GRState *state, SymbolRef sym,
+ const llvm::APSInt& V) const = 0;
+
+ virtual const GRState *RemoveDeadBindings(const GRState *state,
+ SymbolReaper& SymReaper) = 0;
+
+ virtual void print(const GRState *state, llvm::raw_ostream& Out,
+ const char* nl, const char *sep) = 0;
+
+ virtual void EndPath(const GRState *state) {}
+
+ /// 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
+ /// GRExprEngine 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;
+};
+
+ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr,
+ GRSubEngine &subengine);
+ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr,
+ GRSubEngine &subengine);
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Environment.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Environment.h
new file mode 100644
index 0000000..b9bbebc
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Environment.h
@@ -0,0 +1,96 @@
+//== 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_ANALYSIS_ENVIRONMENT_H
+#define LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
+
+// For using typedefs in StoreManager. Should find a better place for these
+// typedefs.
+#include "clang/Checker/PathSensitive/Store.h"
+
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "llvm/ADT/ImmutableMap.h"
+
+namespace clang {
+
+class EnvironmentManager;
+class ValueManager;
+class LiveVariables;
+
+
+class Environment {
+private:
+ friend class EnvironmentManager;
+
+ // Type definitions.
+ typedef llvm::ImmutableMap<const Stmt*,SVal> BindingsTy;
+
+ // Data.
+ BindingsTy ExprBindings;
+
+ Environment(BindingsTy eb)
+ : ExprBindings(eb) {}
+
+public:
+ typedef BindingsTy::iterator iterator;
+ iterator begin() const { return ExprBindings.begin(); }
+ iterator end() const { return ExprBindings.end(); }
+
+ SVal LookupExpr(const Stmt* E) const {
+ const SVal* X = ExprBindings.lookup(E);
+ return X ? *X : UnknownVal();
+ }
+
+ SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const;
+
+ /// Profile - Profile the contents of an Environment object for use
+ /// in a FoldingSet.
+ static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
+ E->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;
+ }
+};
+
+class EnvironmentManager {
+private:
+ typedef Environment::BindingsTy::Factory FactoryTy;
+ FactoryTy F;
+
+public:
+ EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
+ ~EnvironmentManager() {}
+
+ Environment getInitialEnvironment() {
+ return Environment(F.GetEmptyMap());
+ }
+
+ Environment BindExpr(Environment Env, const Stmt *S, SVal V,
+ bool Invalidate);
+
+ Environment RemoveDeadBindings(Environment Env, const Stmt *S,
+ SymbolReaper &SymReaper, const GRState *ST,
+ llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
+};
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ExplodedGraph.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ExplodedGraph.h
new file mode 100644
index 0000000..c09c893
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ExplodedGraph.h
@@ -0,0 +1,436 @@
+//=-- 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_ANALYSIS_EXPLODEDGRAPH
+#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
+
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/Support/Casting.h"
+#include "clang/Analysis/Support/BumpVector.h"
+
+namespace clang {
+
+class GRState;
+class CFG;
+class ASTContext;
+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.
+//===----------------------------------------------------------------------===//
+
+class ExplodedNode : public llvm::FoldingSetNode {
+ friend class ExplodedGraph;
+ friend class GRCoreEngine;
+ friend class GRStmtNodeBuilder;
+ friend class GRBranchNodeBuilder;
+ friend class GRIndirectGotoNodeBuilder;
+ friend class GRSwitchNodeBuilder;
+ friend class GREndPathNodeBuilder;
+
+ class NodeGroup {
+ enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 };
+ uintptr_t P;
+
+ unsigned getKind() const {
+ return P & 0x1;
+ }
+
+ void* getPtr() const {
+ assert (!getFlag());
+ return reinterpret_cast<void*>(P & ~Mask);
+ }
+
+ ExplodedNode *getNode() const {
+ return reinterpret_cast<ExplodedNode*>(getPtr());
+ }
+
+ public:
+ NodeGroup() : P(0) {}
+
+ ExplodedNode **begin() const;
+
+ ExplodedNode **end() const;
+
+ unsigned size() const;
+
+ bool empty() const { return (P & ~Mask) == 0; }
+
+ void addNode(ExplodedNode* N, ExplodedGraph &G);
+
+ void setFlag() {
+ assert(P == 0);
+ P = AuxFlag;
+ }
+
+ bool getFlag() const {
+ return P & AuxFlag ? true : false;
+ }
+ };
+
+ /// Location - The program location (within a function body) associated
+ /// with this node.
+ const ProgramPoint Location;
+
+ /// State - The state associated with this node.
+ const GRState* State;
+
+ /// Preds - The predecessors of this node.
+ NodeGroup Preds;
+
+ /// Succs - The successors of this node.
+ NodeGroup Succs;
+
+public:
+
+ explicit ExplodedNode(const ProgramPoint& loc, const GRState* state)
+ : Location(loc), State(state) {}
+
+ /// getLocation - Returns the edge associated with the given node.
+ ProgramPoint getLocation() const { return Location; }
+
+ const LocationContext *getLocationContext() const {
+ return getLocation().getLocationContext();
+ }
+
+ const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
+
+ CFG &getCFG() const { return *getLocationContext()->getCFG(); }
+
+ ParentMap &getParentMap() const {return getLocationContext()->getParentMap();}
+
+ LiveVariables &getLiveVariables() const {
+ return *getLocationContext()->getLiveVariables();
+ }
+
+ const GRState* getState() const { return State; }
+
+ template <typename T>
+ const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
+
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ const ProgramPoint& Loc, const GRState* state) {
+ ID.Add(Loc);
+ ID.AddPointer(state);
+ }
+
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ Profile(ID, getLocation(), getState());
+ }
+
+ /// 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(); }
+ void markAsSink() { Succs.setFlag(); }
+
+ ExplodedNode* getFirstPred() {
+ return pred_empty() ? NULL : *(pred_begin());
+ }
+
+ const ExplodedNode* getFirstPred() const {
+ return const_cast<ExplodedNode*>(this)->getFirstPred();
+ }
+
+ // Iterators over successor and predecessor vertices.
+ typedef ExplodedNode** succ_iterator;
+ typedef const ExplodedNode* const * const_succ_iterator;
+ typedef ExplodedNode** 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);
+};
+
+// FIXME: Is this class necessary?
+class InterExplodedGraphMap {
+ llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M;
+ friend class ExplodedGraph;
+
+public:
+ ExplodedNode* getMappedNode(const ExplodedNode* N) const;
+
+ InterExplodedGraphMap() {}
+ virtual ~InterExplodedGraphMap() {}
+};
+
+class ExplodedGraph {
+protected:
+ friend class GRCoreEngine;
+
+ // Type definitions.
+ typedef llvm::SmallVector<ExplodedNode*,2> RootsTy;
+ typedef llvm::SmallVector<ExplodedNode*,10> EndNodesTy;
+
+ /// Roots - 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.
+ RootsTy Roots;
+
+ /// EndNodes - The nodes in the simulation graph which have been
+ /// specially marked as the endpoint of an abstract simulation path.
+ EndNodesTy 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;
+
+ /// Ctx - The ASTContext used to "interpret" CodeDecl.
+ ASTContext& Ctx;
+
+ /// NumNodes - The number of nodes in the graph.
+ unsigned NumNodes;
+
+public:
+ /// getNode - 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, const GRState *State,
+ bool* IsNew = 0);
+
+ ExplodedGraph* MakeEmptyGraph() const {
+ return new ExplodedGraph(Ctx);
+ }
+
+ /// 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(ASTContext& ctx) : Ctx(ctx), NumNodes(0) {}
+
+ ~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 NodeTy** roots_iterator;
+ typedef NodeTy* const * const_roots_iterator;
+ typedef NodeTy** eop_iterator;
+ typedef NodeTy* const * 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; }
+
+ ASTContext& getContext() { return Ctx; }
+
+ typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
+
+ std::pair<ExplodedGraph*, InterExplodedGraphMap*>
+ Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
+ llvm::DenseMap<const void*, const void*> *InverseMap = 0) const;
+
+ ExplodedGraph* TrimInternal(const ExplodedNode* const * NBeg,
+ const ExplodedNode* const * NEnd,
+ InterExplodedGraphMap *M,
+ llvm::DenseMap<const void*, const void*> *InverseMap) const;
+};
+
+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);
+ }
+
+ ExplodedNodeSet& operator=(const ExplodedNodeSet &X) {
+ Impl = X.Impl;
+ return *this;
+ }
+
+ typedef ImplTy::iterator iterator;
+ typedef ImplTy::const_iterator const_iterator;
+
+ unsigned size() const { return Impl.size(); }
+ bool empty() const { return Impl.empty(); }
+
+ void clear() { Impl.clear(); }
+ void insert(const ExplodedNodeSet &S) {
+ 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 clang namespace
+
+// GraphTraits
+
+namespace llvm {
+ template<> struct GraphTraits<clang::ExplodedNode*> {
+ typedef clang::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::ExplodedNode*> {
+ typedef const clang::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/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRAuditor.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRAuditor.h
new file mode 100644
index 0000000..015c82e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRAuditor.h
@@ -0,0 +1,35 @@
+//==- GRAuditor.h - Observers of the creation of ExplodedNodes------*- 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 GRAuditor and its primary subclasses, an interface
+// to audit the creation of ExplodedNodes. This interface can be used
+// to implement simple checkers that do not mutate analysis state but
+// instead operate by perfoming simple logical checks at key monitoring
+// locations (e.g., function calls).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRAUDITOR
+#define LLVM_CLANG_ANALYSIS_GRAUDITOR
+
+namespace clang {
+
+class ExplodedNode;
+class GRStateManager;
+
+class GRAuditor {
+public:
+ virtual ~GRAuditor() {}
+ virtual bool Audit(ExplodedNode* N, GRStateManager& M) = 0;
+};
+
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRBlockCounter.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRBlockCounter.h
new file mode 100644
index 0000000..b7d0e8a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRBlockCounter.h
@@ -0,0 +1,55 @@
+//==- GRBlockCounter.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 GRBlockCounter, an abstract data type used to count
+// the number of times a given block has been visited along a path
+// analyzed by GRCoreEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
+#define LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
+
+namespace llvm {
+ class BumpPtrAllocator;
+}
+
+namespace clang {
+
+class StackFrameContext;
+
+class GRBlockCounter {
+ void* Data;
+
+ GRBlockCounter(void* D) : Data(D) {}
+
+public:
+ GRBlockCounter() : Data(0) {}
+
+ unsigned getNumVisited(const StackFrameContext *CallSite,
+ unsigned BlockID) const;
+
+ class Factory {
+ void* F;
+ public:
+ Factory(llvm::BumpPtrAllocator& Alloc);
+ ~Factory();
+
+ GRBlockCounter GetEmptyCounter();
+ GRBlockCounter IncrementCount(GRBlockCounter BC,
+ const StackFrameContext *CallSite,
+ unsigned BlockID);
+ };
+
+ friend class Factory;
+};
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRCoreEngine.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRCoreEngine.h
new file mode 100644
index 0000000..2d8afee
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRCoreEngine.h
@@ -0,0 +1,487 @@
+//==- GRCoreEngine.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_ANALYSIS_GRENGINE
+#define LLVM_CLANG_ANALYSIS_GRENGINE
+
+#include "clang/AST/Expr.h"
+#include "clang/Checker/PathSensitive/ExplodedGraph.h"
+#include "clang/Checker/PathSensitive/GRWorkList.h"
+#include "clang/Checker/PathSensitive/GRBlockCounter.h"
+#include "clang/Checker/PathSensitive/GRAuditor.h"
+#include "clang/Checker/PathSensitive/GRSubEngine.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+/// GRCoreEngine - 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 GRCoreEngine (which subclasses GRCoreEngine)
+/// 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 GRCoreEngine {
+ friend class GRStmtNodeBuilder;
+ friend class GRBranchNodeBuilder;
+ friend class GRIndirectGotoNodeBuilder;
+ friend class GRSwitchNodeBuilder;
+ friend class GREndPathNodeBuilder;
+ friend class GRCallEnterNodeBuilder;
+ friend class GRCallExitNodeBuilder;
+
+ GRSubEngine& SubEngine;
+
+ /// G - The simulation graph. Each node is a (location,state) pair.
+ llvm::OwningPtr<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.
+ GRWorkList* WList;
+
+ /// BCounterFactory - A factory object for created GRBlockCounter objects.
+ /// These are used to record for key nodes in the ExplodedGraph the
+ /// number of times different CFGBlocks have been visited along a path.
+ GRBlockCounter::Factory BCounterFactory;
+
+ void GenerateNode(const ProgramPoint& Loc, const GRState* State,
+ ExplodedNode* Pred);
+
+ void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
+ void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
+ void HandleBlockExit(CFGBlock* B, ExplodedNode* Pred);
+ void HandlePostStmt(const PostStmt& S, CFGBlock* B,
+ unsigned StmtIdx, ExplodedNode *Pred);
+
+ void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
+ ExplodedNode* Pred);
+ void HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
+ unsigned Index, ExplodedNode *Pred);
+ void HandleCallExit(const CallExit &L, ExplodedNode *Pred);
+
+ /// Get the initial state from the subengine.
+ const GRState* getInitialState(const LocationContext *InitLoc) {
+ return SubEngine.getInitialState(InitLoc);
+ }
+
+ void ProcessEndPath(GREndPathNodeBuilder& Builder);
+
+ void ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder);
+
+ bool ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
+ GRBlockCounter BC);
+
+
+ void ProcessBranch(Stmt* Condition, Stmt* Terminator,
+ GRBranchNodeBuilder& Builder);
+
+
+ void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& Builder);
+
+
+ void ProcessSwitch(GRSwitchNodeBuilder& Builder);
+
+ void ProcessCallEnter(GRCallEnterNodeBuilder &Builder);
+ void ProcessCallExit(GRCallExitNodeBuilder &Builder);
+
+private:
+ GRCoreEngine(const GRCoreEngine&); // Do not implement.
+ GRCoreEngine& operator=(const GRCoreEngine&);
+
+public:
+ /// Construct a GRCoreEngine object to analyze the provided CFG using
+ /// a DFS exploration of the exploded graph.
+ GRCoreEngine(ASTContext& ctx, GRSubEngine& subengine)
+ : SubEngine(subengine), G(new ExplodedGraph(ctx)),
+ WList(GRWorkList::MakeBFS()),
+ BCounterFactory(G->getAllocator()) {}
+
+ /// Construct a GRCoreEngine object to analyze the provided CFG and to
+ /// use the provided worklist object to execute the worklist algorithm.
+ /// The GRCoreEngine object assumes ownership of 'wlist'.
+ GRCoreEngine(ASTContext& ctx, GRWorkList* wlist, GRSubEngine& subengine)
+ : SubEngine(subengine), G(new ExplodedGraph(ctx)), WList(wlist),
+ BCounterFactory(G->getAllocator()) {}
+
+ ~GRCoreEngine() {
+ delete WList;
+ }
+
+ /// getGraph - Returns the exploded graph.
+ ExplodedGraph& getGraph() { return *G.get(); }
+
+ /// takeGraph - Returns the exploded graph. Ownership of the graph is
+ /// transfered to the caller.
+ ExplodedGraph* takeGraph() { return G.take(); }
+
+ /// 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);
+};
+
+class GRStmtNodeBuilder {
+ GRCoreEngine& Eng;
+ CFGBlock& B;
+ const unsigned Idx;
+ ExplodedNode* Pred;
+ GRStateManager& Mgr;
+ GRAuditor* Auditor;
+
+public:
+ bool PurgingDeadSymbols;
+ bool BuildSinks;
+ bool HasGeneratedNode;
+ ProgramPoint::Kind PointKind;
+ const void *Tag;
+
+ const GRState* CleanedState;
+
+
+ typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
+ DeferredTy Deferred;
+
+ void GenerateAutoTransition(ExplodedNode* N);
+
+public:
+ GRStmtNodeBuilder(CFGBlock* b, unsigned idx, ExplodedNode* N,
+ GRCoreEngine* e, GRStateManager &mgr);
+
+ ~GRStmtNodeBuilder();
+
+ ExplodedNode* getBasePredecessor() const { return Pred; }
+
+ // FIXME: This should not be exposed.
+ GRWorkList *getWorkList() { return Eng.WList; }
+
+ void SetCleanedState(const GRState* St) {
+ CleanedState = St;
+ }
+
+ GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
+
+ unsigned getCurrentBlockCount() const {
+ return getBlockCounter().getNumVisited(
+ Pred->getLocationContext()->getCurrentStackFrame(),
+ B.getBlockID());
+ }
+
+ ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) {
+ HasGeneratedNode = true;
+ return generateNodeInternal(PP, St, Pred);
+ }
+
+ ExplodedNode* generateNode(const Stmt *S, const GRState *St,
+ ExplodedNode *Pred, ProgramPoint::Kind K) {
+ HasGeneratedNode = true;
+
+ if (PurgingDeadSymbols)
+ K = ProgramPoint::PostPurgeDeadSymbolsKind;
+
+ return generateNodeInternal(S, St, Pred, K, Tag);
+ }
+
+ ExplodedNode* generateNode(const Stmt *S, const GRState *St,
+ ExplodedNode *Pred) {
+ return generateNode(S, St, Pred, PointKind);
+ }
+
+ ExplodedNode *generateNode(const ProgramPoint &PP, const GRState* State,
+ ExplodedNode* Pred) {
+ HasGeneratedNode = true;
+ return generateNodeInternal(PP, State, Pred);
+ }
+
+ ExplodedNode*
+ generateNodeInternal(const ProgramPoint &PP, const GRState* State,
+ ExplodedNode* Pred);
+
+ ExplodedNode*
+ generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred,
+ ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
+ const void *tag = 0);
+
+ /// getStmt - Return the current block-level expression associated with
+ /// this builder.
+ Stmt* getStmt() const { return B[Idx]; }
+
+ /// getBlock - Return the CFGBlock associated with the block-level expression
+ /// of this builder.
+ CFGBlock* getBlock() const { return &B; }
+
+ unsigned getIndex() const { return Idx; }
+
+ void setAuditor(GRAuditor* A) { Auditor = A; }
+
+ const GRState* GetState(ExplodedNode* Pred) const {
+ if (Pred == getBasePredecessor())
+ return CleanedState;
+ else
+ return Pred->getState();
+ }
+
+ ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
+ const GRState* St) {
+ return MakeNode(Dst, S, Pred, St, PointKind);
+ }
+
+ ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
+ const GRState* St, ProgramPoint::Kind K);
+
+ ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, Stmt* S,
+ ExplodedNode* Pred, const GRState* St) {
+ bool Tmp = BuildSinks;
+ BuildSinks = true;
+ ExplodedNode* N = MakeNode(Dst, S, Pred, St);
+ BuildSinks = Tmp;
+ return N;
+ }
+};
+
+class GRBranchNodeBuilder {
+ GRCoreEngine& Eng;
+ CFGBlock* Src;
+ CFGBlock* DstT;
+ CFGBlock* DstF;
+ ExplodedNode* Pred;
+
+ typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy;
+ DeferredTy Deferred;
+
+ bool GeneratedTrue;
+ bool GeneratedFalse;
+ bool InFeasibleTrue;
+ bool InFeasibleFalse;
+
+public:
+ GRBranchNodeBuilder(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
+ ExplodedNode* pred, GRCoreEngine* e)
+ : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
+ GeneratedTrue(false), GeneratedFalse(false),
+ InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
+
+ ~GRBranchNodeBuilder();
+
+ ExplodedNode* getPredecessor() const { return Pred; }
+
+ const ExplodedGraph& getGraph() const { return *Eng.G; }
+
+ GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
+
+ ExplodedNode* generateNode(const GRState* State, bool branch);
+
+ CFGBlock* getTargetBlock(bool branch) const {
+ return branch ? DstT : DstF;
+ }
+
+ void markInfeasible(bool branch) {
+ if (branch)
+ InFeasibleTrue = GeneratedTrue = true;
+ else
+ InFeasibleFalse = GeneratedFalse = true;
+ }
+
+ bool isFeasible(bool branch) {
+ return branch ? !InFeasibleTrue : !InFeasibleFalse;
+ }
+
+ const GRState* getState() const {
+ return getPredecessor()->getState();
+ }
+};
+
+class GRIndirectGotoNodeBuilder {
+ GRCoreEngine& Eng;
+ CFGBlock* Src;
+ CFGBlock& DispatchBlock;
+ Expr* E;
+ ExplodedNode* Pred;
+
+public:
+ GRIndirectGotoNodeBuilder(ExplodedNode* pred, CFGBlock* src, Expr* e,
+ CFGBlock* dispatch, GRCoreEngine* eng)
+ : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
+
+ class iterator {
+ CFGBlock::succ_iterator I;
+
+ friend class GRIndirectGotoNodeBuilder;
+ iterator(CFGBlock::succ_iterator i) : I(i) {}
+ public:
+
+ iterator& operator++() { ++I; return *this; }
+ bool operator!=(const iterator& X) const { return I != X.I; }
+
+ LabelStmt* getLabel() const {
+ return llvm::cast<LabelStmt>((*I)->getLabel());
+ }
+
+ CFGBlock* getBlock() const {
+ return *I;
+ }
+ };
+
+ iterator begin() { return iterator(DispatchBlock.succ_begin()); }
+ iterator end() { return iterator(DispatchBlock.succ_end()); }
+
+ ExplodedNode* generateNode(const iterator& I, const GRState* State,
+ bool isSink = false);
+
+ Expr* getTarget() const { return E; }
+
+ const GRState* getState() const { return Pred->State; }
+};
+
+class GRSwitchNodeBuilder {
+ GRCoreEngine& Eng;
+ CFGBlock* Src;
+ Expr* Condition;
+ ExplodedNode* Pred;
+
+public:
+ GRSwitchNodeBuilder(ExplodedNode* pred, CFGBlock* src,
+ Expr* condition, GRCoreEngine* eng)
+ : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
+
+ class iterator {
+ CFGBlock::succ_reverse_iterator I;
+
+ friend class GRSwitchNodeBuilder;
+ iterator(CFGBlock::succ_reverse_iterator i) : I(i) {}
+
+ public:
+ iterator& operator++() { ++I; return *this; }
+ bool operator!=(const iterator& X) const { return I != X.I; }
+
+ CaseStmt* getCase() const {
+ return llvm::cast<CaseStmt>((*I)->getLabel());
+ }
+
+ CFGBlock* getBlock() const {
+ return *I;
+ }
+ };
+
+ iterator begin() { return iterator(Src->succ_rbegin()+1); }
+ iterator end() { return iterator(Src->succ_rend()); }
+
+ ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State);
+
+ ExplodedNode* generateDefaultCaseNode(const GRState* State,
+ bool isSink = false);
+
+ Expr* getCondition() const { return Condition; }
+
+ const GRState* getState() const { return Pred->State; }
+};
+
+class GREndPathNodeBuilder {
+ GRCoreEngine &Eng;
+ CFGBlock& B;
+ ExplodedNode* Pred;
+
+public:
+ bool HasGeneratedNode;
+
+public:
+ GREndPathNodeBuilder(CFGBlock* b, ExplodedNode* N, GRCoreEngine* e)
+ : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}
+
+ ~GREndPathNodeBuilder();
+
+ GRWorkList &getWorkList() { return *Eng.WList; }
+
+ ExplodedNode* getPredecessor() const { return Pred; }
+
+ GRBlockCounter getBlockCounter() const {
+ return Eng.WList->getBlockCounter();
+ }
+
+ unsigned getCurrentBlockCount() const {
+ return getBlockCounter().getNumVisited(
+ Pred->getLocationContext()->getCurrentStackFrame(),
+ B.getBlockID());
+ }
+
+ ExplodedNode* generateNode(const GRState* State, const void *tag = 0,
+ ExplodedNode *P = 0);
+
+ void GenerateCallExitNode(const GRState *state);
+
+ CFGBlock* getBlock() const { return &B; }
+
+ const GRState* getState() const {
+ return getPredecessor()->getState();
+ }
+};
+
+class GRCallEnterNodeBuilder {
+ GRCoreEngine &Eng;
+
+ const ExplodedNode *Pred;
+
+ // The call site.
+ const Stmt *CE;
+
+ // The definition of callee.
+ const FunctionDecl *FD;
+
+ // The parent block of the CallExpr.
+ const CFGBlock *Block;
+
+ // The CFGBlock index of the CallExpr.
+ unsigned Index;
+
+public:
+ GRCallEnterNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred,
+ const Stmt *s, const FunctionDecl *fd,
+ const CFGBlock *blk, unsigned idx)
+ : Eng(eng), Pred(pred), CE(s), FD(fd), Block(blk), Index(idx) {}
+
+ const GRState *getState() const { return Pred->getState(); }
+
+ const LocationContext *getLocationContext() const {
+ return Pred->getLocationContext();
+ }
+
+ const Stmt *getCallExpr() const { return CE; }
+
+ const FunctionDecl *getCallee() const { return FD; }
+
+ const CFGBlock *getBlock() const { return Block; }
+
+ unsigned getIndex() const { return Index; }
+
+ void GenerateNode(const GRState *state, const LocationContext *LocCtx);
+};
+
+class GRCallExitNodeBuilder {
+ GRCoreEngine &Eng;
+ const ExplodedNode *Pred;
+
+public:
+ GRCallExitNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred)
+ : Eng(eng), Pred(pred) {}
+
+ const ExplodedNode *getPredecessor() const { return Pred; }
+
+ const GRState *getState() const { return Pred->getState(); }
+
+ void GenerateNode(const GRState *state);
+};
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRExprEngine.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRExprEngine.h
new file mode 100644
index 0000000..ac407f6
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRExprEngine.h
@@ -0,0 +1,465 @@
+//===-- GRExprEngine.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 GRCoreEngine, but provides the boilerplate to execute transfer
+// functions and build the ExplodedGraph at the expression level.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
+#define LLVM_CLANG_ANALYSIS_GREXPRENGINE
+
+#include "clang/Checker/PathSensitive/GRSubEngine.h"
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRSimpleAPICheck.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprCXX.h"
+
+namespace clang {
+class AnalysisManager;
+class Checker;
+class ObjCForCollectionStmt;
+
+class GRExprEngine : public GRSubEngine {
+ AnalysisManager &AMgr;
+
+ GRCoreEngine CoreEngine;
+
+ /// G - the simulation graph.
+ ExplodedGraph& G;
+
+ /// Builder - The current GRStmtNodeBuilder which is used when building the
+ /// nodes for a given statement.
+ GRStmtNodeBuilder* Builder;
+
+ /// StateMgr - Object that manages the data for all created states.
+ GRStateManager StateMgr;
+
+ /// SymMgr - Object that manages the symbol information.
+ SymbolManager& SymMgr;
+
+ /// ValMgr - Object that manages/creates SVals.
+ ValueManager &ValMgr;
+
+ /// SVator - SValuator object that creates SVals from expressions.
+ SValuator &SVator;
+
+ /// EntryNode - The immediate predecessor node.
+ ExplodedNode* EntryNode;
+
+ /// CleanedState - The state for EntryNode "cleaned" of all dead
+ /// variables and symbols (as determined by a liveness analysis).
+ const GRState* CleanedState;
+
+ /// CurrentStmt - The current block-level statement.
+ Stmt* CurrentStmt;
+
+ // Obj-C Class Identifiers.
+ IdentifierInfo* NSExceptionII;
+
+ // Obj-C Selectors.
+ Selector* NSExceptionInstanceRaiseSelectors;
+ Selector RaiseSel;
+
+ llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor;
+
+ typedef llvm::DenseMap<void *, unsigned> CheckerMap;
+ CheckerMap CheckerM;
+
+ typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered;
+ CheckersOrdered Checkers;
+
+ /// BR - 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 GRExprEngine is destroyed.
+ GRBugReporter BR;
+
+ llvm::OwningPtr<GRTransferFuncs> TF;
+
+ class CallExprWLItem {
+ public:
+ CallExpr::arg_iterator I;
+ ExplodedNode *N;
+
+ CallExprWLItem(const CallExpr::arg_iterator &i, ExplodedNode *n)
+ : I(i), N(n) {}
+ };
+
+public:
+ GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf);
+
+ ~GRExprEngine();
+
+ void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
+ CoreEngine.ExecuteWorkList(L, Steps);
+ }
+
+ /// getContext - Return the ASTContext associated with this analysis.
+ ASTContext& getContext() const { return G.getContext(); }
+
+ AnalysisManager &getAnalysisManager() const { return AMgr; }
+
+ SValuator &getSValuator() { return SVator; }
+
+ GRTransferFuncs& getTF() { return *TF; }
+
+ BugReporter& getBugReporter() { return BR; }
+
+ GRStmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
+
+ // FIXME: Remove once GRTransferFuncs is no longer referenced.
+ void setTransferFunction(GRTransferFuncs* tf);
+
+ /// ViewGraph - Visualize the ExplodedGraph created by executing the
+ /// simulation.
+ void ViewGraph(bool trim = false);
+
+ void ViewGraph(ExplodedNode** Beg, ExplodedNode** End);
+
+ /// getInitialState - Return the initial state used for the root vertex
+ /// in the ExplodedGraph.
+ const GRState* getInitialState(const LocationContext *InitLoc);
+
+ ExplodedGraph& getGraph() { return G; }
+ const ExplodedGraph& getGraph() const { return G; }
+
+ template <typename CHECKER>
+ void registerCheck(CHECKER *check) {
+ unsigned entry = Checkers.size();
+ void *tag = CHECKER::getTag();
+ Checkers.push_back(std::make_pair(tag, check));
+ CheckerM[tag] = entry;
+ }
+
+ Checker *lookupChecker(void *tag) const;
+
+ template <typename CHECKER>
+ CHECKER *getChecker() const {
+ return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
+ }
+
+ void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
+ void AddCheck(GRSimpleAPICheck* A);
+
+ /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
+ /// nodes by processing the 'effects' of a block-level statement.
+ void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder);
+
+ /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
+ /// a CFGBlock. This method returns true if the analysis should continue
+ /// exploring the given path, and false otherwise.
+ bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
+ GRBlockCounter BC);
+
+ /// ProcessBranch - Called by GRCoreEngine. Used to generate successor
+ /// nodes by processing the 'effects' of a branch condition.
+ void ProcessBranch(Stmt* Condition, Stmt* Term, GRBranchNodeBuilder& builder);
+
+ /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
+ /// nodes by processing the 'effects' of a computed goto jump.
+ void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder);
+
+ /// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
+ /// nodes by processing the 'effects' of a switch statement.
+ void ProcessSwitch(GRSwitchNodeBuilder& builder);
+
+ /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
+ /// nodes when the control reaches the end of a function.
+ void ProcessEndPath(GREndPathNodeBuilder& builder);
+
+ // Generate the entry node of the callee.
+ void ProcessCallEnter(GRCallEnterNodeBuilder &builder);
+
+ // Generate the first post callsite node.
+ void ProcessCallExit(GRCallExitNodeBuilder &builder);
+
+ /// EvalAssume - Callback function invoked by the ConstraintManager when
+ /// making assumptions about state values.
+ const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption);
+
+ GRStateManager& getStateManager() { return StateMgr; }
+ const GRStateManager& getStateManager() const { return StateMgr; }
+
+ StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
+
+ ConstraintManager& getConstraintManager() {
+ return StateMgr.getConstraintManager();
+ }
+
+ // FIXME: Remove when we migrate over to just using ValueManager.
+ BasicValueFactory& getBasicVals() {
+ return StateMgr.getBasicVals();
+ }
+ const BasicValueFactory& getBasicVals() const {
+ return StateMgr.getBasicVals();
+ }
+
+ ValueManager &getValueManager() { return ValMgr; }
+ const ValueManager &getValueManager() const { return ValMgr; }
+
+ // FIXME: Remove when we migrate over to just using ValueManager.
+ SymbolManager& getSymbolManager() { return SymMgr; }
+ const SymbolManager& getSymbolManager() const { return SymMgr; }
+
+protected:
+ const GRState* GetState(ExplodedNode* N) {
+ return N == EntryNode ? CleanedState : N->getState();
+ }
+
+public:
+ ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
+ const GRState* St,
+ ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
+ const void *tag = 0);
+
+ /// CheckerVisit - Dispatcher for performing checker-specific logic
+ /// at specific statements.
+ void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
+ bool isPrevisit);
+
+ bool CheckerEvalCall(const CallExpr *CE,
+ ExplodedNodeSet &Dst,
+ ExplodedNode *Pred);
+
+ void CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
+ ExplodedNodeSet &Dst,
+ const GRState *state,
+ ExplodedNode *Pred);
+
+ void CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
+ ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
+ SVal location, SVal val, bool isPrevisit);
+
+
+ /// Visit - Transfer function logic for all statements. Dispatches to
+ /// other functions that handle specific kinds of statements.
+ void Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ /// VisitLValue - Evaluate the lvalue of the expression. For example, if Ex is
+ /// a DeclRefExpr, it evaluates to the MemRegionVal which represents its
+ /// storage location. Note that not all kinds of expressions has lvalue.
+ void VisitLValue(Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ /// VisitArraySubscriptExpr - Transfer function for array accesses.
+ void VisitArraySubscriptExpr(ArraySubscriptExpr* Ex, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ /// VisitAsmStmt - Transfer function logic for inline asm.
+ void VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ void VisitAsmStmtHelperOutputs(AsmStmt* A,
+ AsmStmt::outputs_iterator I,
+ AsmStmt::outputs_iterator E,
+ ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ void VisitAsmStmtHelperInputs(AsmStmt* A,
+ AsmStmt::inputs_iterator I,
+ AsmStmt::inputs_iterator E,
+ ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ /// VisitBlockExpr - Transfer function logic for BlockExprs.
+ void VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+ /// VisitBinaryOperator - Transfer function logic for binary operators.
+ void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+
+ /// VisitCall - Transfer function for function calls.
+ void VisitCall(CallExpr* CE, ExplodedNode* Pred,
+ CallExpr::arg_iterator AI, CallExpr::arg_iterator AE,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ /// VisitCast - Transfer function logic for all casts (implicit and explicit).
+ void VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst, bool asLValue);
+
+ /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
+ void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ /// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
+ void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ /// VisitBlockDeclRefExpr - Transfer function logic for BlockDeclRefExprs.
+ void VisitBlockDeclRefExpr(BlockDeclRefExpr* DR, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ void VisitCommonDeclRefExpr(Expr* DR, const NamedDecl *D,ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ /// VisitDeclStmt - Transfer function logic for DeclStmts.
+ void VisitDeclStmt(DeclStmt* DS, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
+ void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
+
+ /// VisitCondInit - Transfer function for handling the initialization
+ /// of a condition variable in an IfStmt, SwitchStmt, etc.
+ void VisitCondInit(VarDecl *VD, Stmt *S, ExplodedNode *Pred,
+ ExplodedNodeSet& Dst);
+
+ void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
+
+ /// VisitLogicalExpr - Transfer function logic for '&&', '||'
+ void VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
+
+ /// VisitMemberExpr - Transfer function for member expressions.
+ void VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred, ExplodedNodeSet& Dst,
+ bool asLValue);
+
+ /// VisitObjCIvarRefExpr - Transfer function logic for ObjCIvarRefExprs.
+ void VisitObjCIvarRefExpr(ObjCIvarRefExpr* DR, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ /// VisitObjCForCollectionStmt - Transfer function logic for
+ /// ObjCForCollectionStmt.
+ void VisitObjCForCollectionStmt(ObjCForCollectionStmt* S, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
+
+ void VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
+ ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, SVal ElementV);
+
+ /// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
+ void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ /// VisitReturnStmt - Transfer function logic for return statements.
+ void VisitReturnStmt(ReturnStmt* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ /// VisitOffsetOfExpr - Transfer function for offsetof.
+ void VisitOffsetOfExpr(OffsetOfExpr* Ex, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
+
+ /// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
+ void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
+
+ /// VisitUnaryOperator - Transfer function logic for unary operators.
+ void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
+ ExplodedNodeSet & Dst);
+
+ void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
+ void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
+ void VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
+ void VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
+ void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
+ /// Create a C++ temporary object for an rvalue.
+ void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
+ /// Synthesize CXXThisRegion.
+ const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *MD,
+ const StackFrameContext *SFC);
+
+ /// Evaluate arguments with a work list algorithm.
+ void EvalArguments(ExprIterator AI, ExprIterator AE,
+ const FunctionProtoType *FnType,
+ ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+ /// EvalEagerlyAssume - 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 EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, Expr *Ex);
+
+ SVal EvalMinus(SVal X) {
+ return X.isValid() ? SVator.EvalMinus(cast<NonLoc>(X)) : X;
+ }
+
+ SVal EvalComplement(SVal X) {
+ return X.isValid() ? SVator.EvalComplement(cast<NonLoc>(X)) : X;
+ }
+
+public:
+
+ SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
+ NonLoc L, NonLoc R, QualType T) {
+ return SVator.EvalBinOpNN(state, op, L, R, T);
+ }
+
+ SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
+ NonLoc L, SVal R, QualType T) {
+ return R.isValid() ? SVator.EvalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
+ }
+
+ SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
+ SVal LHS, SVal RHS, QualType T) {
+ return SVator.EvalBinOp(ST, Op, LHS, RHS, T);
+ }
+
+protected:
+ void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME,
+ ExplodedNode* Pred, const GRState *state) {
+ assert (Builder && "GRStmtNodeBuilder must be defined.");
+ getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred, state);
+ }
+
+ const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
+ bool branchTaken);
+
+ /// 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, Stmt *AssignE,
+ Stmt* StoreE, ExplodedNode* Pred,
+ const GRState* St, SVal location, SVal Val,
+ bool atDeclInit = false);
+
+public:
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
+ void EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
+ const GRState* St, SVal location, const void *tag = 0,
+ QualType LoadTy = QualType());
+
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
+ void EvalStore(ExplodedNodeSet& Dst, Expr* AssignE, Expr* StoreE,
+ ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
+ const void *tag = 0);
+private:
+ void EvalLoadCommon(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
+ const GRState* St, SVal location, const void *tag,
+ QualType LoadTy);
+
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
+ void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred,
+ const GRState* St, SVal location,
+ const void *tag, bool isLoad);
+
+ bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
+};
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h
new file mode 100644
index 0000000..5503412
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h
@@ -0,0 +1,76 @@
+//===-- GRExprEngineBuilders.h - "Builder" classes for GRExprEngine -*- 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 smart builder "references" which are used to marshal
+// builders between GRExprEngine objects and their related components.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
+#define LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Analysis/Support/SaveAndRestore.h"
+
+namespace clang {
+
+class GRStmtNodeBuilderRef {
+ ExplodedNodeSet &Dst;
+ GRStmtNodeBuilder &B;
+ GRExprEngine& Eng;
+ ExplodedNode* Pred;
+ const GRState* state;
+ const Stmt* stmt;
+ const unsigned OldSize;
+ const bool AutoCreateNode;
+ SaveAndRestore<bool> OldSink;
+ SaveAndRestore<const void*> OldTag;
+ SaveOr OldHasGen;
+
+private:
+ friend class GRExprEngine;
+
+ GRStmtNodeBuilderRef(); // do not implement
+ void operator=(const GRStmtNodeBuilderRef&); // do not implement
+
+ GRStmtNodeBuilderRef(ExplodedNodeSet &dst,
+ GRStmtNodeBuilder &builder,
+ GRExprEngine& eng,
+ ExplodedNode* pred,
+ const GRState *st,
+ const Stmt* s, bool auto_create_node)
+ : Dst(dst), B(builder), Eng(eng), Pred(pred),
+ state(st), stmt(s), OldSize(Dst.size()), AutoCreateNode(auto_create_node),
+ OldSink(B.BuildSinks), OldTag(B.Tag), OldHasGen(B.HasGeneratedNode) {}
+
+public:
+
+ ~GRStmtNodeBuilderRef() {
+ // Handle the case where no nodes where generated. Auto-generate that
+ // contains the updated state if we aren't generating sinks.
+ if (!B.BuildSinks && Dst.size() == OldSize && !B.HasGeneratedNode) {
+ if (AutoCreateNode)
+ B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state);
+ else
+ Dst.Add(Pred);
+ }
+ }
+
+ const GRState *getState() { return state; }
+
+ GRStateManager& getStateManager() {
+ return Eng.getStateManager();
+ }
+
+ ExplodedNode* MakeNode(const GRState* state) {
+ return B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state);
+ }
+};
+
+} // end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
new file mode 100644
index 0000000..6d85e5f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
@@ -0,0 +1,31 @@
+// GRCheckAPI.h - Simple API checks based on GRAuditor ------------*- 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 for building simple, path-sensitive checks
+// that are stateless and only emit warnings at errors that occur at
+// CallExpr or ObjCMessageExpr.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRAPICHECKS
+#define LLVM_CLANG_ANALYSIS_GRAPICHECKS
+
+#include "clang/Checker/PathSensitive/GRAuditor.h"
+
+namespace clang {
+
+class GRSimpleAPICheck : public GRAuditor {
+public:
+ GRSimpleAPICheck() {}
+ virtual ~GRSimpleAPICheck() {}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRState.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRState.h
new file mode 100644
index 0000000..25ba1f8
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRState.h
@@ -0,0 +1,750 @@
+//== GRState*h - Path-Sens. "State" for tracking valuues -----*- 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 SymbolRef, ExprBindKey, and GRState*
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
+#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
+
+#include "clang/Checker/PathSensitive/ConstraintManager.h"
+#include "clang/Checker/PathSensitive/Environment.h"
+#include "clang/Checker/PathSensitive/Store.h"
+#include "clang/Checker/PathSensitive/ValueManager.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+class APSInt;
+class BumpPtrAllocator;
+class raw_ostream;
+}
+
+namespace clang {
+class ASTContext;
+class GRStateManager;
+class Checker;
+
+typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&,
+ GRSubEngine&);
+typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
+
+//===----------------------------------------------------------------------===//
+// GRStateTrait - Traits used by the Generic Data Map of a GRState.
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct GRStatePartialTrait;
+
+template <typename T> struct GRStateTrait {
+ typedef typename T::data_type data_type;
+ static inline void* GDMIndex() { return &T::TagInt; }
+ 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;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// GRState- An ImmutableMap type Stmt*/Decl*/Symbols to SVals.
+//===----------------------------------------------------------------------===//
+
+class GRStateManager;
+
+/// GRState - This class encapsulates the actual data values for
+/// for a "state" in our symbolic value tracking. It 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 GRState : public llvm::FoldingSetNode {
+public:
+ typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
+ typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
+
+private:
+ void operator=(const GRState& R) const; // Do not implement.
+
+ friend class GRStateManager;
+
+ GRStateManager *StateMgr;
+ Environment Env;
+ Store St;
+ GenericDataMap GDM;
+
+public:
+
+ /// This ctor is used when creating the first GRState object.
+ GRState(GRStateManager *mgr, const Environment& env,
+ Store st, GenericDataMap gdm)
+ : StateMgr(mgr),
+ Env(env),
+ St(st),
+ GDM(gdm) {}
+
+ /// Copy ctor - We must explicitly define this or else the "Next" ptr
+ /// in FoldingSetNode will also get copied.
+ GRState(const GRState& RHS)
+ : llvm::FoldingSetNode(),
+ StateMgr(RHS.StateMgr),
+ Env(RHS.Env),
+ St(RHS.St),
+ GDM(RHS.GDM) {}
+
+ /// getStateManager - Return the GRStateManager associated with this state.
+ GRStateManager &getStateManager() const {
+ return *StateMgr;
+ }
+
+ /// getEnvironment - Return the environment associated with this state.
+ /// The environment is the mapping from expressions to values.
+ const Environment& getEnvironment() const { return Env; }
+
+ /// getStore - Return the store associated with this state. The store
+ /// is a mapping from locations to values.
+ Store getStore() const { return St; }
+
+ void setStore(Store s) { St = s; }
+
+ /// 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 GRState object for use
+ /// in a FoldingSet.
+ static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) {
+ V->Env.Profile(ID);
+ ID.AddPointer(V->St);
+ 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);
+ }
+
+ SVal LookupExpr(Expr* E) const {
+ return Env.LookupExpr(E);
+ }
+
+ /// makeWithStore - Return a GRState with the same values as the current
+ /// state with the exception of using the specified Store.
+ const GRState *makeWithStore(Store store) const;
+
+ BasicValueFactory &getBasicVals() const;
+ SymbolManager &getSymbolManager() const;
+
+ //==---------------------------------------------------------------------==//
+ // Constraints on values.
+ //==---------------------------------------------------------------------==//
+ //
+ // Each GRState records constraints on symbolic values. These constraints
+ // are managed using the ConstraintManager associated with a GRStateManager.
+ // 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 GRExprEngine/GRState.
+ //
+ // 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 GRState 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" are two values:
+ //
+ // (a) "isFeasible" is set to true or false to indicate whether or not
+ // the assumption is feasible.
+ //
+ // (b) A new GRState object with the added constraints.
+ //
+ // FIXME: (a) should probably disappear since it is redundant with (b).
+ // (i.e., (b) could just be set to NULL).
+ //
+
+ const GRState *Assume(DefinedOrUnknownSVal cond, bool assumption) const;
+
+ std::pair<const GRState*, const GRState*>
+ Assume(DefinedOrUnknownSVal cond) const;
+
+ const GRState *AssumeInBound(DefinedOrUnknownSVal idx,
+ DefinedOrUnknownSVal upperBound,
+ bool assumption) const;
+
+ //==---------------------------------------------------------------------==//
+ // Utility methods for getting regions.
+ //==---------------------------------------------------------------------==//
+
+ const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
+
+ //==---------------------------------------------------------------------==//
+ // Binding and retrieving values to/from the environment and symbolic store.
+ //==---------------------------------------------------------------------==//
+
+ /// BindCompoundLiteral - Return the state that has the bindings currently
+ /// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region
+ /// for the compound literal and 'BegInit' and 'EndInit' represent an
+ /// array of initializer values.
+ const GRState *bindCompoundLiteral(const CompoundLiteralExpr* CL,
+ const LocationContext *LC,
+ SVal V) const;
+
+ const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const;
+
+ const GRState *bindDecl(const VarRegion *VR, SVal V) const;
+
+ const GRState *bindDeclWithNoInit(const VarRegion *VR) const;
+
+ const GRState *bindLoc(Loc location, SVal V) const;
+
+ const GRState *bindLoc(SVal location, SVal V) const;
+
+ const GRState *unbindLoc(Loc LV) const;
+
+ /// Get the lvalue for a variable reference.
+ SVal getLValue(const VarDecl *D, const LocationContext *LC) const;
+
+ /// Get the lvalue for a StringLiteral.
+ SVal getLValue(const StringLiteral *literal) const;
+
+ SVal 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 array index.
+ SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
+
+ const llvm::APSInt *getSymVal(SymbolRef sym) const;
+
+ SVal getSVal(const Stmt* Ex) const;
+
+ SVal getSValAsScalarOrLoc(const Stmt *Ex) const;
+
+ SVal getSVal(Loc LV, QualType T = QualType()) const;
+
+ SVal getSVal(const MemRegion* R) const;
+
+ SVal getSValAsScalarOrLoc(const MemRegion *R) const;
+
+ const llvm::APSInt *getSymVal(SymbolRef sym);
+
+ bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
+
+ bool scanReachableSymbols(const SVal *I, const SVal *E,
+ SymbolVisitor &visitor) const;
+
+ 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;
+
+ //==---------------------------------------------------------------------==//
+ // Accessing the Generic Data Map (GDM).
+ //==---------------------------------------------------------------------==//
+
+ void* const* FindGDM(void* K) const;
+
+ template<typename T>
+ const GRState *add(typename GRStateTrait<T>::key_type K) const;
+
+ template <typename T>
+ typename GRStateTrait<T>::data_type
+ get() const {
+ return GRStateTrait<T>::MakeData(FindGDM(GRStateTrait<T>::GDMIndex()));
+ }
+
+ template<typename T>
+ typename GRStateTrait<T>::lookup_type
+ get(typename GRStateTrait<T>::key_type key) const {
+ void* const* d = FindGDM(GRStateTrait<T>::GDMIndex());
+ return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key);
+ }
+
+ template <typename T>
+ typename GRStateTrait<T>::context_type get_context() const;
+
+
+ template<typename T>
+ const GRState *remove(typename GRStateTrait<T>::key_type K) const;
+
+ template<typename T>
+ const GRState *remove(typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::context_type C) const;
+ template <typename T>
+ const GRState *remove() const;
+
+ template<typename T>
+ const GRState *set(typename GRStateTrait<T>::data_type D) const;
+
+ template<typename T>
+ const GRState *set(typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::value_type E) const;
+
+ template<typename T>
+ const GRState *set(typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::value_type E,
+ typename GRStateTrait<T>::context_type C) const;
+
+ template<typename T>
+ bool contains(typename GRStateTrait<T>::key_type key) const {
+ void* const* d = FindGDM(GRStateTrait<T>::GDMIndex());
+ return GRStateTrait<T>::Contains(GRStateTrait<T>::MakeData(d), key);
+ }
+
+ // State pretty-printing.
+ class Printer {
+ public:
+ virtual ~Printer() {}
+ virtual void Print(llvm::raw_ostream& Out, const GRState* state,
+ const char* nl, const char* sep) = 0;
+ };
+
+ // Pretty-printing.
+ void print(llvm::raw_ostream& Out, CFG &C, const char *nl = "\n",
+ const char *sep = "") const;
+
+ void printStdErr(CFG &C) const;
+
+ void printDOT(llvm::raw_ostream& Out, CFG &C) const;
+};
+
+class GRStateSet {
+ typedef llvm::SmallPtrSet<const GRState*,5> ImplTy;
+ ImplTy Impl;
+public:
+ GRStateSet() {}
+
+ inline void Add(const GRState* St) {
+ Impl.insert(St);
+ }
+
+ typedef ImplTy::const_iterator iterator;
+
+ inline unsigned size() const { return Impl.size(); }
+ inline bool empty() const { return Impl.empty(); }
+
+ inline iterator begin() const { return Impl.begin(); }
+ inline iterator end() const { return Impl.end(); }
+
+ class AutoPopulate {
+ GRStateSet& S;
+ unsigned StartSize;
+ const GRState* St;
+ public:
+ AutoPopulate(GRStateSet& s, const GRState* st)
+ : S(s), StartSize(S.size()), St(st) {}
+
+ ~AutoPopulate() {
+ if (StartSize == S.size())
+ S.Add(St);
+ }
+ };
+};
+
+//===----------------------------------------------------------------------===//
+// GRStateManager - Factory object for GRStates.
+//===----------------------------------------------------------------------===//
+
+class GRStateManager {
+ friend class GRState;
+ friend class GRExprEngine; // FIXME: Remove.
+private:
+ EnvironmentManager EnvMgr;
+ llvm::OwningPtr<StoreManager> StoreMgr;
+ llvm::OwningPtr<ConstraintManager> ConstraintMgr;
+
+ GRState::GenericDataMap::Factory GDMFactory;
+
+ typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
+ GDMContextsTy GDMContexts;
+
+ /// Printers - A set of printer objects used for pretty-printing a GRState.
+ /// GRStateManager owns these objects.
+ std::vector<GRState::Printer*> Printers;
+
+ /// StateSet - FoldingSet containing all the states created for analyzing
+ /// a particular function. This is used to unique states.
+ llvm::FoldingSet<GRState> StateSet;
+
+ /// ValueMgr - Object that manages the data for all created SVals.
+ ValueManager ValueMgr;
+
+ /// Alloc - A BumpPtrAllocator to allocate states.
+ llvm::BumpPtrAllocator &Alloc;
+
+public:
+ GRStateManager(ASTContext& Ctx,
+ StoreManagerCreator CreateStoreManager,
+ ConstraintManagerCreator CreateConstraintManager,
+ llvm::BumpPtrAllocator& alloc,
+ GRSubEngine &subeng)
+ : EnvMgr(alloc),
+ GDMFactory(alloc),
+ ValueMgr(alloc, Ctx, *this),
+ Alloc(alloc) {
+ StoreMgr.reset((*CreateStoreManager)(*this));
+ ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng));
+ }
+
+ ~GRStateManager();
+
+ const GRState *getInitialState(const LocationContext *InitLoc);
+
+ ASTContext &getContext() { return ValueMgr.getContext(); }
+ const ASTContext &getContext() const { return ValueMgr.getContext(); }
+
+ BasicValueFactory &getBasicVals() {
+ return ValueMgr.getBasicValueFactory();
+ }
+ const BasicValueFactory& getBasicVals() const {
+ return ValueMgr.getBasicValueFactory();
+ }
+
+ SymbolManager &getSymbolManager() {
+ return ValueMgr.getSymbolManager();
+ }
+ const SymbolManager &getSymbolManager() const {
+ return ValueMgr.getSymbolManager();
+ }
+
+ ValueManager &getValueManager() { return ValueMgr; }
+ const ValueManager &getValueManager() const { return ValueMgr; }
+
+ llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
+
+ MemRegionManager& getRegionManager() {
+ return ValueMgr.getRegionManager();
+ }
+ const MemRegionManager& getRegionManager() const {
+ return ValueMgr.getRegionManager();
+ }
+
+ StoreManager& getStoreManager() { return *StoreMgr; }
+ ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
+
+ const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
+ const StackFrameContext *LCtx,
+ SymbolReaper& SymReaper);
+
+public:
+
+ SVal ArrayToPointer(Loc Array) {
+ return StoreMgr->ArrayToPointer(Array);
+ }
+
+ // Methods that manipulate the GDM.
+ const GRState* addGDM(const GRState* St, void* Key, void* Data);
+ const GRState *removeGDM(const GRState *state, void *Key);
+
+ // Methods that query & manipulate the Store.
+
+ void iterBindings(const GRState* state, StoreManager::BindingsHandler& F) {
+ StoreMgr->iterBindings(state->getStore(), F);
+ }
+
+ const GRState* getPersistentState(GRState& Impl);
+
+ bool isEqual(const GRState* state, const Expr* Ex, const llvm::APSInt& V);
+ bool isEqual(const GRState* state, const Expr* Ex, uint64_t);
+
+ //==---------------------------------------------------------------------==//
+ // Generic Data Map methods.
+ //==---------------------------------------------------------------------==//
+ //
+ // GRStateManager and GRState support a "generic data map" that allows
+ // different clients of GRState objects to embed arbitrary data within a
+ // GRState 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 GRStateTrait<T> class
+ // to resolve keys into the GDM and to return data values to clients.
+ //
+
+ // Trait based GDM dispatch.
+ template <typename T>
+ const GRState* set(const GRState* st, typename GRStateTrait<T>::data_type D) {
+ return addGDM(st, GRStateTrait<T>::GDMIndex(),
+ GRStateTrait<T>::MakeVoidPtr(D));
+ }
+
+ template<typename T>
+ const GRState* set(const GRState* st,
+ typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::value_type V,
+ typename GRStateTrait<T>::context_type C) {
+
+ return addGDM(st, GRStateTrait<T>::GDMIndex(),
+ GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C)));
+ }
+
+ template <typename T>
+ const GRState* add(const GRState* st,
+ typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::context_type C) {
+ return addGDM(st, GRStateTrait<T>::GDMIndex(),
+ GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Add(st->get<T>(), K, C)));
+ }
+
+ template <typename T>
+ const GRState* remove(const GRState* st,
+ typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::context_type C) {
+
+ return addGDM(st, GRStateTrait<T>::GDMIndex(),
+ GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C)));
+ }
+
+ template <typename T>
+ const GRState *remove(const GRState *st) {
+ return removeGDM(st, GRStateTrait<T>::GDMIndex());
+ }
+
+ void* FindGDMContext(void* index,
+ void* (*CreateContext)(llvm::BumpPtrAllocator&),
+ void (*DeleteContext)(void*));
+
+ template <typename T>
+ typename GRStateTrait<T>::context_type get_context() {
+ void* p = FindGDMContext(GRStateTrait<T>::GDMIndex(),
+ GRStateTrait<T>::CreateContext,
+ GRStateTrait<T>::DeleteContext);
+
+ return GRStateTrait<T>::MakeContext(p);
+ }
+
+ const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) {
+ return ConstraintMgr->getSymVal(St, sym);
+ }
+
+ void EndPath(const GRState* St) {
+ ConstraintMgr->EndPath(St);
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Out-of-line method definitions for GRState.
+//===----------------------------------------------------------------------===//
+
+inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) {
+ return getStateManager().getSymVal(this, sym);
+}
+
+inline const VarRegion* GRState::getRegion(const VarDecl *D,
+ const LocationContext *LC) const {
+ return getStateManager().getRegionManager().getVarRegion(D, LC);
+}
+
+inline const GRState *GRState::Assume(DefinedOrUnknownSVal Cond,
+ bool Assumption) const {
+ if (Cond.isUnknown())
+ return this;
+
+ return getStateManager().ConstraintMgr->Assume(this, cast<DefinedSVal>(Cond),
+ Assumption);
+}
+
+inline std::pair<const GRState*, const GRState*>
+GRState::Assume(DefinedOrUnknownSVal Cond) const {
+ if (Cond.isUnknown())
+ return std::make_pair(this, this);
+
+ return getStateManager().ConstraintMgr->AssumeDual(this,
+ cast<DefinedSVal>(Cond));
+}
+
+inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
+ DefinedOrUnknownSVal UpperBound,
+ bool Assumption) const {
+ if (Idx.isUnknown() || UpperBound.isUnknown())
+ return this;
+
+ ConstraintManager &CM = *getStateManager().ConstraintMgr;
+ return CM.AssumeInBound(this, cast<DefinedSVal>(Idx),
+ cast<DefinedSVal>(UpperBound), Assumption);
+}
+
+inline const GRState *
+GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
+ const LocationContext *LC, SVal V) const {
+ Store new_store =
+ getStateManager().StoreMgr->BindCompoundLiteral(St, CL, LC, V);
+ return makeWithStore(new_store);
+}
+
+inline const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
+ Store new_store = getStateManager().StoreMgr->BindDecl(St, VR, IVal);
+ return makeWithStore(new_store);
+}
+
+inline const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const {
+ Store new_store = getStateManager().StoreMgr->BindDeclWithNoInit(St, VR);
+ return makeWithStore(new_store);
+}
+
+inline const GRState *GRState::bindLoc(Loc LV, SVal V) const {
+ Store new_store = getStateManager().StoreMgr->Bind(St, LV, V);
+ return makeWithStore(new_store);
+}
+
+inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
+ return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
+}
+
+inline SVal GRState::getLValue(const VarDecl* VD,
+ const LocationContext *LC) const {
+ return getStateManager().StoreMgr->getLValueVar(VD, LC);
+}
+
+inline SVal GRState::getLValue(const StringLiteral *literal) const {
+ return getStateManager().StoreMgr->getLValueString(literal);
+}
+
+inline SVal GRState::getLValue(const CompoundLiteralExpr *literal,
+ const LocationContext *LC) const {
+ return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
+}
+
+inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
+ return getStateManager().StoreMgr->getLValueIvar(D, Base);
+}
+
+inline SVal GRState::getLValue(const FieldDecl* D, SVal Base) const {
+ return getStateManager().StoreMgr->getLValueField(D, Base);
+}
+
+inline SVal GRState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
+ return getStateManager().StoreMgr->getLValueElement(ElementType, Idx, Base);
+}
+
+inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const {
+ return getStateManager().getSymVal(this, sym);
+}
+
+inline SVal GRState::getSVal(const Stmt* Ex) const {
+ return Env.GetSVal(Ex, getStateManager().ValueMgr);
+}
+
+inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
+ if (const Expr *Ex = dyn_cast<Expr>(S)) {
+ QualType T = Ex->getType();
+ if (Loc::IsLocType(T) || T->isIntegerType())
+ return getSVal(S);
+ }
+
+ return UnknownVal();
+}
+
+inline SVal GRState::getSVal(Loc LV, QualType T) const {
+ return getStateManager().StoreMgr->Retrieve(St, LV, T);
+}
+
+inline SVal GRState::getSVal(const MemRegion* R) const {
+ return getStateManager().StoreMgr->Retrieve(St, loc::MemRegionVal(R));
+}
+
+inline BasicValueFactory &GRState::getBasicVals() const {
+ return getStateManager().getBasicVals();
+}
+
+inline SymbolManager &GRState::getSymbolManager() const {
+ return getStateManager().getSymbolManager();
+}
+
+template<typename T>
+const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const {
+ return getStateManager().add<T>(this, K, get_context<T>());
+}
+
+template <typename T>
+typename GRStateTrait<T>::context_type GRState::get_context() const {
+ return getStateManager().get_context<T>();
+}
+
+template<typename T>
+const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const {
+ return getStateManager().remove<T>(this, K, get_context<T>());
+}
+
+template<typename T>
+const GRState *GRState::remove(typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::context_type C) const {
+ return getStateManager().remove<T>(this, K, C);
+}
+
+template <typename T>
+const GRState *GRState::remove() const {
+ return getStateManager().remove<T>(this);
+}
+
+template<typename T>
+const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const {
+ return getStateManager().set<T>(this, D);
+}
+
+template<typename T>
+const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::value_type E) const {
+ return getStateManager().set<T>(this, K, E, get_context<T>());
+}
+
+template<typename T>
+const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::value_type E,
+ typename GRStateTrait<T>::context_type C) const {
+ return getStateManager().set<T>(this, K, E, C);
+}
+
+template <typename CB>
+CB GRState::scanReachableSymbols(SVal val) const {
+ CB cb(this);
+ scanReachableSymbols(val, cb);
+ return cb;
+}
+
+template <typename CB>
+CB GRState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
+ CB cb(this);
+ scanReachableSymbols(beg, end, cb);
+ return cb;
+}
+
+template <typename CB>
+CB GRState::scanReachableSymbols(const MemRegion * const *beg,
+ const MemRegion * const *end) const {
+ CB cb(this);
+ scanReachableSymbols(beg, end, cb);
+ return cb;
+}
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRStateTrait.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRStateTrait.h
new file mode 100644
index 0000000..5189a1f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRStateTrait.h
@@ -0,0 +1,148 @@
+//==- GRStateTrait.h - Partial implementations of GRStateTrait -----*- 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 GRStateTrait<>. GRStateTrait<> is used by GRState to implement
+// set/get methods for mapulating a GRState's generic data map.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H
+#define LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H
+
+namespace llvm {
+ class BumpPtrAllocator;
+ 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 {
+ template <typename T> struct GRStatePartialTrait;
+
+ // Partial-specialization for ImmutableMap.
+
+ template <typename Key, typename Data, typename Info>
+ struct GRStatePartialTrait< 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(0);
+ }
+ 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;
+ }
+ };
+
+
+ // Partial-specialization for ImmutableSet.
+
+ template <typename Key, typename Info>
+ struct GRStatePartialTrait< 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(0);
+ }
+
+ 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 GRStatePartialTrait< 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 inline data_type MakeData(void* const* p) {
+ return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
+ : data_type(0);
+ }
+
+ static inline void* MakeVoidPtr(data_type D) {
+ return (void*) 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;
+ }
+ };
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRSubEngine.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRSubEngine.h
new file mode 100644
index 0000000..d2e7457
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRSubEngine.h
@@ -0,0 +1,84 @@
+//== GRSubEngine.h - Interface of the subengine of GRCoreEngine ----*- 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 GRCoreEngine.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
+#define LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
+
+#include "clang/Checker/PathSensitive/SVals.h"
+
+namespace clang {
+
+class Stmt;
+class CFGBlock;
+class CFGElement;
+class ExplodedNode;
+class GRState;
+class GRStateManager;
+class GRBlockCounter;
+class GRStmtNodeBuilder;
+class GRBranchNodeBuilder;
+class GRIndirectGotoNodeBuilder;
+class GRSwitchNodeBuilder;
+class GREndPathNodeBuilder;
+class GRCallEnterNodeBuilder;
+class GRCallExitNodeBuilder;
+class LocationContext;
+
+class GRSubEngine {
+public:
+ virtual ~GRSubEngine() {}
+
+ virtual const GRState* getInitialState(const LocationContext *InitLoc) = 0;
+
+ virtual GRStateManager& getStateManager() = 0;
+
+ /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
+ /// nodes by processing the 'effects' of a block-level statement.
+ virtual void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder) = 0;
+
+ /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
+ /// a CFGBlock. This method returns true if the analysis should continue
+ /// exploring the given path, and false otherwise.
+ virtual bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
+ GRBlockCounter BC) = 0;
+
+ /// ProcessBranch - Called by GRCoreEngine. Used to generate successor
+ /// nodes by processing the 'effects' of a branch condition.
+ virtual void ProcessBranch(Stmt* Condition, Stmt* Term,
+ GRBranchNodeBuilder& builder) = 0;
+
+ /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
+ /// nodes by processing the 'effects' of a computed goto jump.
+ virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) = 0;
+
+ /// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
+ /// nodes by processing the 'effects' of a switch statement.
+ virtual void ProcessSwitch(GRSwitchNodeBuilder& builder) = 0;
+
+ /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
+ /// nodes when the control reaches the end of a function.
+ virtual void ProcessEndPath(GREndPathNodeBuilder& builder) = 0;
+
+ // Generate the entry node of the callee.
+ virtual void ProcessCallEnter(GRCallEnterNodeBuilder &builder) = 0;
+
+ // Generate the first post callsite node.
+ virtual void ProcessCallExit(GRCallExitNodeBuilder &builder) = 0;
+
+ /// EvalAssume - Called by ConstraintManager. Used to call checker-specific
+ /// logic for handling assumptions on symbolic values.
+ virtual const GRState* ProcessAssume(const GRState *state,
+ SVal cond, bool assumption) = 0;
+};
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRTransferFuncs.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRTransferFuncs.h
new file mode 100644
index 0000000..13325ed
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRTransferFuncs.h
@@ -0,0 +1,87 @@
+//== GRTransferFuncs.h - Path-Sens. Transfer Functions 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 GRTransferFuncs, which provides a base-class that
+// defines an interface for transfer functions used by GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRTF
+#define LLVM_CLANG_ANALYSIS_GRTF
+
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include <vector>
+
+namespace clang {
+class ExplodedNode;
+class ExplodedNodeSet;
+class GREndPathNodeBuilder;
+class GRExprEngine;
+class GRStmtNodeBuilder;
+class GRStmtNodeBuilderRef;
+class ObjCMessageExpr;
+
+class GRTransferFuncs {
+public:
+ GRTransferFuncs() {}
+ virtual ~GRTransferFuncs() {}
+
+ virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {}
+ virtual void RegisterChecks(GRExprEngine& Eng) {}
+
+
+ // Calls.
+
+ virtual void EvalCall(ExplodedNodeSet& Dst,
+ GRExprEngine& Engine,
+ GRStmtNodeBuilder& Builder,
+ CallExpr* CE, SVal L,
+ ExplodedNode* Pred) {}
+
+ virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
+ GRExprEngine& Engine,
+ GRStmtNodeBuilder& Builder,
+ ObjCMessageExpr* ME,
+ ExplodedNode* Pred,
+ const GRState *state) {}
+
+ // Stores.
+
+ virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {}
+
+ // End-of-path and dead symbol notification.
+
+ virtual void EvalEndPath(GRExprEngine& Engine,
+ GREndPathNodeBuilder& Builder) {}
+
+
+ virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
+ GRExprEngine& Engine,
+ GRStmtNodeBuilder& Builder,
+ ExplodedNode* Pred,
+ Stmt* S, const GRState* state,
+ SymbolReaper& SymReaper) {}
+
+ // Return statements.
+ virtual void EvalReturn(ExplodedNodeSet& Dst,
+ GRExprEngine& Engine,
+ GRStmtNodeBuilder& Builder,
+ ReturnStmt* S,
+ ExplodedNode* Pred) {}
+
+ // Assumptions.
+ virtual const GRState* EvalAssume(const GRState *state,
+ SVal Cond, bool Assumption) {
+ return state;
+ }
+};
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRWorkList.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRWorkList.h
new file mode 100644
index 0000000..b8f90fa
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/GRWorkList.h
@@ -0,0 +1,79 @@
+//==- GRWorkList.h - Worklist class used by GRCoreEngine -----------*- 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 GRWorkList, a pure virtual class that represents an opaque
+// worklist used by GRCoreEngine to explore the reachability state space.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRWORKLIST
+#define LLVM_CLANG_ANALYSIS_GRWORKLIST
+
+#include "clang/Checker/PathSensitive/GRBlockCounter.h"
+#include <cstddef>
+
+namespace clang {
+
+class CFGBlock;
+class ExplodedNode;
+class ExplodedNodeImpl;
+
+class GRWorkListUnit {
+ ExplodedNode* Node;
+ GRBlockCounter Counter;
+ CFGBlock* Block;
+ unsigned BlockIdx; // This is the index of the next statement.
+
+public:
+ GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
+ CFGBlock* B, unsigned idx)
+ : Node(N),
+ Counter(C),
+ Block(B),
+ BlockIdx(idx) {}
+
+ explicit GRWorkListUnit(ExplodedNode* N, GRBlockCounter C)
+ : Node(N),
+ Counter(C),
+ Block(NULL),
+ BlockIdx(0) {}
+
+ ExplodedNode* getNode() const { return Node; }
+ GRBlockCounter getBlockCounter() const { return Counter; }
+ CFGBlock* getBlock() const { return Block; }
+ unsigned getIndex() const { return BlockIdx; }
+};
+
+class GRWorkList {
+ GRBlockCounter CurrentCounter;
+public:
+ virtual ~GRWorkList();
+ virtual bool hasWork() const = 0;
+
+ virtual void Enqueue(const GRWorkListUnit& U) = 0;
+
+ void Enqueue(ExplodedNode* N, CFGBlock& B, unsigned idx) {
+ Enqueue(GRWorkListUnit(N, CurrentCounter, &B, idx));
+ }
+
+ void Enqueue(ExplodedNode* N) {
+ Enqueue(GRWorkListUnit(N, CurrentCounter));
+ }
+
+ virtual GRWorkListUnit Dequeue() = 0;
+
+ void setBlockCounter(GRBlockCounter C) { CurrentCounter = C; }
+ GRBlockCounter getBlockCounter() const { return CurrentCounter; }
+
+ static GRWorkList *MakeDFS();
+ static GRWorkList *MakeBFS();
+ static GRWorkList *MakeBFSBlockDFSContents();
+};
+} // end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/MemRegion.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/MemRegion.h
new file mode 100644
index 0000000..2ab3b42
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/MemRegion.h
@@ -0,0 +1,967 @@
+//== 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_ANALYSIS_MEMREGION_H
+#define LLVM_CLANG_ANALYSIS_MEMREGION_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <string>
+
+namespace llvm {
+class BumpPtrAllocator;
+class raw_ostream;
+}
+
+namespace clang {
+
+class MemRegionManager;
+class MemSpaceRegion;
+class LocationContext;
+class StackFrameContext;
+class VarRegion;
+
+//===----------------------------------------------------------------------===//
+// 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.
+ BEG_MEMSPACES,
+ GenericMemSpaceRegionKind = BEG_MEMSPACES,
+ StackLocalsSpaceRegionKind,
+ StackArgumentsSpaceRegionKind,
+ HeapSpaceRegionKind,
+ UnknownSpaceRegionKind,
+ GlobalsSpaceRegionKind,
+ END_MEMSPACES = GlobalsSpaceRegionKind,
+ // Untyped regions.
+ SymbolicRegionKind,
+ AllocaRegionKind,
+ // Typed regions.
+ BEG_TYPED_REGIONS,
+ FunctionTextRegionKind = BEG_TYPED_REGIONS,
+ BlockTextRegionKind,
+ BlockDataRegionKind,
+ CompoundLiteralRegionKind,
+ CXXThisRegionKind,
+ StringRegionKind,
+ ElementRegionKind,
+ // Decl Regions.
+ BEG_DECL_REGIONS,
+ VarRegionKind = BEG_DECL_REGIONS,
+ FieldRegionKind,
+ ObjCIvarRegionKind,
+ CXXObjectRegionKind,
+ END_DECL_REGIONS = CXXObjectRegionKind,
+ END_TYPED_REGIONS = END_DECL_REGIONS
+ };
+
+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;
+
+ std::string getString() const;
+
+ const MemSpaceRegion *getMemorySpace() const;
+
+ const MemRegion *getBaseRegion() const;
+
+ const MemRegion *StripCasts() const;
+
+ bool hasGlobalsOrParametersStorage() const;
+
+ bool hasStackStorage() const;
+
+ bool hasStackNonParametersStorage() const;
+
+ bool hasStackParametersStorage() const;
+
+ virtual void dumpToStream(llvm::raw_ostream& os) const;
+
+ void dump() const;
+
+ Kind getKind() const { return kind; }
+
+ template<typename RegionTy> const RegionTy* getAs() const;
+
+ virtual bool isBoundable() const { return false; }
+
+ static bool classof(const MemRegion*) { return true; }
+};
+
+/// MemSpaceRegion - A memory region that represents and "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 { return Mgr; }
+
+public:
+ bool isBoundable() const { return false; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
+ static bool classof(const MemRegion *R) {
+ Kind k = R->getKind();
+ return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
+ }
+};
+
+class GlobalsSpaceRegion : public MemSpaceRegion {
+ friend class MemRegionManager;
+
+ GlobalsSpaceRegion(MemRegionManager *mgr)
+ : MemSpaceRegion(mgr, GlobalsSpaceRegionKind) {}
+public:
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == GlobalsSpaceRegionKind;
+ }
+};
+
+class HeapSpaceRegion : public MemSpaceRegion {
+ friend class MemRegionManager;
+
+ HeapSpaceRegion(MemRegionManager *mgr)
+ : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
+public:
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == HeapSpaceRegionKind;
+ }
+};
+
+class UnknownSpaceRegion : public MemSpaceRegion {
+ friend class MemRegionManager;
+ UnknownSpaceRegion(MemRegionManager *mgr)
+ : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
+public:
+ 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;
+
+ static bool classof(const MemRegion *R) {
+ Kind k = R->getKind();
+ return k >= StackLocalsSpaceRegionKind &&
+ k <= StackArgumentsSpaceRegionKind;
+ }
+};
+
+class StackLocalsSpaceRegion : public StackSpaceRegion {
+private:
+ friend class MemRegionManager;
+ StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+ : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
+public:
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == StackLocalsSpaceRegionKind;
+ }
+};
+
+class StackArgumentsSpaceRegion : public StackSpaceRegion {
+private:
+ friend class MemRegionManager;
+ StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+ : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
+public:
+ 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 {
+protected:
+ const MemRegion* superRegion;
+ SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
+public:
+ const MemRegion* getSuperRegion() const {
+ return superRegion;
+ }
+
+ MemRegionManager* getMemRegionManager() const;
+
+ bool isSubRegionOf(const MemRegion* R) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() > END_MEMSPACES;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Auxillary data classes for use with MemRegions.
+//===----------------------------------------------------------------------===//
+
+class ElementRegion;
+
+class RegionRawOffset {
+private:
+ friend class ElementRegion;
+
+ const MemRegion *Region;
+ int64_t Offset;
+
+ RegionRawOffset(const MemRegion* reg, int64_t offset = 0)
+ : Region(reg), Offset(offset) {}
+
+public:
+ // FIXME: Eventually support symbolic offsets.
+ int64_t getByteOffset() const { return Offset; }
+ const MemRegion *getRegion() const { return Region; }
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+ void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+// 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 { return true; }
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
+ unsigned Cnt, const MemRegion *superRegion);
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == AllocaRegionKind;
+ }
+};
+
+/// TypedRegion - An abstract class representing regions that are typed.
+class TypedRegion : public SubRegion {
+protected:
+ TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
+
+public:
+ virtual QualType getValueType(ASTContext &C) const = 0;
+
+ virtual QualType getLocationType(ASTContext& C) const {
+ // FIXME: We can possibly optimize this later to cache this value.
+ return C.getPointerType(getValueType(C));
+ }
+
+ QualType getDesugaredValueType(ASTContext& C) const {
+ QualType T = getValueType(C);
+ return T.getTypePtr() ? T.getDesugaredType() : T;
+ }
+
+ QualType getDesugaredLocationType(ASTContext& C) const {
+ return getLocationType(C).getDesugaredType();
+ }
+
+ bool isBoundable() const {
+ return !getValueType(getContext()).isNull();
+ }
+
+ static bool classof(const MemRegion* R) {
+ unsigned k = R->getKind();
+ return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
+ }
+};
+
+
+class CodeTextRegion : public TypedRegion {
+protected:
+ CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
+public:
+ QualType getValueType(ASTContext &C) const {
+ // Do not get the object type of a CodeTextRegion.
+ assert(0);
+ return QualType();
+ }
+
+ bool isBoundable() const { 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 FunctionDecl *FD;
+public:
+ FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
+ : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
+
+ QualType getLocationType(ASTContext &C) const {
+ return C.getPointerType(FD->getType());
+ }
+
+ const FunctionDecl *getDecl() const {
+ return FD;
+ }
+
+ virtual void dumpToStream(llvm::raw_ostream& os) const;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *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;
+ AnalysisContext *AC;
+ CanQualType locTy;
+
+ BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
+ AnalysisContext *ac, const MemRegion* sreg)
+ : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
+
+public:
+ QualType getLocationType(ASTContext &C) const {
+ return locTy;
+ }
+
+ const BlockDecl *getDecl() const {
+ return BD;
+ }
+
+ AnalysisContext *getAnalysisContext() const { return AC; }
+
+ virtual void dumpToStream(llvm::raw_ostream& os) const;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
+ CanQualType, const AnalysisContext*,
+ 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 SubRegion {
+ friend class MemRegionManager;
+ const BlockTextRegion *BC;
+ const LocationContext *LC; // Can be null */
+ void *ReferencedVars;
+
+ BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
+ const MemRegion *sreg)
+ : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
+
+public:
+ const BlockTextRegion *getCodeRegion() const { return BC; }
+
+ const BlockDecl *getDecl() const { return BC->getDecl(); }
+
+ class referenced_vars_iterator {
+ const MemRegion * const *R;
+ public:
+ explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {}
+
+ operator const MemRegion * const *() const {
+ return R;
+ }
+
+ const VarRegion* operator*() const {
+ return cast<VarRegion>(*R);
+ }
+
+ bool operator==(const referenced_vars_iterator &I) const {
+ return I.R == R;
+ }
+ bool operator!=(const referenced_vars_iterator &I) const {
+ return I.R != R;
+ }
+ referenced_vars_iterator& operator++() {
+ ++R;
+ return *this;
+ }
+ };
+
+ referenced_vars_iterator referenced_vars_begin() const;
+ referenced_vars_iterator referenced_vars_end() const;
+
+ virtual void dumpToStream(llvm::raw_ostream& os) const;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
+ const LocationContext *, const MemRegion *);
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == BlockDataRegionKind;
+ }
+private:
+ void LazyInitializeReferencedVars();
+};
+
+/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
+/// clases, 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 { return true; }
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+ SymbolRef sym,
+ const MemRegion* superRegion);
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == SymbolicRegionKind;
+ }
+};
+
+/// StringRegion - Region associated with a StringLiteral.
+class StringRegion : public TypedRegion {
+ friend class MemRegionManager;
+ const StringLiteral* Str;
+protected:
+
+ StringRegion(const StringLiteral* str, const MemRegion* sreg)
+ : TypedRegion(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(ASTContext& C) const {
+ return Str->getType();
+ }
+
+ bool isBoundable() const { return false; }
+
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ ProfileRegion(ID, Str, superRegion);
+ }
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == StringRegionKind;
+ }
+};
+
+/// 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 TypedRegion {
+private:
+ friend class MemRegionManager;
+ const CompoundLiteralExpr* CL;
+
+ CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg)
+ : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+ const CompoundLiteralExpr* CL,
+ const MemRegion* superRegion);
+public:
+ QualType getValueType(ASTContext& C) const {
+ return C.getCanonicalType(CL->getType());
+ }
+
+ bool isBoundable() const { return !CL->isFileScope(); }
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ const CompoundLiteralExpr* getLiteralExpr() const { return CL; }
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == CompoundLiteralRegionKind;
+ }
+};
+
+class DeclRegion : public TypedRegion {
+protected:
+ const Decl* D;
+
+ DeclRegion(const Decl* d, const MemRegion* sReg, Kind k)
+ : TypedRegion(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;
+
+ 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;
+
+public:
+ const VarDecl *getDecl() const { return cast<VarDecl>(D); }
+
+ const StackFrameContext *getStackFrame() const;
+
+ QualType getValueType(ASTContext& C) const {
+ // FIXME: We can cache this if needed.
+ return C.getCanonicalType(getDecl()->getType());
+ }
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == VarRegionKind;
+ }
+};
+
+/// 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 TypedRegion {
+ friend class MemRegionManager;
+ CXXThisRegion(const PointerType *thisPointerTy,
+ const MemRegion *sReg)
+ : TypedRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
+
+ static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+ const PointerType *PT,
+ const MemRegion *sReg);
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
+public:
+ QualType getValueType(ASTContext &C) const {
+ return QualType(ThisPointerTy, 0);
+ }
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ 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:
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
+
+ QualType getValueType(ASTContext& C) const {
+ // FIXME: We can cache this if needed.
+ return C.getCanonicalType(getDecl()->getType());
+ }
+
+ 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;
+ }
+};
+
+class ObjCIvarRegion : public DeclRegion {
+
+ friend class MemRegionManager;
+
+ ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg)
+ : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl* ivd,
+ const MemRegion* superRegion) {
+ DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
+ }
+
+public:
+ const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
+ QualType getValueType(ASTContext&) const { return getDecl()->getType(); }
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == ObjCIvarRegionKind;
+ }
+};
+
+class ElementRegion : public TypedRegion {
+ friend class MemRegionManager;
+
+ QualType ElementType;
+ SVal Index;
+
+ ElementRegion(QualType elementType, SVal Idx, const MemRegion* sReg)
+ : TypedRegion(sReg, ElementRegionKind),
+ ElementType(elementType), Index(Idx) {
+ assert((!isa<nonloc::ConcreteInt>(&Idx) ||
+ cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
+ "The index must be signed");
+ }
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
+ SVal Idx, const MemRegion* superRegion);
+
+public:
+
+ SVal getIndex() const { return Index; }
+
+ QualType getValueType(ASTContext&) const {
+ return ElementType;
+ }
+
+ QualType getElementType() const {
+ return ElementType;
+ }
+
+ RegionRawOffset getAsRawOffset() const;
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == ElementRegionKind;
+ }
+};
+
+// C++ temporary object associated with an expression.
+class CXXObjectRegion : public TypedRegion {
+ friend class MemRegionManager;
+
+ Expr const *Ex;
+
+ CXXObjectRegion(Expr const *E, MemRegion const *sReg)
+ : TypedRegion(sReg, CXXObjectRegionKind), Ex(E) {}
+
+ static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+ Expr const *E, const MemRegion *sReg);
+
+public:
+ QualType getValueType(ASTContext& C) const {
+ return Ex->getType();
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == CXXObjectRegionKind;
+ }
+};
+
+template<typename RegionTy>
+const RegionTy* MemRegion::getAs() const {
+ if (const RegionTy* RT = dyn_cast<RegionTy>(this))
+ return RT;
+
+ return NULL;
+}
+
+//===----------------------------------------------------------------------===//
+// MemRegionManager - Factory object for creating regions.
+//===----------------------------------------------------------------------===//
+
+class MemRegionManager {
+ ASTContext &C;
+ llvm::BumpPtrAllocator& A;
+ llvm::FoldingSet<MemRegion> Regions;
+
+ GlobalsSpaceRegion *globals;
+
+ llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
+ StackLocalsSpaceRegions;
+ llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
+ StackArgumentsSpaceRegions;
+
+ HeapSpaceRegion *heap;
+ UnknownSpaceRegion *unknown;
+ MemSpaceRegion *code;
+
+public:
+ MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
+ : C(c), A(a), globals(0), heap(0), unknown(0), code(0) {}
+
+ ~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
+ /// all global variables.
+ const GlobalsSpaceRegion *getGlobalsRegion();
+
+ /// 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 [artifical] region associated with the
+ /// parameter 'this'.
+ const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
+ const LocationContext *LC);
+
+ /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
+ const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
+
+ const StringRegion* getStringRegion(const StringLiteral* 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, SVal 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 CXXObjectRegion *getCXXObjectRegion(Expr const *Ex,
+ LocationContext const *LC);
+
+ const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
+ const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
+ CanQualType locTy,
+ AnalysisContext *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 = NULL);
+
+ bool isGlobalsRegion(const MemRegion* R) {
+ assert(R);
+ return R == globals;
+ }
+
+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();
+}
+
+} // end clang namespace
+
+//===----------------------------------------------------------------------===//
+// Pretty-printing regions.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+static inline raw_ostream& operator<<(raw_ostream& os,
+ const clang::MemRegion* R) {
+ R->dumpToStream(os);
+ return os;
+}
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SVals.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SVals.h
new file mode 100644
index 0000000..040db83
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SVals.h
@@ -0,0 +1,502 @@
+//== 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_ANALYSIS_RVALUE_H
+#define LLVM_CLANG_ANALYSIS_RVALUE_H
+
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/ImmutableList.h"
+
+namespace llvm {
+ class raw_ostream;
+}
+
+//==------------------------------------------------------------------------==//
+// Base SVal types.
+//==------------------------------------------------------------------------==//
+
+namespace clang {
+
+class CompoundValData;
+class LazyCompoundValData;
+class GRState;
+class BasicValueFactory;
+class MemRegion;
+class TypedRegion;
+class MemRegionManager;
+class GRStateManager;
+class ValueManager;
+
+class SVal {
+public:
+ enum BaseKind { UndefinedKind, UnknownKind, LocKind, NonLocKind };
+ enum { BaseBits = 2, BaseMask = 0x3 };
+
+protected:
+ void* Data;
+ unsigned Kind;
+
+protected:
+ SVal(const void* d, bool isLoc, unsigned ValKind)
+ : Data(const_cast<void*>(d)),
+ Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
+
+ explicit SVal(BaseKind k, void* D = NULL)
+ : Data(D), Kind(k) {}
+
+public:
+ SVal() : Data(0), Kind(0) {}
+ ~SVal() {}
+
+ /// BufferTy - A temporary buffer to hold a set of SVals.
+ typedef llvm::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; }
+
+ inline void Profile(llvm::FoldingSetNodeID& ID) const {
+ ID.AddInteger((unsigned) getRawKind());
+ ID.AddPointer(reinterpret_cast<void*>(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 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;
+
+ /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
+ /// wraps a symbol, return that SymbolRef. Otherwise return a SymbolData*
+ SymbolRef getAsLocSymbol() const;
+
+ /// Get the symbol in the SVal or its base region.
+ SymbolRef getLocSymbolInBase() const;
+
+ /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
+ /// Otherwise return a SymbolRef where 'isValid()' returns false.
+ SymbolRef getAsSymbol() const;
+
+ /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
+ /// return that expression. Otherwise return NULL.
+ const SymExpr *getAsSymbolicExpression() const;
+
+ const MemRegion *getAsRegion() const;
+
+ void dumpToStream(llvm::raw_ostream& OS) const;
+ void dump() const;
+
+ // Iterators.
+ class symbol_iterator {
+ llvm::SmallVector<const SymExpr*, 5> itr;
+ void expand();
+ public:
+ symbol_iterator() {}
+ symbol_iterator(const SymExpr* SE);
+
+ symbol_iterator& operator++();
+ SymbolRef operator*();
+
+ bool operator==(const symbol_iterator& X) const;
+ bool operator!=(const symbol_iterator& X) const;
+ };
+
+ symbol_iterator symbol_begin() const {
+ const SymExpr *SE = getAsSymbolicExpression();
+ if (SE)
+ return symbol_iterator(SE);
+ else
+ return symbol_iterator();
+ }
+
+ symbol_iterator symbol_end() const { return symbol_iterator(); }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SVal*) { return true; }
+};
+
+
+class UndefinedVal : public SVal {
+public:
+ UndefinedVal() : SVal(UndefinedKind) {}
+ UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
+
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == UndefinedKind;
+ }
+
+ void* getData() const { return Data; }
+};
+
+class DefinedOrUnknownSVal : public SVal {
+private:
+ // Do not implement. We want calling these methods to be a compiler
+ // error since they are tautologically false.
+ bool isUndef() const;
+ bool isValid() const;
+
+protected:
+ explicit DefinedOrUnknownSVal(const void* d, bool isLoc, unsigned ValKind)
+ : SVal(d, isLoc, ValKind) {}
+
+ explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
+ : SVal(k, D) {}
+
+public:
+ // Implement isa<T> support.
+ static inline bool classof(const SVal *V) {
+ return !V->isUndef();
+ }
+};
+
+class UnknownVal : public DefinedOrUnknownSVal {
+public:
+ UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
+
+ static inline bool classof(const SVal *V) {
+ return V->getBaseKind() == UnknownKind;
+ }
+};
+
+class DefinedSVal : public DefinedOrUnknownSVal {
+private:
+ // Do not implement. We want calling these methods to be a compiler
+ // error since they are tautologically true/false.
+ bool isUnknown() const;
+ bool isUnknownOrUndef() const;
+ bool isValid() const;
+protected:
+ DefinedSVal(const void* d, bool isLoc, unsigned ValKind)
+ : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
+public:
+ // Implement isa<T> support.
+ static inline bool classof(const SVal *V) {
+ return !V->isUnknownOrUndef();
+ }
+};
+
+class NonLoc : public DefinedSVal {
+protected:
+ NonLoc(unsigned SubKind, const void* d) : DefinedSVal(d, false, SubKind) {}
+
+public:
+ void dumpToStream(llvm::raw_ostream& Out) const;
+
+ // Implement isa<T> support.
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == NonLocKind;
+ }
+};
+
+class Loc : public DefinedSVal {
+protected:
+ Loc(unsigned SubKind, const void* D)
+ : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
+
+public:
+ void dumpToStream(llvm::raw_ostream& Out) const;
+
+ Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {}
+ Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == LocKind;
+ }
+
+ static inline bool IsLocType(QualType T) {
+ return T->isAnyPointerType() || T->isBlockPointerType() ||
+ T->isReferenceType();
+ }
+};
+
+//==------------------------------------------------------------------------==//
+// Subclasses of NonLoc.
+//==------------------------------------------------------------------------==//
+
+namespace nonloc {
+
+enum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
+ LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
+
+class SymbolVal : public NonLoc {
+public:
+ SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
+
+ SymbolRef getSymbol() const {
+ return (const SymbolData*) Data;
+ }
+
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == NonLocKind &&
+ V->getSubKind() == SymbolValKind;
+ }
+
+ static inline bool classof(const NonLoc* V) {
+ return V->getSubKind() == SymbolValKind;
+ }
+};
+
+class SymExprVal : public NonLoc {
+public:
+ SymExprVal(const SymExpr *SE)
+ : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {}
+
+ const SymExpr *getSymbolicExpression() const {
+ return reinterpret_cast<SymExpr*>(Data);
+ }
+
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == NonLocKind &&
+ V->getSubKind() == SymExprValKind;
+ }
+
+ static inline bool classof(const NonLoc* V) {
+ return V->getSubKind() == SymExprValKind;
+ }
+};
+
+class ConcreteInt : public NonLoc {
+public:
+ ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
+
+ const llvm::APSInt& getValue() const {
+ return *static_cast<llvm::APSInt*>(Data);
+ }
+
+ // Transfer functions for binary/unary operations on ConcreteInts.
+ SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op,
+ const ConcreteInt& R) const;
+
+ ConcreteInt evalComplement(ValueManager &ValMgr) const;
+
+ ConcreteInt evalMinus(ValueManager &ValMgr) const;
+
+ // Implement isa<T> support.
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == NonLocKind &&
+ V->getSubKind() == ConcreteIntKind;
+ }
+
+ static inline bool classof(const NonLoc* V) {
+ return V->getSubKind() == ConcreteIntKind;
+ }
+};
+
+class LocAsInteger : public NonLoc {
+ friend class clang::ValueManager;
+
+ LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
+ NonLoc(LocAsIntegerKind, &data) {
+ assert (isa<Loc>(data.first));
+ }
+
+public:
+
+ Loc getLoc() const {
+ return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
+ }
+
+ const Loc& getPersistentLoc() const {
+ const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
+ return cast<Loc>(V);
+ }
+
+ unsigned getNumBits() const {
+ return ((std::pair<SVal, unsigned>*) Data)->second;
+ }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == NonLocKind &&
+ V->getSubKind() == LocAsIntegerKind;
+ }
+
+ static inline bool classof(const NonLoc* V) {
+ return V->getSubKind() == LocAsIntegerKind;
+ }
+};
+
+class CompoundVal : public NonLoc {
+ friend class clang::ValueManager;
+
+ CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
+
+public:
+ const CompoundValData* getValue() const {
+ return static_cast<CompoundValData*>(Data);
+ }
+
+ typedef llvm::ImmutableList<SVal>::iterator iterator;
+ iterator begin() const;
+ iterator end() const;
+
+ static bool classof(const SVal* V) {
+ return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
+ }
+
+ static bool classof(const NonLoc* V) {
+ return V->getSubKind() == CompoundValKind;
+ }
+};
+
+class LazyCompoundVal : public NonLoc {
+ friend class clang::ValueManager;
+
+ LazyCompoundVal(const LazyCompoundValData *D)
+ : NonLoc(LazyCompoundValKind, D) {}
+public:
+ const LazyCompoundValData *getCVData() const {
+ return static_cast<const LazyCompoundValData*>(Data);
+ }
+ const void *getStore() const;
+ const TypedRegion *getRegion() const;
+
+ static bool classof(const SVal *V) {
+ return V->getBaseKind() == NonLocKind &&
+ V->getSubKind() == LazyCompoundValKind;
+ }
+ static bool classof(const NonLoc *V) {
+ return V->getSubKind() == LazyCompoundValKind;
+ }
+};
+
+} // end namespace clang::nonloc
+
+//==------------------------------------------------------------------------==//
+// Subclasses of Loc.
+//==------------------------------------------------------------------------==//
+
+namespace loc {
+
+enum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind };
+
+class GotoLabel : public Loc {
+public:
+ GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
+
+ LabelStmt* getLabel() const {
+ return static_cast<LabelStmt*>(Data);
+ }
+
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == LocKind &&
+ V->getSubKind() == GotoLabelKind;
+ }
+
+ static inline bool classof(const Loc* V) {
+ return V->getSubKind() == GotoLabelKind;
+ }
+};
+
+
+class MemRegionVal : public Loc {
+public:
+ MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
+
+ const MemRegion* getRegion() const {
+ return static_cast<MemRegion*>(Data);
+ }
+
+ const MemRegion* StripCasts() const;
+
+ template <typename REGION>
+ const REGION* getRegionAs() const {
+ return llvm::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();
+ }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == LocKind &&
+ V->getSubKind() == MemRegionKind;
+ }
+
+ static inline bool classof(const Loc* V) {
+ return V->getSubKind() == MemRegionKind;
+ }
+};
+
+class ConcreteInt : public Loc {
+public:
+ ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
+
+ const llvm::APSInt& getValue() const {
+ return *static_cast<llvm::APSInt*>(Data);
+ }
+
+ // Transfer functions for binary/unary operations on ConcreteInts.
+ SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
+ const ConcreteInt& R) const;
+
+ // Implement isa<T> support.
+ static inline bool classof(const SVal* V) {
+ return V->getBaseKind() == LocKind &&
+ V->getSubKind() == ConcreteIntKind;
+ }
+
+ static inline bool classof(const Loc* V) {
+ return V->getSubKind() == ConcreteIntKind;
+ }
+};
+
+} // end clang::loc namespace
+} // end clang namespace
+
+namespace llvm {
+static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os,
+ clang::SVal V) {
+ V.dumpToStream(os);
+ return os;
+}
+} // end llvm namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SValuator.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SValuator.h
new file mode 100644
index 0000000..9beb8cb
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SValuator.h
@@ -0,0 +1,66 @@
+// SValuator.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 SValuator, a class that defines the interface for
+// "symbolical evaluators" which construct an SVal from an expression.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SVALUATOR
+#define LLVM_CLANG_ANALYSIS_SVALUATOR
+
+#include "clang/AST/Expr.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+
+namespace clang {
+
+class GRState;
+class ValueManager;
+
+class SValuator {
+ friend class ValueManager;
+protected:
+ ValueManager &ValMgr;
+
+public:
+ // FIXME: Make these protected again one RegionStoreManager correctly
+ // handles loads from differening bound value types.
+ virtual SVal EvalCastNL(NonLoc val, QualType castTy) = 0;
+ virtual SVal EvalCastL(Loc val, QualType castTy) = 0;
+
+public:
+ SValuator(ValueManager &valMgr) : ValMgr(valMgr) {}
+ virtual ~SValuator() {}
+
+ SVal EvalCast(SVal V, QualType castTy, QualType originalType);
+
+ virtual SVal EvalMinus(NonLoc val) = 0;
+
+ virtual SVal EvalComplement(NonLoc val) = 0;
+
+ virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
+ NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
+
+ virtual SVal EvalBinOpLL(BinaryOperator::Opcode Op, Loc lhs, Loc rhs,
+ QualType resultTy) = 0;
+
+ virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
+ Loc lhs, NonLoc rhs, QualType resultTy) = 0;
+
+ SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
+ SVal L, SVal R, QualType T);
+
+ DefinedOrUnknownSVal EvalEQ(const GRState *ST, DefinedOrUnknownSVal L,
+ DefinedOrUnknownSVal R);
+};
+
+SValuator* CreateSimpleSValuator(ValueManager &valMgr);
+
+} // end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Store.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Store.h
new file mode 100644
index 0000000..f3155b9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/Store.h
@@ -0,0 +1,237 @@
+//== 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_ANALYSIS_STORE_H
+#define LLVM_CLANG_ANALYSIS_STORE_H
+
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/ValueManager.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+
+namespace clang {
+
+typedef const void* Store;
+
+class GRState;
+class GRStateManager;
+class Stmt;
+class Expr;
+class ObjCIvarDecl;
+class SubRegionMap;
+class StackFrameContext;
+
+class StoreManager {
+protected:
+ ValueManager &ValMgr;
+ GRStateManager &StateMgr;
+
+ /// MRMgr - Manages region objects associated with this StoreManager.
+ MemRegionManager &MRMgr;
+ ASTContext &Ctx;
+
+ StoreManager(GRStateManager &stateMgr);
+
+public:
+ virtual ~StoreManager() {}
+
+ /// Return the value bound to specified location in a given state.
+ /// \param[in] state 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 Retrieve(Store store, Loc loc, QualType T = QualType()) = 0;
+
+ /// Return a state with the specified value bound to the given location.
+ /// \param[in] state 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 GRState 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 Store Bind(Store store, Loc loc, SVal val) = 0;
+
+ virtual Store Remove(Store St, Loc L) = 0;
+
+ /// BindCompoundLiteral - Return the store that has the bindings currently
+ /// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region
+ /// for the compound literal and 'BegInit' and 'EndInit' represent an
+ /// array of initializer values.
+ virtual Store BindCompoundLiteral(Store store,
+ const CompoundLiteralExpr* cl,
+ const LocationContext *LC, SVal v) = 0;
+
+ /// getInitialStore - Returns the initial "empty" store representing the
+ /// value bindings upon entry to an analyzed function.
+ virtual Store getInitialStore(const LocationContext *InitLoc) = 0;
+
+ /// getRegionManager - Returns the internal RegionManager object that is
+ /// used to query and manipulate MemRegion objects.
+ MemRegionManager& getRegionManager() { return MRMgr; }
+
+ /// getSubRegionMap - Returns an opaque map object that clients can query
+ /// to get the subregions of a given MemRegion object. It is the
+ // caller's responsibility to 'delete' the returned map.
+ virtual SubRegionMap *getSubRegionMap(Store store) = 0;
+
+ virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) {
+ return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
+ }
+
+ virtual SVal getLValueString(const StringLiteral* S) {
+ return ValMgr.makeLoc(MRMgr.getStringRegion(S));
+ }
+
+ SVal getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
+ const LocationContext *LC) {
+ return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
+ }
+
+ virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) {
+ return getLValueFieldOrIvar(decl, base);
+ }
+
+ virtual SVal getLValueField(const FieldDecl* D, SVal Base) {
+ return getLValueFieldOrIvar(D, Base);
+ }
+
+ virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base);
+
+ // FIXME: Make out-of-line.
+ virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
+ const MemRegion *region,
+ QualType EleTy) {
+ return UnknownVal();
+ }
+
+ /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
+ /// conversions between arrays and pointers.
+ virtual SVal ArrayToPointer(Loc Array) = 0;
+
+ class CastResult {
+ const GRState *state;
+ const MemRegion *region;
+ public:
+ const GRState *getState() const { return state; }
+ const MemRegion* getRegion() const { return region; }
+ CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){}
+ };
+
+ const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
+
+ /// CastRegion - Used by GRExprEngine::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);
+
+
+ /// EvalBinOp - Perform pointer arithmetic.
+ virtual SVal EvalBinOp(BinaryOperator::Opcode Op,
+ Loc lhs, NonLoc rhs, QualType resultTy) {
+ return UnknownVal();
+ }
+
+ virtual const GRState *RemoveDeadBindings(GRState &state, Stmt* Loc,
+ const StackFrameContext *LCtx,
+ SymbolReaper& SymReaper,
+ llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
+
+ virtual Store BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0;
+
+ virtual Store BindDeclWithNoInit(Store store, const VarRegion *VR) = 0;
+
+ typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
+
+ virtual Store InvalidateRegion(Store store,
+ const MemRegion *R,
+ const Expr *E, unsigned Count,
+ InvalidatedSymbols *IS) = 0;
+
+ virtual Store InvalidateRegions(Store store,
+ const MemRegion * const *Begin,
+ const MemRegion * const *End,
+ const Expr *E, unsigned Count,
+ InvalidatedSymbols *IS);
+
+ // FIXME: Make out-of-line.
+ virtual const GRState *setExtent(const GRState *state,
+ const MemRegion *region, SVal extent) {
+ return state;
+ }
+
+ virtual llvm::Optional<SVal> getExtent(const GRState *state,
+ const MemRegion *R) {
+ return llvm::Optional<SVal>();
+ }
+
+ /// EnterStackFrame - Let the StoreManager to do something when execution
+ /// engine is about to execute into a callee.
+ virtual const GRState *EnterStackFrame(const GRState *state,
+ const StackFrameContext *frame) {
+ return state;
+ }
+
+ virtual void print(Store store, llvm::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;
+ };
+
+ /// iterBindings - Iterate over the bindings in the Store.
+ virtual void iterBindings(Store store, BindingsHandler& f) = 0;
+
+protected:
+ const MemRegion *MakeElementRegion(const MemRegion *Base,
+ 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 TypedRegion *R, QualType castTy,
+ bool performTestOnly = true);
+
+private:
+ SVal getLValueFieldOrIvar(const Decl* D, SVal Base);
+};
+
+// FIXME: Do we still need this?
+/// SubRegionMap - An abstract interface that represents a queryable map
+/// between MemRegion objects and their subregions.
+class SubRegionMap {
+public:
+ virtual ~SubRegionMap() {}
+
+ class Visitor {
+ public:
+ virtual ~Visitor() {}
+ virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0;
+ };
+
+ virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0;
+};
+
+// FIXME: Do we need to pass GRStateManager anymore?
+StoreManager *CreateBasicStoreManager(GRStateManager& StMgr);
+StoreManager *CreateRegionStoreManager(GRStateManager& StMgr);
+StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr);
+StoreManager *CreateFlatStoreManager(GRStateManager &StMgr);
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SummaryManager.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SummaryManager.h
new file mode 100644
index 0000000..fd23189
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SummaryManager.h
@@ -0,0 +1,57 @@
+//== 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_CHECKER_SUMMARY
+#define LLVM_CLANG_CHECKER_SUMMARY
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+
+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 clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SymbolManager.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SymbolManager.h
new file mode 100644
index 0000000..dea877c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/SymbolManager.h
@@ -0,0 +1,379 @@
+//== 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 GRExprEngine and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SYMMGR_H
+#define LLVM_CLANG_ANALYSIS_SYMMGR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace llvm {
+class BumpPtrAllocator;
+class raw_ostream;
+}
+
+namespace clang {
+ class ASTContext;
+ class BasicValueFactory;
+ class MemRegion;
+ class TypedRegion;
+ class VarRegion;
+ class StackFrameContext;
+
+class SymExpr : public llvm::FoldingSetNode {
+public:
+ enum Kind { BEGIN_SYMBOLS,
+ RegionValueKind, ConjuredKind, DerivedKind,
+ END_SYMBOLS,
+ SymIntKind, SymSymKind };
+private:
+ Kind K;
+
+protected:
+ SymExpr(Kind k) : K(k) {}
+
+public:
+ virtual ~SymExpr() {}
+
+ Kind getKind() const { return K; }
+
+ void dump() const;
+
+ virtual void dumpToStream(llvm::raw_ostream &os) const = 0;
+
+ virtual QualType getType(ASTContext&) const = 0;
+ virtual void Profile(llvm::FoldingSetNodeID& profile) = 0;
+
+ // Implement isa<T> support.
+ static inline bool classof(const SymExpr*) { return true; }
+};
+
+typedef unsigned SymbolID;
+
+class SymbolData : public SymExpr {
+private:
+ const SymbolID Sym;
+
+protected:
+ SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {}
+
+public:
+ virtual ~SymbolData() {}
+
+ 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;
+ }
+};
+
+typedef const SymbolData* SymbolRef;
+
+// A symbol representing the value of a MemRegion.
+class SymbolRegionValue : public SymbolData {
+ const TypedRegion *R;
+
+public:
+ SymbolRegionValue(SymbolID sym, const TypedRegion *r)
+ : SymbolData(RegionValueKind, sym), R(r) {}
+
+ const TypedRegion* getRegion() const { return R; }
+
+ static void Profile(llvm::FoldingSetNodeID& profile, const TypedRegion* R) {
+ profile.AddInteger((unsigned) RegionValueKind);
+ profile.AddPointer(R);
+ }
+
+ virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ Profile(profile, R);
+ }
+
+ void dumpToStream(llvm::raw_ostream &os) const;
+
+ QualType getType(ASTContext&) const;
+
+ // Implement isa<T> support.
+ static inline bool classof(const SymExpr* SE) {
+ return SE->getKind() == RegionValueKind;
+ }
+};
+
+// A symbol representing the result of an expression.
+class SymbolConjured : public SymbolData {
+ const Stmt* S;
+ QualType T;
+ unsigned Count;
+ const void* SymbolTag;
+
+public:
+ SymbolConjured(SymbolID sym, const Stmt* s, QualType t, unsigned count,
+ const void* symbolTag)
+ : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count),
+ SymbolTag(symbolTag) {}
+
+ const Stmt* getStmt() const { return S; }
+ unsigned getCount() const { return Count; }
+ const void* getTag() const { return SymbolTag; }
+
+ QualType getType(ASTContext&) const;
+
+ void dumpToStream(llvm::raw_ostream &os) const;
+
+ static void Profile(llvm::FoldingSetNodeID& profile, const Stmt* S,
+ QualType T, unsigned Count, const void* SymbolTag) {
+ profile.AddInteger((unsigned) ConjuredKind);
+ profile.AddPointer(S);
+ profile.Add(T);
+ profile.AddInteger(Count);
+ profile.AddPointer(SymbolTag);
+ }
+
+ virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ Profile(profile, S, T, Count, 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 TypedRegion *R;
+
+public:
+ SymbolDerived(SymbolID sym, SymbolRef parent, const TypedRegion *r)
+ : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {}
+
+ SymbolRef getParentSymbol() const { return parentSymbol; }
+ const TypedRegion *getRegion() const { return R; }
+
+ QualType getType(ASTContext&) const;
+
+ void dumpToStream(llvm::raw_ostream &os) const;
+
+ static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
+ const TypedRegion *r) {
+ profile.AddInteger((unsigned) DerivedKind);
+ profile.AddPointer(r);
+ profile.AddPointer(parent);
+ }
+
+ virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ Profile(profile, parentSymbol, R);
+ }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SymExpr* SE) {
+ return SE->getKind() == DerivedKind;
+ }
+};
+
+// SymIntExpr - Represents symbolic expression like 'x' + 3.
+class SymIntExpr : public SymExpr {
+ const SymExpr *LHS;
+ BinaryOperator::Opcode Op;
+ const llvm::APSInt& RHS;
+ QualType T;
+
+public:
+ SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+ const llvm::APSInt& rhs, QualType t)
+ : SymExpr(SymIntKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
+
+ // FIXME: We probably need to make this out-of-line to avoid redundant
+ // generation of virtual functions.
+ QualType getType(ASTContext& C) const { return T; }
+
+ BinaryOperator::Opcode getOpcode() const { return Op; }
+
+ void dumpToStream(llvm::raw_ostream &os) const;
+
+ 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) {
+ Profile(ID, LHS, Op, RHS, T);
+ }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SymExpr* SE) {
+ return SE->getKind() == SymIntKind;
+ }
+};
+
+// SymSymExpr - Represents symbolic expression like 'x' + 'y'.
+class SymSymExpr : public SymExpr {
+ const SymExpr *LHS;
+ BinaryOperator::Opcode Op;
+ const SymExpr *RHS;
+ QualType T;
+
+public:
+ SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs,
+ QualType t)
+ : SymExpr(SymSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
+
+ BinaryOperator::Opcode getOpcode() const { return Op; }
+ const SymExpr *getLHS() const { return LHS; }
+ const SymExpr *getRHS() const { return RHS; }
+
+ // FIXME: We probably need to make this out-of-line to avoid redundant
+ // generation of virtual functions.
+ QualType getType(ASTContext& C) const { return T; }
+
+ void dumpToStream(llvm::raw_ostream &os) const;
+
+ 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) {
+ Profile(ID, LHS, Op, RHS, T);
+ }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SymExpr* SE) {
+ return SE->getKind() == SymSymKind;
+ }
+};
+
+class SymbolManager {
+ typedef llvm::FoldingSet<SymExpr> DataSetTy;
+ DataSetTy DataSet;
+ unsigned SymbolCounter;
+ llvm::BumpPtrAllocator& BPAlloc;
+ BasicValueFactory &BV;
+ ASTContext& Ctx;
+
+public:
+ SymbolManager(ASTContext& ctx, BasicValueFactory &bv,
+ llvm::BumpPtrAllocator& bpalloc)
+ : SymbolCounter(0), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {}
+
+ ~SymbolManager();
+
+ static bool canSymbolicate(QualType T);
+
+ /// Make a unique symbol for MemRegion R according to its kind.
+ const SymbolRegionValue* getRegionValueSymbol(const TypedRegion* R);
+
+ const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
+ unsigned VisitCount,
+ const void* SymbolTag = 0);
+
+ const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
+ const void* SymbolTag = 0) {
+ return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag);
+ }
+
+ const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,
+ const TypedRegion *R);
+
+ 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 SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+ const SymExpr *rhs, QualType t);
+
+ QualType getType(const SymExpr *SE) const {
+ return SE->getType(Ctx);
+ }
+
+ ASTContext &getContext() { return Ctx; }
+ BasicValueFactory &getBasicVals() { return BV; }
+};
+
+class SymbolReaper {
+ typedef llvm::DenseSet<SymbolRef> SetTy;
+
+ SetTy TheLiving;
+ SetTy TheDead;
+ const LocationContext *LCtx;
+ SymbolManager& SymMgr;
+
+public:
+ SymbolReaper(const LocationContext *ctx, SymbolManager& symmgr)
+ : LCtx(ctx), SymMgr(symmgr) {}
+
+ ~SymbolReaper() {}
+
+ const LocationContext *getLocationContext() const { return LCtx; }
+
+ bool isLive(SymbolRef sym);
+
+ bool isLive(const Stmt* Loc, const Stmt* ExprVal) const;
+
+ bool isLive(const Stmt* Loc, const VarRegion *VR) const;
+
+ void markLive(SymbolRef sym);
+ bool maybeDead(SymbolRef sym);
+
+ typedef SetTy::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();
+ }
+};
+
+class SymbolVisitor {
+public:
+ // VisitSymbol - A visitor method invoked by
+ // GRStateManager::scanReachableSymbols. The method returns \c true if
+ // symbols should continue be scanned and \c false otherwise.
+ virtual bool VisitSymbol(SymbolRef sym) = 0;
+ virtual ~SymbolVisitor();
+};
+
+} // end clang namespace
+
+namespace llvm {
+static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os,
+ const clang::SymExpr *SE) {
+ SE->dumpToStream(os);
+ return os;
+}
+} // end llvm namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ValueManager.h b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ValueManager.h
new file mode 100644
index 0000000..5a9d54d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Checker/PathSensitive/ValueManager.h
@@ -0,0 +1,213 @@
+//== ValueManager.h - Aggregate manager of symbols and SVals ----*- 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 ValueManager, a class that manages symbolic values
+// and SVals created for use by GRExprEngine and related classes. It
+// wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
+#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/BasicValueFactory.h"
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "clang/Checker/PathSensitive/SValuator.h"
+#include "clang/AST/ExprCXX.h"
+
+namespace llvm { class BumpPtrAllocator; }
+
+namespace clang {
+
+class GRStateManager;
+
+class ValueManager {
+
+ ASTContext &Context;
+ BasicValueFactory BasicVals;
+
+ /// SymMgr - Object that manages the symbol information.
+ SymbolManager SymMgr;
+
+ /// SVator - SValuator object that creates SVals from expressions.
+ llvm::OwningPtr<SValuator> SVator;
+
+ MemRegionManager MemMgr;
+
+ GRStateManager &StateMgr;
+
+ const QualType ArrayIndexTy;
+ const unsigned ArrayIndexWidth;
+
+public:
+ ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context,
+ GRStateManager &stateMgr)
+ : Context(context), BasicVals(context, alloc),
+ SymMgr(context, BasicVals, alloc),
+ MemMgr(context, alloc), StateMgr(stateMgr),
+ ArrayIndexTy(context.IntTy),
+ ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {
+ // FIXME: Generalize later.
+ SVator.reset(clang::CreateSimpleSValuator(*this));
+ }
+
+ // Accessors to submanagers.
+
+ ASTContext &getContext() { return Context; }
+ const ASTContext &getContext() const { return Context; }
+
+ GRStateManager &getStateManager() { return StateMgr; }
+
+ BasicValueFactory &getBasicValueFactory() { return BasicVals; }
+ const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
+
+ SymbolManager &getSymbolManager() { return SymMgr; }
+ const SymbolManager &getSymbolManager() const { return SymMgr; }
+
+ SValuator &getSValuator() { return *SVator.get(); }
+
+ MemRegionManager &getRegionManager() { return MemMgr; }
+ const MemRegionManager &getRegionManager() const { return MemMgr; }
+
+ // Forwarding methods to SymbolManager.
+
+ const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
+ unsigned VisitCount,
+ const void* SymbolTag = 0) {
+ return SymMgr.getConjuredSymbol(E, T, VisitCount, SymbolTag);
+ }
+
+ const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
+ const void* SymbolTag = 0) {
+ return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag);
+ }
+
+ /// makeZeroVal - Construct an SVal representing '0' for the specified type.
+ DefinedOrUnknownSVal makeZeroVal(QualType T);
+
+ /// getRegionValueSymbolVal - make a unique symbol for value of R.
+ DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R);
+
+ DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
+ const Expr *E, unsigned Count);
+ DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
+ const Expr *E, QualType T,
+ unsigned Count);
+
+ DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
+ const TypedRegion *R);
+
+ DefinedSVal getFunctionPointer(const FunctionDecl *FD);
+
+ DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy,
+ const LocationContext *LC);
+
+ NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
+ return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
+ }
+
+ NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) {
+ return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R));
+ }
+
+ NonLoc makeZeroArrayIndex() {
+ return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
+ }
+
+ NonLoc makeArrayIndex(uint64_t idx) {
+ return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
+ }
+
+ SVal convertToArrayIndex(SVal V);
+
+ nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
+ return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
+ I->getType()->isUnsignedIntegerType()));
+ }
+
+ nonloc::ConcreteInt makeIntVal(const CXXBoolLiteralExpr *E) {
+ return E->getValue() ? nonloc::ConcreteInt(BasicVals.getValue(1, 1, true))
+ : nonloc::ConcreteInt(BasicVals.getValue(0, 1, true));
+ }
+
+ nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) {
+ return nonloc::ConcreteInt(BasicVals.getValue(V));
+ }
+
+ loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) {
+ return loc::ConcreteInt(BasicVals.getValue(v));
+ }
+
+ NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) {
+ return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned));
+ }
+
+ DefinedSVal makeIntVal(uint64_t X, QualType T) {
+ if (Loc::IsLocType(T))
+ return loc::ConcreteInt(BasicVals.getValue(X, T));
+
+ return nonloc::ConcreteInt(BasicVals.getValue(X, T));
+ }
+
+ NonLoc makeIntVal(uint64_t X, bool isUnsigned) {
+ return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
+ }
+
+ NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) {
+ return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned));
+ }
+
+ NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) {
+ return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
+ }
+
+ NonLoc makeLocAsInteger(Loc V, unsigned Bits) {
+ return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits));
+ }
+
+ NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+ const llvm::APSInt& rhs, QualType T);
+
+ NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+ const SymExpr *rhs, QualType T);
+
+ NonLoc makeTruthVal(bool b, QualType T) {
+ return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T));
+ }
+
+ NonLoc 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* R) {
+ return loc::MemRegionVal(R);
+ }
+
+ Loc makeLoc(const AddrLabelExpr* E) {
+ return loc::GotoLabel(E->getLabel());
+ }
+
+ Loc makeLoc(const llvm::APSInt& V) {
+ return loc::ConcreteInt(BasicVals.getValue(V));
+ }
+};
+} // end clang namespace
+#endif
+
diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenOptions.h b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenOptions.h
new file mode 100644
index 0000000..6241230
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenOptions.h
@@ -0,0 +1,131 @@
+//===--- 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_CODEGEN_CODEGENOPTIONS_H
+#define LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
+
+#include <string>
+
+namespace clang {
+
+/// CodeGenOptions - Track various options which control how the code
+/// is optimized and passed to the backend.
+class CodeGenOptions {
+public:
+ enum InliningMethod {
+ NoInlining, // Perform no inlining whatsoever.
+ NormalInlining, // Use the standard function inlining pass.
+ OnlyAlwaysInlining // Only run the always inlining pass.
+ };
+
+ enum ObjCDispatchMethodKind {
+ Legacy = 0,
+ NonLegacy = 1,
+ Mixed = 2
+ };
+
+ unsigned AsmVerbose : 1; /// -dA, -fverbose-asm.
+ unsigned CXAAtExit : 1; /// Use __cxa_atexit for calling destructors.
+ unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
+ /// aliases to base ctors when possible.
+ unsigned DataSections : 1; /// Set when -fdata-sections is enabled
+ unsigned DebugInfo : 1; /// Should generate deubg info (-g).
+ unsigned DisableFPElim : 1; /// Set when -fomit-frame-pointer is enabled.
+ unsigned DisableLLVMOpts : 1; /// Don't run any optimizations, for use in
+ /// getting .bc files that correspond to the
+ /// internal state before optimizations are
+ /// done.
+ unsigned DisableRedZone : 1; /// Set when -mno-red-zone is enabled.
+ unsigned FunctionSections : 1; /// Set when -ffunction-sections is enabled
+ unsigned MergeAllConstants : 1; /// Merge identical constants.
+ unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
+ unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
+ unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
+ unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
+ unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
+ unsigned OptimizeSize : 1; /// If -Os is specified.
+ unsigned RelaxAll : 1; /// Relax all machine code instructions.
+ unsigned SoftFloat : 1; /// -soft-float.
+ unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
+ unsigned UnitAtATime : 1; /// Unused. For mirroring GCC optimization
+ /// selection.
+ unsigned UnrollLoops : 1; /// Control whether loops are unrolled.
+ unsigned UnwindTables : 1; /// Emit unwind tables.
+ unsigned VerifyModule : 1; /// Control whether the module should be run
+ /// through the LLVM Verifier.
+
+ /// The code model to use (-mcmodel).
+ std::string CodeModel;
+
+ /// Enable additional debugging information.
+ std::string DebugPass;
+
+ /// The string to embed in the debug information for the compile unit, if
+ /// non-empty.
+ std::string DwarfDebugFlags;
+
+ /// 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 kind of inlining to perform.
+ InliningMethod Inlining;
+
+ /// 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 of the relocation model to use.
+ std::string RelocationModel;
+
+public:
+ CodeGenOptions() {
+ AsmVerbose = 0;
+ CXAAtExit = 1;
+ CXXCtorDtorAliases = 0;
+ DataSections = 0;
+ DebugInfo = 0;
+ DisableFPElim = 0;
+ DisableLLVMOpts = 0;
+ DisableRedZone = 0;
+ FunctionSections = 0;
+ MergeAllConstants = 1;
+ NoCommon = 0;
+ NoImplicitFloat = 0;
+ NoZeroInitializedInBSS = 0;
+ ObjCDispatchMethod = Legacy;
+ OptimizationLevel = 0;
+ OptimizeSize = 0;
+ RelaxAll = 0;
+ SoftFloat = 0;
+ TimePasses = 0;
+ UnitAtATime = 1;
+ UnrollLoops = 0;
+ UnwindTables = 0;
+ VerifyModule = 1;
+
+ Inlining = NoInlining;
+ RelocationModel = "pic";
+ }
+
+ ObjCDispatchMethodKind getObjCDispatchMethod() const {
+ return ObjCDispatchMethodKind(ObjCDispatchMethod);
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/ModuleBuilder.h b/contrib/llvm/tools/clang/include/clang/CodeGen/ModuleBuilder.h
new file mode 100644
index 0000000..2a3aa6a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -0,0 +1,42 @@
+//===--- 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 Diagnostic;
+ class LangOptions;
+ class CodeGenOptions;
+
+ class CodeGenerator : public ASTConsumer {
+ public:
+ virtual llvm::Module* GetModule() = 0;
+ virtual llvm::Module* ReleaseModule() = 0;
+ };
+
+ CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
+ const std::string &ModuleName,
+ const CodeGenOptions &CGO,
+ llvm::LLVMContext& C);
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Action.h b/contrib/llvm/tools/clang/include/clang/Driver/Action.h
new file mode 100644
index 0000000..ab3162a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Action.h
@@ -0,0 +1,217 @@
+//===--- 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 CLANG_DRIVER_ACTION_H_
+#define CLANG_DRIVER_ACTION_H_
+
+#include "llvm/ADT/SmallVector.h"
+
+#include "clang/Driver/Types.h"
+#include "clang/Driver/Util.h"
+
+#include "llvm/Support/Casting.h"
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+namespace clang {
+namespace driver {
+ class Arg;
+
+/// 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,
+ PreprocessJobClass,
+ PrecompileJobClass,
+ AnalyzeJobClass,
+ CompileJobClass,
+ AssembleJobClass,
+ LinkJobClass,
+ LipoJobClass,
+
+ JobClassFirst=PreprocessJobClass,
+ JobClassLast=LipoJobClass
+ };
+
+ 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, Action *Input, types::ID _Type)
+ : Kind(_Kind), Type(_Type), Inputs(&Input, &Input + 1), 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(); }
+
+ static bool classof(const Action *) { return true; }
+};
+
+class InputAction : public Action {
+ const Arg &Input;
+public:
+ InputAction(const Arg &_Input, types::ID _Type);
+
+ const Arg &getInputArg() const { return Input; }
+
+ static bool classof(const Action *A) {
+ return A->getKind() == InputClass;
+ }
+ static bool classof(const InputAction *) { return true; }
+};
+
+class BindArchAction : public Action {
+ /// The architecture to bind, or 0 if the default architecture
+ /// should be bound.
+ const char *ArchName;
+
+public:
+ BindArchAction(Action *Input, const char *_ArchName);
+
+ const char *getArchName() const { return ArchName; }
+
+ static bool classof(const Action *A) {
+ return A->getKind() == BindArchClass;
+ }
+ static bool classof(const BindArchAction *) { return true; }
+};
+
+class JobAction : public Action {
+protected:
+ JobAction(ActionClass Kind, 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);
+ }
+ static bool classof(const JobAction *) { return true; }
+};
+
+class PreprocessJobAction : public JobAction {
+public:
+ PreprocessJobAction(Action *Input, types::ID OutputType);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == PreprocessJobClass;
+ }
+ static bool classof(const PreprocessJobAction *) { return true; }
+};
+
+class PrecompileJobAction : public JobAction {
+public:
+ PrecompileJobAction(Action *Input, types::ID OutputType);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == PrecompileJobClass;
+ }
+ static bool classof(const PrecompileJobAction *) { return true; }
+};
+
+class AnalyzeJobAction : public JobAction {
+public:
+ AnalyzeJobAction(Action *Input, types::ID OutputType);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == AnalyzeJobClass;
+ }
+ static bool classof(const AnalyzeJobAction *) { return true; }
+};
+
+class CompileJobAction : public JobAction {
+public:
+ CompileJobAction(Action *Input, types::ID OutputType);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == CompileJobClass;
+ }
+ static bool classof(const CompileJobAction *) { return true; }
+};
+
+class AssembleJobAction : public JobAction {
+public:
+ AssembleJobAction(Action *Input, types::ID OutputType);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == AssembleJobClass;
+ }
+ static bool classof(const AssembleJobAction *) { return true; }
+};
+
+class LinkJobAction : public JobAction {
+public:
+ LinkJobAction(ActionList &Inputs, types::ID Type);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == LinkJobClass;
+ }
+ static bool classof(const LinkJobAction *) { return true; }
+};
+
+class LipoJobAction : public JobAction {
+public:
+ LipoJobAction(ActionList &Inputs, types::ID Type);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == LipoJobClass;
+ }
+ static bool classof(const LipoJobAction *) { return true; }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Arg.h b/contrib/llvm/tools/clang/include/clang/Driver/Arg.h
new file mode 100644
index 0000000..ebf40d4
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Arg.h
@@ -0,0 +1,230 @@
+//===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_ARG_H_
+#define CLANG_DRIVER_ARG_H_
+
+#include "llvm/Support/Casting.h"
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+#include "Util.h"
+#include <vector>
+#include <string>
+
+namespace clang {
+namespace driver {
+ class ArgList;
+ class Option;
+
+ /// Arg - A concrete instance of a particular driver option.
+ ///
+ /// The Arg class encodes just enough information to be able to
+ /// derive the argument values efficiently. In addition, Arg
+ /// instances have an intrusive double linked list which is used by
+ /// ArgList to provide efficient iteration over all instances of a
+ /// particular option.
+ class Arg {
+ public:
+ enum ArgClass {
+ FlagClass = 0,
+ PositionalClass,
+ JoinedClass,
+ SeparateClass,
+ CommaJoinedClass,
+ JoinedAndSeparateClass
+ };
+
+ private:
+ ArgClass Kind;
+
+ /// The option this argument is an instance of.
+ const Option *Opt;
+
+ /// The argument this argument was derived from (during tool chain
+ /// argument translation), if any.
+ const Arg *BaseArg;
+
+ /// The index at which this argument appears in the containing
+ /// ArgList.
+ unsigned Index;
+
+ /// Flag indicating whether this argument was used to effect
+ /// compilation; used for generating "argument unused"
+ /// diagnostics.
+ mutable bool Claimed;
+
+ protected:
+ Arg(ArgClass Kind, const Option *Opt, unsigned Index,
+ const Arg *BaseArg = 0);
+
+ public:
+ Arg(const Arg &);
+ virtual ~Arg();
+
+ ArgClass getKind() const { return Kind; }
+ const Option &getOption() const { return *Opt; }
+ unsigned getIndex() const { return Index; }
+
+ /// getBaseArg - Return the base argument which generated this
+ /// arg; this is either the argument itself or the argument it was
+ /// derived from during tool chain specific argument translation.
+ const Arg &getBaseArg() const {
+ return BaseArg ? *BaseArg : *this;
+ }
+ void setBaseArg(const Arg *_BaseArg) {
+ BaseArg = _BaseArg;
+ }
+
+ bool isClaimed() const { return getBaseArg().Claimed; }
+
+ /// claim - Set the Arg claimed bit.
+
+ // FIXME: We need to deal with derived arguments and set the bit
+ // in the original argument; not the derived one.
+ void claim() const { getBaseArg().Claimed = true; }
+
+ virtual unsigned getNumValues() const = 0;
+ virtual const char *getValue(const ArgList &Args, unsigned N=0) const = 0;
+
+ /// render - Append the argument onto the given array as strings.
+ virtual void render(const ArgList &Args, ArgStringList &Output) const = 0;
+
+ /// renderAsInput - Append the argument, render as an input, onto
+ /// the given array as strings. The distinction is that some
+ /// options only render their values when rendered as a input
+ /// (e.g., Xlinker).
+ void renderAsInput(const ArgList &Args, ArgStringList &Output) const;
+
+ static bool classof(const Arg *) { return true; }
+
+ void dump() const;
+
+ /// getAsString - Return a formatted version of the argument and
+ /// its values, for debugging and diagnostics.
+ std::string getAsString(const ArgList &Args) const;
+ };
+
+ /// FlagArg - An argument with no value.
+ class FlagArg : public Arg {
+ public:
+ FlagArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+
+ virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+ virtual unsigned getNumValues() const { return 0; }
+ virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+ static bool classof(const Arg *A) {
+ return A->getKind() == Arg::FlagClass;
+ }
+ static bool classof(const FlagArg *) { return true; }
+ };
+
+ /// PositionalArg - A simple positional argument.
+ class PositionalArg : public Arg {
+ public:
+ PositionalArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+
+ virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+ virtual unsigned getNumValues() const { return 1; }
+ virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+ static bool classof(const Arg *A) {
+ return A->getKind() == Arg::PositionalClass;
+ }
+ static bool classof(const PositionalArg *) { return true; }
+ };
+
+ /// JoinedArg - A single value argument where the value is joined
+ /// (suffixed) to the option.
+ class JoinedArg : public Arg {
+ public:
+ JoinedArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+
+ virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+ virtual unsigned getNumValues() const { return 1; }
+ virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+ static bool classof(const Arg *A) {
+ return A->getKind() == Arg::JoinedClass;
+ }
+ static bool classof(const JoinedArg *) { return true; }
+ };
+
+ /// SeparateArg - An argument where one or more values follow the
+ /// option specifier immediately in the argument vector.
+ class SeparateArg : public Arg {
+ unsigned NumValues;
+
+ public:
+ SeparateArg(const Option *Opt, unsigned Index, unsigned NumValues,
+ const Arg *BaseArg = 0);
+
+ virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+ virtual unsigned getNumValues() const { return NumValues; }
+ virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+ static bool classof(const Arg *A) {
+ return A->getKind() == Arg::SeparateClass;
+ }
+ static bool classof(const SeparateArg *) { return true; }
+ };
+
+ /// CommaJoinedArg - An argument with multiple values joined by
+ /// commas and joined (suffixed) to the option specifier.
+ ///
+ /// The key point of this arg is that it renders its values into
+ /// separate arguments, which allows it to be used as a generic
+ /// mechanism for passing arguments through to tools.
+ class CommaJoinedArg : public Arg {
+ std::vector<std::string> Values;
+
+ public:
+ CommaJoinedArg(const Option *Opt, unsigned Index, const char *Str,
+ const Arg *BaseArg = 0);
+
+ virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+ virtual unsigned getNumValues() const { return Values.size(); }
+ virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+ static bool classof(const Arg *A) {
+ return A->getKind() == Arg::CommaJoinedClass;
+ }
+ static bool classof(const CommaJoinedArg *) { return true; }
+ };
+
+ /// JoinedAndSeparateArg - An argument with both joined and separate
+ /// values.
+ class JoinedAndSeparateArg : public Arg {
+ public:
+ JoinedAndSeparateArg(const Option *Opt, unsigned Index,
+ const Arg *BaseArg = 0);
+
+ virtual void render(const ArgList &Args, ArgStringList &Output) const;
+
+ virtual unsigned getNumValues() const { return 2; }
+ virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
+
+ static bool classof(const Arg *A) {
+ return A->getKind() == Arg::JoinedAndSeparateClass;
+ }
+ static bool classof(const JoinedAndSeparateArg *) { return true; }
+ };
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h b/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h
new file mode 100644
index 0000000..7a14ae8
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h
@@ -0,0 +1,359 @@
+//===--- ArgList.h - Argument List Management ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_ARGLIST_H_
+#define CLANG_DRIVER_ARGLIST_H_
+
+#include "clang/Driver/OptSpecifier.h"
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <list>
+#include <string>
+#include <vector>
+
+namespace llvm {
+ class Twine;
+}
+
+namespace clang {
+ class Diagnostic;
+
+namespace driver {
+ class Arg;
+ class ArgList;
+ class Option;
+
+ /// arg_iterator - Iterates through arguments stored inside an ArgList.
+ class arg_iterator {
+ /// The current argument.
+ llvm::SmallVectorImpl<Arg*>::const_iterator Current;
+
+ /// The argument list we are iterating over.
+ const ArgList &Args;
+
+ /// Optional filters on the arguments which will be match. Most clients
+ /// should never want to iterate over arguments without filters, so we won't
+ /// bother to factor this into two separate iterator implementations.
+ //
+ // FIXME: Make efficient; the idea is to provide efficient iteration over
+ // all arguments which match a particular id and then just provide an
+ // iterator combinator which takes multiple iterators which can be
+ // efficiently compared and returns them in order.
+ OptSpecifier Id0, Id1, Id2;
+
+ void SkipToNextArg();
+
+ public:
+ typedef const Arg* value_type;
+ typedef const Arg* reference;
+ typedef const Arg* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ arg_iterator(llvm::SmallVectorImpl<Arg*>::const_iterator it,
+ const ArgList &_Args, OptSpecifier _Id0 = 0U,
+ OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
+ : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
+ SkipToNextArg();
+ }
+
+ operator const Arg*() { return *Current; }
+ reference operator*() const { return *Current; }
+ pointer operator->() const { return *Current; }
+
+ arg_iterator &operator++() {
+ ++Current;
+ SkipToNextArg();
+ return *this;
+ }
+
+ arg_iterator operator++(int) {
+ arg_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
+ return LHS.Current == RHS.Current;
+ }
+ friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
+ return !(LHS == RHS);
+ }
+ };
+
+ /// ArgList - Ordered collection of driver arguments.
+ ///
+ /// The ArgList class manages a list of Arg instances as well as
+ /// auxiliary data and convenience methods to allow Tools to quickly
+ /// check for the presence of Arg instances for a particular Option
+ /// and to iterate over groups of arguments.
+ class ArgList {
+ public:
+ typedef llvm::SmallVector<Arg*, 16> arglist_type;
+ typedef arglist_type::iterator iterator;
+ typedef arglist_type::const_iterator const_iterator;
+ typedef arglist_type::reverse_iterator reverse_iterator;
+ typedef arglist_type::const_reverse_iterator const_reverse_iterator;
+
+ private:
+ /// The full list of arguments.
+ arglist_type &Args;
+
+ protected:
+ ArgList(arglist_type &Args);
+
+ public:
+ virtual ~ArgList();
+
+ /// @name Arg Access
+ /// @{
+
+ /// append - Append \arg A to the arg list.
+ void append(Arg *A);
+
+ arglist_type &getArgs() { return Args; }
+ const arglist_type &getArgs() const { return Args; }
+
+ unsigned size() const { return Args.size(); }
+
+ /// @}
+ /// @name Arg Iteration
+ /// @{
+
+ iterator begin() { return Args.begin(); }
+ iterator end() { return Args.end(); }
+
+ reverse_iterator rbegin() { return Args.rbegin(); }
+ reverse_iterator rend() { return Args.rend(); }
+
+ const_iterator begin() const { return Args.begin(); }
+ const_iterator end() const { return Args.end(); }
+
+ const_reverse_iterator rbegin() const { return Args.rbegin(); }
+ const_reverse_iterator rend() const { return Args.rend(); }
+
+ arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
+ OptSpecifier Id2 = 0U) const {
+ return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
+ }
+ arg_iterator filtered_end() const {
+ return arg_iterator(Args.end(), *this);
+ }
+
+ /// @}
+ /// @name Arg Access
+ /// @{
+
+ /// hasArg - Does the arg list contain any option matching \arg Id.
+ ///
+ /// \arg Claim Whether the argument should be claimed, if it exists.
+ bool hasArgNoClaim(OptSpecifier Id) const {
+ return getLastArgNoClaim(Id) != 0;
+ }
+ bool hasArg(OptSpecifier Id) const {
+ return getLastArg(Id) != 0;
+ }
+ bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
+ return getLastArg(Id0, Id1) != 0;
+ }
+ bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
+ return getLastArg(Id0, Id1, Id2) != 0;
+ }
+
+ /// getLastArg - Return the last argument matching \arg Id, or null.
+ ///
+ /// \arg Claim Whether the argument should be claimed, if it exists.
+ Arg *getLastArgNoClaim(OptSpecifier Id) const;
+ Arg *getLastArg(OptSpecifier Id) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
+
+ /// getArgString - Return the input argument string at \arg Index.
+ virtual const char *getArgString(unsigned Index) const = 0;
+
+ /// @}
+ /// @name Argument Lookup Utilities
+ /// @{
+
+ /// getLastArgValue - Return the value of the last argument, or a default.
+ llvm::StringRef getLastArgValue(OptSpecifier Id,
+ llvm::StringRef Default = "") const;
+
+ /// getLastArgValue - Return the value of the last argument as an integer,
+ /// or a default. Emits an error if the argument is given, but non-integral.
+ int getLastArgIntValue(OptSpecifier Id, int Default,
+ Diagnostic &Diags) const;
+
+ /// getAllArgValues - Get the values of all instances of the given argument
+ /// as strings.
+ std::vector<std::string> getAllArgValues(OptSpecifier Id) const;
+
+ /// @}
+ /// @name Translation Utilities
+ /// @{
+
+ /// hasFlag - Given an option \arg Pos and its negative form \arg
+ /// Neg, return true if the option is present, false if the
+ /// negation is present, and \arg Default if neither option is
+ /// given. If both the option and its negation are present, the
+ /// last one wins.
+ bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
+
+ /// AddLastArg - Render only the last argument match \arg Id0, if
+ /// present.
+ void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
+
+ /// AddAllArgs - Render all arguments matching the given ids.
+ void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+
+ /// AddAllArgValues - Render the argument values of all arguments
+ /// matching the given ids.
+ void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+
+ /// AddAllArgsTranslated - Render all the arguments matching the
+ /// given ids, but forced to separate args and using the provided
+ /// name instead of the first option value.
+ ///
+ /// \param Joined - If true, render the argument as joined with
+ /// the option specifier.
+ void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
+ const char *Translation,
+ bool Joined = false) const;
+
+ /// ClaimAllArgs - Claim all arguments which match the given
+ /// option id.
+ void ClaimAllArgs(OptSpecifier Id0) const;
+
+ /// @}
+ /// @name Arg Synthesis
+ /// @{
+
+ /// MakeArgString - Construct a constant string pointer whose
+ /// lifetime will match that of the ArgList.
+ virtual const char *MakeArgString(llvm::StringRef Str) const = 0;
+ const char *MakeArgString(const char *Str) const {
+ return MakeArgString(llvm::StringRef(Str));
+ }
+ const char *MakeArgString(std::string Str) const {
+ return MakeArgString(llvm::StringRef(Str));
+ }
+ const char *MakeArgString(const llvm::Twine &Str) const;
+
+ /// @}
+ };
+
+ class InputArgList : public ArgList {
+ private:
+ /// The internal list of arguments.
+ arglist_type ActualArgs;
+
+ /// List of argument strings used by the contained Args.
+ ///
+ /// This is mutable since we treat the ArgList as being the list
+ /// of Args, and allow routines to add new strings (to have a
+ /// convenient place to store the memory) via MakeIndex.
+ mutable ArgStringList ArgStrings;
+
+ /// Strings for synthesized arguments.
+ ///
+ /// This is mutable since we treat the ArgList as being the list
+ /// of Args, and allow routines to add new strings (to have a
+ /// convenient place to store the memory) via MakeIndex.
+ mutable std::list<std::string> SynthesizedStrings;
+
+ /// The number of original input argument strings.
+ unsigned NumInputArgStrings;
+
+ public:
+ InputArgList(const char **ArgBegin, const char **ArgEnd);
+ InputArgList(const ArgList &);
+ ~InputArgList();
+
+ virtual const char *getArgString(unsigned Index) const {
+ return ArgStrings[Index];
+ }
+
+ /// getNumInputArgStrings - Return the number of original input
+ /// argument strings.
+ unsigned getNumInputArgStrings() const { return NumInputArgStrings; }
+
+ /// @name Arg Synthesis
+ /// @{
+
+ public:
+ /// MakeIndex - Get an index for the given string(s).
+ unsigned MakeIndex(llvm::StringRef String0) const;
+ unsigned MakeIndex(llvm::StringRef String0, llvm::StringRef String1) const;
+
+ virtual const char *MakeArgString(llvm::StringRef Str) const;
+
+ /// @}
+ };
+
+ /// DerivedArgList - An ordered collection of driver arguments,
+ /// whose storage may be in another argument list.
+ class DerivedArgList : public ArgList {
+ InputArgList &BaseArgs;
+
+ /// The internal list of arguments.
+ arglist_type ActualArgs;
+
+ /// The list of arguments we synthesized.
+ mutable arglist_type SynthesizedArgs;
+
+ /// Is this only a proxy for the base ArgList?
+ bool OnlyProxy;
+
+ public:
+ /// Construct a new derived arg list from \arg BaseArgs.
+ ///
+ /// \param OnlyProxy - If true, this is only a proxy for the base
+ /// list (to adapt the type), and it's Args list is unused.
+ DerivedArgList(InputArgList &BaseArgs, bool OnlyProxy);
+ ~DerivedArgList();
+
+ virtual const char *getArgString(unsigned Index) const {
+ return BaseArgs.getArgString(Index);
+ }
+
+ /// @name Arg Synthesis
+ /// @{
+
+ virtual const char *MakeArgString(llvm::StringRef Str) const;
+
+ /// MakeFlagArg - Construct a new FlagArg for the given option
+ /// \arg Id.
+ Arg *MakeFlagArg(const Arg *BaseArg, const Option *Opt) const;
+
+ /// MakePositionalArg - Construct a new Positional arg for the
+ /// given option \arg Id, with the provided \arg Value.
+ Arg *MakePositionalArg(const Arg *BaseArg, const Option *Opt,
+ llvm::StringRef Value) const;
+
+ /// MakeSeparateArg - Construct a new Positional arg for the
+ /// given option \arg Id, with the provided \arg Value.
+ Arg *MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
+ llvm::StringRef Value) const;
+
+ /// MakeJoinedArg - Construct a new Positional arg for the
+ /// given option \arg Id, with the provided \arg Value.
+ Arg *MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
+ llvm::StringRef Value) const;
+
+ /// @}
+ };
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h
new file mode 100644
index 0000000..0508213
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h
@@ -0,0 +1,32 @@
+//===--- CC1AsOptions.h - Clang Assembler Options Table ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_CC1ASOPTIONS_H
+#define CLANG_DRIVER_CC1ASOPTIONS_H
+
+namespace clang {
+namespace driver {
+ class OptTable;
+
+namespace cc1asoptions {
+ enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR) OPT_##ID,
+#include "clang/Driver/CC1AsOptions.inc"
+ LastOption
+#undef OPTION
+ };
+}
+
+ OptTable *createCC1AsOptTable();
+}
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td
new file mode 100644
index 0000000..5c08dc6
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td
@@ -0,0 +1,71 @@
+//===--- CC1AsOptions.td - Options for clang -cc1as -----------------------===//
+//
+// 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 -cc1as.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the common option parsing interfaces.
+include "OptParser.td"
+
+//===----------------------------------------------------------------------===//
+// Target Options
+//===----------------------------------------------------------------------===//
+
+def triple : Separate<"-triple">,
+ HelpText<"Specify target triple (e.g. x86_64-pc-linux-gnu)">;
+
+//===----------------------------------------------------------------------===//
+// Language Options
+//===----------------------------------------------------------------------===//
+
+def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">,
+ HelpText<"Add directory to include search path">;
+def n : Flag<"-n">,
+ HelpText<"Don't automatically start assembly file with a text section">;
+
+//===----------------------------------------------------------------------===//
+// Frontend Options
+//===----------------------------------------------------------------------===//
+
+def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
+
+def filetype : Separate<"-filetype">,
+ HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
+
+def help : Flag<"-help">,
+ HelpText<"Print this help text">;
+def _help : Flag<"--help">, Alias<help>;
+
+def version : Flag<"-version">,
+ HelpText<"Print the assembler version">;
+def _version : Flag<"--version">, Alias<version>;
+
+// Generic forwarding to LLVM options. This should only be used for debugging
+// and experimental features.
+def mllvm : Separate<"-mllvm">,
+ HelpText<"Additional arguments to forward to LLVM's option processing">;
+
+//===----------------------------------------------------------------------===//
+// 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 relax_all : Flag<"-relax-all">,
+ HelpText<"Relax all fixups (for performance testing)">;
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.h b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.h
new file mode 100644
index 0000000..4a8bbe5
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.h
@@ -0,0 +1,32 @@
+//===--- CC1Options.h - Clang CC1 Options Table -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_CC1OPTIONS_H
+#define CLANG_DRIVER_CC1OPTIONS_H
+
+namespace clang {
+namespace driver {
+ class OptTable;
+
+namespace cc1options {
+ enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR) OPT_##ID,
+#include "clang/Driver/CC1Options.inc"
+ LastOption
+#undef OPTION
+ };
+}
+
+ OptTable *createCC1OptTable();
+}
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td
new file mode 100644
index 0000000..fd8322b
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td
@@ -0,0 +1,511 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the common option parsing interfaces.
+include "OptParser.td"
+
+//===----------------------------------------------------------------------===//
+// Target Options
+//===----------------------------------------------------------------------===//
+
+def target_abi : Separate<"-target-abi">,
+ HelpText<"Target a particular ABI type">;
+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 triple_EQ : Joined<"-triple=">, Alias<triple>;
+
+//===----------------------------------------------------------------------===//
+// Analyzer Options
+//===----------------------------------------------------------------------===//
+
+def analysis_CFGDump : Flag<"-cfg-dump">,
+ HelpText<"Display Control-Flow Graphs">;
+def analysis_CFGView : Flag<"-cfg-view">,
+ HelpText<"View Control-Flow Graphs using GraphViz">;
+def analysis_DisplayLiveVariables : Flag<"-dump-live-variables">,
+ HelpText<"Print results of live variable analysis">;
+def analysis_LLVMConventionChecker : Flag<"-analyzer-check-llvm-conventions">,
+ HelpText<"Check code for LLVM codebase conventions (domain-specific)">;
+def analysis_SecuritySyntacticChecks : Flag<"-analyzer-check-security-syntactic">,
+ HelpText<"Perform quick security checks that require no data flow">;
+def analysis_WarnDeadStores : Flag<"-analyzer-check-dead-stores">,
+ HelpText<"Warn about stores to dead variables">;
+def analysis_WarnUninitVals : Flag<"-warn-uninit-values">,
+ HelpText<"Warn about uses of uninitialized variables">;
+def analysis_WarnObjCMethSigs : Flag<"-analyzer-check-objc-methodsigs">,
+ HelpText<"Warn about Objective-C method signatures with type incompatibilities">;
+def analysis_WarnObjCDealloc : Flag<"-analyzer-check-objc-missing-dealloc">,
+ HelpText<"Warn about Objective-C classes that lack a correct implementation of -dealloc">;
+def analysis_WarnObjCUnusedIvars : Flag<"-analyzer-check-objc-unused-ivars">,
+ HelpText<"Warn about private ivars that are never used">;
+def analysis_ObjCMemChecker : Flag<"-analyzer-check-objc-mem">,
+ HelpText<"Run the [Core] Foundation reference count checker">;
+def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">,
+ HelpText<"Warn about unintended use of sizeof() on pointer expressions">;
+
+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_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 analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">,
+ HelpText<"Use experimental path-sensitive checks">;
+def analyzer_experimental_internal_checks :
+ Flag<"-analyzer-experimental-internal-checks">,
+ HelpText<"Use new default path-sensitive checks currently in testing">;
+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 analyzer_no_purge_dead : Flag<"-analyzer-no-purge-dead">,
+ HelpText<"Don't remove dead symbols, bindings, and constraints before processing a statement">;
+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_call : Flag<"-analyzer-inline-call">,
+ HelpText<"Experimental transfer function inlining callees when its definition is available.">;
+def analyzer_max_nodes : Separate<"-analyzer-max-nodes">,
+ HelpText<"The maximum number of nodes the analyzer can generate">;
+def analyzer_max_loop : Separate<"-analyzer-max-loop">,
+ HelpText<"The maximum number of times the analyzer will go through a loop">;
+
+//===----------------------------------------------------------------------===//
+// CodeGen Options
+//===----------------------------------------------------------------------===//
+
+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_red_zone : Flag<"-disable-red-zone">,
+ HelpText<"Do not emit code that uses the red zone.">;
+def dwarf_debug_flags : Separate<"-dwarf-debug-flags">,
+ HelpText<"The string to embed in the Dwarf debug flags record.">;
+def g : Flag<"-g">, HelpText<"Generate source level debug information">;
+def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
+ HelpText<"Generate runtime checks for undefined behavior.">;
+def fno_common : Flag<"-fno-common">,
+ HelpText<"Compile common globals like normal definitions">;
+def no_implicit_float : Flag<"-no-implicit-float">,
+ HelpText<"Don't generate implicit floating point instructions (x86-only)">;
+def fno_merge_all_constants : Flag<"-fno-merge-all-constants">,
+ HelpText<"Disallow merging of constants.">;
+def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">,
+ HelpText<"Do not emit code to make initialization of local statics thread safe">;
+def fdump_vtable_layouts : Flag<"-fdump-vtable-layouts">,
+ HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
+def ffunction_sections : Flag<"-ffunction-sections">,
+ HelpText<"Place each function in its own section (ELF Only)">;
+def fdata_sections : Flag<"-fdata-sections">,
+ HelpText<"Place each data in its own section (ELF Only)">;
+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 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 mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">,
+ HelpText<"Do not put zero initialized data in the BSS">;
+def msoft_float : Flag<"-msoft-float">,
+ HelpText<"Use software floating point">;
+def mrelax_all : Flag<"-mrelax-all">,
+ HelpText<"Relax all machine instructions">;
+def mrelocation_model : Separate<"-mrelocation-model">,
+ HelpText<"The relocation model to use">;
+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 O : Joined<"-O">, HelpText<"Optimization level">;
+def Os : Flag<"-Os">, HelpText<"Optimize for size">;
+
+//===----------------------------------------------------------------------===//
+// Dependency Output Options
+//===----------------------------------------------------------------------===//
+
+def dependency_file : Separate<"-dependency-file">,
+ HelpText<"Filename (or -) to write dependency output to">;
+def sys_header_deps : Flag<"-sys-header-deps">,
+ HelpText<"Include system headers in dependency output">;
+def MQ : Separate<"-MQ">, HelpText<"Specify target to quote for dependency">;
+def MT : Separate<"-MT">, HelpText<"Specify target for dependency">;
+def MP : Flag<"-MP">,
+ HelpText<"Create phony target for each dependency (other than main file)">;
+
+//===----------------------------------------------------------------------===//
+// Diagnostic Options
+//===----------------------------------------------------------------------===//
+
+def dump_build_information : Separate<"-dump-build-information">,
+ MetaVarName<"<filename>">,
+ HelpText<"output a dump of some build information to a file">;
+def fno_show_column : Flag<"-fno-show-column">,
+ HelpText<"Do not include column number on diagnostics">;
+def fno_show_source_location : Flag<"-fno-show-source-location">,
+ HelpText<"Do not include source location information with diagnostics">;
+def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">,
+ HelpText<"Do not include source line and caret with diagnostics">;
+def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">,
+ HelpText<"Do not include fixit information in diagnostics">;
+def fdiagnostics_binary : Flag<"-fdiagnostics-binary">;
+def w : Flag<"-w">, HelpText<"Suppress all warnings">;
+def pedantic : Flag<"-pedantic">;
+def pedantic_errors : Flag<"-pedantic-errors">;
+
+// This gets all -W options, including -Werror, -W[no-]system-headers, etc. The
+// driver has stripped off -Wa,foo etc. The driver has also translated -W to
+// -Wextra, so we don't need to worry about it.
+def W : Joined<"-W">;
+
+def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">,
+ HelpText<"Print source range spans in numeric form">;
+def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
+ HelpText<"Print diagnostic name with mappable diagnostics">;
+def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">,
+ HelpText<"Print diagnostic category">;
+
+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 instantiation 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 fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">,
+ HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
+def fcolor_diagnostics : Flag<"-fcolor-diagnostics">,
+ HelpText<"Use colors in diagnostics">;
+def Wno_rewrite_macros : Flag<"-Wno-rewrite-macros">,
+ HelpText<"Silence ObjC rewriting warnings">;
+def Wwrite_strings : Flag<"-Wwrite-strings">,
+ HelpText<"Add const qualifier to string literals">;
+def verify : Flag<"-verify">,
+ HelpText<"Verify emitted diagnostics and 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 ast_merge : Separate<"-ast-merge">,
+ MetaVarName<"<ast file>">,
+ HelpText<"Merge the given AST file into the translation unit being compiled.">;
+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 no_code_completion_debug_printer : Flag<"-no-code-completion-debug-printer">,
+ HelpText<"Don't use the \"debug\" code-completion print">;
+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 disable_free : Flag<"-disable-free">,
+ HelpText<"Disable freeing of memory on exit">;
+def help : Flag<"-help">,
+ HelpText<"Print this help text">;
+def _help : Flag<"--help">, Alias<help>;
+def x : Separate<"-x">, HelpText<"Input language type">;
+def cxx_inheritance_view : Separate<"-cxx-inheritance-view">,
+ MetaVarName<"<class name>">,
+ HelpText<"View C++ inheritance for a specified class">;
+def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
+def load : Separate<"-load">, MetaVarName<"<dsopath>">,
+ HelpText<"Load the named plugin (dynamic shared object)">;
+def plugin : Separate<"-plugin">,
+ HelpText<"Use the named plugin action (use \"help\" to list available options)">;
+def resource_dir : Separate<"-resource-dir">,
+ HelpText<"The directory which holds the compiler resource files">;
+def version : Flag<"-version">,
+ HelpText<"Print the compiler version">;
+def _version : Flag<"--version">, Alias<version>;
+
+def Action_Group : OptionGroup<"<action group>">;
+let Group = Action_Group in {
+
+def Eonly : Flag<"-Eonly">,
+ HelpText<"Just run preprocessor, no output (for timings)">;
+def E : Flag<"-E">,
+ HelpText<"Run preprocessor, emit preprocessed file">;
+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 parse_noop : Flag<"-parse-noop">,
+ HelpText<"Run parser with noop callbacks (for timings)">;
+def fsyntax_only : Flag<"-fsyntax-only">,
+ HelpText<"Run parser and perform semantic analysis">;
+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 parse_print_callbacks : Flag<"-parse-print-callbacks">,
+ HelpText<"Run parser and print each callback invoked">;
+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_print_xml : Flag<"-ast-print-xml">,
+ HelpText<"Build ASTs and then print them in XML format">;
+def ast_dump : Flag<"-ast-dump">,
+ HelpText<"Build ASTs and then debug dump them">;
+def ast_view : Flag<"-ast-view">,
+ HelpText<"Build ASTs and view them with GraphViz">;
+def boostcon : Flag<"-boostcon">,
+ HelpText<"BoostCon workshop mode">;
+def print_decl_contexts : Flag<"-print-decl-contexts">,
+ HelpText<"Print DeclContexts and their Decls">;
+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 S : Flag<"-S">,
+ HelpText<"Emit native assembly code">;
+def emit_llvm : Flag<"-emit-llvm">,
+ HelpText<"Build ASTs then convert to LLVM, emit .ll 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_objc : Flag<"-rewrite-objc">,
+ HelpText<"Rewrite ObjC into C (code rewriter example)">;
+def rewrite_macros : Flag<"-rewrite-macros">,
+ HelpText<"Expand macros without full preprocessing">;
+
+}
+
+def relocatable_pch : Flag<"-relocatable-pch">,
+ HelpText<"Whether to build a relocatable precompiled header">;
+def print_stats : Flag<"-print-stats">,
+ HelpText<"Print performance metrics and statistics">;
+def ftime_report : Flag<"-ftime-report">,
+ HelpText<"Print the amount of time each phase of compilation takes">;
+
+def fdump_record_layouts : Flag<"-fdump-record-layouts">,
+ HelpText<"Dump record layout information">;
+
+// Generic forwarding to LLVM options. This should only be used for debugging
+// and experimental features.
+def mllvm : Separate<"-mllvm">,
+ HelpText<"Additional arguments to forward to LLVM's option processing">;
+
+//===----------------------------------------------------------------------===//
+// Language Options
+//===----------------------------------------------------------------------===//
+
+def fno_builtin : Flag<"-fno-builtin">,
+ HelpText<"Disable implicit builtin knowledge of functions">;
+def faltivec : Flag<"-faltivec">,
+ HelpText<"Enable AltiVec vector initializer syntax">;
+def fno_access_control : Flag<"-fno-access-control">,
+ HelpText<"Disable C++ access control">;
+def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">,
+ HelpText<"Don't assume that C++'s global operator new can't alias any pointer">;
+def fgnu_keywords : Flag<"-fgnu-keywords">,
+ HelpText<"Allow GNU-extension keywords regardless of language standard">;
+def fno_gnu_keywords : Flag<"-fno-gnu-keywords">,
+ HelpText<"Disallow GNU-extension keywords regardless of language standard">;
+def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">,
+ HelpText<"Allow '$' in identifiers">;
+def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">,
+ HelpText<"Disallow '$' in identifiers">;
+def femit_all_decls : Flag<"-femit-all-decls">,
+ HelpText<"Emit all declarations, even if unused">;
+def fblocks : Flag<"-fblocks">,
+ HelpText<"enable the 'blocks' language feature">;
+def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
+def fexceptions : Flag<"-fexceptions">,
+ HelpText<"Enable support for exception handling">;
+def fsjlj_exceptions : Flag<"-fsjlj-exceptions">,
+ HelpText<"Use SjLj style exceptions">;
+def ffreestanding : Flag<"-ffreestanding">,
+ HelpText<"Assert that the compilation takes place in a freestanding environment">;
+def fgnu_runtime : Flag<"-fgnu-runtime">,
+ HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
+def std_EQ : Joined<"-std=">,
+ HelpText<"Language standard to compile for">;
+def fmath_errno : Flag<"-fmath-errno">,
+ HelpText<"Require math functions to indicate errors by setting errno">;
+def fms_extensions : Flag<"-fms-extensions">,
+ HelpText<"Accept some non-standard constructs used in Microsoft header files ">;
+def main_file_name : Separate<"-main-file-name">,
+ HelpText<"Main file name to use for debug info">;
+def fno_elide_constructors : Flag<"-fno-elide-constructors">,
+ HelpText<"Disable C++ copy constructor elision">;
+def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">,
+ HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">;
+def fno_operator_names : Flag<"-fno-operator-names">,
+ HelpText<"Do not treat C++ operator name keywords as synonyms for operators">;
+def fno_signed_char : Flag<"-fno-signed-char">,
+ HelpText<"Char is unsigned">;
+def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">,
+ HelpText<"Don't use __cxa_atexit for calling destructors">;
+def fconstant_string_class : Separate<"-fconstant-string-class">,
+ MetaVarName<"<class name>">,
+ HelpText<"Specify the class to use for constant Objective-C string objects.">;
+def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">,
+ HelpText<"Enable creation of CodeFoundation-type constant strings">;
+def fobjc_gc : Flag<"-fobjc-gc">,
+ HelpText<"Enable Objective-C garbage collection">;
+def fobjc_gc_only : Flag<"-fobjc-gc-only">,
+ HelpText<"Use GC exclusively for Objective-C related memory management">;
+def fobjc_dispatch_method_EQ : Joined<"-fobjc-dispatch-method=">,
+ HelpText<"Objective-C dispatch method to use">;
+def print_ivar_layout : Flag<"-print-ivar-layout">,
+ HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
+def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
+ HelpText<"enable objective-c's nonfragile abi">;
+def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">,
+ HelpText<"enable objective-c's enhanced nonfragile abi">;
+def ftrapv : Flag<"-ftrapv">,
+ HelpText<"Trap on integer overflow">;
+def pic_level : Separate<"-pic-level">,
+ HelpText<"Value for __PIC__">;
+def pthread : Flag<"-pthread">,
+ HelpText<"Support POSIX threads in generated code">;
+def fpascal_strings : Flag<"-fpascal-strings">,
+ HelpText<"Recognize and construct Pascal-style string literals">;
+def fno_rtti : Flag<"-fno-rtti">,
+ HelpText<"Disable generation of rtti information">;
+def fshort_wchar : Flag<"-fshort-wchar">,
+ HelpText<"Force wchar_t to be a short unsigned int">;
+def static_define : Flag<"-static-define">,
+ HelpText<"Should __STATIC__ be defined">;
+def stack_protector : Separate<"-stack-protector">,
+ HelpText<"Enable stack protectors">;
+def fvisibility : Separate<"-fvisibility">,
+ HelpText<"Default symbol visibility">;
+def ftemplate_depth : Separate<"-ftemplate-depth">,
+ HelpText<"Maximum depth of recursive template instantiation">;
+def trigraphs : Flag<"-trigraphs">,
+ HelpText<"Process trigraph sequences">;
+def fwritable_strings : Flag<"-fwritable-strings">,
+ HelpText<"Store string literals as writable data">;
+def fno_bitfield_type_align : Flag<"-fno-bitfield-type-align">,
+ HelpText<"Ignore bit-field types when aligning structures">;
+
+//===----------------------------------------------------------------------===//
+// Header Search Options
+//===----------------------------------------------------------------------===//
+
+def nostdinc : Flag<"-nostdinc">,
+ HelpText<"Disable standard #include directories">;
+def nostdincxx : Flag<"-nostdinc++">,
+ HelpText<"Disable standard #include directories for the C++ standard library">;
+def nobuiltininc : Flag<"-nobuiltininc">,
+ HelpText<"Disable builtin #include directories">;
+def F : JoinedOrSeparate<"-F">, MetaVarName<"<directory>">,
+ HelpText<"Add directory to framework include search path">;
+def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">,
+ HelpText<"Add directory to include search path">;
+def idirafter : JoinedOrSeparate<"-idirafter">, MetaVarName<"<directory>">,
+ HelpText<"Add directory to AFTER include search path">;
+def iquote : JoinedOrSeparate<"-iquote">, MetaVarName<"<directory>">,
+ HelpText<"Add directory to QUOTE include search path">;
+def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"<directory>">,
+ HelpText<"Add directory to SYSTEM include search path">;
+def iprefix : JoinedOrSeparate<"-iprefix">, MetaVarName<"<prefix>">,
+ HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">;
+def iwithprefix : JoinedOrSeparate<"-iwithprefix">, MetaVarName<"<dir>">,
+ HelpText<"Set directory to SYSTEM include search path with prefix">;
+def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">,
+ MetaVarName<"<dir>">,
+ HelpText<"Set directory to include search path with prefix">;
+def isysroot : JoinedOrSeparate<"-isysroot">, MetaVarName<"<dir>">,
+ HelpText<"Set the system root directory (usually /)">;
+def v : Flag<"-v">, HelpText<"Enable verbose output">;
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Options
+//===----------------------------------------------------------------------===//
+
+def D : JoinedOrSeparate<"-D">, MetaVarName<"<macro>">,
+ HelpText<"Predefine the specified macro">;
+def include_ : JoinedOrSeparate<"-include">, MetaVarName<"<file>">, EnumName<"include">,
+ HelpText<"Include file before parsing">;
+def imacros : JoinedOrSeparate<"-imacros">, MetaVarName<"<file>">,
+ HelpText<"Include macros from file before parsing">;
+def include_pch : Separate<"-include-pch">, MetaVarName<"<file>">,
+ HelpText<"Include precompiled header file">;
+def include_pth : Separate<"-include-pth">, MetaVarName<"<file>">,
+ HelpText<"Include file before parsing">;
+def token_cache : Separate<"-token-cache">, MetaVarName<"<path>">,
+ HelpText<"Use specified token cache file">;
+def U : JoinedOrSeparate<"-U">, MetaVarName<"<macro>">,
+ HelpText<"Undefine the specified macro">;
+def undef : Flag<"-undef">, MetaVarName<"<macro>">,
+ HelpText<"undef all system defines">;
+def detailed_preprocessing_record : Flag<"-detailed-preprocessing-record">,
+ HelpText<"include a detailed record of preprocessing actions">;
+
+//===----------------------------------------------------------------------===//
+// Preprocessed Output Options
+//===----------------------------------------------------------------------===//
+
+def P : Flag<"-P">,
+ HelpText<"Disable linemarker output in -E mode">;
+def C : Flag<"-C">,
+ HelpText<"Enable comment output in -E mode">;
+def CC : Flag<"-CC">,
+ HelpText<"Enable comment output in -E mode, even from macro expansions">;
+def dM : Flag<"-dM">,
+ HelpText<"Print macro definitions in -E mode instead of normal output">;
+def dD : Flag<"-dD">,
+ HelpText<"Print macro definitions in -E mode in addition to normal output">;
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/Driver/CMakeLists.txt
new file mode 100644
index 0000000..99be53f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(LLVM_TARGET_DEFINITIONS Options.td)
+tablegen(Options.inc
+ -gen-opt-parser-defs)
+add_custom_target(ClangDriverOptions
+ DEPENDS Options.inc)
+
+set(LLVM_TARGET_DEFINITIONS CC1Options.td)
+tablegen(CC1Options.inc
+ -gen-opt-parser-defs)
+add_custom_target(ClangCC1Options
+ DEPENDS CC1Options.inc)
+
+set(LLVM_TARGET_DEFINITIONS CC1AsOptions.td)
+tablegen(CC1AsOptions.inc
+ -gen-opt-parser-defs)
+add_custom_target(ClangCC1AsOptions
+ DEPENDS CC1AsOptions.inc)
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h
new file mode 100644
index 0000000..56786a7
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h
@@ -0,0 +1,136 @@
+//===--- 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 CLANG_DRIVER_COMPILATION_H_
+#define CLANG_DRIVER_COMPILATION_H_
+
+#include "clang/Driver/Job.h"
+#include "clang/Driver/Util.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace clang {
+namespace driver {
+ class DerivedArgList;
+ class Driver;
+ class InputArgList;
+ 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;
+
+ /// The original (untranslated) input argument list.
+ InputArgList *Args;
+
+ /// The list of actions.
+ ActionList Actions;
+
+ /// The root list of jobs.
+ JobList Jobs;
+
+ /// Cache of translated arguments for a particular tool chain.
+ llvm::DenseMap<std::pair<const ToolChain*, const char*>,
+ DerivedArgList*> TCArgs;
+
+ /// Temporary files which should be removed on exit.
+ ArgStringList TempFiles;
+
+ /// Result files which should be removed on failure.
+ ArgStringList ResultFiles;
+
+public:
+ Compilation(const Driver &D, const ToolChain &DefaultToolChain,
+ InputArgList *Args);
+ ~Compilation();
+
+ const Driver &getDriver() const { return TheDriver; }
+
+ const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
+
+ const InputArgList &getArgs() const { return *Args; }
+
+ ActionList &getActions() { return Actions; }
+ const ActionList &getActions() const { return Actions; }
+
+ JobList &getJobs() { return Jobs; }
+ const JobList &getJobs() const { return Jobs; }
+
+ const ArgStringList &getTempFiles() const { return TempFiles; }
+
+ const ArgStringList &getResultFiles() const { return ResultFiles; }
+
+ /// getArgsForToolChain - Return the derived argument list for the
+ /// tool chain \arg TC (or the default tool chain, if TC is not
+ /// specified).
+ ///
+ /// \param BoundArch - The bound architecture name, or 0.
+ const 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) {
+ ResultFiles.push_back(Name);
+ return Name;
+ }
+
+ /// CleanupFileList - Remove the files in the given list.
+ ///
+ /// \param IssueErrors - Report failures as errors.
+ /// \return Whether all files were removed successfully.
+ bool CleanupFileList(const ArgStringList &Files,
+ bool IssueErrors=false) const;
+
+ /// PrintJob - Print one job in -### format.
+ ///
+ /// \param OS - The stream to print on.
+ /// \param J - The job to print.
+ /// \param Terminator - A string to print at the end of the line.
+ /// \param Quote - Should separate arguments be quoted.
+ void PrintJob(llvm::raw_ostream &OS, const Job &J,
+ const char *Terminator, bool Quote) 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 FailingCommand - For non-zero results, this will be set to the
+ /// Command which failed.
+ /// \return The accumulated result code of the job.
+ int ExecuteJob(const Job &J, const Command *&FailingCommand) const;
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Driver.h b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h
new file mode 100644
index 0000000..90c3a0d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h
@@ -0,0 +1,318 @@
+//===--- 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 CLANG_DRIVER_DRIVER_H_
+#define CLANG_DRIVER_DRIVER_H_
+
+#include "clang/Basic/Diagnostic.h"
+
+#include "clang/Driver/Phases.h"
+#include "clang/Driver/Util.h"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/System/Path.h" // FIXME: Kill when CompilationInfo
+ // lands.
+#include <list>
+#include <set>
+#include <string>
+
+namespace llvm {
+ class raw_ostream;
+}
+namespace clang {
+namespace driver {
+ class Action;
+ class ArgList;
+ class Compilation;
+ class HostInfo;
+ class InputArgList;
+ class InputInfo;
+ class JobAction;
+ class OptTable;
+ class PipedJob;
+ class ToolChain;
+
+/// Driver - Encapsulate logic for constructing compilation processes
+/// from a set of gcc-driver-like command line arguments.
+class Driver {
+ OptTable *Opts;
+
+ Diagnostic &Diags;
+
+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 path to the compiler resource directory.
+ std::string ResourceDir;
+
+ /// A prefix directory used to emulated 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.
+ std::string PrefixDir;
+
+ /// Default host triple.
+ std::string DefaultHostTriple;
+
+ /// Default name for linked images (e.g., "a.out").
+ std::string DefaultImageName;
+
+ /// Driver title to use with help.
+ std::string DriverTitle;
+
+ /// Host information for the platform the driver is running as. This
+ /// will generally be the actual host platform, but not always.
+ const HostInfo *Host;
+
+ /// Information about the host which can be overriden by the user.
+ std::string HostBits, HostMachine, HostSystem, HostRelease;
+
+ /// Name to use when calling the generic gcc.
+ std::string CCCGenericGCCName;
+
+ /// The file to log CC_PRINT_OPTIONS output to, if enabled.
+ const char *CCPrintOptionsFilename;
+
+ /// Whether the driver should follow g++ like behavior.
+ unsigned CCCIsCXX : 1;
+
+ /// Echo commands while executing (in -v style).
+ unsigned CCCEcho : 1;
+
+ /// 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;
+
+private:
+ /// Whether to check that input files exist when constructing compilation
+ /// jobs.
+ unsigned CheckInputsExist : 1;
+
+ /// Use the clang compiler where possible.
+ unsigned CCCUseClang : 1;
+
+ /// Use clang for handling C++ and Objective-C++ inputs.
+ unsigned CCCUseClangCXX : 1;
+
+ /// Use clang as a preprocessor (clang's preprocessor will still be
+ /// used where an integrated CPP would).
+ unsigned CCCUseClangCPP : 1;
+
+public:
+ /// Use lazy precompiled headers for PCH support.
+ unsigned CCCUsePCH : 1;
+
+private:
+ /// Only use clang for the given architectures (only used when
+ /// non-empty).
+ std::set<llvm::Triple::ArchType> CCCClangArchs;
+
+ /// Certain options suppress the 'no input files' warning.
+ bool SuppressMissingInputWarning : 1;
+
+ std::list<std::string> TempFiles;
+ std::list<std::string> ResultFiles;
+
+public:
+ Driver(llvm::StringRef _Name, llvm::StringRef _Dir,
+ llvm::StringRef _DefaultHostTriple,
+ llvm::StringRef _DefaultImageName,
+ bool IsProduction, bool CXXIsProduction,
+ Diagnostic &_Diags);
+ ~Driver();
+
+ /// @name Accessors
+ /// @{
+
+ const OptTable &getOpts() const { return *Opts; }
+
+ const Diagnostic &getDiags() const { return Diags; }
+
+ bool getCheckInputsExist() const { return CheckInputsExist; }
+
+ void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
+
+ const std::string &getTitle() { return DriverTitle; }
+ void setTitle(std::string Value) { DriverTitle = Value; }
+
+ /// @}
+ /// @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(int argc, const char **argv);
+
+ /// @name Driver Steps
+ /// @{
+
+ /// ParseArgStrings - Parse the given list of strings into an
+ /// ArgList.
+ InputArgList *ParseArgStrings(const char **ArgBegin, const char **ArgEnd);
+
+ /// BuildActions - Construct the list of actions to perform for the
+ /// given arguments, which are only done for a single architecture.
+ ///
+ /// \param Args - The input arguments.
+ /// \param Actions - The list to store the resulting actions onto.
+ void BuildActions(const ArgList &Args, ActionList &Actions) const;
+
+ /// BuildUniversalActions - Construct the list of actions to perform
+ /// for the given arguments, which may require a universal build.
+ ///
+ /// \param Args - The input arguments.
+ /// \param Actions - The list to store the resulting actions onto.
+ void BuildUniversalActions(const ArgList &Args, ActionList &Actions) const;
+
+ /// BuildJobs - Bind actions to concrete tools and translate
+ /// arguments to form the list of jobs to run.
+ ///
+ /// \arg 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, removing
+ /// temporary files, etc.
+ int ExecuteCompilation(const Compilation &C) const;
+
+ /// @}
+ /// @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;
+
+ /// PrintOptions - Print the list of arguments.
+ void PrintOptions(const ArgList &Args) const;
+
+ /// PrintVersion - Print the driver version.
+ void PrintVersion(const Compilation &C, llvm::raw_ostream &OS) const;
+
+ /// GetFilePath - Lookup \arg Name in the list of file search paths.
+ ///
+ /// \arg 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 \arg Name in the list of program search
+ /// paths.
+ ///
+ /// \arg TC - The provided tool chain for additional information on
+ /// directories to search.
+ ///
+ /// \arg WantFile - False when searching for an executable file, otherwise
+ /// true. Defaults to false.
+ //
+ // FIXME: This should be in CompilationInfo.
+ std::string GetProgramPath(const char *Name, const ToolChain &TC,
+ bool WantFile = false) 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
+ /// \arg Phase on the \arg Input, taking in to account arguments
+ /// like -fsyntax-only or --analyze.
+ Action *ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
+ Action *Input) const;
+
+
+ /// BuildJobsForAction - Construct the jobs to perform for the
+ /// action \arg A.
+ void BuildJobsForAction(Compilation &C,
+ const Action *A,
+ const ToolChain *TC,
+ const char *BoundArch,
+ bool CanAcceptPipe,
+ bool AtTopLevel,
+ const char *LinkingOutput,
+ InputInfo &Result) const;
+
+ /// GetNamedOutputPath - Return the name to use for the output of
+ /// the action \arg 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 AtTopLevel - Whether this is a "top-level" action.
+ const char *GetNamedOutputPath(Compilation &C,
+ const JobAction &JA,
+ const char *BaseInput,
+ bool AtTopLevel) const;
+
+ /// GetTemporaryPath - Return the pathname of a temporary file to
+ /// use as part of compilation; the file will have the given suffix.
+ ///
+ /// GCC goes to extra lengths here to be a bit more robust.
+ std::string GetTemporaryPath(const char *Suffix) const;
+
+ /// GetHostInfo - Construct a new host info object for the given
+ /// host triple.
+ const HostInfo *GetHostInfo(const char *HostTriple) const;
+
+ /// ShouldUseClangCompilar - Should the clang compiler be used to
+ /// handle this action.
+ bool ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
+ const llvm::Triple &ArchName) const;
+
+ /// @}
+
+ /// 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);
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h
new file mode 100644
index 0000000..c20d807b
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- 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_DRIVERDIAGNOSTIC_H
+#define LLVM_CLANG_DRIVERDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+ namespace diag {
+ enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,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/contrib/llvm/tools/clang/include/clang/Driver/HostInfo.h b/contrib/llvm/tools/clang/include/clang/Driver/HostInfo.h
new file mode 100644
index 0000000..ca1ee9a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/HostInfo.h
@@ -0,0 +1,91 @@
+//===--- HostInfo.h - Host specific information -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_HOSTINFO_H_
+#define CLANG_DRIVER_HOSTINFO_H_
+
+#include "clang/Driver/Types.h"
+#include "llvm/ADT/Triple.h"
+#include <string>
+
+namespace clang {
+namespace driver {
+ class ArgList;
+ class Driver;
+ class ToolChain;
+
+/// HostInfo - Config information about a particular host which may interact
+/// with driver behavior.
+///
+/// The host information is used for controlling the parts of the driver which
+/// interact with the platform the driver is ostensibly being run from. For
+/// testing purposes, the HostInfo used by the driver may differ from the actual
+/// host.
+class HostInfo {
+protected:
+ const Driver &TheDriver;
+ const llvm::Triple Triple;
+
+ HostInfo(const Driver &D, const llvm::Triple &_Triple);
+
+public:
+ virtual ~HostInfo();
+
+ const Driver &getDriver() const { return TheDriver; }
+
+ const llvm::Triple& getTriple() const { return Triple; }
+ std::string getArchName() const { return Triple.getArchName(); }
+ std::string getPlatformName() const { return Triple.getVendorName(); }
+ std::string getOSName() const { return Triple.getOSName(); }
+
+ /// useDriverDriver - Whether the driver should act as a driver driver for
+ /// this host and support -arch, -Xarch, etc.
+ virtual bool useDriverDriver() const = 0;
+
+ /// lookupTypeForExtension - Return the default language type to use for the
+ /// given extension.
+ virtual types::ID lookupTypeForExtension(const char *Ext) const = 0;
+
+ /// CreateToolChain - Construct the toolchain to use for this host (which the
+ /// host retains ownership of).
+ ///
+ /// \param Args - The argument list, which may be used to alter the default
+ /// toolchain, for example in the presence of -m32 or -m64.
+ ///
+ /// \param ArchName - The architecture to return a toolchain for, or 0 if
+ /// unspecified. This will only ever be non-zero for hosts which support a
+ /// driver driver.
+
+ // FIXME: Pin down exactly what the HostInfo is allowed to use Args
+ // for here. Currently this is for -m32 / -m64 defaulting.
+ virtual ToolChain *CreateToolChain(const ArgList &Args,
+ const char *ArchName=0) const = 0;
+};
+
+const HostInfo *createAuroraUXHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
+const HostInfo *createDarwinHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
+const HostInfo *createOpenBSDHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
+const HostInfo *createFreeBSDHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
+const HostInfo *createDragonFlyHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
+const HostInfo *createLinuxHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
+const HostInfo *createTCEHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
+const HostInfo *createUnknownHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Job.h b/contrib/llvm/tools/clang/include/clang/Driver/Job.h
new file mode 100644
index 0000000..5a789fb
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Job.h
@@ -0,0 +1,157 @@
+//===--- 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 CLANG_DRIVER_JOB_H_
+#define CLANG_DRIVER_JOB_H_
+
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/SmallVector.h"
+
+#include "llvm/Support/Casting.h"
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+namespace clang {
+namespace driver {
+class Command;
+class Tool;
+
+class Job {
+public:
+ enum JobClass {
+ CommandClass,
+ PipedJobClass,
+ JobListClass
+ };
+
+private:
+ JobClass Kind;
+
+protected:
+ Job(JobClass _Kind) : Kind(_Kind) {}
+public:
+ virtual ~Job();
+
+ JobClass getKind() const { return Kind; }
+
+ /// addCommand - Append a command to the current job, which must be
+ /// either a piped job or a job list.
+ void addCommand(Command *C);
+
+ static bool classof(const Job *) { return true; }
+};
+
+ /// Command - An executable path/name and argument vector to
+ /// execute.
+class Command : public Job {
+ /// 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).
+ ArgStringList Arguments;
+
+public:
+ Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
+ const ArgStringList &_Arguments);
+
+ /// 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; }
+
+ const char *getExecutable() const { return Executable; }
+
+ const ArgStringList &getArguments() const { return Arguments; }
+
+ static bool classof(const Job *J) {
+ return J->getKind() == CommandClass;
+ }
+ static bool classof(const Command *) { return true; }
+};
+
+ /// PipedJob - A list of Commands which should be executed together
+ /// with their standard inputs and outputs connected.
+class PipedJob : public Job {
+public:
+ typedef llvm::SmallVector<Command*, 4> list_type;
+ typedef list_type::size_type size_type;
+ typedef list_type::iterator iterator;
+ typedef list_type::const_iterator const_iterator;
+
+private:
+ list_type Commands;
+
+public:
+ PipedJob();
+ virtual ~PipedJob();
+
+ /// Add a command to the piped job (taking ownership).
+ void addCommand(Command *C) { Commands.push_back(C); }
+
+ const list_type &getCommands() const { return Commands; }
+
+ size_type size() const { return Commands.size(); }
+ iterator begin() { return Commands.begin(); }
+ const_iterator begin() const { return Commands.begin(); }
+ iterator end() { return Commands.end(); }
+ const_iterator end() const { return Commands.end(); }
+
+ static bool classof(const Job *J) {
+ return J->getKind() == PipedJobClass;
+ }
+ static bool classof(const PipedJob *) { return true; }
+};
+
+ /// JobList - A sequence of jobs to perform.
+class JobList : public Job {
+public:
+ typedef llvm::SmallVector<Job*, 4> list_type;
+ typedef list_type::size_type size_type;
+ typedef list_type::iterator iterator;
+ typedef list_type::const_iterator const_iterator;
+
+private:
+ list_type Jobs;
+
+public:
+ JobList();
+ virtual ~JobList();
+
+ /// Add a job to the list (taking ownership).
+ void addJob(Job *J) { Jobs.push_back(J); }
+
+ 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(); }
+
+ static bool classof(const Job *J) {
+ return J->getKind() == JobListClass;
+ }
+ static bool classof(const JobList *) { return true; }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Makefile b/contrib/llvm/tools/clang/include/clang/Driver/Makefile
new file mode 100644
index 0000000..b462aaa
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Makefile
@@ -0,0 +1,18 @@
+LEVEL = ../../../../..
+BUILT_SOURCES = Options.inc CC1Options.inc CC1AsOptions.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(LEVEL)/Makefile.common
+
+$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang Driver Option tables with tblgen"
+ $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang CC1 Option tables with tblgen"
+ $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/CC1AsOptions.inc.tmp : CC1AsOptions.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang CC1 Assembler Option tables with tblgen"
+ $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td b/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td
new file mode 100644
index 0000000..a9f4289
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td
@@ -0,0 +1,135 @@
+//===--- OptParser.td - Common Option Parsing Interfaces ------------------===//
+//
+// 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 common interfaces used by the option parsing TableGen
+// backend.
+//
+//===----------------------------------------------------------------------===//
+
+// Define the kinds of options.
+
+class OptionKind<string name, int predecence = 0, bit sentinel = 0> {
+ string Name = name;
+ // The kind precedence, kinds with lower precedence are matched first.
+ int Precedence = predecence;
+ // Indicate a sentinel option.
+ bit Sentinel = sentinel;
+}
+
+// An option group.
+def KIND_GROUP : OptionKind<"Group">;
+// The input option kind.
+def KIND_INPUT : OptionKind<"Input", 1, 1>;
+// The unknown option kind.
+def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>;
+// A flag with no values.
+def KIND_FLAG : OptionKind<"Flag">;
+// An option which prefixes its (single) value.
+def KIND_JOINED : OptionKind<"Joined", 1>;
+// An option which is followed by its value.
+def KIND_SEPARATE : OptionKind<"Separate">;
+// An option followed by its values, which are separated by commas.
+def KIND_COMMAJOINED : OptionKind<"CommaJoined">;
+// An option which is which takes multiple (separate) arguments.
+def KIND_MULTIARG : OptionKind<"MultiArg">;
+// An option which is either joined to its (non-empty) value, or followed by its
+// value.
+def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
+// An option which is both joined to its (first) value, and followed by its
+// (second) value.
+def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
+
+// Define the option flags.
+
+class OptionFlag {}
+
+// DriverOption - The option is a "driver" option, and should not be forwarded
+// to gcc.
+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;
+
+// RenderAsInput - The option should not render the name when rendered as an
+// input (i.e., the option is rendered as values).
+def RenderAsInput : OptionFlag;
+
+// RenderJoined - The option should be rendered joined, even if separate (only
+// sensible on single value separate options).
+def RenderJoined : OptionFlag;
+
+// RenderSeparate - The option should be rendered separately, even if joined
+// (only sensible on joined options).
+def RenderSeparate : OptionFlag;
+
+// Unsupported - The option is unsupported, and the driver will reject command
+// lines that use it.
+def Unsupported : OptionFlag;
+
+// HelpHidden - The option should not be displayed in --help, even if it has
+// help text. Clients *can* use this in conjuction with the OptTable::PrintHelp
+// arguments to implement hidden help groups.
+def HelpHidden : OptionFlag;
+
+// Define the option group class.
+
+class OptionGroup<string name> {
+ string EnumName = ?; // Uses the def name if undefined.
+ string Name = name;
+ string HelpText = ?;
+ OptionGroup Group = ?;
+}
+
+// Define the option class.
+
+class Option<string name, OptionKind kind> {
+ string EnumName = ?; // Uses the def name if undefined.
+ string Name = name;
+ OptionKind Kind = kind;
+ // Used by MultiArg option kind.
+ int NumArgs = 0;
+ string HelpText = ?;
+ string MetaVarName = ?;
+ list<OptionFlag> Flags = [];
+ OptionGroup Group = ?;
+ Option Alias = ?;
+}
+
+// Helpers for defining options.
+
+class Flag<string name> : Option<name, KIND_FLAG>;
+class Joined<string name> : Option<name, KIND_JOINED>;
+class Separate<string name> : Option<name, KIND_SEPARATE>;
+class CommaJoined<string name> : Option<name, KIND_COMMAJOINED>;
+class MultiArg<string name, int numargs> : Option<name, KIND_MULTIARG> {
+ int NumArgs = numargs;
+}
+class JoinedOrSeparate<string name> : Option<name, KIND_JOINED_OR_SEPARATE>;
+class JoinedAndSeparate<string name> : Option<name, KIND_JOINED_AND_SEPARATE>;
+
+// Mix-ins for adding optional attributes.
+
+class Alias<Option alias> { Option Alias = alias; }
+class EnumName<string name> { string EnumName = name; }
+class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
+class Group<OptionGroup group> { OptionGroup Group = group; }
+class HelpText<string text> { string HelpText = text; }
+class MetaVarName<string name> { string MetaVarName = name; }
+
+// Predefined options.
+
+// FIXME: Have generator validate that these appear in correct position (and
+// aren't duplicated).
+def INPUT : Option<"<input>", KIND_INPUT>, Flags<[DriverOption]>;
+def UNKNOWN : Option<"<unknown>", KIND_UNKNOWN>;
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptSpecifier.h b/contrib/llvm/tools/clang/include/clang/Driver/OptSpecifier.h
new file mode 100644
index 0000000..bb1cd17
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/OptSpecifier.h
@@ -0,0 +1,39 @@
+//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTSPECIFIER_H
+#define CLANG_DRIVER_OPTSPECIFIER_H
+
+namespace clang {
+namespace driver {
+ class Option;
+
+ /// OptSpecifier - Wrapper class for abstracting references to option IDs.
+ class OptSpecifier {
+ unsigned ID;
+
+ private:
+ explicit OptSpecifier(bool); // DO NOT IMPLEMENT
+
+ public:
+ OptSpecifier() : ID(0) {}
+ /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
+ /*implicit*/ OptSpecifier(const Option *Opt);
+
+ bool isValid() const { return ID != 0; }
+
+ unsigned getID() const { return ID; }
+
+ bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
+ bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
+ };
+}
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h b/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h
new file mode 100644
index 0000000..edae75c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h
@@ -0,0 +1,188 @@
+//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTTABLE_H
+#define CLANG_DRIVER_OPTTABLE_H
+
+#include "clang/Driver/OptSpecifier.h"
+#include <cassert>
+
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace clang {
+namespace driver {
+namespace options {
+ enum DriverFlag {
+ DriverOption = (1 << 0),
+ HelpHidden = (1 << 1),
+ LinkerInput = (1 << 2),
+ NoArgumentUnused = (1 << 3),
+ RenderAsInput = (1 << 4),
+ RenderJoined = (1 << 5),
+ RenderSeparate = (1 << 6),
+ Unsupported = (1 << 7)
+ };
+}
+
+ class Arg;
+ class InputArgList;
+ class Option;
+
+ /// OptTable - Provide access to the Option info table.
+ ///
+ /// The OptTable class provides a layer of indirection which allows Option
+ /// instance to be created lazily. In the common case, only a few options will
+ /// be needed at runtime; the OptTable class maintains enough information to
+ /// parse command lines without instantiating Options, while letting other
+ /// parts of the driver still use Option instances where convenient.
+ class OptTable {
+ public:
+ /// Info - Entry for a single option instance in the option data table.
+ struct Info {
+ const char *Name;
+ const char *HelpText;
+ const char *MetaVar;
+ unsigned char Kind;
+ unsigned char Flags;
+ unsigned char Param;
+ unsigned short GroupID;
+ unsigned short AliasID;
+ };
+
+ private:
+ /// The static option information table.
+ const Info *OptionInfos;
+ unsigned NumOptionInfos;
+
+ /// The lazily constructed options table, indexed by option::ID - 1.
+ mutable Option **Options;
+
+ /// Prebound input option instance.
+ const Option *TheInputOption;
+
+ /// Prebound unknown option instance.
+ const Option *TheUnknownOption;
+
+ /// The index of the first option which can be parsed (i.e., is not a
+ /// special option like 'input' or 'unknown', and is not an option group).
+ unsigned FirstSearchableIndex;
+
+ private:
+ const Info &getInfo(OptSpecifier Opt) const {
+ unsigned id = Opt.getID();
+ assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID.");
+ return OptionInfos[id - 1];
+ }
+
+ Option *CreateOption(unsigned id) const;
+
+ protected:
+ OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos);
+ public:
+ ~OptTable();
+
+ /// getNumOptions - Return the total number of option classes.
+ unsigned getNumOptions() const { return NumOptionInfos; }
+
+ /// getOption - Get the given \arg id's Option instance, lazily creating it
+ /// if necessary.
+ ///
+ /// \return The option, or null for the INVALID option id.
+ const Option *getOption(OptSpecifier Opt) const {
+ unsigned id = Opt.getID();
+ if (id == 0)
+ return 0;
+
+ assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
+ Option *&Entry = Options[id - 1];
+ if (!Entry)
+ Entry = CreateOption(id);
+ return Entry;
+ }
+
+ /// getOptionName - Lookup the name of the given option.
+ const char *getOptionName(OptSpecifier id) const {
+ return getInfo(id).Name;
+ }
+
+ /// getOptionKind - Get the kind of the given option.
+ unsigned getOptionKind(OptSpecifier id) const {
+ return getInfo(id).Kind;
+ }
+
+ /// getOptionGroupID - Get the group id for the given option.
+ unsigned getOptionGroupID(OptSpecifier id) const {
+ return getInfo(id).GroupID;
+ }
+
+ /// isOptionHelpHidden - Should the help for the given option be hidden by
+ /// default.
+ bool isOptionHelpHidden(OptSpecifier id) const {
+ return getInfo(id).Flags & options::HelpHidden;
+ }
+
+ /// getOptionHelpText - Get the help text to use to describe this option.
+ const char *getOptionHelpText(OptSpecifier id) const {
+ return getInfo(id).HelpText;
+ }
+
+ /// getOptionMetaVar - Get the meta-variable name to use when describing
+ /// this options values in the help text.
+ const char *getOptionMetaVar(OptSpecifier id) const {
+ return getInfo(id).MetaVar;
+ }
+
+ /// ParseOneArg - Parse a single argument; returning the new argument and
+ /// updating Index.
+ ///
+ /// \param [in] [out] Index - The current parsing position in the argument
+ /// string list; on return this will be the index of the next argument
+ /// string to parse.
+ ///
+ /// \return - The parsed argument, or 0 if the argument is missing values
+ /// (in which case Index still points at the conceptual next argument string
+ /// to parse).
+ Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const;
+
+ /// ParseArgs - Parse an list of arguments into an InputArgList.
+ ///
+ /// The resulting InputArgList will reference the strings in [ArgBegin,
+ /// ArgEnd), and their lifetime should extend past that of the returned
+ /// InputArgList.
+ ///
+ /// The only error that can occur in this routine is if an argument is
+ /// missing values; in this case \arg MissingArgCount will be non-zero.
+ ///
+ /// \param ArgBegin - The beginning of the argument vector.
+ /// \param ArgEnd - The end of the argument vector.
+ /// \param MissingArgIndex - On error, the index of the option which could
+ /// not be parsed.
+ /// \param MissingArgCount - On error, the number of missing options.
+ /// \return - An InputArgList; on error this will contain all the options
+ /// which could be parsed.
+ InputArgList *ParseArgs(const char **ArgBegin,
+ const char **ArgEnd,
+ unsigned &MissingArgIndex,
+ unsigned &MissingArgCount) const;
+
+ /// PrintHelp - Render the help text for an option table.
+ ///
+ /// \param OS - The stream to write the help text to.
+ /// \param Name - The name to use in the usage line.
+ /// \param Title - The title to use in the usage line.
+ /// \param ShowHidden - Whether help-hidden arguments should be shown.
+ void PrintHelp(llvm::raw_ostream &OS, const char *Name,
+ const char *Title, bool ShowHidden = false) const;
+ };
+}
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Option.h b/contrib/llvm/tools/clang/include/clang/Driver/Option.h
new file mode 100644
index 0000000..08b94b1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Option.h
@@ -0,0 +1,311 @@
+//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTION_H_
+#define CLANG_DRIVER_OPTION_H_
+
+#include "clang/Driver/OptSpecifier.h"
+#include "llvm/Support/Casting.h"
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+namespace clang {
+namespace driver {
+ class Arg;
+ class InputArgList;
+ class OptionGroup;
+
+ /// Option - Abstract representation for a single form of driver
+ /// argument.
+ ///
+ /// An Option class represents a form of option that the driver
+ /// takes, for example how many arguments the option has and how
+ /// they can be provided. Individual option instances store
+ /// additional information about what group the option is a member
+ /// of (if any), if the option is an alias, and a number of
+ /// flags. At runtime the driver parses the command line into
+ /// concrete Arg instances, each of which corresponds to a
+ /// particular Option instance.
+ class Option {
+ public:
+ enum OptionClass {
+ GroupClass = 0,
+ InputClass,
+ UnknownClass,
+ FlagClass,
+ JoinedClass,
+ SeparateClass,
+ CommaJoinedClass,
+ MultiArgClass,
+ JoinedOrSeparateClass,
+ JoinedAndSeparateClass
+ };
+
+ private:
+ OptionClass Kind;
+
+ /// The option ID.
+ OptSpecifier ID;
+
+ /// The option name.
+ const char *Name;
+
+ /// Group this option is a member of, if any.
+ const OptionGroup *Group;
+
+ /// Option that this is an alias for, if any.
+ const Option *Alias;
+
+ /// Unsupported options will not be rejected.
+ bool Unsupported : 1;
+
+ /// Treat this option like a linker input?
+ bool LinkerInput : 1;
+
+ /// When rendering as an input, don't render the option.
+
+ // FIXME: We should ditch the render/renderAsInput distinction.
+ bool NoOptAsInput : 1;
+
+ /// Always render this option as separate form its value.
+ bool ForceSeparateRender : 1;
+
+ /// Always render this option joined with its value.
+ bool ForceJoinedRender : 1;
+
+ /// This option is only consumed by the driver.
+ bool DriverOption : 1;
+
+ /// This option should not report argument unused errors.
+ bool NoArgumentUnused : 1;
+
+ protected:
+ Option(OptionClass Kind, OptSpecifier ID, const char *Name,
+ const OptionGroup *Group, const Option *Alias);
+ public:
+ virtual ~Option();
+
+ unsigned getID() const { return ID.getID(); }
+ OptionClass getKind() const { return Kind; }
+ const char *getName() const { return Name; }
+ const OptionGroup *getGroup() const { return Group; }
+ const Option *getAlias() const { return Alias; }
+
+ bool isUnsupported() const { return Unsupported; }
+ void setUnsupported(bool Value) { Unsupported = Value; }
+
+ bool isLinkerInput() const { return LinkerInput; }
+ void setLinkerInput(bool Value) { LinkerInput = Value; }
+
+ bool hasNoOptAsInput() const { return NoOptAsInput; }
+ void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
+
+ bool hasForceSeparateRender() const { return ForceSeparateRender; }
+ void setForceSeparateRender(bool Value) { ForceSeparateRender = Value; }
+
+ bool hasForceJoinedRender() const { return ForceJoinedRender; }
+ void setForceJoinedRender(bool Value) { ForceJoinedRender = Value; }
+
+ bool isDriverOption() const { return DriverOption; }
+ void setDriverOption(bool Value) { DriverOption = Value; }
+
+ bool hasNoArgumentUnused() const { return NoArgumentUnused; }
+ void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
+
+ bool hasForwardToGCC() const { return !DriverOption && !LinkerInput; }
+
+ /// getUnaliasedOption - Return the final option this option
+ /// aliases (itself, if the option has no alias).
+ const Option *getUnaliasedOption() const {
+ if (Alias) return Alias->getUnaliasedOption();
+ return this;
+ }
+
+ /// getRenderName - Return the name to use when rendering this
+ /// option.
+ const char *getRenderName() const {
+ return getUnaliasedOption()->getName();
+ }
+
+ /// matches - Predicate for whether this option is part of the
+ /// given option (which may be a group).
+ ///
+ /// Note that matches against options which are an alias should never be
+ /// done -- aliases do not participate in matching and so such a query will
+ /// always be false.
+ bool matches(OptSpecifier ID) const;
+
+ /// accept - Potentially accept the current argument, returning a
+ /// new Arg instance, or 0 if the option does not accept this
+ /// argument (or the argument is missing values).
+ ///
+ /// If the option accepts the current argument, accept() sets
+ /// Index to the position where argument parsing should resume
+ /// (even if the argument is missing values).
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const = 0;
+
+ void dump() const;
+
+ static bool classof(const Option *) { return true; }
+ };
+
+ /// OptionGroup - A set of options which are can be handled uniformly
+ /// by the driver.
+ class OptionGroup : public Option {
+ public:
+ OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::GroupClass;
+ }
+ static bool classof(const OptionGroup *) { return true; }
+ };
+
+ // Dummy option classes.
+
+ /// InputOption - Dummy option class for representing driver inputs.
+ class InputOption : public Option {
+ public:
+ InputOption(OptSpecifier ID);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::InputClass;
+ }
+ static bool classof(const InputOption *) { return true; }
+ };
+
+ /// UnknownOption - Dummy option class for represent unknown arguments.
+ class UnknownOption : public Option {
+ public:
+ UnknownOption(OptSpecifier ID);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::UnknownClass;
+ }
+ static bool classof(const UnknownOption *) { return true; }
+ };
+
+ // Normal options.
+
+ class FlagOption : public Option {
+ public:
+ FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
+ const Option *Alias);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::FlagClass;
+ }
+ static bool classof(const FlagOption *) { return true; }
+ };
+
+ class JoinedOption : public Option {
+ public:
+ JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
+ const Option *Alias);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::JoinedClass;
+ }
+ static bool classof(const JoinedOption *) { return true; }
+ };
+
+ class SeparateOption : public Option {
+ public:
+ SeparateOption(OptSpecifier ID, const char *Name,
+ const OptionGroup *Group, const Option *Alias);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::SeparateClass;
+ }
+ static bool classof(const SeparateOption *) { return true; }
+ };
+
+ class CommaJoinedOption : public Option {
+ public:
+ CommaJoinedOption(OptSpecifier ID, const char *Name,
+ const OptionGroup *Group, const Option *Alias);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::CommaJoinedClass;
+ }
+ static bool classof(const CommaJoinedOption *) { return true; }
+ };
+
+ // FIXME: Fold MultiArgOption into SeparateOption?
+
+ /// MultiArgOption - An option which takes multiple arguments (these
+ /// are always separate arguments).
+ class MultiArgOption : public Option {
+ unsigned NumArgs;
+
+ public:
+ MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
+ const Option *Alias, unsigned NumArgs);
+
+ unsigned getNumArgs() const { return NumArgs; }
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::MultiArgClass;
+ }
+ static bool classof(const MultiArgOption *) { return true; }
+ };
+
+ /// JoinedOrSeparateOption - An option which either literally
+ /// prefixes its (non-empty) value, or is follwed by a value.
+ class JoinedOrSeparateOption : public Option {
+ public:
+ JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
+ const OptionGroup *Group, const Option *Alias);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::JoinedOrSeparateClass;
+ }
+ static bool classof(const JoinedOrSeparateOption *) { return true; }
+ };
+
+ /// JoinedAndSeparateOption - An option which literally prefixes its
+ /// value and is followed by another value.
+ class JoinedAndSeparateOption : public Option {
+ public:
+ JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
+ const OptionGroup *Group, const Option *Alias);
+
+ virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+
+ static bool classof(const Option *O) {
+ return O->getKind() == Option::JoinedAndSeparateClass;
+ }
+ static bool classof(const JoinedAndSeparateOption *) { return true; }
+ };
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.h b/contrib/llvm/tools/clang/include/clang/Driver/Options.h
new file mode 100644
index 0000000..ac312cd
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.h
@@ -0,0 +1,32 @@
+//===--- 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 CLANG_DRIVER_OPTIONS_H
+#define CLANG_DRIVER_OPTIONS_H
+
+namespace clang {
+namespace driver {
+ class OptTable;
+
+namespace options {
+ enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR) OPT_##ID,
+#include "clang/Driver/Options.inc"
+ LastOption
+#undef OPTION
+ };
+}
+
+ OptTable *createDriverOptTable();
+}
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.td b/contrib/llvm/tools/clang/include/clang/Driver/Options.td
new file mode 100644
index 0000000..a9a52c0
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.td
@@ -0,0 +1,715 @@
+//===--- DriverOptions.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 "OptParser.td"
+
+/////////
+// Groups
+
+// Meta-group which defines
+def CompileOnly_Group : OptionGroup<"<CompileOnly 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 W_Group : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
+def X_Group : OptionGroup<"<X group>">;
+def a_Group : OptionGroup<"<a group>">;
+def d_Group : OptionGroup<"<d group>">;
+def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
+def g_Group : OptionGroup<"<g 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>;
+def m_x86_Features_Group : OptionGroup<"<m x86 features group>">, Group<m_Group>;
+def u_Group : OptionGroup<"<u group>">;
+
+def pedantic_Group : OptionGroup<"<pedantic group>">,
+ Group<CompileOnly_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>;
+
+/////////
+// 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:
+// _ => __
+// - => _
+// # => _HASH
+// , => _COMMA
+// = => _EQ
+// C++ => CXX
+// . => _
+
+// Developer Driver Options
+
+def ccc_Group : OptionGroup<"<clang internal options>">;
+def ccc_driver_Group : OptionGroup<"<clang driver internal options>">,
+ Group<ccc_Group>, HelpText<"DRIVER OPTIONS">;
+def ccc_debug_Group : OptionGroup<"<clang debug/development internal options>">,
+ Group<ccc_Group>, HelpText<"DEBUG/DEVELOPMENT OPTIONS">;
+
+class CCCDriverOpt : Group<ccc_driver_Group>, Flags<[DriverOption, HelpHidden]>;
+def ccc_cxx : Flag<"-ccc-cxx">, CCCDriverOpt,
+ HelpText<"Act as a C++ driver">;
+def ccc_echo : Flag<"-ccc-echo">, CCCDriverOpt,
+ HelpText<"Echo commands before running them">;
+def ccc_gcc_name : Separate<"-ccc-gcc-name">, CCCDriverOpt,
+ HelpText<"Name for native GCC compiler">,
+ MetaVarName<"<gcc-path>">;
+def ccc_clang_cxx : Flag<"-ccc-clang-cxx">, CCCDriverOpt,
+ HelpText<"Enable the clang compiler for C++">;
+def ccc_no_clang_cxx : Flag<"-ccc-no-clang-cxx">, CCCDriverOpt,
+ HelpText<"Disable the clang compiler for C++">;
+def ccc_no_clang : Flag<"-ccc-no-clang">, CCCDriverOpt,
+ HelpText<"Disable the clang compiler">;
+def ccc_no_clang_cpp : Flag<"-ccc-no-clang-cpp">, CCCDriverOpt,
+ HelpText<"Disable the clang preprocessor">;
+def ccc_clang_archs : Separate<"-ccc-clang-archs">, CCCDriverOpt,
+ HelpText<"Comma separate list of architectures to use the clang compiler for">,
+ MetaVarName<"<arch-list>">;
+def ccc_pch_is_pch : Flag<"-ccc-pch-is-pch">, CCCDriverOpt,
+ HelpText<"Use lazy PCH for precompiled headers">;
+def ccc_pch_is_pth : Flag<"-ccc-pch-is-pth">, CCCDriverOpt,
+ HelpText<"Use pretokenized headers for precompiled headers">;
+
+class CCCDebugOpt : Group<ccc_debug_Group>, Flags<[DriverOption, HelpHidden]>;
+def ccc_host_triple : Separate<"-ccc-host-triple">, CCCDebugOpt,
+ HelpText<"Simulate running on the given target">;
+def ccc_install_dir : Separate<"-ccc-install-dir">, CCCDebugOpt,
+ HelpText<"Simulate installation in the given directory">;
+def ccc_print_options : Flag<"-ccc-print-options">, CCCDebugOpt,
+ HelpText<"Dump parsed command line arguments">;
+def ccc_print_phases : Flag<"-ccc-print-phases">, CCCDebugOpt,
+ HelpText<"Dump list of actions to perform">;
+def ccc_print_bindings : Flag<"-ccc-print-bindings">, CCCDebugOpt,
+ HelpText<"Show bindings of tools to actions">;
+
+// Make sure all other -ccc- options are rejected.
+def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>;
+
+// Standard Options
+
+def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>,
+ HelpText<"Print the commands to run for this compilation">;
+def A : JoinedOrSeparate<"-A">;
+def B : JoinedOrSeparate<"-B">;
+def CC : Flag<"-CC">;
+def C : Flag<"-C">;
+def D : JoinedOrSeparate<"-D">, Group<CompileOnly_Group>;
+def E : Flag<"-E">, Flags<[DriverOption]>,
+ HelpText<"Only run the preprocessor">;
+def F : JoinedOrSeparate<"-F">;
+def H : Flag<"-H">;
+def I_ : Flag<"-I-">, Group<I_Group>;
+def I : JoinedOrSeparate<"-I">, Group<I_Group>;
+def L : JoinedOrSeparate<"-L">;
+def MD : Flag<"-MD">, Group<M_Group>;
+def MF : JoinedOrSeparate<"-MF">, Group<M_Group>;
+def MG : Flag<"-MG">, Group<M_Group>;
+def MMD : Flag<"-MMD">, Group<M_Group>;
+def MM : Flag<"-MM">, Group<M_Group>;
+def MP : Flag<"-MP">, Group<M_Group>;
+def MQ : JoinedOrSeparate<"-MQ">, Group<M_Group>;
+def MT : JoinedOrSeparate<"-MT">, Group<M_Group>;
+def Mach : Flag<"-Mach">;
+def M : Flag<"-M">, Group<M_Group>;
+def O0 : Joined<"-O0">, Group<O_Group>;
+def O4 : Joined<"-O4">, Group<O_Group>;
+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>;
+def P : Flag<"-P">;
+def Qn : Flag<"-Qn">;
+def Qunused_arguments : Flag<"-Qunused-arguments">, Flags<[DriverOption]>,
+ HelpText<"Don't emit warning for unused driver arguments">;
+def Q : Flag<"-Q">;
+def R : Flag<"-R">;
+def S : Flag<"-S">, Flags<[DriverOption]>,
+ 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>;
+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>;
+def Wextra : Flag<"-Wextra">, Group<W_Group>;
+def Wl_COMMA : CommaJoined<"-Wl,">, Flags<[LinkerInput, RenderAsInput]>,
+ HelpText<"Pass the comma separated arguments in <arg> to the linker">,
+ MetaVarName<"<arg>">;
+def Wno_nonportable_cfstrings : Joined<"-Wno-nonportable-cfstrings">, Group<W_Group>;
+def Wnonportable_cfstrings : Joined<"-Wnonportable-cfstrings">, Group<W_Group>;
+def Wp_COMMA : CommaJoined<"-Wp,">,
+ HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
+ MetaVarName<"<arg>">;
+def W_Joined : Joined<"-W">, Group<W_Group>;
+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>">;
+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">, Group<a_Group>;
+def arch__errors__fatal : Flag<"-arch_errors_fatal">;
+def arch : Separate<"-arch">, Flags<[DriverOption]>;
+def a : Joined<"-a">, Group<a_Group>;
+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">;
+def current__version : JoinedOrSeparate<"-current_version">;
+def c : Flag<"-c">, Flags<[DriverOption]>,
+ HelpText<"Only run preprocess, compile, and assemble steps">;
+def dA : Flag<"-dA">, Group<d_Group>;
+def dD : Flag<"-dD">, Group<d_Group>;
+def dM : Flag<"-dM">, Group<d_Group>;
+def dead__strip : Flag<"-dead_strip">;
+def dependency_file : Separate<"-dependency-file">;
+def dumpmachine : Flag<"-dumpmachine">, Flags<[Unsupported]>;
+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">,
+ 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 fPIE : Flag<"-fPIE">, Group<f_Group>;
+def faccess_control : Flag<"-faccess-control">, Group<f_Group>;
+def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
+def fasm : Flag<"-fasm">, Group<f_Group>;
+def fasm_blocks : Flag<"-fasm-blocks">, Group<clang_ignored_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 fblocks : Flag<"-fblocks">, Group<f_Group>;
+def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>;
+def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>;
+def fbuiltin_strcpy : Flag<"-fbuiltin-strcpy">, Group<f_Group>;
+def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>;
+def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
+ Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior.">;
+def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>;
+def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, Group<f_Group>;
+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 fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
+def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
+def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>;
+def fdiagnostics_binary : Flag<"-fdiagnostics-binary">, Group<f_Group>, Flags<[HelpHidden]>;
+def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>;
+def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_Group>;
+def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
+def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_Group>;
+def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>;
+def feliminate_unused_debug_symbols : Flag<"-feliminate-unused-debug-symbols">, Group<f_Group>;
+def femit_all_decls : Flag<"-femit-all-decls">, Group<f_Group>;
+def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>;
+def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
+def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
+def fhosted : Flag<"-fhosted">, Group<f_Group>;
+def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
+def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>;
+def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
+def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
+def filelist : Separate<"-filelist">, Flags<[LinkerInput]>;
+def findirect_virtual_calls : Flag<"-findirect-virtual-calls">, Group<f_Group>;
+def finline_functions : Flag<"-finline-functions">, Group<clang_ignored_f_Group>;
+def finline : Flag<"-finline">, Group<clang_ignored_f_Group>;
+def fkeep_inline_functions : Flag<"-fkeep-inline-functions">, Group<clang_ignored_f_Group>;
+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 : Flag<"-flto">, Group<f_Group>;
+def fmacro_backtrace_limit_EQ : Joined<"-fmacro-backtrace-limit=">,
+ Group<f_Group>;
+def fmath_errno : Flag<"-fmath-errno">, Group<f_Group>;
+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>;
+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>;
+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>;
+def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>;
+def fno_builtin_strcat : Flag<"-fno-builtin-strcat">, Group<f_Group>;
+def fno_builtin_strcpy : Flag<"-fno-builtin-strcpy">, Group<f_Group>;
+def fno_builtin : Flag<"-fno-builtin">, Group<f_Group>;
+def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">, Group<f_Group>;
+def fno_color_diagnostics : Flag<"-fno-color-diagnostics">, Group<f_Group>;
+def fno_common : Flag<"-fno-common">, Group<f_Group>;
+def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">, Group<f_Group>;
+def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">, Group<f_Group>;
+def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_Group>;
+def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
+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>;
+def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>;
+def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>;
+def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
+def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, Group<f_Group>;
+def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>;
+def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>;
+def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>;
+def fno_objc_legacy_dispatch : Flag<"-fno-objc-legacy-dispatch">, Group<f_Group>;
+def fno_omit_frame_pointer : Flag<"-fno-omit-frame-pointer">, Group<f_Group>;
+def fno_pascal_strings : Flag<"-fno-pascal-strings">, Group<f_Group>;
+def fno_rtti : Flag<"-fno-rtti">, Group<f_Group>;
+def fno_show_column : Flag<"-fno-show-column">, Group<f_Group>;
+def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>;
+def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
+def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<clang_ignored_f_Group>;
+def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>;
+def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, Group<f_Group>;
+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_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>;
+def fobjc_abi_version_EQ : Joined<"-fobjc-abi-version=">, 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_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>;
+def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>;
+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_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, Group<f_Group>;
+def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">, Group<f_Group>;
+def fobjc_sender_dependent_dispatch : Flag<"-fobjc-sender-dependent-dispatch">, Group<f_Group>;
+def fobjc : Flag<"-fobjc">, Group<f_Group>;
+def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>;
+def fopenmp : Flag<"-fopenmp">, Group<f_Group>;
+def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">;
+def force__flat__namespace : Flag<"-force_flat_namespace">;
+def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>;
+def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>;
+def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>;
+def fpic : Flag<"-fpic">, Group<f_Group>;
+def fpie : Flag<"-fpie">, Group<f_Group>;
+def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>;
+def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>;
+def framework : Separate<"-framework">, Flags<[LinkerInput]>;
+def frtti : Flag<"-frtti">, Group<f_Group>;
+def fsched_interblock : Flag<"-fsched-interblock">, Group<clang_ignored_f_Group>;
+def fshort_enums : Flag<"-fshort-enums">, Group<clang_ignored_f_Group>;
+def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>;
+def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
+def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
+def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;
+def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>;
+def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>;
+def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>;
+def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<clang_ignored_f_Group>;
+def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>;
+def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
+def ferror_limit_EQ : Joined<"-ferror-limit=">, 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 fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
+def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
+def ftime_report : Flag<"-ftime-report">, Group<f_Group>;
+def ftrapv : Flag<"-ftrapv">, Group<f_Group>;
+def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>;
+def funsigned_bitfields : Flag<"-funsigned-bitfields">, Group<f_Group>;
+def funsigned_char : Flag<"-funsigned-char">, Group<f_Group>;
+def funwind_tables : Flag<"-funwind-tables">, Group<f_Group>;
+def fuse_cxa_atexit : Flag<"-fuse-cxa-atexit">, Group<f_Group>;
+def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>;
+def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>;
+def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>;
+def fzero_initialized_in_bss : Flag<"-fzero-initialized-in-bss">, Group<f_Group>;
+def ffunction_sections: Flag <"-ffunction-sections">, Group<f_Group>;
+def fdata_sections : Flag <"-fdata-sections">, Group<f_Group>;
+def f : Joined<"-f">, Group<f_Group>;
+def g0 : Joined<"-g0">, Group<g_Group>;
+def g3 : Joined<"-g3">, Group<g_Group>;
+def gfull : Joined<"-gfull">, Group<g_Group>;
+def gstabs : Joined<"-gstabs">, Group<g_Group>;
+def gused : Joined<"-gused">, Group<g_Group>;
+def g_Flag : Flag<"-g">, Group<g_Group>;
+def g_Joined : Joined<"-g">, Group<g_Group>;
+def headerpad__max__install__names : Joined<"-headerpad_max_install_names">;
+def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>;
+def iframework : JoinedOrSeparate<"-iframework">, Group<clang_i_Group>;
+def imacros : JoinedOrSeparate<"-imacros">, Group<clang_i_Group>;
+def image__base : Separate<"-image_base">;
+def include_ : JoinedOrSeparate<"-include">, Group<clang_i_Group>, EnumName<"include">;
+def init : Separate<"-init">;
+def install__name : Separate<"-install_name">;
+def integrated_as : Flag<"-integrated-as">, Flags<[DriverOption]>;
+def iprefix : JoinedOrSeparate<"-iprefix">, Group<clang_i_Group>;
+def iquote : JoinedOrSeparate<"-iquote">, Group<clang_i_Group>;
+def isysroot : JoinedOrSeparate<"-isysroot">, Group<clang_i_Group>;
+def isystem : JoinedOrSeparate<"-isystem">, Group<clang_i_Group>;
+def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">, Group<clang_i_Group>;
+def iwithprefix : JoinedOrSeparate<"-iwithprefix">, Group<clang_i_Group>;
+def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">, Group<i_Group>;
+def i : Joined<"-i">, Group<i_Group>;
+def keep__private__externs : Flag<"-keep_private_externs">;
+def l : JoinedOrSeparate<"-l">, Flags<[LinkerInput, RenderJoined]>;
+def m32 : Flag<"-m32">, Group<m_Group>, Flags<[DriverOption]>;
+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]>;
+def mabi_EQ : Joined<"-mabi=">, Group<m_Group>, Flags<[DriverOption]>;
+def march_EQ : Joined<"-march=">, Group<m_Group>, Flags<[DriverOption]>;
+def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>, Flags<[DriverOption]>;
+def mconstant_cfstrings : Flag<"-mconstant-cfstrings">, Group<clang_ignored_m_Group>;
+def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>, Flags<[DriverOption]>;
+def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>, Flags<[NoArgumentUnused]>;
+def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>;
+def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>;
+def mfpu_EQ : Joined<"-mfpu=">, Group<m_Group>;
+def mhard_float : Flag<"-mhard-float">, Group<m_Group>;
+def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
+def mkernel : Flag<"-mkernel">, Group<m_Group>;
+def mllvm : Separate<"-mllvm">;
+def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
+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_mmx : Flag<"-mno-mmx">, Group<m_x86_Features_Group>;
+def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group<m_Group>;
+def mno_red_zone : Flag<"-mno-red-zone">, Group<m_Group>;
+def mno_relax_all : Flag<"-mno-relax-all">, Group<m_Group>;
+def mno_soft_float : Flag<"-mno-soft-float">, 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 : Flag<"-mno-sse4">, 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>;
+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_thumb : Flag<"-mno-thumb">, Group<m_Group>;
+def marm : Flag<"-marm">, Alias<mno_thumb>;
+
+def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>;
+def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
+def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
+def mrelax_all : Flag<"-mrelax-all">, Group<m_Group>;
+def msoft_float : Flag<"-msoft-float">, Group<m_Group>;
+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 : Flag<"-msse4">, 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 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 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 m_Separate : Separate<"-m">, Group<m_Group>;
+def m_Joined : Joined<"-m">, 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">;
+def no_integrated_as : Flag<"-no-integrated-as">, Flags<[DriverOption]>;
+def no_integrated_cpp : Flag<"-no-integrated-cpp">, Flags<[DriverOption]>;
+def no__dead__strip__inits__and__terms : Flag<"-no_dead_strip_inits_and_terms">;
+def nobuiltininc : Flag<"-nobuiltininc">;
+def nodefaultlibs : Flag<"-nodefaultlibs">;
+def nofixprebinding : Flag<"-nofixprebinding">;
+def nolibc : Flag<"-nolibc">;
+def nomultidefs : Flag<"-nomultidefs">;
+def noprebind : Flag<"-noprebind">;
+def noseglinkedit : Flag<"-noseglinkedit">;
+def nostartfiles : Flag<"-nostartfiles">;
+def nostdinc : Flag<"-nostdinc">;
+def nostdincxx : Flag<"-nostdinc++">;
+def nostdlib : Flag<"-nostdlib">;
+def object : Flag<"-object">;
+def o : JoinedOrSeparate<"-o">, Flags<[DriverOption, RenderAsInput]>,
+ HelpText<"Write output to <file>">, MetaVarName<"<file>">;
+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>;
+def pedantic : Flag<"-pedantic">, Group<pedantic_Group>;
+def pg : Flag<"-pg">;
+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">;
+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">;
+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">;
+def p : Flag<"-p">;
+def read__only__relocs : Separate<"-read_only_relocs">;
+def remap : Flag<"-remap">;
+def rewrite_objc : Flag<"-rewrite-objc">, Flags<[DriverOption]>,
+ HelpText<"Rewrite Objective-C source to C++">;
+def rpath : Separate<"-rpath">, Flags<[LinkerInput]>;
+def r : Flag<"-r">;
+def save_temps : Flag<"-save-temps">, Flags<[DriverOption]>,
+ HelpText<"Save intermediate compilation results">;
+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 : Flag<"-static">, Flags<[NoArgumentUnused]>;
+def std_default_EQ : Joined<"-std-default=">;
+def std_EQ : Joined<"-std=">;
+def sub__library : JoinedOrSeparate<"-sub_library">;
+def sub__umbrella : JoinedOrSeparate<"-sub_umbrella">;
+def s : Flag<"-s">;
+def time : Flag<"-time">,
+ HelpText<"Time individual commands">;
+def traditional_cpp : Flag<"-traditional-cpp">;
+def traditional : Flag<"-traditional">;
+def trigraphs : Flag<"-trigraphs">;
+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>;
+def unexported__symbols__list : Separate<"-unexported_symbols_list">;
+def u : JoinedOrSeparate<"-u">, Group<u_Group>;
+def v : Flag<"-v">,
+ HelpText<"Show commands to run and use verbose 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">;
+def x : JoinedOrSeparate<"-x">, Flags<[DriverOption]>,
+ HelpText<"Treat subsequent input files as having type <language>">,
+ MetaVarName<"<language>">;
+def y : Joined<"-y">;
+
+// Double dash options, which are usually an alias for one of the previous
+// options.
+
+def _CLASSPATH_EQ : Joined<"--CLASSPATH=">, Alias<fclasspath_EQ>;
+def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
+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]>,
+ HelpText<"Run the static analyzer">;
+def _ansi : Flag<"--ansi">, Alias<ansi>;
+def _assemble : Flag<"--assemble">, Alias<S>;
+def _assert_EQ : Joined<"--assert=">, Alias<A>, Flags<[RenderSeparate]>;
+def _assert : Separate<"--assert">, Alias<A>;
+def _bootclasspath_EQ : Joined<"--bootclasspath=">, Alias<fbootclasspath_EQ>;
+def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>, Flags<[RenderJoined]>;
+def _classpath_EQ : Joined<"--classpath=">, Alias<fclasspath_EQ>;
+def _classpath : Separate<"--classpath">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
+def _combine : Flag<"--combine">, Alias<combine>, Flags<[Unsupported]>;
+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 _coverage : Flag<"--coverage">, Alias<coverage>;
+def _debug_EQ : Joined<"--debug=">, Alias<g_Flag>, Flags<[Unsupported]>;
+def _debug : Flag<"--debug">, Alias<g_Flag>, Flags<[Unsupported]>;
+def _define_macro_EQ : Joined<"--define-macro=">, Alias<D>;
+def _define_macro : Separate<"--define-macro">, Alias<D>, Flags<[RenderJoined]>;
+def _dependencies : Flag<"--dependencies">, Alias<M>;
+def _encoding_EQ : Joined<"--encoding=">, Alias<fencoding_EQ>;
+def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>, Flags<[RenderJoined]>;
+def _entry : Flag<"--entry">, Alias<e>;
+def _extdirs_EQ : Joined<"--extdirs=">, Alias<fextdirs_EQ>;
+def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>, Flags<[RenderJoined]>;
+def _extra_warnings : Flag<"--extra-warnings">, Alias<W_Joined>;
+def _for_linker_EQ : Joined<"--for-linker=">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput, RenderSeparate]>;
+def _for_linker : Separate<"--for-linker">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput]>;
+def _force_link_EQ : Joined<"--force-link=">, Alias<u>, Flags<[RenderSeparate]>;
+def _force_link : Separate<"--force-link">, Alias<u>;
+def _help_hidden : Flag<"--help-hidden">;
+def _help : Flag<"--help">,
+ HelpText<"Display available options">;
+def _imacros_EQ : Joined<"--imacros=">, Alias<imacros>, Flags<[RenderSeparate]>;
+def _imacros : Separate<"--imacros">, Alias<imacros>;
+def _include_barrier : Flag<"--include-barrier">, Alias<I_>;
+def _include_directory_after_EQ : Joined<"--include-directory-after=">, Alias<idirafter>, Flags<[RenderSeparate]>;
+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>, Flags<[RenderJoined]>;
+def _include_prefix_EQ : Joined<"--include-prefix=">, Alias<iprefix>, Flags<[RenderSeparate]>;
+def _include_prefix : Separate<"--include-prefix">, Alias<iprefix>;
+def _include_with_prefix_after_EQ : Joined<"--include-with-prefix-after=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
+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>, Flags<[RenderSeparate]>;
+def _include_with_prefix_before : Separate<"--include-with-prefix-before">, Alias<iwithprefixbefore>;
+def _include_with_prefix_EQ : Joined<"--include-with-prefix=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
+def _include_with_prefix : Separate<"--include-with-prefix">, Alias<iwithprefix>;
+def _include_EQ : Joined<"--include=">, Alias<include_>, Flags<[RenderSeparate]>;
+def _include : Separate<"--include">, Alias<include_>;
+def _language_EQ : Joined<"--language=">, Alias<x>, Flags<[RenderSeparate]>;
+def _language : Separate<"--language">, Alias<x>;
+def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>, Flags<[RenderSeparate]>;
+def _library_directory : Separate<"--library-directory">, Alias<L>;
+def _machine__EQ : Joined<"--machine-=">, Alias<m_Joined>, Flags<[Unsupported]>;
+def _machine_ : Joined<"--machine-">, Alias<m_Joined>, Flags<[Unsupported]>;
+def _machine_EQ : Joined<"--machine=">, Alias<m_Joined>;
+def _machine : Separate<"--machine">, Alias<m_Joined>, Flags<[RenderJoined]>;
+def _no_integrated_cpp : Flag<"--no-integrated-cpp">, Alias<no_integrated_cpp>;
+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>, Flags<[Unsupported]>;
+def _optimize : Flag<"--optimize">, Alias<O>, Flags<[Unsupported]>;
+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>, Flags<[RenderJoined]>;
+def _output_EQ : Joined<"--output=">, Alias<o>, Flags<[RenderSeparate]>;
+def _output : Separate<"--output">, Alias<o>;
+def _param : Separate<"--param">;
+def _param_EQ : Joined<"--param=">, Alias<_param>, Flags<[RenderSeparate]>;
+def _pass_exit_codes : Flag<"--pass-exit-codes">, Alias<pass_exit_codes>;
+def _pedantic_errors : Flag<"--pedantic-errors">, Alias<pedantic_errors>;
+def _pedantic : Flag<"--pedantic">, Alias<pedantic>;
+def _pipe : Flag<"--pipe">, Alias<pipe>, Flags<[DriverOption]>;
+def _prefix_EQ : Joined<"--prefix=">, Alias<B>, Flags<[RenderSeparate]>;
+def _prefix : Separate<"--prefix">, Alias<B>;
+def _preprocess : Flag<"--preprocess">, Alias<E>;
+def _print_diagnostic_categories : Flag<"--print-diagnostic-categories">;
+def _print_file_name_EQ : Joined<"--print-file-name=">, Alias<print_file_name_EQ>;
+def _print_file_name : Separate<"--print-file-name">, Alias<print_file_name_EQ>;
+def _print_libgcc_file_name : Flag<"--print-libgcc-file-name">, Alias<print_libgcc_file_name>;
+def _print_missing_file_dependencies : Flag<"--print-missing-file-dependencies">, Alias<MG>;
+def _print_multi_directory : Flag<"--print-multi-directory">, Alias<print_multi_directory>;
+def _print_multi_lib : Flag<"--print-multi-lib">, Alias<print_multi_lib>;
+def _print_multi_os_directory : Flag<"--print-multi-os-directory">, Alias<print_multi_os_directory>;
+def _print_prog_name_EQ : Joined<"--print-prog-name=">, Alias<print_prog_name_EQ>;
+def _print_prog_name : Separate<"--print-prog-name">, Alias<print_prog_name_EQ>;
+def _print_search_dirs : Flag<"--print-search-dirs">, Alias<print_search_dirs>;
+def _profile_blocks : Flag<"--profile-blocks">, Alias<a>;
+def _profile : Flag<"--profile">, Alias<p>;
+def _relocatable_pch : Flag<"--relocatable-pch">,
+ HelpText<"Build a relocatable precompiled header">;
+def _resource_EQ : Joined<"--resource=">, Alias<fcompile_resource_EQ>;
+def _resource : Separate<"--resource">, Alias<fcompile_resource_EQ>, Flags<[RenderJoined]>;
+def _save_temps : Flag<"--save-temps">, Alias<save_temps>;
+def _shared : Flag<"--shared">, Alias<shared>;
+def _signed_char : Flag<"--signed-char">, Alias<fsigned_char>;
+def _specs_EQ : Joined<"--specs=">, Alias<specs_EQ>, Flags<[Unsupported]>;
+def _specs : Separate<"--specs">, Alias<specs_EQ>, Flags<[RenderJoined, Unsupported]>;
+def _static : Flag<"--static">, Alias<static>;
+def _std_EQ : Joined<"--std=">, Alias<std_EQ>;
+def _std : Separate<"--std">, Alias<std_EQ>, Flags<[RenderJoined]>;
+def _sysroot_EQ : Joined<"--sysroot=">;
+def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>, Flags<[RenderJoined]>;
+def _target_help : Flag<"--target-help">;
+def _trace_includes : Flag<"--trace-includes">, Alias<H>;
+def _traditional_cpp : Flag<"--traditional-cpp">, Alias<traditional_cpp>;
+def _traditional : Flag<"--traditional">, Alias<traditional>;
+def _trigraphs : Flag<"--trigraphs">, Alias<trigraphs>;
+def _undefine_macro_EQ : Joined<"--undefine-macro=">, Alias<U>;
+def _undefine_macro : Separate<"--undefine-macro">, Alias<U>, Flags<[RenderJoined]>;
+def _unsigned_char : Flag<"--unsigned-char">, Alias<funsigned_char>;
+def _user_dependencies : Flag<"--user-dependencies">, Alias<MM>;
+def _verbose : Flag<"--verbose">, Alias<v>;
+def _version : Flag<"--version">;
+def _warn__EQ : Joined<"--warn-=">, Alias<W_Joined>, Flags<[Unsupported]>;
+def _warn_ : Joined<"--warn-">, Alias<W_Joined>, Flags<[Unsupported]>;
+def _write_dependencies : Flag<"--write-dependencies">, Alias<MD>;
+def _write_user_dependencies : Flag<"--write-user-dependencies">, Alias<MMD>;
+def _ : Joined<"--">, Alias<f>, Flags<[Unsupported]>;
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Phases.h b/contrib/llvm/tools/clang/include/clang/Driver/Phases.h
new file mode 100644
index 0000000..a0c42ea
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Phases.h
@@ -0,0 +1,32 @@
+//===--- 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 CLANG_DRIVER_PHASES_H_
+#define 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,
+ Assemble,
+ Link
+ };
+
+ const char *getPhaseName(ID Id);
+
+} // end namespace phases
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Tool.h b/contrib/llvm/tools/clang/include/clang/Driver/Tool.h
new file mode 100644
index 0000000..4368a81
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Tool.h
@@ -0,0 +1,80 @@
+//===--- 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 CLANG_DRIVER_TOOL_H_
+#define CLANG_DRIVER_TOOL_H_
+
+namespace llvm {
+ template<typename T, unsigned N> class SmallVector;
+}
+
+namespace clang {
+namespace driver {
+ class ArgList;
+ class Compilation;
+ class InputInfo;
+ class Job;
+ class JobAction;
+ class ToolChain;
+
+ typedef llvm::SmallVector<InputInfo, 4> InputInfoList;
+
+/// Tool - Information on a specific compilation tool.
+class Tool {
+ /// 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;
+
+public:
+ Tool(const char *Name, const char *ShortName,
+ const ToolChain &TC);
+
+public:
+ virtual ~Tool();
+
+ const char *getName() const { return Name; }
+
+ const char *getShortName() const { return ShortName; }
+
+ const ToolChain &getToolChain() const { return TheToolChain; }
+
+ virtual bool acceptsPipedInput() const = 0;
+ virtual bool canPipeOutput() const = 0;
+ virtual bool hasIntegratedAssembler() const { return false; }
+ virtual bool hasIntegratedCPP() const = 0;
+
+ /// \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 \arg JA,
+ /// writing to \arg Output and with \arg Inputs.
+ ///
+ /// \param Dest - Where to put the resulting commands.
+ /// \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,
+ Job &Dest,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const = 0;
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h
new file mode 100644
index 0000000..1a8ae77
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h
@@ -0,0 +1,141 @@
+//===--- 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 CLANG_DRIVER_TOOLCHAIN_H_
+#define CLANG_DRIVER_TOOLCHAIN_H_
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/System/Path.h"
+#include <string>
+
+namespace clang {
+namespace driver {
+ class Compilation;
+ class DerivedArgList;
+ class Driver;
+ class HostInfo;
+ class InputArgList;
+ class JobAction;
+ class Tool;
+
+/// ToolChain - Access to tools for a single platform.
+class ToolChain {
+public:
+ typedef llvm::SmallVector<std::string, 4> path_list;
+
+private:
+ const HostInfo &Host;
+ const llvm::Triple Triple;
+
+ /// 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;
+
+protected:
+ ToolChain(const HostInfo &Host, const llvm::Triple &_Triple);
+
+public:
+ virtual ~ToolChain();
+
+ // Accessors
+
+ const Driver &getDriver() const;
+ const llvm::Triple &getTriple() const { return Triple; }
+
+ llvm::StringRef getArchName() const { return Triple.getArchName(); }
+ llvm::StringRef getPlatform() const { return Triple.getVendorName(); }
+ llvm::StringRef getOS() const { return Triple.getOSName(); }
+
+ 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; }
+
+ // Tool access.
+
+ /// TranslateArgs - Create a new derived argument list for any argument
+ /// translations this ToolChain may wish to perform.
+ ///
+ /// \param BoundArch - The bound architecture name, or 0.
+ virtual DerivedArgList *TranslateArgs(InputArgList &Args,
+ const char *BoundArch) const = 0;
+
+ /// SelectTool - Choose a tool to use to handle the action \arg JA.
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const = 0;
+
+ // Helper methods
+
+ std::string GetFilePath(const Compilation &C, const char *Name) const;
+ std::string GetProgramPath(const Compilation &C, const char *Name,
+ bool WantFile = false) const;
+
+ // Platform defaults information
+
+ /// 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; }
+
+ /// IsObjCNonFragileABIDefault - Does this tool chain set
+ /// -fobjc-nonfragile-abi by default.
+ virtual bool IsObjCNonFragileABIDefault() const { return false; }
+
+ /// IsObjCLegacyDispatchDefault - Does this tool chain set
+ /// -fobjc-legacy-dispatch by default (this is only used with the non-fragile
+ /// ABI).
+ virtual bool IsObjCLegacyDispatchDefault() 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=all).
+ virtual unsigned GetDefaultStackProtectorLevel() const { return 0; }
+
+ /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
+ /// by default.
+ virtual bool IsUnwindTablesDefault() const = 0;
+
+ /// GetDefaultRelocationModel - Return the LLVM name of the default
+ /// relocation model for this tool chain.
+ virtual const char *GetDefaultRelocationModel() const = 0;
+
+ /// GetForcedPicModel - Return the LLVM name of the forced PIC model
+ /// for this tool chain, or 0 if this tool chain does not force a
+ /// particular PIC mode.
+ virtual const char *GetForcedPicModel() const = 0;
+
+ /// Does this tool chain support Objective-C garbage collection.
+ virtual bool SupportsObjCGC() const { return false; }
+
+ /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
+ /// compile unit information.
+ virtual bool UseDwarfDebugFlags() const { return false; }
+
+ /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
+ virtual bool UseSjLjExceptions() const { return false; }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Types.def b/contrib/llvm/tools/clang/include/clang/Driver/Types.def
new file mode 100644
index 0000000..61a5043
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Types.def
@@ -0,0 +1,81 @@
+//===--- 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 containt 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, 0, "u")
+TYPE("cl", CL, PP_C, 0, "u")
+TYPE("objective-c-cpp-output", PP_ObjC, INVALID, "mi", "u")
+TYPE("objective-c", ObjC, PP_ObjC, 0, "u")
+TYPE("c++-cpp-output", PP_CXX, INVALID, "ii", "u")
+TYPE("c++", CXX, PP_CXX, 0, "u")
+TYPE("objective-c++-cpp-output", PP_ObjCXX, INVALID, "mii", "u")
+TYPE("objective-c++", ObjCXX, PP_ObjCXX, 0, "u")
+
+// C family input files to precompile.
+TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", "p")
+TYPE("c-header", CHeader, PP_CHeader, 0, "pu")
+TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID, "mi", "p")
+TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, 0, "pu")
+TYPE("c++-header-cpp-output", PP_CXXHeader, INVALID, "ii", "p")
+TYPE("c++-header", CXXHeader, PP_CXXHeader, 0, "pu")
+TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
+TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, 0, "pu")
+
+// Other languages.
+TYPE("ada", Ada, INVALID, 0, "u")
+TYPE("assembler", PP_Asm, INVALID, "s", "au")
+TYPE("assembler-with-cpp", Asm, PP_Asm, 0, "au")
+TYPE("f95", PP_Fortran, INVALID, 0, "u")
+TYPE("f95-cpp-input", Fortran, PP_Fortran, 0, "u")
+TYPE("java", Java, INVALID, 0, "u")
+
+// Misc.
+TYPE("ast", AST, INVALID, "ast", "u")
+TYPE("llvm-asm", LLVMAsm, INVALID, "s", "")
+TYPE("llvm-bc", LLVMBC, INVALID, "o", "")
+TYPE("plist", Plist, INVALID, "plist", "")
+TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", "")
+TYPE("precompiled-header", PCH, INVALID, "gch", "A")
+TYPE("object", Object, INVALID, "o", "")
+TYPE("treelang", Treelang, INVALID, 0, "u")
+TYPE("image", Image, INVALID, "out", "")
+TYPE("dependencies", Dependencies, INVALID, "d", "")
+TYPE("none", Nothing, INVALID, 0, "u")
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Types.h b/contrib/llvm/tools/clang/include/clang/Driver/Types.h
new file mode 100644
index 0000000..d933230
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Types.h
@@ -0,0 +1,92 @@
+//===--- 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 CLANG_DRIVER_TYPES_H_
+#define CLANG_DRIVER_TYPES_H_
+
+#include "clang/Driver/Phases.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 \arg 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);
+
+ /// 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);
+
+ /// 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 \arg Ext.
+ ID lookupTypeForExtension(const char *Ext);
+
+ /// lookupTypeForTypSpecifier - Lookup the type to use for a user
+ /// specified type name.
+ ID lookupTypeForTypeSpecifier(const char *Name);
+
+ /// getNumCompilationPhases - Return the complete number of phases
+ /// to be done for this type.
+ unsigned getNumCompilationPhases(ID Id);
+
+ /// getCompilationPhase - Return the \args N th compilation phase to
+ /// be done for this type.
+ phases::ID getCompilationPhase(ID Id, unsigned N);
+
+ /// 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/contrib/llvm/tools/clang/include/clang/Driver/Util.h b/contrib/llvm/tools/clang/include/clang/Driver/Util.h
new file mode 100644
index 0000000..52f268d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Util.h
@@ -0,0 +1,30 @@
+//===--- 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 CLANG_DRIVER_UTIL_H_
+#define CLANG_DRIVER_UTIL_H_
+
+namespace llvm {
+ template<typename T, unsigned N> class SmallVector;
+}
+
+namespace clang {
+namespace driver {
+ class Action;
+
+ /// ArgStringList - Type used for constructing argv lists for subprocesses.
+ typedef llvm::SmallVector<const char*, 16> ArgStringList;
+
+ /// ActionList - Type used for lists of actions.
+ typedef llvm::SmallVector<Action*, 3> ActionList;
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h
new file mode 100644
index 0000000..9163a20
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h
@@ -0,0 +1,87 @@
+//===--- 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 DRIVER_ASTCONSUMERS_H
+#define DRIVER_ASTCONSUMERS_H
+
+#include <string>
+
+namespace llvm {
+ class raw_ostream;
+ class Module;
+ class LLVMContext;
+ namespace sys { class Path; }
+}
+namespace clang {
+
+class ASTConsumer;
+class CodeGenOptions;
+class Diagnostic;
+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.
+ASTConsumer *CreateASTPrinter(llvm::raw_ostream *OS);
+
+// AST XML-printer: prints out the AST in a XML format
+// The output is intended to be in a format such that
+// clang or any other tool could re-parse the output back into the same AST,
+// but the implementation is still incomplete.
+ASTConsumer *CreateASTPrinterXML(llvm::raw_ostream *OS);
+
+// AST dumper: dumps the raw AST in human-readable form to stderr; this is
+// intended for debugging.
+ASTConsumer *CreateASTDumper();
+
+// 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.
+ASTConsumer *CreateASTViewer();
+
+// DeclContext printer: prints out the DeclContext tree in human-readable form
+// to stderr; this is intended for debugging.
+ASTConsumer *CreateDeclContextPrinter();
+
+// ObjC rewriter: attempts tp rewrite ObjC constructs into pure C code.
+// This is considered experimental, and only works with Apple's ObjC runtime.
+ASTConsumer *CreateObjCRewriter(const std::string &InFile,
+ llvm::raw_ostream *OS,
+ Diagnostic &Diags,
+ const LangOptions &LOpts,
+ bool SilenceRewriteMacroWarning);
+
+/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
+/// HTML with syntax highlighting suitable for viewing in a web-browser.
+ASTConsumer *CreateHTMLPrinter(llvm::raw_ostream *OS, Preprocessor &PP,
+ bool SyntaxHighlight = true,
+ bool HighlightMacros = true);
+
+// PCH generator: generates a precompiled header file; this file can be used
+// later with the PCHReader (clang -cc1 option -include-pch) to speed up compile
+// times.
+ASTConsumer *CreatePCHGenerator(const Preprocessor &PP,
+ llvm::raw_ostream *OS,
+ const char *isysroot = 0);
+
+// Inheritance viewer: for C++ code, creates a graph of the inheritance
+// tree for the given class and displays it with "dotty".
+ASTConsumer *CreateInheritanceViewer(const std::string& clsname);
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h
new file mode 100644
index 0000000..9252358
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h
@@ -0,0 +1,266 @@
+//===--- 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/Lex/PreprocessingRecord.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Index/ASTLocation.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/System/Path.h"
+#include <map>
+#include <string>
+#include <vector>
+#include <cassert>
+#include <utility>
+
+namespace llvm {
+ class MemoryBuffer;
+}
+
+namespace clang {
+class ASTContext;
+class CompilerInvocation;
+class Decl;
+class Diagnostic;
+class FileEntry;
+class FileManager;
+class HeaderSearch;
+class Preprocessor;
+class SourceManager;
+class TargetInfo;
+
+using namespace idx;
+
+/// \brief Utility class for loading a ASTContext from a PCH file.
+///
+class ASTUnit {
+public:
+ typedef std::map<FileID, std::vector<PreprocessedEntity *> >
+ PreprocessedEntitiesByFileMap;
+private:
+ llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
+ llvm::OwningPtr<FileManager> FileMgr;
+ llvm::OwningPtr<SourceManager> SourceMgr;
+ llvm::OwningPtr<HeaderSearch> HeaderInfo;
+ llvm::OwningPtr<TargetInfo> Target;
+ llvm::OwningPtr<Preprocessor> PP;
+ llvm::OwningPtr<ASTContext> Ctx;
+
+ /// Optional owned invocation, just used to make the invocation used in
+ /// LoadFromCommandLine available.
+ llvm::OwningPtr<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;
+
+ /// Track whether the main file was loaded from an AST or not.
+ bool MainFileIsAST;
+
+ /// 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;
+
+ /// The name of the original source file used to generate this ASTUnit.
+ std::string OriginalSourceFile;
+
+ // Critical optimization when using clang_getCursor().
+ ASTLocation LastLoc;
+
+ /// \brief The set of diagnostics produced when creating this
+ /// translation unit.
+ llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
+
+ /// \brief Temporary files that should be removed when the ASTUnit is
+ /// destroyed.
+ llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles;
+
+ /// \brief A mapping from file IDs to the set of preprocessed entities
+ /// stored in that file.
+ ///
+ /// FIXME: This is just an optimization hack to avoid searching through
+ /// many preprocessed entities during cursor traversal in the CIndex library.
+ /// Ideally, we would just be able to perform a binary search within the
+ /// list of preprocessed entities.
+ PreprocessedEntitiesByFileMap PreprocessedEntitiesByFile;
+
+ /// \brief Simple hack to allow 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.
+ unsigned int ConcurrencyCheckValue;
+ static const unsigned int CheckLocked = 28573289;
+ static const unsigned int CheckUnlocked = 9803453;
+
+ ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
+ ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
+
+ explicit ASTUnit(bool MainFileIsAST);
+
+public:
+ class ConcurrencyCheck {
+ volatile ASTUnit &Self;
+
+ public:
+ explicit ConcurrencyCheck(ASTUnit &Self)
+ : Self(Self)
+ {
+ assert(Self.ConcurrencyCheckValue == CheckUnlocked &&
+ "Concurrent access to ASTUnit!");
+ Self.ConcurrencyCheckValue = CheckLocked;
+ }
+
+ ~ConcurrencyCheck() {
+ Self.ConcurrencyCheckValue = CheckUnlocked;
+ }
+ };
+ friend class ConcurrencyCheck;
+
+ ~ASTUnit();
+
+ bool isMainFileAST() const { return MainFileIsAST; }
+
+ const Diagnostic &getDiagnostics() const { return *Diagnostics; }
+ Diagnostic &getDiagnostics() { return *Diagnostics; }
+
+ const SourceManager &getSourceManager() const { return *SourceMgr; }
+ SourceManager &getSourceManager() { return *SourceMgr; }
+
+ const Preprocessor &getPreprocessor() const { return *PP.get(); }
+ Preprocessor &getPreprocessor() { return *PP.get(); }
+
+ const ASTContext &getASTContext() const { return *Ctx.get(); }
+ ASTContext &getASTContext() { return *Ctx.get(); }
+
+ const FileManager &getFileManager() const { return *FileMgr; }
+ FileManager &getFileManager() { return *FileMgr; }
+
+ const std::string &getOriginalSourceFileName();
+ const std::string &getPCHFileName();
+
+ /// \brief Add a temporary file that the ASTUnit depends on.
+ ///
+ /// This file will be erased when the ASTUnit is destroyed.
+ void addTemporaryFile(const llvm::sys::Path &TempFile) {
+ TemporaryFiles.push_back(TempFile);
+ }
+
+ bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
+
+ void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; }
+ ASTLocation getLastASTLocation() const { return LastLoc; }
+
+ std::vector<Decl*> &getTopLevelDecls() {
+ assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+ return TopLevelDecls;
+ }
+ const std::vector<Decl*> &getTopLevelDecls() const {
+ assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+ return TopLevelDecls;
+ }
+
+ /// \brief Retrieve the mapping from File IDs to the preprocessed entities
+ /// within that file.
+ PreprocessedEntitiesByFileMap &getPreprocessedEntitiesByFile() {
+ return PreprocessedEntitiesByFile;
+ }
+
+ // Retrieve the diagnostics associated with this AST
+ typedef const StoredDiagnostic *stored_diag_iterator;
+ stored_diag_iterator stored_diag_begin() const {
+ return StoredDiagnostics.begin();
+ }
+ stored_diag_iterator stored_diag_end() const {
+ return StoredDiagnostics.end();
+ }
+ unsigned stored_diag_size() const { return StoredDiagnostics.size(); }
+
+ llvm::SmallVector<StoredDiagnostic, 4> &getStoredDiagnostics() {
+ return StoredDiagnostics;
+ }
+
+ /// \brief A mapping from a file name to the memory buffer that stores the
+ /// remapped contents of that file.
+ typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile;
+
+ /// \brief Create a ASTUnit from a PCH file.
+ ///
+ /// \param Filename - The PCH file to load.
+ ///
+ /// \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 PCH failed to load.
+ static ASTUnit *LoadFromPCHFile(const std::string &Filename,
+ llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+ bool OnlyLocalDecls = false,
+ RemappedFile *RemappedFiles = 0,
+ unsigned NumRemappedFiles = 0,
+ bool CaptureDiagnostics = false);
+
+ /// 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 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 ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
+ llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+ bool OnlyLocalDecls = false,
+ bool CaptureDiagnostics = 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 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.
+ //
+ // 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,
+ llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+ llvm::StringRef ResourceFilesPath,
+ bool OnlyLocalDecls = false,
+ RemappedFile *RemappedFiles = 0,
+ unsigned NumRemappedFiles = 0,
+ bool CaptureDiagnostics = false);
+};
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def b/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def
new file mode 100644
index 0000000..aaa3920
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def
@@ -0,0 +1,85 @@
+//===-- 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
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)
+#endif
+
+ANALYSIS(CFGDump, "cfg-dump",
+ "Display Control-Flow Graphs", Code)
+
+ANALYSIS(CFGView, "cfg-view",
+ "View Control-Flow Graphs using GraphViz", Code)
+
+ANALYSIS(DisplayLiveVariables, "dump-live-variables",
+ "Print results of live variable analysis", Code)
+
+ANALYSIS(SecuritySyntacticChecks, "analyzer-check-security-syntactic",
+ "Perform quick security checks that require no data flow", Code)
+
+ANALYSIS(LLVMConventionChecker, "analyzer-check-llvm-conventions",
+ "Check code for LLVM codebase conventions (domain-specific)",
+ TranslationUnit)
+
+ANALYSIS(WarnDeadStores, "analyzer-check-dead-stores",
+ "Warn about stores to dead variables", Code)
+
+ANALYSIS(WarnUninitVals, "warn-uninit-values",
+ "Warn about uses of uninitialized variables", Code)
+
+ANALYSIS(WarnObjCMethSigs, "analyzer-check-objc-methodsigs",
+ "Warn about Objective-C method signatures with type incompatibilities",
+ ObjCImplementation)
+
+ANALYSIS(WarnObjCDealloc, "analyzer-check-objc-missing-dealloc",
+"Warn about Objective-C classes that lack a correct implementation of -dealloc",
+ ObjCImplementation)
+
+ANALYSIS(WarnObjCUnusedIvars, "analyzer-check-objc-unused-ivars",
+ "Warn about private ivars that are never used", ObjCImplementation)
+
+ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
+ "Run the [Core] Foundation reference count checker", Code)
+
+ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer",
+ "Warn about unintended use of sizeof() on pointer expressions", Code)
+
+#ifndef ANALYSIS_STORE
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
+#endif
+
+ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store", CreateBasicStoreManager)
+ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateRegionStoreManager)
+ANALYSIS_STORE(FlatStore, "flat", "Use flat analyzer store", CreateFlatStoreManager)
+
+#ifndef ANALYSIS_CONSTRAINTS
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)
+#endif
+
+ANALYSIS_CONSTRAINTS(BasicConstraints, "basic", "Use basic constraint tracking", CreateBasicConstraintManager)
+ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager)
+
+#ifndef ANALYSIS_DIAGNOSTICS
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)
+#endif
+
+ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", CreateHTMLDiagnosticClient, false)
+ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", CreatePlistDiagnosticClient, true)
+ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", CreatePlistHTMLDiagnosticClient, true)
+
+#undef ANALYSIS
+#undef ANALYSIS_STORE
+#undef ANALYSIS_CONSTRAINTS
+#undef ANALYSIS_DIAGNOSTICS
+#undef ANALYSIS_STORE
+
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/AnalysisConsumer.h b/contrib/llvm/tools/clang/include/clang/Frontend/AnalysisConsumer.h
new file mode 100644
index 0000000..2cbdf36
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/AnalysisConsumer.h
@@ -0,0 +1,104 @@
+//===--- 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_FRONTEND_ANALYSISCONSUMER_H
+#define LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+class ASTConsumer;
+class Diagnostic;
+class Preprocessor;
+class LangOptions;
+
+/// Analysis - Set of available source code analyses.
+enum Analyses {
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
+#include "clang/Frontend/Analyses.def"
+NumAnalyses
+};
+
+/// AnalysisStores - Set of available analysis store models.
+enum AnalysisStores {
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
+#include "clang/Frontend/Analyses.def"
+NumStores
+};
+
+/// AnalysisConstraints - Set of available constraint models.
+enum AnalysisConstraints {
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
+#include "clang/Frontend/Analyses.def"
+NumConstraints
+};
+
+/// AnalysisDiagClients - Set of available diagnostic clients for rendering
+/// analysis results.
+enum AnalysisDiagClients {
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME,
+#include "clang/Frontend/Analyses.def"
+NUM_ANALYSIS_DIAG_CLIENTS
+};
+
+class AnalyzerOptions {
+public:
+ std::vector<Analyses> AnalysisList;
+ AnalysisStores AnalysisStoreOpt;
+ AnalysisConstraints AnalysisConstraintsOpt;
+ AnalysisDiagClients AnalysisDiagOpt;
+ std::string AnalyzeSpecificFunction;
+ unsigned MaxNodes;
+ unsigned MaxLoop;
+ unsigned AnalyzeAll : 1;
+ unsigned AnalyzerDisplayProgress : 1;
+ unsigned AnalyzeNestedBlocks : 1;
+ unsigned EagerlyAssume : 1;
+ unsigned PurgeDead : 1;
+ unsigned TrimGraph : 1;
+ unsigned VisualizeEGDot : 1;
+ unsigned VisualizeEGUbi : 1;
+ unsigned EnableExperimentalChecks : 1;
+ unsigned EnableExperimentalInternalChecks : 1;
+ unsigned InlineCall : 1;
+
+public:
+ AnalyzerOptions() {
+ AnalysisStoreOpt = BasicStoreModel;
+ AnalysisConstraintsOpt = RangeConstraintsModel;
+ AnalysisDiagOpt = PD_HTML;
+ AnalyzeAll = 0;
+ AnalyzerDisplayProgress = 0;
+ AnalyzeNestedBlocks = 0;
+ EagerlyAssume = 0;
+ PurgeDead = 1;
+ TrimGraph = 0;
+ VisualizeEGDot = 0;
+ VisualizeEGUbi = 0;
+ EnableExperimentalChecks = 0;
+ EnableExperimentalInternalChecks = 0;
+ }
+};
+
+/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
+/// analysis passes. (The set of analyses run is controlled by command-line
+/// options.)
+ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp,
+ const std::string &output,
+ const AnalyzerOptions& Opts);
+
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticClient.h b/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticClient.h
new file mode 100644
index 0000000..2d5e128
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticClient.h
@@ -0,0 +1,58 @@
+//===--- ChainedDiagnosticClient.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_CHAINEDDIAGNOSTICCLIENT_H
+#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+class LangOptions;
+
+/// ChainedDiagnosticClient - 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 ChainedDiagnosticClient : public DiagnosticClient {
+ llvm::OwningPtr<DiagnosticClient> Primary;
+ llvm::OwningPtr<DiagnosticClient> Secondary;
+
+public:
+ ChainedDiagnosticClient(DiagnosticClient *_Primary,
+ DiagnosticClient *_Secondary) {
+ Primary.reset(_Primary);
+ Secondary.reset(_Secondary);
+ }
+
+ virtual void BeginSourceFile(const LangOptions &LO,
+ const Preprocessor *PP) {
+ Primary->BeginSourceFile(LO, PP);
+ Secondary->BeginSourceFile(LO, PP);
+ }
+
+ virtual void EndSourceFile() {
+ Secondary->EndSourceFile();
+ Primary->EndSourceFile();
+ }
+
+ virtual bool IncludeInDiagnosticCounts() const {
+ return Primary->IncludeInDiagnosticCounts();
+ }
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info) {
+ Primary->HandleDiagnostic(DiagLevel, Info);
+ Secondary->HandleDiagnostic(DiagLevel, Info);
+ }
+};
+
+} // end namspace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenAction.h b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenAction.h
new file mode 100644
index 0000000..dfc117a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenAction.h
@@ -0,0 +1,70 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace llvm {
+ class Module;
+}
+
+namespace clang {
+
+class CodeGenAction : public ASTFrontendAction {
+private:
+ unsigned Act;
+ llvm::OwningPtr<llvm::Module> TheModule;
+
+protected:
+ CodeGenAction(unsigned _Act);
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual void EndSourceFileAction();
+
+public:
+ ~CodeGenAction();
+
+ /// takeModule - Take the generated LLVM module, for use after the action has
+ /// been run. The result may be null on failure.
+ llvm::Module *takeModule();
+};
+
+class EmitAssemblyAction : public CodeGenAction {
+public:
+ EmitAssemblyAction();
+};
+
+class EmitBCAction : public CodeGenAction {
+public:
+ EmitBCAction();
+};
+
+class EmitLLVMAction : public CodeGenAction {
+public:
+ EmitLLVMAction();
+};
+
+class EmitLLVMOnlyAction : public CodeGenAction {
+public:
+ EmitLLVMOnlyAction();
+};
+
+class EmitCodeGenOnlyAction : public CodeGenAction {
+public:
+ EmitCodeGenOnlyAction();
+};
+
+class EmitObjAction : public CodeGenAction {
+public:
+ EmitObjAction();
+};
+
+}
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h b/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h
new file mode 100644
index 0000000..bea468b
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h
@@ -0,0 +1,80 @@
+
+//===--- 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 "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(llvm::StringRef Str) {
+ ParsedSourceLocation PSL;
+ std::pair<llvm::StringRef, llvm::StringRef> ColSplit = Str.rsplit(':');
+ std::pair<llvm::StringRef, llvm::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;
+
+ 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>
+ : 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/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h
new file mode 100644
index 0000000..06dc800
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h
@@ -0,0 +1,589 @@
+//===-- 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/Frontend/CompilerInvocation.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <cassert>
+#include <list>
+#include <string>
+
+namespace llvm {
+class LLVMContext;
+class raw_ostream;
+class raw_fd_ostream;
+class Timer;
+}
+
+namespace clang {
+class ASTContext;
+class ASTConsumer;
+class CodeCompleteConsumer;
+class Diagnostic;
+class DiagnosticClient;
+class ExternalASTSource;
+class FileManager;
+class FrontendAction;
+class Preprocessor;
+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 {
+ /// The LLVM context used for this instance.
+ llvm::OwningPtr<llvm::LLVMContext> LLVMContext;
+
+ /// The options used in this compiler instance.
+ llvm::OwningPtr<CompilerInvocation> Invocation;
+
+ /// The diagnostics engine instance.
+ llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
+
+ /// The diagnostics client instance.
+ llvm::OwningPtr<DiagnosticClient> DiagClient;
+
+ /// The target being compiled for.
+ llvm::OwningPtr<TargetInfo> Target;
+
+ /// The file manager.
+ llvm::OwningPtr<FileManager> FileMgr;
+
+ /// The source manager.
+ llvm::OwningPtr<SourceManager> SourceMgr;
+
+ /// The preprocessor.
+ llvm::OwningPtr<Preprocessor> PP;
+
+ /// The AST context.
+ llvm::OwningPtr<ASTContext> Context;
+
+ /// The AST consumer.
+ llvm::OwningPtr<ASTConsumer> Consumer;
+
+ /// The code completion consumer.
+ llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
+
+ /// The frontend timer
+ llvm::OwningPtr<llvm::Timer> FrontendTimer;
+
+ /// The list of active output files.
+ std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
+
+ void operator=(const CompilerInstance &); // DO NOT IMPLEMENT
+ CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT
+public:
+ CompilerInstance();
+ ~CompilerInstance();
+
+ /// @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 LLVM Context
+ /// {
+
+ bool hasLLVMContext() const { return LLVMContext != 0; }
+
+ llvm::LLVMContext &getLLVMContext() const {
+ assert(LLVMContext && "Compiler instance has no LLVM context!");
+ return *LLVMContext;
+ }
+
+ llvm::LLVMContext *takeLLVMContext() { return LLVMContext.take(); }
+
+ /// setLLVMContext - Replace the current LLVM context and take ownership of
+ /// \arg Value.
+ void setLLVMContext(llvm::LLVMContext *Value);
+
+ /// }
+ /// @name Compiler Invocation and Options
+ /// {
+
+ bool hasInvocation() const { return Invocation != 0; }
+
+ CompilerInvocation &getInvocation() {
+ assert(Invocation && "Compiler instance has no invocation!");
+ return *Invocation;
+ }
+
+ CompilerInvocation *takeInvocation() { return Invocation.take(); }
+
+ /// setInvocation - Replace the current invocation; the compiler instance
+ /// takes ownership of \arg Value.
+ void setInvocation(CompilerInvocation *Value);
+
+ /// }
+ /// @name Forwarding Methods
+ /// {
+
+ AnalyzerOptions &getAnalyzerOpts() {
+ return Invocation->getAnalyzerOpts();
+ }
+ const AnalyzerOptions &getAnalyzerOpts() const {
+ 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();
+ }
+
+ 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 != 0; }
+
+ Diagnostic &getDiagnostics() const {
+ assert(Diagnostics && "Compiler instance has no diagnostics!");
+ return *Diagnostics;
+ }
+
+ /// setDiagnostics - Replace the current diagnostics engine; the compiler
+ /// instance takes ownership of \arg Value.
+ void setDiagnostics(Diagnostic *Value);
+
+ DiagnosticClient &getDiagnosticClient() const {
+ assert(DiagClient && "Compiler instance has no diagnostic client!");
+ return *DiagClient;
+ }
+
+ /// takeDiagnosticClient - Remove the current diagnostics client and give
+ /// ownership to the caller.
+ DiagnosticClient *takeDiagnosticClient() { return DiagClient.take(); }
+
+ /// setDiagnosticClient - Replace the current diagnostics client; the compiler
+ /// instance takes ownership of \arg Value.
+ void setDiagnosticClient(DiagnosticClient *Value);
+
+ /// }
+ /// @name Target Info
+ /// {
+
+ bool hasTarget() const { return Target != 0; }
+
+ TargetInfo &getTarget() const {
+ assert(Target && "Compiler instance has no target!");
+ return *Target;
+ }
+
+ /// takeTarget - Remove the current diagnostics engine and give ownership
+ /// to the caller.
+ TargetInfo *takeTarget() { return Target.take(); }
+
+ /// setTarget - Replace the current diagnostics engine; the compiler
+ /// instance takes ownership of \arg Value.
+ void setTarget(TargetInfo *Value);
+
+ /// }
+ /// @name File Manager
+ /// {
+
+ bool hasFileManager() const { return FileMgr != 0; }
+
+ FileManager &getFileManager() const {
+ assert(FileMgr && "Compiler instance has no file manager!");
+ return *FileMgr;
+ }
+
+ /// takeFileManager - Remove the current file manager and give ownership to
+ /// the caller.
+ FileManager *takeFileManager() { return FileMgr.take(); }
+
+ /// setFileManager - Replace the current file manager; the compiler instance
+ /// takes ownership of \arg Value.
+ void setFileManager(FileManager *Value);
+
+ /// }
+ /// @name Source Manager
+ /// {
+
+ bool hasSourceManager() const { return SourceMgr != 0; }
+
+ SourceManager &getSourceManager() const {
+ assert(SourceMgr && "Compiler instance has no source manager!");
+ return *SourceMgr;
+ }
+
+ /// takeSourceManager - Remove the current source manager and give ownership
+ /// to the caller.
+ SourceManager *takeSourceManager() { return SourceMgr.take(); }
+
+ /// setSourceManager - Replace the current source manager; the compiler
+ /// instance takes ownership of \arg Value.
+ void setSourceManager(SourceManager *Value);
+
+ /// }
+ /// @name Preprocessor
+ /// {
+
+ bool hasPreprocessor() const { return PP != 0; }
+
+ Preprocessor &getPreprocessor() const {
+ assert(PP && "Compiler instance has no preprocessor!");
+ return *PP;
+ }
+
+ /// takePreprocessor - Remove the current preprocessor and give ownership to
+ /// the caller.
+ Preprocessor *takePreprocessor() { return PP.take(); }
+
+ /// setPreprocessor - Replace the current preprocessor; the compiler instance
+ /// takes ownership of \arg Value.
+ void setPreprocessor(Preprocessor *Value);
+
+ /// }
+ /// @name ASTContext
+ /// {
+
+ bool hasASTContext() const { return Context != 0; }
+
+ ASTContext &getASTContext() const {
+ assert(Context && "Compiler instance has no AST context!");
+ return *Context;
+ }
+
+ /// takeASTContext - Remove the current AST context and give ownership to the
+ /// caller.
+ ASTContext *takeASTContext() { return Context.take(); }
+
+ /// setASTContext - Replace the current AST context; the compiler instance
+ /// takes ownership of \arg Value.
+ void setASTContext(ASTContext *Value);
+
+ /// }
+ /// @name ASTConsumer
+ /// {
+
+ bool hasASTConsumer() const { return Consumer != 0; }
+
+ 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.
+ ASTConsumer *takeASTConsumer() { return Consumer.take(); }
+
+ /// setASTConsumer - Replace the current AST consumer; the compiler instance
+ /// takes ownership of \arg Value.
+ void setASTConsumer(ASTConsumer *Value);
+
+ /// }
+ /// @name Code Completion
+ /// {
+
+ bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
+
+ CodeCompleteConsumer &getCodeCompletionConsumer() const {
+ assert(CompletionConsumer &&
+ "Compiler instance has no code completion consumer!");
+ return *CompletionConsumer;
+ }
+
+ /// takeCodeCompletionConsumer - Remove the current code completion consumer
+ /// and give ownership to the caller.
+ CodeCompleteConsumer *takeCodeCompletionConsumer() {
+ return CompletionConsumer.take();
+ }
+
+ /// setCodeCompletionConsumer - Replace the current code completion consumer;
+ /// the compiler instance takes ownership of \arg Value.
+ void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
+
+ /// }
+ /// @name Frontend timer
+ /// {
+
+ bool hasFrontendTimer() const { return FrontendTimer != 0; }
+
+ llvm::Timer &getFrontendTimer() const {
+ assert(FrontendTimer && "Compiler instance has no frontend timer!");
+ return *FrontendTimer;
+ }
+
+ /// }
+ /// @name Output Files
+ /// {
+
+ /// getOutputFileList - Get the list of (path, output stream) pairs of output
+ /// files; the path may be empty but the stream will always be non-null.
+ const std::list< std::pair<std::string,
+ llvm::raw_ostream*> > &getOutputFileList() const;
+
+ /// addOutputFile - Add an output file onto the list of tracked output files.
+ ///
+ /// \param Path - The path to the output file, or empty.
+ /// \param OS - The output stream, which should be non-null.
+ void addOutputFile(llvm::StringRef Path, llvm::raw_ostream *OS);
+
+ /// 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.
+ void createDiagnostics(int Argc, char **Argv);
+
+ /// Create a Diagnostic object with a the TextDiagnosticPrinter.
+ ///
+ /// The \arg Argc and \arg Argv arguments are used only for logging purposes,
+ /// when the diagnostic options indicate that the compiler should output
+ /// logging information.
+ ///
+ /// Note that this creates an unowned DiagnosticClient, if using directly the
+ /// caller is responsible for releasing the returned Diagnostic's client
+ /// eventually.
+ ///
+ /// \param Opts - The diagnostic options; note that the created text
+ /// diagnostic object contains a reference to these options and its lifetime
+ /// must extend past that of the diagnostic engine.
+ ///
+ /// \return The new object on success, or null on failure.
+ static llvm::IntrusiveRefCntPtr<Diagnostic>
+ createDiagnostics(const DiagnosticOptions &Opts, int Argc, char **Argv);
+
+ /// 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();
+
+ /// Create the preprocessor, using the invocation, file, and source managers,
+ /// and replace any existing one with it.
+ void createPreprocessor();
+
+ /// Create a Preprocessor object.
+ ///
+ /// Note that this also creates a new HeaderSearch object which will be owned
+ /// by the resulting Preprocessor.
+ ///
+ /// \return The new object on success, or null on failure.
+ static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &,
+ const PreprocessorOptions &,
+ const HeaderSearchOptions &,
+ const DependencyOutputOptions &,
+ const TargetInfo &,
+ const FrontendOptions &,
+ SourceManager &, FileManager &);
+
+ /// 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(llvm::StringRef Path);
+
+ /// Create an external AST source to read a PCH file.
+ ///
+ /// \return - The new object on success, or null on failure.
+ static ExternalASTSource *
+ createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
+ Preprocessor &PP, ASTContext &Context);
+
+ /// 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
+ /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg
+ /// OS.
+ static CodeCompleteConsumer *
+ createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
+ unsigned Line, unsigned Column,
+ bool UseDebugPrinter, bool ShowMacros,
+ bool ShowCodePatterns, llvm::raw_ostream &OS);
+
+ /// 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.
+ ///
+ /// \return - Null on error.
+ llvm::raw_fd_ostream *
+ createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "",
+ llvm::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.
+ llvm::raw_fd_ostream *
+ createOutputFile(llvm::StringRef OutputPath, bool Binary = true,
+ llvm::StringRef BaseInput = "",
+ llvm::StringRef Extension = "");
+
+ /// Create a new output file, optionally deriving the output path name.
+ ///
+ /// If \arg OutputPath is empty, then createOutputFile will derive an output
+ /// path location as \arg BaseInput, with any suffix removed, and \arg
+ /// Extension appended.
+ ///
+ /// \param OutputPath - If given, the path to the output file.
+ /// \param Error [out] - On failure, the error message.
+ /// \param BaseInput - If \arg 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 ResultPathName [out] - If given, the result path name will be
+ /// stored here on success.
+ static llvm::raw_fd_ostream *
+ createOutputFile(llvm::StringRef OutputPath, std::string &Error,
+ bool Binary = true, llvm::StringRef BaseInput = "",
+ llvm::StringRef Extension = "",
+ std::string *ResultPathName = 0);
+
+ /// }
+ /// @name Initialization Utility Methods
+ /// {
+
+ /// InitializeSourceManager - Initialize the source manager to set InputFile
+ /// as the main file.
+ ///
+ /// \return True on success.
+ bool InitializeSourceManager(llvm::StringRef InputFile);
+
+ /// InitializeSourceManager - Initialize the source manager to set InputFile
+ /// as the main file.
+ ///
+ /// \return True on success.
+ static bool InitializeSourceManager(llvm::StringRef InputFile,
+ Diagnostic &Diags,
+ FileManager &FileMgr,
+ SourceManager &SourceMgr,
+ const FrontendOptions &Opts);
+
+ /// }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h
new file mode 100644
index 0000000..f5a9053
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h
@@ -0,0 +1,162 @@
+//===-- 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/LangOptions.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/AnalysisConsumer.h"
+#include "clang/Frontend/DependencyOutputOptions.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/HeaderSearchOptions.h"
+#include "clang/Frontend/PreprocessorOptions.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+ template<typename T> class SmallVectorImpl;
+}
+
+namespace clang {
+
+class Diagnostic;
+
+/// CompilerInvocation - 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 {
+ /// Options controlling the static analyzer.
+ AnalyzerOptions AnalyzerOpts;
+
+ /// Options controlling IRgen and the backend.
+ CodeGenOptions CodeGenOpts;
+
+ /// Options controlling dependency output.
+ DependencyOutputOptions DependencyOutputOpts;
+
+ /// Options controlling the diagnostic engine.
+ DiagnosticOptions DiagnosticOpts;
+
+ /// Options controlling the frontend itself.
+ FrontendOptions FrontendOpts;
+
+ /// Options controlling the #include directive.
+ HeaderSearchOptions HeaderSearchOpts;
+
+ /// Options controlling the language variant.
+ LangOptions LangOpts;
+
+ /// Options controlling the preprocessor (aside from #include handling).
+ PreprocessorOptions PreprocessorOpts;
+
+ /// Options controlling preprocessed output.
+ PreprocessorOutputOptions PreprocessorOutputOpts;
+
+ /// Options controlling the target.
+ TargetOptions TargetOpts;
+
+public:
+ CompilerInvocation() {}
+
+ /// @name Utility Methods
+ /// @{
+
+ /// CreateFromArgs - Create a compiler invocation from a list of input
+ /// options.
+ ///
+ /// \param Res [out] - 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 void CreateFromArgs(CompilerInvocation &Res, const char **ArgBegin,
+ const char **ArgEnd, Diagnostic &Diags);
+
+ /// GetBuiltinIncludePath - 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);
+
+ /// toArgs - Convert the CompilerInvocation to a list of strings suitable for
+ /// passing to CreateFromArgs.
+ void toArgs(std::vector<std::string> &Res);
+
+ /// @}
+ /// @name Option Subgroups
+ /// @{
+
+ AnalyzerOptions &getAnalyzerOpts() { return AnalyzerOpts; }
+ const AnalyzerOptions &getAnalyzerOpts() const {
+ return AnalyzerOpts;
+ }
+
+ CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
+ const CodeGenOptions &getCodeGenOpts() const {
+ return CodeGenOpts;
+ }
+
+ DependencyOutputOptions &getDependencyOutputOpts() {
+ return DependencyOutputOpts;
+ }
+ const DependencyOutputOptions &getDependencyOutputOpts() const {
+ return DependencyOutputOpts;
+ }
+
+ DiagnosticOptions &getDiagnosticOpts() { return DiagnosticOpts; }
+ const DiagnosticOptions &getDiagnosticOpts() const { return DiagnosticOpts; }
+
+ HeaderSearchOptions &getHeaderSearchOpts() { return HeaderSearchOpts; }
+ const HeaderSearchOptions &getHeaderSearchOpts() const {
+ return HeaderSearchOpts;
+ }
+
+ FrontendOptions &getFrontendOpts() { return FrontendOpts; }
+ const FrontendOptions &getFrontendOpts() const {
+ return FrontendOpts;
+ }
+
+ LangOptions &getLangOpts() { return LangOpts; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
+
+ PreprocessorOptions &getPreprocessorOpts() { return PreprocessorOpts; }
+ const PreprocessorOptions &getPreprocessorOpts() const {
+ return PreprocessorOpts;
+ }
+
+ PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+ return PreprocessorOutputOpts;
+ }
+ const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+ return PreprocessorOutputOpts;
+ }
+
+ TargetOptions &getTargetOpts() { return TargetOpts; }
+ const TargetOptions &getTargetOpts() const {
+ return TargetOpts;
+ }
+
+ /// @}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DeclContextXML.def b/contrib/llvm/tools/clang/include/clang/Frontend/DeclContextXML.def
new file mode 100644
index 0000000..39ed5f9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/DeclContextXML.def
@@ -0,0 +1,113 @@
+//===-- DeclContextXML.def - Metadata about Context XML 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 XML context info database as written in the
+// <ReferenceSection>/<Contexts> sub-nodes of the XML document. Type nodes
+// are referred by "context" reference attributes throughout the document.
+// A context node never contains sub-nodes.
+// The semantics of the attributes and enums are mostly self-documenting
+// by looking at the appropriate internally used functions and values.
+// The following macros are used:
+//
+// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+// context of class CLASS where CLASS is a class name used internally by clang.
+// After a NODE_XML the definition of all (optional) attributes of that context
+// node and possible sub-nodes follows.
+//
+// END_NODE_XML - Closes the attribute definition of the current node.
+//
+// ID_ATTRIBUTE_XML - Context nodes have an "id" attribute containing a
+// string, which value uniquely identify that statement. Other nodes may refer
+// by "context" attributes to this value.
+//
+// TYPE_ATTRIBUTE_XML( FN ) - Context nodes may refer to the ids of type
+// nodes by a "type" attribute, if they create a type during declaration.
+// For instance 'struct S;' creates both a context 'S::' and a type 'S'.
+// Contexts and types always have different ids, however declarations and
+// contexts may share the same ids. FN is internally used by clang.
+//
+// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
+// used by clang. A boolean attribute have the values "0" or "1".
+//
+// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+// is an enumeration defined with ENUM_XML macros immediately following after
+// that macro. An optional attribute is ommited, if the particular enum is the
+// empty string. FN is internally used by clang.
+//
+// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
+// internally used by clang.
+//
+// END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TYPE_ATTRIBUTE_XML
+# define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
+#endif
+
+NODE_XML(TranslationUnitDecl, "TranslationUnit")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(FunctionDecl, "Function")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType()->getAsFunctionType())
+END_NODE_XML
+
+NODE_XML(NamespaceDecl, "Namespace")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(RecordDecl, "Record")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getTypeForDecl())
+END_NODE_XML
+
+NODE_XML(EnumDecl, "Enum")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getTypeForDecl())
+END_NODE_XML
+
+NODE_XML(LinkageSpecDecl, "LinkageSpec")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_ENUM_OPT_XML(getLanguage(), "lang")
+ ENUM_XML(LinkageSpecDecl::lang_c, "C")
+ ENUM_XML(LinkageSpecDecl::lang_cxx, "CXX")
+ END_ENUM_XML
+END_NODE_XML
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML
+#undef END_NODE_XML
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DeclXML.def b/contrib/llvm/tools/clang/include/clang/Frontend/DeclXML.def
new file mode 100644
index 0000000..16551ee
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/DeclXML.def
@@ -0,0 +1,367 @@
+//===-- DeclXML.def - Metadata about Decl XML 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 XML statement database structure as written in
+// <TranslationUnit> sub-nodes of the XML document.
+// The semantics of the attributes and enums are mostly self-documenting
+// by looking at the appropriate internally used functions and values.
+// The following macros are used:
+//
+// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+// statement of class CLASS where CLASS is a class name used internally by clang.
+// After a NODE_XML the definition of all (optional) attributes of that statement
+// node and possible sub-nodes follows.
+//
+// END_NODE_XML - Closes the attribute definition of the current node.
+//
+// ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a
+// string, which value uniquely identify that statement. Other nodes may refer
+// by reference attributes to this value (currently used only for Label).
+//
+// TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an
+// expression by a "type" attribute. FN is internally used by clang.
+//
+// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
+// used by clang. A boolean attribute have the values "0" or "1".
+//
+// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
+// a special handling. See the appropriate documentations.
+//
+// ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of
+// a statement in the source file(s).
+//
+// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
+// Optional attributes are omitted for boolean types, if the value is false,
+// for integral types, if the value is null and for strings,
+// if the value is the empty string. FN is internally used by clang.
+//
+// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+// is an enumeration defined with ENUM_XML macros immediately following after
+// that macro. An optional attribute is ommited, if the particular enum is the
+// empty string. FN is internally used by clang.
+//
+// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
+// internally used by clang.
+//
+// END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+// SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+// SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes.
+//
+// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
+// its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ATTRIBUTE_FILE_LOCATION_XML
+# define ATTRIBUTE_FILE_LOCATION_XML \
+ ATTRIBUTE_XML(getFilename(), "file") \
+ ATTRIBUTE_XML(getLine(), "line") \
+ ATTRIBUTE_XML(getColumn(), "col") \
+ ATTRIBUTE_OPT_XML(getFilename(), "endfile") \
+ ATTRIBUTE_OPT_XML(getLine(), "endline") \
+ ATTRIBUTE_OPT_XML(getColumn(), "endcol")
+#endif
+
+#ifndef TYPE_ATTRIBUTE_XML
+# define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
+#endif
+
+//NODE_XML(TranslationUnitDecl, "TranslationUnit")
+// SUB_NODE_SEQUENCE_XML(Decl)
+//END_NODE_XML
+
+NODE_XML(Decl, "FIXME_Decl")
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclKindName(), "unhandled_decl_name")
+END_NODE_XML
+
+NODE_XML(FunctionDecl, "Function")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
+ ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
+ ATTRIBUTE_ENUM_OPT_XML(getStorageClass(), "storage_class")
+ ENUM_XML(FunctionDecl::None, "")
+ ENUM_XML(FunctionDecl::Extern, "extern")
+ ENUM_XML(FunctionDecl::Static, "static")
+ ENUM_XML(FunctionDecl::PrivateExtern, "__private_extern__")
+ END_ENUM_XML
+ ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+ //ATTRIBUTE_OPT_XML(isVariadic(), "variadic") // in the type reference
+ ATTRIBUTE_XML(getNumParams(), "num_args")
+ SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+ SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(CXXMethodDecl, "CXXMethod")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
+ ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
+ ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+ ATTRIBUTE_OPT_XML(isStatic(), "static")
+ ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+ ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+ ENUM_XML(AS_none, "")
+ ENUM_XML(AS_public, "public")
+ ENUM_XML(AS_protected, "protected")
+ ENUM_XML(AS_private, "private")
+ END_ENUM_XML
+ ATTRIBUTE_XML(getNumParams(), "num_args")
+ SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+ SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(CXXConstructorDecl, "CXXConstructor")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
+ ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
+ ATTRIBUTE_OPT_XML(isExplicit(), "is_explicit")
+ ATTRIBUTE_OPT_XML(isDefaultConstructor(), "is_default_ctor")
+ ATTRIBUTE_OPT_XML(isCopyConstructor(), "is_copy_ctor")
+ ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+ ATTRIBUTE_OPT_XML(isStatic(), "static")
+ ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+ ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+ ENUM_XML(AS_none, "")
+ ENUM_XML(AS_public, "public")
+ ENUM_XML(AS_protected, "protected")
+ ENUM_XML(AS_private, "private")
+ END_ENUM_XML
+ ATTRIBUTE_XML(getNumParams(), "num_args")
+ SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+ SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(CXXDestructorDecl, "CXXDestructor")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
+ ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
+ ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+ ATTRIBUTE_OPT_XML(isStatic(), "static")
+ ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+ ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+ ENUM_XML(AS_none, "")
+ ENUM_XML(AS_public, "public")
+ ENUM_XML(AS_protected, "protected")
+ ENUM_XML(AS_private, "private")
+ END_ENUM_XML
+ ATTRIBUTE_XML(getNumParams(), "num_args")
+ SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+ SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(CXXConversionDecl, "CXXConversion")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
+ ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
+ ATTRIBUTE_OPT_XML(isExplicit(), "is_explicit")
+ ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+ ATTRIBUTE_OPT_XML(isStatic(), "static")
+ ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+ ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+ ENUM_XML(AS_none, "")
+ ENUM_XML(AS_public, "public")
+ ENUM_XML(AS_protected, "protected")
+ ENUM_XML(AS_private, "private")
+ END_ENUM_XML
+ ATTRIBUTE_XML(getNumParams(), "num_args")
+ SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+ SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(NamespaceDecl, "Namespace")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ SUB_NODE_SEQUENCE_XML(DeclContext)
+END_NODE_XML
+
+NODE_XML(UsingDirectiveDecl, "UsingDirective")
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ ATTRIBUTE_XML(getNominatedNamespace(), "ref")
+END_NODE_XML
+
+NODE_XML(NamespaceAliasDecl, "NamespaceAlias")
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ ATTRIBUTE_XML(getNamespace(), "ref")
+END_NODE_XML
+
+NODE_XML(RecordDecl, "Record")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+ ATTRIBUTE_XML(getTypeForDecl(), "type") // refers to the type this decl creates
+ SUB_NODE_SEQUENCE_XML(FieldDecl)
+END_NODE_XML
+
+NODE_XML(CXXRecordDecl, "CXXRecord")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+ ATTRIBUTE_XML(getTypeForDecl(), "type") // refers to the type this decl creates
+ SUB_NODE_SEQUENCE_XML(FieldDecl)
+END_NODE_XML
+
+NODE_XML(EnumDecl, "Enum")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+ ATTRIBUTE_SPECIAL_XML(getIntegerType(), "type") // is NULL in pure declarations thus deserves special handling
+ SUB_NODE_SEQUENCE_XML(EnumConstantDecl) // only present in definition
+END_NODE_XML
+
+NODE_XML(EnumConstantDecl, "EnumConstant")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getInitVal().toString(10, true), "value") // integer
+ SUB_NODE_OPT_XML(Expr) // init expr of this constant
+END_NODE_XML
+
+NODE_XML(FieldDecl, "Field")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_OPT_XML(isMutable(), "mutable")
+ ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+ ENUM_XML(AS_none, "")
+ ENUM_XML(AS_public, "public")
+ ENUM_XML(AS_protected, "protected")
+ ENUM_XML(AS_private, "private")
+ END_ENUM_XML
+ ATTRIBUTE_OPT_XML(isBitField(), "bitfield")
+ SUB_NODE_OPT_XML(Expr) // init expr of a bit field
+END_NODE_XML
+
+NODE_XML(TypedefDecl, "Typedef")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getUnderlyingType())
+END_NODE_XML
+
+NODE_XML(VarDecl, "Var")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_ENUM_OPT_XML(getStorageClass(), "storage_class")
+ ENUM_XML(VarDecl::None, "")
+ ENUM_XML(VarDecl::Auto, "auto")
+ ENUM_XML(VarDecl::Register, "register")
+ ENUM_XML(VarDecl::Extern, "extern")
+ ENUM_XML(VarDecl::Static, "static")
+ ENUM_XML(VarDecl::PrivateExtern, "__private_extern__")
+ END_ENUM_XML
+ SUB_NODE_OPT_XML(Expr) // init expr
+END_NODE_XML
+
+NODE_XML(ParmVarDecl, "ParmVar")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_OPT_XML(Expr) // default argument expression
+END_NODE_XML
+
+NODE_XML(LinkageSpecDecl, "LinkageSpec")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_ENUM_OPT_XML(getLanguage(), "lang")
+ ENUM_XML(LinkageSpecDecl::lang_c, "C")
+ ENUM_XML(LinkageSpecDecl::lang_cxx, "CXX")
+ END_ENUM_XML
+END_NODE_XML
+
+NODE_XML(TemplateDecl, "Template")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(TemplateTypeParmDecl, "TemplateTypeParm")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(UsingShadowDecl, "UsingShadow")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getTargetDecl(), "target_decl")
+ ATTRIBUTE_XML(getUsingDecl(), "using_decl")
+END_NODE_XML
+
+NODE_XML(UsingDecl, "Using")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getTargetNestedNameDecl(), "target_nested_namespace_decl")
+ ATTRIBUTE_XML(isTypeName(), "is_typename")
+END_NODE_XML
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML
+#undef END_NODE_XML
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
+#undef SUB_NODE_FN_BODY_XML
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h
new file mode 100644
index 0000000..ab8e49d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h
@@ -0,0 +1,43 @@
+//===--- 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 {
+
+/// DependencyOutputOptions - Options for controlling the compiler dependency
+/// file generation.
+class DependencyOutputOptions {
+public:
+ unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies.
+ unsigned UsePhonyTargets : 1; ///< Include phony targets for each
+ /// dependency, which can avoid some 'make'
+ /// problems.
+
+ /// The file to write depencency output to.
+ std::string OutputFile;
+
+ /// 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;
+
+public:
+ DependencyOutputOptions() {
+ IncludeSystemHeaders = 0;
+ UsePhonyTargets = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h
new file mode 100644
index 0000000..8eb66e5
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h
@@ -0,0 +1,91 @@
+//===--- 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_FRONTEND_DIAGNOSTICOPTIONS_H
+#define LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// DiagnosticOptions - Options for controlling the compiler diagnostics
+/// engine.
+class DiagnosticOptions {
+public:
+ unsigned IgnoreWarnings : 1; /// -w
+ unsigned NoRewriteMacros : 1; /// -Wno-rewrite-macros
+ unsigned Pedantic : 1; /// -pedantic
+ unsigned PedanticErrors : 1; /// -pedantic-errors
+ unsigned ShowColumn : 1; /// Show column number on diagnostics.
+ unsigned ShowLocation : 1; /// Show source location information.
+ unsigned ShowCarets : 1; /// Show carets in diagnostics.
+ unsigned ShowFixits : 1; /// Show fixit information.
+ unsigned ShowSourceRanges : 1; /// Show source ranges in numeric form.
+ unsigned ShowOptionNames : 1; /// Show the diagnostic name for mappable
+ /// diagnostics.
+ unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number,
+ /// 2 -> Full Name.
+ unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences.
+ unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected
+ /// diagnostics, indicated by markers in the
+ /// input source file.
+ unsigned BinaryOutput : 1; /// Emit diagnostics via the diagnostic
+ /// binary serialization mechanism, to be
+ /// deserialized by, e.g., the CIndex library.
+
+ unsigned ErrorLimit; /// Limit # errors emitted.
+ unsigned MacroBacktraceLimit; /// Limit depth of macro instantiation
+ /// backtrace.
+ unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace.
+
+ /// The distance between tab stops.
+ unsigned TabStop;
+ enum { DefaultTabStop = 8, MaxTabStop = 100,
+ DefaultMacroBacktraceLimit = 6,
+ DefaultTemplateBacktraceLimit = 10 };
+
+ /// Column limit for formatting message diagnostics, or 0 if unused.
+ unsigned MessageLength;
+
+ /// If non-empty, a file to log extended build information to, for development
+ /// testing and analysis.
+ std::string DumpBuildInformation;
+
+ /// The list of -W... options used to alter the diagnostic mappings, with the
+ /// prefixes removed.
+ std::vector<std::string> Warnings;
+
+public:
+ DiagnosticOptions() {
+ IgnoreWarnings = 0;
+ TabStop = DefaultTabStop;
+ MessageLength = 0;
+ NoRewriteMacros = 0;
+ Pedantic = 0;
+ PedanticErrors = 0;
+ ShowCarets = 1;
+ ShowColors = 0;
+ ShowColumn = 1;
+ ShowFixits = 1;
+ ShowLocation = 1;
+ ShowOptionNames = 0;
+ ShowCategories = 0;
+ ShowSourceRanges = 0;
+ VerifyDiagnostics = 0;
+ BinaryOutput = 0;
+ ErrorLimit = 0;
+ TemplateBacktraceLimit = DefaultTemplateBacktraceLimit;
+ MacroBacktraceLimit = DefaultMacroBacktraceLimit;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DocumentXML.def b/contrib/llvm/tools/clang/include/clang/Frontend/DocumentXML.def
new file mode 100644
index 0000000..4c52bd8
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/DocumentXML.def
@@ -0,0 +1,75 @@
+//===-- DocumentXML.def - Metadata about Document XML 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 XML root database structure as written in
+// an AST XML document.
+// The following macros are used:
+//
+// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+// statement of class CLASS where CLASS is a class name used internally by clang.
+// After a NODE_XML the definition of all (optional) attributes of that statement
+// node and possible sub-nodes follows.
+//
+// END_NODE_XML - Closes the attribute definition of the current node.
+//
+// ID_ATTRIBUTE_XML - Some nodes have an "id" attribute containing a
+// string, which value uniquely identify the entity represented by that node.
+// Other nodes may refer by reference attributes to this value.
+//
+// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
+// a special handling. See the appropriate documentations.
+//
+// SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
+// its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+ROOT_NODE_XML("CLANG_XML")
+ ATTRIBUTE_SPECIAL_XML(ignore, "version") // special retrieving needed
+ SUB_NODE_XML("TranslationUnit")
+ SUB_NODE_XML("ReferenceSection")
+END_NODE_XML
+
+NODE_XML("TranslationUnit")
+ SUB_NODE_SEQUENCE_XML(Decl)
+END_NODE_XML
+
+NODE_XML("ReferenceSection")
+ SUB_NODE_XML("Types")
+ SUB_NODE_XML("Contexts")
+ SUB_NODE_XML("Files")
+END_NODE_XML
+
+NODE_XML("Types")
+ SUB_NODE_SEQUENCE_XML(Type)
+END_NODE_XML
+
+NODE_XML("Contexts")
+ SUB_NODE_SEQUENCE_XML(DeclContext)
+END_NODE_XML
+
+NODE_XML("Files")
+ SUB_NODE_SEQUENCE_XML("File")
+END_NODE_XML
+
+NODE_XML("File")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_SPECIAL_XML(ignore, "name") // special retrieving needed, denotes the source file name
+END_NODE_XML
+
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef END_NODE_XML
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DocumentXML.h b/contrib/llvm/tools/clang/include/clang/Frontend/DocumentXML.h
new file mode 100644
index 0000000..73d8921
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/DocumentXML.h
@@ -0,0 +1,186 @@
+//===--- DocumentXML.h - XML document for 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 implements the XML document class, which provides the means to
+// dump out the AST in a XML form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DOCUMENTXML_H
+#define LLVM_CLANG_FRONTEND_DOCUMENTXML_H
+
+#include <string>
+#include <map>
+#include <stack>
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeOrdering.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+//--------------------------------------------------------- forwards
+class DeclContext;
+class Decl;
+class NamedDecl;
+class FunctionDecl;
+class ASTContext;
+class LabelStmt;
+
+//---------------------------------------------------------
+namespace XML {
+ // id maps:
+ template<class T>
+ struct IdMap : llvm::DenseMap<T, unsigned> {};
+
+ template<>
+ struct IdMap<QualType> : std::map<QualType, unsigned, QualTypeOrdering> {};
+
+ template<>
+ struct IdMap<std::string> : std::map<std::string, unsigned> {};
+}
+
+//---------------------------------------------------------
+class DocumentXML {
+public:
+ DocumentXML(const std::string& rootName, llvm::raw_ostream& out);
+
+ void initialize(ASTContext &Context);
+ void PrintDecl(Decl *D);
+ void PrintStmt(const Stmt *S); // defined in StmtXML.cpp
+ void finalize();
+
+
+ DocumentXML& addSubNode(const std::string& name); // also enters the sub node, returns *this
+ DocumentXML& toParent(); // returns *this
+
+ void addAttribute(const char* pName, const QualType& pType);
+ void addAttribute(const char* pName, bool value);
+
+ template<class T>
+ void addAttribute(const char* pName, const T* value) {
+ addPtrAttribute(pName, value);
+ }
+
+ template<class T>
+ void addAttribute(const char* pName, T* value) {
+ addPtrAttribute(pName, value);
+ }
+
+ template<class T>
+ void addAttribute(const char* pName, const T& value);
+
+ template<class T>
+ void addAttributeOptional(const char* pName, const T& value);
+
+ void addSourceFileAttribute(const std::string& fileName);
+
+ PresumedLoc addLocation(const SourceLocation& Loc);
+ void addLocationRange(const SourceRange& R);
+
+ static std::string escapeString(const char* pStr, std::string::size_type len);
+
+private:
+ DocumentXML(const DocumentXML&); // not defined
+ DocumentXML& operator=(const DocumentXML&); // not defined
+
+ std::stack<std::string> NodeStack;
+ llvm::raw_ostream& Out;
+ ASTContext *Ctx;
+ bool HasCurrentNodeSubNodes;
+
+
+ XML::IdMap<QualType> Types;
+ XML::IdMap<const DeclContext*> Contexts;
+ XML::IdMap<const Type*> BasicTypes;
+ XML::IdMap<std::string> SourceFiles;
+ XML::IdMap<const NamedDecl*> Decls;
+ XML::IdMap<const LabelStmt*> Labels;
+
+ void addContextsRecursively(const DeclContext *DC);
+ void addTypeRecursively(const Type* pType);
+ void addTypeRecursively(const QualType& pType);
+
+ void Indent();
+
+ // forced pointer dispatch:
+ void addPtrAttribute(const char* pName, const Type* pType);
+ void addPtrAttribute(const char* pName, const NamedDecl* D);
+ void addPtrAttribute(const char* pName, const DeclContext* D);
+ void addPtrAttribute(const char* pName, const NamespaceDecl* D); // disambiguation
+ void addPtrAttribute(const char* pName, const NestedNameSpecifier* N);
+ void addPtrAttribute(const char* pName, const LabelStmt* L);
+ void addPtrAttribute(const char* pName, const char* text);
+
+ // defined in TypeXML.cpp:
+ void addParentTypes(const Type* pType);
+ void writeTypeToXML(const Type* pType);
+ void writeTypeToXML(const QualType& pType);
+ class TypeAdder;
+ friend class TypeAdder;
+
+ // defined in DeclXML.cpp:
+ void writeDeclToXML(Decl *D);
+ class DeclPrinter;
+ friend class DeclPrinter;
+
+ // for addAttributeOptional:
+ static bool isDefault(unsigned value) { return value == 0; }
+ static bool isDefault(bool value) { return !value; }
+ static bool isDefault(Qualifiers::GC value) { return value == Qualifiers::GCNone; }
+ static bool isDefault(const std::string& value) { return value.empty(); }
+};
+
+//--------------------------------------------------------- inlines
+
+inline void DocumentXML::initialize(ASTContext &Context) {
+ Ctx = &Context;
+}
+
+//---------------------------------------------------------
+template<class T>
+inline void DocumentXML::addAttribute(const char* pName, const T& value) {
+ std::string repr;
+ {
+ llvm::raw_string_ostream buf(repr);
+ buf << value;
+ buf.flush();
+ }
+
+ Out << ' ' << pName << "=\""
+ << DocumentXML::escapeString(repr.c_str(), repr.size())
+ << "\"";
+}
+
+//---------------------------------------------------------
+inline void DocumentXML::addPtrAttribute(const char* pName, const char* text) {
+ Out << ' ' << pName << "=\""
+ << DocumentXML::escapeString(text, strlen(text))
+ << "\"";
+}
+
+//---------------------------------------------------------
+inline void DocumentXML::addAttribute(const char* pName, bool value) {
+ addPtrAttribute(pName, value ? "1" : "0");
+}
+
+//---------------------------------------------------------
+template<class T>
+inline void DocumentXML::addAttributeOptional(const char* pName,
+ const T& value) {
+ if (!isDefault(value)) {
+ addAttribute(pName, value);
+ }
+}
+
+//---------------------------------------------------------
+
+} //namespace clang
+
+#endif //LLVM_CLANG_DOCUMENTXML_H
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FixItRewriter.h b/contrib/llvm/tools/clang/include/clang/Frontend/FixItRewriter.h
new file mode 100644
index 0000000..b432d74
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/FixItRewriter.h
@@ -0,0 +1,104 @@
+//===--- 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_FRONTEND_FIX_IT_REWRITER_H
+#define LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm { class raw_ostream; }
+
+namespace clang {
+
+class SourceManager;
+class FileEntry;
+
+class FixItPathRewriter {
+public:
+ virtual ~FixItPathRewriter();
+
+ /// \brief This file is about to be rewritten. Return the name of the file
+ /// that is okay to write to.
+ virtual std::string RewriteFilename(const std::string &Filename) = 0;
+};
+
+class FixItRewriter : public DiagnosticClient {
+ /// \brief The diagnostics machinery.
+ Diagnostic &Diags;
+
+ /// \brief The rewriter used to perform the various code
+ /// modifications.
+ Rewriter Rewrite;
+
+ /// \brief The diagnostic client that performs the actual formatting
+ /// of error messages.
+ DiagnosticClient *Client;
+
+ /// \brief Turn an input path into an output path. NULL implies overwriting
+ /// the original.
+ FixItPathRewriter *PathRewriter;
+
+ /// \brief The number of rewriter failures.
+ unsigned NumFailures;
+
+public:
+ typedef Rewriter::buffer_iterator iterator;
+
+ /// \brief Initialize a new fix-it rewriter.
+ FixItRewriter(Diagnostic &Diags, SourceManager &SourceMgr,
+ const LangOptions &LangOpts, FixItPathRewriter *PathRewriter);
+
+ /// \brief Destroy the fix-it rewriter.
+ ~FixItRewriter();
+
+ /// \brief Check whether there are modifications for a given file.
+ bool IsModified(FileID ID) const {
+ return Rewrite.getRewriteBufferFor(ID) != NULL;
+ }
+
+ // 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, llvm::raw_ostream &OS);
+
+ /// \brief Write the modified source files.
+ ///
+ /// \returns true if there was an error, false otherwise.
+ bool WriteFixedFiles();
+
+ /// IncludeInDiagnosticCounts - This method (whose default implementation
+ /// returns true) indicates whether the diagnostics handled by this
+ /// DiagnosticClient should be included in the number of diagnostics
+ /// reported by Diagnostic.
+ virtual bool IncludeInDiagnosticCounts() const;
+
+ /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
+ /// capturing it to a log as needed.
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info);
+
+ /// \brief Emit a diagnostic via the adapted diagnostic client.
+ void Diag(FullSourceLoc Loc, unsigned DiagID);
+};
+
+}
+
+#endif // LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h
new file mode 100644
index 0000000..7b7db37
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h
@@ -0,0 +1,204 @@
+//===-- 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <string>
+
+namespace clang {
+class ASTUnit;
+class ASTConsumer;
+class CompilerInstance;
+class ASTMergeAction;
+
+/// FrontendAction - Abstract base class for actions which can be performed by
+/// the frontend.
+class FrontendAction {
+ std::string CurrentFile;
+ llvm::OwningPtr<ASTUnit> CurrentASTUnit;
+ CompilerInstance *Instance;
+ friend class ASTMergeAction;
+
+protected:
+ /// @name Implementation Action Interface
+ /// @{
+
+ /// CreateASTConsumer - Create the AST consumer object for this action, if
+ /// supported.
+ ///
+ /// This routine is called as part of \see BeginSourceAction(), 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 0 on failure.
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile) = 0;
+
+ /// BeginSourceFileAction - Callback at the start of processing a single
+ /// input.
+ ///
+ /// \return True on success; on failure \see ExecutionAction() and
+ /// EndSourceFileAction() will not be called.
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename) {
+ return true;
+ }
+
+ /// ExecuteAction - Callback to run the program action, using the initialized
+ /// compiler instance.
+ ///
+ /// This routine is guaranteed to only be called between \see
+ /// BeginSourceFileAction() and \see EndSourceFileAction().
+ virtual void ExecuteAction() = 0;
+
+ /// EndSourceFileAction - Callback at the end of processing a single input;
+ /// this is guaranteed to only be called following a successful call to
+ /// BeginSourceFileAction (and BeingSourceFile).
+ virtual void EndSourceFileAction() {}
+
+ /// @}
+
+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(!CurrentFile.empty() && "No current file!");
+ return CurrentASTUnit != 0;
+ }
+
+ const std::string &getCurrentFile() const {
+ assert(!CurrentFile.empty() && "No current file!");
+ return CurrentFile;
+ }
+
+ ASTUnit &getCurrentASTUnit() const {
+ assert(!CurrentASTUnit && "No current AST unit!");
+ return *CurrentASTUnit;
+ }
+
+ ASTUnit *takeCurrentASTUnit() {
+ return CurrentASTUnit.take();
+ }
+
+ void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0);
+
+ /// @}
+ /// @name Supported Modes
+ /// @{
+
+ /// usesPreprocessorOnly - Does this action only use the preprocessor? If so
+ /// no AST context will be created and this action will be invalid with PCH
+ /// inputs.
+ virtual bool usesPreprocessorOnly() const = 0;
+
+ /// usesCompleteTranslationUnit - For AST based actions, should the
+ /// translation unit be completed?
+ virtual bool usesCompleteTranslationUnit() { return true; }
+
+ /// hasPCHSupport - Does this action support use with PCH?
+ virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
+
+ /// hasASTSupport - Does this action support use with AST files?
+ virtual bool hasASTSupport() const { return !usesPreprocessorOnly(); }
+
+ /// hasCodeCompletionSupport - Does this action support use with code
+ /// completion?
+ virtual bool hasCodeCompletionSupport() const { return false; }
+
+ /// @}
+ /// @name Public Action Interface
+ /// @{
+
+ /// BeginSourceFile - Prepare the action for processing the input file \arg
+ /// Filename; 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 Filename - The input filename, which will be made available to
+ /// clients via \see getCurrentFile().
+ ///
+ /// \param IsAST - Indicates whether this is an AST input. AST inputs require
+ /// special handling, 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 \see BeginSourceFile() and \see EndSourceFile().
+ ///
+ /// \return True on success; the compilation of this file should be aborted
+ /// and neither Execute nor EndSourceFile should be called.
+ bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename,
+ bool IsAST = false);
+
+ /// Execute - Set the source managers main input file, and run the action.
+ void Execute();
+
+ /// EndSourceFile - Perform any per-file post processing, deallocate per-file
+ /// objects, and run statistics and output file cleanup code.
+ void EndSourceFile();
+
+ /// @}
+};
+
+/// ASTFrontendAction - Abstract base class to use for AST consumer based
+/// frontend actions.
+class ASTFrontendAction : public FrontendAction {
+ /// ExecuteAction - 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.
+ virtual void ExecuteAction();
+
+public:
+ virtual bool usesPreprocessorOnly() const { return false; }
+};
+
+/// PreprocessorFrontendAction - Abstract base class to use for preprocessor
+/// based frontend actions.
+class PreprocessorFrontendAction : public FrontendAction {
+protected:
+ /// CreateASTConsumer - Provide a default implementation which returns aborts,
+ /// this method should never be called by FrontendAction clients.
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+public:
+ virtual bool usesPreprocessorOnly() const { return true; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h
new file mode 100644
index 0000000..cee1c1d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h
@@ -0,0 +1,230 @@
+//===-- 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 FixItRewriter;
+class FixItPathRewriter;
+
+//===----------------------------------------------------------------------===//
+// Custom Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class InitOnlyAction : public FrontendAction {
+ virtual void ExecuteAction();
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+public:
+ // Don't claim to only use the preprocessor, we want to follow the AST path,
+ // but do nothing.
+ virtual bool usesPreprocessorOnly() const { return false; }
+};
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class AnalysisAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTPrintXMLAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTDumpAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTViewAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class DeclContextPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class FixItAction : public ASTFrontendAction {
+protected:
+ llvm::OwningPtr<FixItRewriter> Rewriter;
+ llvm::OwningPtr<FixItPathRewriter> PathRewriter;
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename);
+
+ virtual void EndSourceFileAction();
+
+ virtual bool hasASTSupport() const { return false; }
+
+public:
+ FixItAction();
+ ~FixItAction();
+};
+
+class GeneratePCHAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool usesCompleteTranslationUnit() { return false; }
+
+ virtual bool hasASTSupport() const { return false; }
+};
+
+class HTMLPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class InheritanceViewAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class RewriteObjCAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class SyntaxOnlyAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+public:
+ virtual bool hasCodeCompletionSupport() const { return true; }
+};
+
+class BoostConAction : public SyntaxOnlyAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+/**
+ * \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:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename);
+
+ virtual void ExecuteAction();
+ virtual void EndSourceFileAction();
+
+public:
+ ASTMergeAction(FrontendAction *AdaptedAction,
+ std::string *ASTFiles, unsigned NumASTFiles);
+ virtual ~ASTMergeAction();
+
+ virtual bool usesPreprocessorOnly() const;
+ virtual bool usesCompleteTranslationUnit();
+ virtual bool hasPCHSupport() const;
+ virtual bool hasASTSupport() const;
+ virtual bool hasCodeCompletionSupport() const;
+};
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+class DumpRawTokensAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class DumpTokensAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class GeneratePTHAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class ParseOnlyAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PreprocessOnlyAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PrintParseAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PrintPreprocessedAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+
+ virtual bool hasPCHSupport() const { return true; }
+};
+
+class RewriteMacrosAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class RewriteTestAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h
new file mode 100644
index 0000000..61ad22c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- 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_FRONTENDDIAGNOSTIC_H
+#define LLVM_CLANG_FRONTENDDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+ namespace diag {
+ enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,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/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h
new file mode 100644
index 0000000..c43e680
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h
@@ -0,0 +1,146 @@
+//===--- 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 "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+ enum ActionKind {
+ ASTDump, ///< Parse ASTs and dump them.
+ ASTPrint, ///< Parse ASTs and print them.
+ ASTPrintXML, ///< Parse ASTs and print them in XML.
+ ASTView, ///< Parse ASTs and view them in Graphviz.
+ BoostCon, ///< BoostCon mode.
+ 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.
+ GeneratePCH, ///< Generate pre-compiled header.
+ GeneratePTH, ///< Generate pre-tokenized header.
+ InheritanceView, ///< View C++ inheritance for a specified class.
+ InitOnly, ///< Only execute frontend initialization.
+ ParseNoop, ///< Parse with noop callbacks.
+ ParsePrintCallbacks, ///< Parse and print each callback.
+ ParseSyntaxOnly, ///< Parse and perform semantic analysis.
+ PluginAction, ///< Run a plugin action, \see ActionName.
+ PrintDeclContext, ///< Print DeclContext and their Decls.
+ PrintPreprocessedInput, ///< -E mode.
+ RewriteMacros, ///< Expand macros but not #includes.
+ RewriteObjC, ///< ObjC->C Rewriter.
+ RewriteTest, ///< Rewriter playground
+ RunAnalysis, ///< Run one or more source code analyses.
+ RunPreprocessorOnly ///< Just lex, no output.
+ };
+}
+
+/// FrontendOptions - Options for controlling the behavior of the frontend.
+class FrontendOptions {
+public:
+ 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_AST
+ };
+
+ unsigned DebugCodeCompletionPrinter : 1; ///< Use the debug printer for code
+ /// completion results.
+ unsigned DisableFree : 1; ///< Disable memory freeing on exit.
+ unsigned RelocatablePCH : 1; ///< When generating PCH files,
+ /// instruct the PCH writer to create
+ /// relocatable PCH files.
+ unsigned ShowHelp : 1; ///< Show the -help text.
+ unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
+ /// results.
+ unsigned ShowCodePatternsInCodeCompletion : 1; ///< Show code patterns in code
+ /// completion results.
+ unsigned ShowStats : 1; ///< Show frontend performance
+ /// metrics and statistics.
+ unsigned ShowTimers : 1; ///< Show timers for individual
+ /// actions.
+ unsigned ShowVersion : 1; ///< Show the -version text.
+
+ /// The input files and their types.
+ std::vector<std::pair<InputKind, std::string> > Inputs;
+
+ /// The output file, if any.
+ std::string OutputFile;
+
+ /// If given, the name for a C++ class to view the inheritance of.
+ std::string ViewClassInheritance;
+
+ /// If given, the new suffix for fix-it rewritten files.
+ std::string FixItSuffix;
+
+ /// 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;
+
+ /// The list of plugins to load.
+ std::vector<std::string> Plugins;
+
+ /// \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;
+
+public:
+ FrontendOptions() {
+ DebugCodeCompletionPrinter = 1;
+ DisableFree = 0;
+ ProgramAction = frontend::ParseSyntaxOnly;
+ ActionName = "";
+ RelocatablePCH = 0;
+ ShowHelp = 0;
+ ShowMacrosInCodeCompletion = 0;
+ ShowCodePatternsInCodeCompletion = 0;
+ ShowStats = 0;
+ ShowTimers = 0;
+ ShowVersion = 0;
+ }
+
+ /// 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(llvm::StringRef Extension);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendPluginRegistry.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendPluginRegistry.h
new file mode 100644
index 0000000..8341492
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendPluginRegistry.h
@@ -0,0 +1,23 @@
+//===-- 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_PLUGINFRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/Support/Registry.h"
+
+namespace clang {
+
+/// The frontend plugin registry.
+typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h
new file mode 100644
index 0000000..c668245
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h
@@ -0,0 +1,95 @@
+//===--- 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_FRONTEND_HEADERSEARCHOPTIONS_H
+#define LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H
+
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+ /// IncludeDirGroup - Identifiers the group a include entry belongs to, which
+ /// represents its relative positive in the search list.
+ enum IncludeDirGroup {
+ Quoted = 0, ///< `#include ""` paths. Thing `gcc -iquote`.
+ Angled, ///< Paths for both `#include ""` and `#include <>`. (`-I`)
+ System, ///< Like Angled, but marks system directories.
+ 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:
+ struct Entry {
+ std::string Path;
+ frontend::IncludeDirGroup Group;
+ unsigned IsUserSupplied : 1;
+ unsigned IsFramework : 1;
+
+ Entry(llvm::StringRef _Path, frontend::IncludeDirGroup _Group,
+ bool _IsUserSupplied, bool _IsFramework)
+ : Path(_Path), Group(_Group), IsUserSupplied(_IsUserSupplied),
+ IsFramework(_IsFramework) {}
+ };
+
+ /// 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;
+
+ /// A (system-path) delimited list of include paths to be added from the
+ /// environment following the user specified includes (but prior to builtin
+ /// and standard includes). This is parsed in the same manner as the CPATH
+ /// environment variable for gcc.
+ std::string EnvIncPath;
+
+ /// Per-language environmental include paths, see \see EnvIncPath.
+ std::string CEnvIncPath;
+ std::string ObjCEnvIncPath;
+ std::string CXXEnvIncPath;
+ std::string ObjCXXEnvIncPath;
+
+ /// The directory which holds the compiler resource files (builtin includes,
+ /// etc.).
+ std::string ResourceDir;
+
+ /// Include the compiler builtin includes.
+ unsigned UseBuiltinIncludes : 1;
+
+ /// Include the system standard include search directories.
+ unsigned UseStandardIncludes : 1;
+
+ /// Include the system standard C++ library include search directories.
+ unsigned UseStandardCXXIncludes : 1;
+
+ /// Whether header search information should be output as for -v.
+ unsigned Verbose : 1;
+
+public:
+ HeaderSearchOptions(llvm::StringRef _Sysroot = "/")
+ : Sysroot(_Sysroot), UseBuiltinIncludes(true),
+ UseStandardIncludes(true), UseStandardCXXIncludes(true),
+ Verbose(false) {}
+
+ /// AddPath - Add the \arg Path path to the specified \arg Group list.
+ void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
+ bool IsUserSupplied, bool IsFramework) {
+ UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework));
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h
new file mode 100644
index 0000000..441d34f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h
@@ -0,0 +1,83 @@
+//===--- 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 "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+namespace frontend {
+
+enum LangFeatures {
+ BCPLComment = (1 << 0),
+ C99 = (1 << 1),
+ CPlusPlus = (1 << 2),
+ CPlusPlus0x = (1 << 3),
+ Digraphs = (1 << 4),
+ GNUMode = (1 << 5),
+ HexFloat = (1 << 6),
+ ImplicitInt = (1 << 7)
+};
+
+}
+
+/// 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; }
+
+ /// hasBCPLComments - Language supports '//' comments.
+ bool hasBCPLComments() const { return Flags & frontend::BCPLComment; }
+
+ /// isC99 - Language is a superset of C99.
+ bool isC99() const { return Flags & frontend::C99; }
+
+ /// isCPlusPlus - Language is a C++ variant.
+ bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
+
+ /// isCPlusPlus0x - Language is a C++0x variant.
+ bool isCPlusPlus0x() const { return Flags & frontend::CPlusPlus0x; }
+
+ /// 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(llvm::StringRef Name);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def
new file mode 100644
index 0000000..52aa463
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def
@@ -0,0 +1,83 @@
+//===-- 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",
+ ImplicitInt)
+LANGSTANDARD(c90, "c90",
+ "ISO C 1990",
+ ImplicitInt)
+LANGSTANDARD(iso9899_1990, "iso9899:1990",
+ "ISO C 1990",
+ ImplicitInt)
+
+LANGSTANDARD(c94, "iso9899:199409",
+ "ISO C 1990 with amendment 1",
+ Digraphs | ImplicitInt)
+
+LANGSTANDARD(gnu89, "gnu89",
+ "ISO C 1990 with GNU extensions",
+ BCPLComment | Digraphs | GNUMode | ImplicitInt)
+
+// C99-ish modes
+LANGSTANDARD(c99, "c99",
+ "ISO C 1999",
+ BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(c9x, "c9x",
+ "ISO C 1999",
+ BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_1999,
+ "iso9899:1999", "ISO C 1999",
+ BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_199x,
+ "iso9899:199x", "ISO C 1999",
+ BCPLComment | C99 | Digraphs | HexFloat)
+
+LANGSTANDARD(gnu99, "gnu99",
+ "ISO C 1999 with GNU extensions",
+ BCPLComment | C99 | Digraphs | GNUMode | HexFloat | Digraphs)
+LANGSTANDARD(gnu9x, "gnu9x",
+ "ISO C 1999 with GNU extensions",
+ BCPLComment | C99 | Digraphs | GNUMode | HexFloat)
+
+// C++ modes
+LANGSTANDARD(cxx98, "c++98",
+ "ISO C++ 1998 with amendments",
+ BCPLComment | CPlusPlus | Digraphs)
+LANGSTANDARD(gnucxx98, "gnu++98",
+ "ISO C++ 1998 with " "amendments and GNU extensions",
+ BCPLComment | CPlusPlus | Digraphs | GNUMode)
+
+LANGSTANDARD(cxx0x, "c++0x",
+ "Upcoming ISO C++ 200x with amendments",
+ BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs)
+LANGSTANDARD(gnucxx0x, "gnu++0x",
+ "Upcoming ISO C++ 200x with amendments and GNU extensions",
+ BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode)
+
+// OpenCL
+
+LANGSTANDARD(opencl, "cl",
+ "OpenCL 1.0",
+ BCPLComment | C99 | Digraphs | HexFloat)
+
+#undef LANGSTANDARD
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PCHBitCodes.h b/contrib/llvm/tools/clang/include/clang/Frontend/PCHBitCodes.h
new file mode 100644
index 0000000..2493cfd
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/PCHBitCodes.h
@@ -0,0 +1,783 @@
+//===- PCHBitCodes.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 precompiled header 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_FRONTEND_PCHBITCODES_H
+#define LLVM_CLANG_FRONTEND_PCHBITCODES_H
+
+#include "llvm/Bitcode/BitCodes.h"
+#include "llvm/System/DataTypes.h"
+
+namespace clang {
+ namespace pch {
+ /// \brief PCH major version number supported by this version of
+ /// Clang.
+ ///
+ /// Whenever the PCH 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 3 of PCH files also requires that the version control branch and
+ /// revision match exactly, since there is no backward compatibility of
+ /// PCH files at this time.
+ const unsigned VERSION_MAJOR = 3;
+
+ /// \brief PCH minor version number supported by this version of
+ /// Clang.
+ ///
+ /// Whenever the PCH 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 a declaration in a PCH file.
+ ///
+ /// The ID numbers of types are consecutive (in order of
+ /// discovery) and start at 2. 0 is reserved for NULL, and 1 is
+ /// reserved for the translation unit declaration.
+ typedef uint32_t DeclID;
+
+ /// \brief An ID number that refers to a type in a PCH 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 An ID number that refers to an identifier in a PCH
+ /// file.
+ typedef uint32_t IdentID;
+
+ typedef uint32_t SelectorID;
+
+ /// \brief Describes the various kinds of blocks that occur within
+ /// a PCH file.
+ enum BlockIDs {
+ /// \brief The PCH block, which acts as a container around the
+ /// full PCH block.
+ PCH_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 PCH file.
+ DECLTYPES_BLOCK_ID
+ };
+
+ /// \brief Record types that occur within the PCH block itself.
+ enum PCHRecordTypes {
+ /// \brief Record code for the offsets of each type.
+ ///
+ /// The TYPE_OFFSET constant describes the record that occurs
+ /// within the PCH 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 PCH 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 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 = 3,
+
+ /// \brief PCH metadata, including the PCH file version number
+ /// and the target triple used to build the PCH file.
+ METADATA = 4,
+
+ /// \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 = 5,
+
+ /// \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 PCH 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 = 6,
+
+ /// \brief Record code for the array of external definitions.
+ ///
+ /// The PCH file contains a list of all of the unnamed external
+ /// definitions present within the parsed headers, stored as an
+ /// array of declaration IDs. These external definitions will be
+ /// reported to the AST consumer after the PCH file has been
+ /// read, since their presence can affect the semantics of the
+ /// program (e.g., for code generation).
+ EXTERNAL_DEFINITIONS = 7,
+
+ /// \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 = 8,
+
+ /// \brief Record code for the extra statistics we gather while
+ /// generating a PCH file.
+ STATISTICS = 9,
+
+ /// \brief Record code for the array of tentative definitions.
+ TENTATIVE_DEFINITIONS = 10,
+
+ /// \brief Record code for the array of locally-scoped external
+ /// declarations.
+ LOCALLY_SCOPED_EXTERNAL_DECLS = 11,
+
+ /// \brief Record code for the table of offsets into the
+ /// Objective-C method pool.
+ SELECTOR_OFFSETS = 12,
+
+ /// \brief Record code for the Objective-C method pool,
+ METHOD_POOL = 13,
+
+ /// \brief The value of the next __COUNTER__ to dispense.
+ /// [PP_COUNTER_VALUE, Val]
+ PP_COUNTER_VALUE = 14,
+
+ /// \brief Record code for the table of offsets into the block
+ /// of source-location information.
+ SOURCE_LOCATION_OFFSETS = 15,
+
+ /// \brief Record code for the set of source location entries
+ /// that need to be preloaded by the PCH 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 = 16,
+
+ /// \brief Record code for the stat() cache.
+ STAT_CACHE = 17,
+
+ /// \brief Record code for the set of ext_vector type names.
+ EXT_VECTOR_DECLS = 18,
+
+ /// \brief Record code for the original file that was used to
+ /// generate the precompiled header.
+ ORIGINAL_FILE_NAME = 19,
+
+ /// Record #20 intentionally left blank.
+
+ /// \brief Record code for the version control branch and revision
+ /// information of the compiler used to build this PCH file.
+ VERSION_CONTROL_BRANCH_REVISION = 21,
+
+ /// \brief Record code for the array of unused static functions.
+ UNUSED_STATIC_FUNCS = 22,
+
+ /// \brief Record code for the table of offsets to macro definition
+ /// entries in the preprocessing record.
+ MACRO_DEFINITION_OFFSETS = 23
+ };
+
+ /// \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.
+ SM_SLOC_BUFFER_BLOB = 3,
+ /// \brief Describes a source location entry (SLocEntry) for a
+ /// macro instantiation.
+ SM_SLOC_INSTANTIATION_ENTRY = 4,
+ /// \brief Describes the SourceManager's line table, with
+ /// information about #line directives.
+ SM_LINE_TABLE = 5
+ };
+
+ /// \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 Describes a macro instantiation within the preprocessing
+ /// record.
+ PP_MACRO_INSTANTIATION = 4,
+
+ /// \brief Describes a macro definition within the preprocessing record.
+ PP_MACRO_DEFINITION = 5
+ };
+
+ /// \defgroup PCHAST Precompiled header AST constants
+ ///
+ /// The constants in this group describe various components of the
+ /// abstract syntax tree within a precompiled header.
+ ///
+ /// @{
+
+ /// \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 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 PCH 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 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 __builtin_va_list
+ SPECIAL_TYPE_BUILTIN_VA_LIST = 0,
+ /// \brief Objective-C "id" type
+ SPECIAL_TYPE_OBJC_ID = 1,
+ /// \brief Objective-C selector type
+ SPECIAL_TYPE_OBJC_SELECTOR = 2,
+ /// \brief Objective-C Protocol type
+ SPECIAL_TYPE_OBJC_PROTOCOL = 3,
+ /// \brief Objective-C Class type
+ SPECIAL_TYPE_OBJC_CLASS = 4,
+ /// \brief CFConstantString type
+ SPECIAL_TYPE_CF_CONSTANT_STRING = 5,
+ /// \brief Objective-C fast enumeration state type
+ SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE = 6,
+ /// \brief C FILE typedef type
+ SPECIAL_TYPE_FILE = 7,
+ /// \brief C jmp_buf typedef type
+ SPECIAL_TYPE_jmp_buf = 8,
+ /// \brief C sigjmp_buf typedef type
+ SPECIAL_TYPE_sigjmp_buf = 9,
+ /// \brief Objective-C "id" redefinition type
+ SPECIAL_TYPE_OBJC_ID_REDEFINITION = 10,
+ /// \brief Objective-C "Class" redefinition type
+ SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 11,
+ /// \brief Block descriptor type for Blocks CodeGen
+ SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12,
+ /// \brief Block extedned descriptor type for Blocks CodeGen
+ SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13,
+ /// \brief Objective-C "SEL" redefinition type
+ SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 14,
+ /// \brief NSConstantString type
+ SPECIAL_TYPE_NS_CONSTANT_STRING = 15
+ };
+
+ /// \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 Attributes attached to a declaration.
+ DECL_ATTR = 50,
+ /// \brief A TranslationUnitDecl record.
+ DECL_TRANSLATION_UNIT,
+ /// \brief A TypedefDecl record.
+ DECL_TYPEDEF,
+ /// \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 ObjCClassDecl record.
+ DECL_OBJC_CLASS,
+ /// \brief A ObjCForwardProtocolDecl record.
+ DECL_OBJC_FORWARD_PROTOCOL,
+ /// \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 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 record that stores the set of declarations that are
+ /// lexically stored within a given DeclContext.
+ ///
+ /// The record itself 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()/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 NamespaceDecl rcord.
+ 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,
+
+ // FIXME: Implement serialization for these decl types. This just
+ // allocates the order in which
+ DECL_FRIEND,
+ DECL_FRIEND_TEMPLATE,
+ DECL_TEMPLATE,
+ DECL_CLASS_TEMPLATE,
+ DECL_CLASS_TEMPLATE_SPECIALIZATION,
+ DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
+ DECL_FUNCTION_TEMPLATE,
+ DECL_TEMPLATE_TYPE_PARM,
+ DECL_NON_TYPE_TEMPLATE_PARM,
+ DECL_TEMPLATE_TEMPLATE_PARM,
+ DECL_STATIC_ASSERT
+ };
+
+ /// \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 100. 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 = 100,
+ /// \brief A NULL expression.
+ STMT_NULL_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 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 An AsmStmt record.
+ STMT_ASM,
+ /// \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 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 An ImplicitValueInitExpr record.
+ EXPR_IMPLICIT_VALUE_INIT,
+ /// \brief A VAArgExpr record.
+ EXPR_VA_ARG,
+ /// \brief An AddrLabelExpr record.
+ EXPR_ADDR_LABEL,
+ /// \brief A StmtExpr record.
+ EXPR_STMT,
+ /// \brief A TypesCompatibleExpr record.
+ EXPR_TYPES_COMPATIBLE,
+ /// \brief A ChooseExpr record.
+ EXPR_CHOOSE,
+ /// \brief A GNUNullExpr record.
+ EXPR_GNU_NULL,
+ /// \brief A ShuffleVectorExpr record.
+ EXPR_SHUFFLE_VECTOR,
+ /// \brief BlockExpr
+ EXPR_BLOCK,
+ /// \brief A BlockDeclRef record.
+ EXPR_BLOCK_DECL_REF,
+
+ // Objective-C
+
+ /// \brief An ObjCStringLiteral record.
+ EXPR_OBJC_STRING_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 ObjCImplicitSetterGetterRefExpr record.
+ EXPR_OBJC_KVC_REF_EXPR,
+ /// \brief An ObjCMessageExpr record.
+ EXPR_OBJC_MESSAGE_EXPR,
+ /// \brief An ObjCSuperExpr record.
+ EXPR_OBJC_SUPER_EXPR,
+ /// \brief An ObjCIsa Expr record.
+ EXPR_OBJC_ISA,
+
+ /// \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,
+
+ // C++
+
+ /// \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 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 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_BIND_TEMPORARY, // CXXBindTemporaryExpr
+ //
+ EXPR_CXX_ZERO_INIT_VALUE, // CXXZeroInitValueExpr
+ EXPR_CXX_NEW, // CXXNewExpr
+
+ EXPR_CXX_EXPR_WITH_TEMPORARIES // CXXExprWithTemporaries
+ };
+
+ /// \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
+ };
+
+ /// @}
+ }
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PCHReader.h b/contrib/llvm/tools/clang/include/clang/Frontend/PCHReader.h
new file mode 100644
index 0000000..e144738
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/PCHReader.h
@@ -0,0 +1,827 @@
+//===--- PCHReader.h - Precompiled Headers 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 PCHReader class, which reads a precompiled header.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PCH_READER_H
+#define LLVM_CLANG_FRONTEND_PCH_READER_H
+
+#include "clang/Frontend/PCHBitCodes.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/System/DataTypes.h"
+#include <deque>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+ class MemoryBuffer;
+}
+
+namespace clang {
+
+class AddrLabelExpr;
+class ASTConsumer;
+class ASTContext;
+class Attr;
+class Decl;
+class DeclContext;
+class NestedNameSpecifier;
+class CXXBaseSpecifier;
+class CXXBaseOrMemberInitializer;
+class GotoStmt;
+class LabelStmt;
+class MacroDefinition;
+class NamedDecl;
+class Preprocessor;
+class Sema;
+class SwitchCase;
+class PCHReader;
+struct HeaderFileInfo;
+
+/// \brief Abstract interface for callback invocations by the PCHReader.
+///
+/// While reading a PCH file, the PCHReader will call the methods of the
+/// listener to pass on specific information. Some of the listener methods can
+/// return true to indicate to the PCHReader that the information (and
+/// consequently the PCH file) is invalid.
+class PCHReaderListener {
+public:
+ virtual ~PCHReaderListener();
+
+ /// \brief Receives the language options.
+ ///
+ /// \returns true to indicate the options are invalid or false otherwise.
+ virtual bool ReadLanguageOptions(const LangOptions &LangOpts) {
+ return false;
+ }
+
+ /// \brief Receives the target triple.
+ ///
+ /// \returns true to indicate the target triple is invalid or false otherwise.
+ virtual bool ReadTargetTriple(llvm::StringRef Triple) {
+ return false;
+ }
+
+ /// \brief Receives the contents of the predefines buffer.
+ ///
+ /// \param PCHPredef The start of the predefines buffer in the PCH
+ /// file.
+ ///
+ /// \param PCHBufferID The FileID for the PCH predefines buffer.
+ ///
+ /// \param OriginalFileName The original file name for the PCH, which will
+ /// appear as an entry in the predefines buffer.
+ ///
+ /// \param SuggestedPredefines If necessary, additional definitions are added
+ /// here.
+ ///
+ /// \returns true to indicate the predefines are invalid or false otherwise.
+ virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
+ FileID PCHBufferID,
+ llvm::StringRef OriginalFileName,
+ std::string &SuggestedPredefines) {
+ return false;
+ }
+
+ /// \brief Receives a HeaderFileInfo entry.
+ virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {}
+
+ /// \brief Receives __COUNTER__ value.
+ virtual void ReadCounter(unsigned Value) {}
+};
+
+/// \brief PCHReaderListener implementation to validate the information of
+/// the PCH file against an initialized Preprocessor.
+class PCHValidator : public PCHReaderListener {
+ Preprocessor &PP;
+ PCHReader &Reader;
+
+ unsigned NumHeaderInfos;
+
+public:
+ PCHValidator(Preprocessor &PP, PCHReader &Reader)
+ : PP(PP), Reader(Reader), NumHeaderInfos(0) {}
+
+ virtual bool ReadLanguageOptions(const LangOptions &LangOpts);
+ virtual bool ReadTargetTriple(llvm::StringRef Triple);
+ virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
+ FileID PCHBufferID,
+ llvm::StringRef OriginalFileName,
+ std::string &SuggestedPredefines);
+ virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID);
+ virtual void ReadCounter(unsigned Value);
+
+private:
+ void Error(const char *Msg);
+};
+
+/// \brief Reads a precompiled head containing the contents of a
+/// translation unit.
+///
+/// The PCHReader class reads a bitstream (produced by the PCHWriter
+/// class) containing the serialized representation of a given
+/// abstract syntax tree and its supporting data structures. An
+/// instance of the PCHReader can be attached to an ASTContext object,
+/// which will provide access to the contents of the PCH file.
+///
+/// The PCH 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 PCHReader
+ : public ExternalPreprocessorSource,
+ public ExternalPreprocessingRecordSource,
+ public ExternalSemaSource,
+ public IdentifierInfoLookup,
+ public ExternalIdentifierLookup,
+ public ExternalSLocEntrySource {
+public:
+ enum PCHReadResult { Success, Failure, IgnorePCH };
+ friend class PCHValidator;
+private:
+ /// \ brief The receiver of some callbacks invoked by PCHReader.
+ llvm::OwningPtr<PCHReaderListener> Listener;
+
+ SourceManager &SourceMgr;
+ FileManager &FileMgr;
+ Diagnostic &Diags;
+
+ /// \brief The semantic analysis object that will be processing the
+ /// PCH file 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 PCH file.
+ ASTContext *Context;
+
+ /// \brief The PCH stat cache installed by this PCHReader, if any.
+ ///
+ /// The dynamic type of this stat cache is always PCHStatCache
+ void *StatCache;
+
+ /// \brief The AST consumer.
+ ASTConsumer *Consumer;
+
+ /// \brief The bitstream reader from which we'll read the PCH file.
+ llvm::BitstreamReader StreamFile;
+ llvm::BitstreamCursor Stream;
+
+ /// \brief The cursor to the start of the preprocessor block, which stores
+ /// all of the macro definitions.
+ llvm::BitstreamCursor MacroCursor;
+
+ /// 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 file name of the PCH file.
+ std::string FileName;
+
+ /// \brief The memory buffer that stores the data associated with
+ /// this PCH file.
+ llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+
+ /// \brief Offset type for all of the source location entries in the
+ /// PCH file.
+ const uint32_t *SLocOffsets;
+
+ /// \brief The number of source location entries in the PCH file.
+ unsigned TotalNumSLocEntries;
+
+ /// \brief Cursor used to read source location entries.
+ llvm::BitstreamCursor SLocEntryCursor;
+
+ /// \brief Offset of each type within the bitstream, indexed by the
+ /// type ID, or the representation of a Type*.
+ const uint32_t *TypeOffsets;
+
+ /// \brief Types that have already been loaded from the PCH file.
+ ///
+ /// When the pointer at index I is non-NULL, the type with
+ /// ID = (I + 1) << 3 has already been loaded from the PCH file.
+ std::vector<QualType> TypesLoaded;
+
+ /// \brief Offset of each declaration within the bitstream, indexed
+ /// by the declaration ID (-1).
+ const uint32_t *DeclOffsets;
+
+ /// \brief Declarations that have already been loaded from the PCH file.
+ ///
+ /// When the pointer at index I is non-NULL, the declaration with ID
+ /// = I + 1 has already been loaded.
+ std::vector<Decl *> DeclsLoaded;
+
+ typedef llvm::DenseMap<const DeclContext *, std::pair<uint64_t, uint64_t> >
+ DeclContextOffsetsMap;
+
+ /// \brief Offsets of the lexical and visible declarations for each
+ /// DeclContext.
+ DeclContextOffsetsMap DeclContextOffsets;
+
+ /// \brief Actual data for the on-disk hash table.
+ ///
+ // 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 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 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;
+
+ /// \brief A pointer to an on-disk hash table of opaque type
+ /// PCHMethodPoolLookupTable.
+ ///
+ /// This hash table provides the instance and factory methods
+ /// associated with every selector known in the PCH file.
+ void *MethodPoolLookupTable;
+
+ /// \brief A pointer to the character data that comprises the method
+ /// pool.
+ ///
+ /// The SelectorOffsets table refers into this memory.
+ const unsigned char *MethodPoolLookupTableData;
+
+ /// \brief The number of selectors stored in the method pool itself.
+ unsigned TotalSelectorsInMethodPool;
+
+ /// \brief Offsets into the method pool lookup table's data array
+ /// where each selector resides.
+ const uint32_t *SelectorOffsets;
+
+ /// \brief The total number of selectors stored in the PCH file.
+ unsigned TotalNumSelectors;
+
+ /// \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.
+ llvm::SmallVector<Selector, 16> SelectorsLoaded;
+
+ /// \brief Offsets of all of the macro definitions in the preprocessing
+ /// record in the PCH file.
+ const uint32_t *MacroDefinitionOffsets;
+
+ /// \brief The macro definitions we have already loaded.
+ llvm::SmallVector<MacroDefinition *, 16> MacroDefinitionsLoaded;
+
+ /// \brief The number of preallocated preprocessing entities in the
+ /// preprocessing record.
+ unsigned NumPreallocatedPreprocessingEntities;
+
+ /// \brief The set of external definitions stored in the the PCH
+ /// file.
+ llvm::SmallVector<uint64_t, 16> ExternalDefinitions;
+
+ /// \brief The set of tentative definitions stored in the the PCH
+ /// file.
+ llvm::SmallVector<uint64_t, 16> TentativeDefinitions;
+
+ /// \brief The set of tentative definitions stored in the the PCH
+ /// file.
+ llvm::SmallVector<uint64_t, 16> UnusedStaticFuncs;
+
+ /// \brief The set of locally-scoped external declarations stored in
+ /// the the PCH file.
+ llvm::SmallVector<uint64_t, 16> LocallyScopedExternalDecls;
+
+ /// \brief The set of ext_vector type declarations stored in the the
+ /// PCH file.
+ llvm::SmallVector<uint64_t, 4> ExtVectorDecls;
+
+ /// \brief The set of Objective-C category definitions stored in the
+ /// the PCH file.
+ llvm::SmallVector<uint64_t, 4> ObjCCategoryImpls;
+
+ /// \brief The original file name that was used to build the PCH file, which
+ /// may have been modified for relocatable-pch support.
+ std::string OriginalFileName;
+
+ /// \brief The actual original file name that was used to build the PCH file.
+ std::string ActualOriginalFileName;
+
+ /// \brief Whether this precompiled header is a relocatable PCH file.
+ bool RelocatablePCH;
+
+ /// \brief The system include root to be used when loading the
+ /// precompiled header.
+ const char *isysroot;
+
+ /// \brief Mapping from switch-case IDs in the PCH file to
+ /// switch-case statements.
+ std::map<unsigned, SwitchCase *> SwitchCaseStmts;
+
+ /// \brief Mapping from label statement IDs in the PCH file to label
+ /// statements.
+ std::map<unsigned, LabelStmt *> LabelStmts;
+
+ /// \brief Mapping from label IDs to the set of "goto" statements
+ /// that point to that label before the label itself has been
+ /// de-serialized.
+ std::multimap<unsigned, GotoStmt *> UnresolvedGotoStmts;
+
+ /// \brief Mapping from label IDs to the set of address label
+ /// expressions that point to that label before the label itself has
+ /// been de-serialized.
+ std::multimap<unsigned, AddrLabelExpr *> UnresolvedAddrLabelExprs;
+
+ /// \brief The number of stat() calls that hit/missed the stat
+ /// cache.
+ unsigned NumStatHits, NumStatMisses;
+
+ /// \brief The number of source location entries de-serialized from
+ /// the PCH file.
+ unsigned NumSLocEntriesRead;
+
+ /// \brief The number of statements (and expressions) de-serialized
+ /// from the PCH file.
+ unsigned NumStatementsRead;
+
+ /// \brief The total number of statements (and expressions) stored
+ /// in the PCH file.
+ unsigned TotalNumStatements;
+
+ /// \brief The number of macros de-serialized from the PCH file.
+ unsigned NumMacrosRead;
+
+ /// \brief The number of method pool entries that have been read.
+ unsigned NumMethodPoolSelectorsRead;
+
+ /// \brief The number of times we have looked into the global method
+ /// pool and not found anything.
+ unsigned NumMethodPoolMisses;
+
+ /// \brief The total number of macros stored in the PCH file.
+ unsigned TotalNumMacros;
+
+ /// Number of lexical decl contexts read/total.
+ unsigned NumLexicalDeclContextsRead, TotalLexicalDeclContexts;
+
+ /// Number of visible decl contexts read/total.
+ unsigned NumVisibleDeclContextsRead, TotalVisibleDeclContexts;
+
+ /// \brief When a type or declaration is being loaded from the PCH file, an
+ /// instantance of this RAII object will be available on the stack to
+ /// indicate when we are in a recursive-loading situation.
+ class LoadingTypeOrDecl {
+ PCHReader &Reader;
+ LoadingTypeOrDecl *Parent;
+
+ LoadingTypeOrDecl(const LoadingTypeOrDecl&); // do not implement
+ LoadingTypeOrDecl &operator=(const LoadingTypeOrDecl&); // do not implement
+
+ public:
+ explicit LoadingTypeOrDecl(PCHReader &Reader);
+ ~LoadingTypeOrDecl();
+ };
+ friend class LoadingTypeOrDecl;
+
+ /// \brief If we are currently loading a type or declaration, points to the
+ /// most recent LoadingTypeOrDecl object on the stack.
+ LoadingTypeOrDecl *CurrentlyLoadingTypeOrDecl;
+
+ /// \brief An IdentifierInfo that has been loaded but whose top-level
+ /// declarations of the same name have not (yet) been loaded.
+ struct PendingIdentifierInfo {
+ IdentifierInfo *II;
+ llvm::SmallVector<uint32_t, 4> DeclIDs;
+ };
+
+ /// \brief The set of identifiers that were read while the PCH reader was
+ /// (recursively) loading declarations.
+ ///
+ /// The declarations on the identifier chain for these identifiers will be
+ /// loaded once the recursive loading has completed.
+ std::deque<PendingIdentifierInfo> PendingIdentifierInfos;
+
+ /// \brief FIXME: document!
+ llvm::SmallVector<uint64_t, 16> SpecialTypes;
+
+ /// \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.
+ llvm::SmallVector<Decl *, 16> InterestingDecls;
+
+ /// \brief The file ID for the predefines buffer in the PCH file.
+ FileID PCHPredefinesBufferID;
+
+ /// \brief Pointer to the beginning of the predefines buffer in the
+ /// PCH file.
+ const char *PCHPredefines;
+
+ /// \brief Length of the predefines buffer in the PCH file.
+ unsigned PCHPredefinesLen;
+
+ /// \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;
+
+ void MaybeAddSystemRootToFilename(std::string &Filename);
+
+ PCHReadResult ReadPCHBlock();
+ bool CheckPredefinesBuffer(llvm::StringRef PCHPredef, FileID PCHBufferID);
+ bool ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record);
+ PCHReadResult ReadSourceManagerBlock();
+ PCHReadResult ReadSLocEntryRecord(unsigned ID);
+
+ bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record);
+ QualType ReadTypeRecord(uint64_t Offset);
+ void LoadedDecl(unsigned Index, Decl *D);
+ Decl *ReadDeclRecord(uint64_t Offset, unsigned Index);
+
+ /// \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 PCH file).
+ void Error(const char *Msg);
+
+ PCHReader(const PCHReader&); // do not implement
+ PCHReader &operator=(const PCHReader &); // do not implement
+public:
+ typedef llvm::SmallVector<uint64_t, 64> RecordData;
+
+ /// \brief Load the PCH 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 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 "/".
+ PCHReader(Preprocessor &PP, ASTContext *Context, const char *isysroot = 0);
+
+ /// \brief Load the PCH file without using any pre-initialized Preprocessor.
+ ///
+ /// The necessary information to initialize a Preprocessor later can be
+ /// obtained by setting a PCHReaderListener.
+ ///
+ /// \param SourceMgr the source manager into which the precompiled header
+ /// will be loaded.
+ ///
+ /// \param FileMgr the file manager into which the precompiled header will
+ /// be loaded.
+ ///
+ /// \param Diags the diagnostics system to use for reporting errors and
+ /// warnings relevant to loading the precompiled header.
+ ///
+ /// \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 "/".
+ PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
+ Diagnostic &Diags, const char *isysroot = 0);
+ ~PCHReader();
+
+ /// \brief Load the precompiled header designated by the given file
+ /// name.
+ PCHReadResult ReadPCH(const std::string &FileName);
+
+ /// \brief Set the PCH callbacks listener.
+ void setListener(PCHReaderListener *listener) {
+ Listener.reset(listener);
+ }
+
+ /// \brief Set the Preprocessor to use.
+ void setPreprocessor(Preprocessor &pp);
+
+ /// \brief Sets and initializes the given Context.
+ void InitializeContext(ASTContext &Context);
+
+ /// \brief Retrieve the name of the PCH file
+ const std::string &getFileName() { return FileName; }
+
+ /// \brief Retrieve the name of the original source file name
+ const std::string &getOriginalSourceFile() { return OriginalFileName; }
+
+ /// \brief Retrieve the name of the original source file name
+ /// directly from the PCH file, without actually loading the PCH
+ /// file.
+ static std::string getOriginalSourceFile(const std::string &PCHFileName,
+ Diagnostic &Diags);
+
+ /// \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 preprocessed entities into the
+ virtual void ReadPreprocessedEntities();
+
+ /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+ /// given TemplateArgument kind.
+ TemplateArgumentLocInfo
+ GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+ const RecordData &Record, unsigned &Idx);
+
+ /// \brief Reads a declarator info from the given record.
+ virtual TypeSourceInfo *GetTypeSourceInfo(const RecordData &Record,
+ unsigned &Idx);
+
+ /// \brief Resolve a type ID into a type, potentially building a new
+ /// type.
+ virtual QualType GetType(pch::TypeID ID);
+
+ /// \brief Resolve a declaration ID into a declaration, potentially
+ /// building a new declaration.
+ virtual Decl *GetDecl(pch::DeclID ID);
+
+ /// \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).
+ virtual Stmt *GetDeclStmt(uint64_t Offset);
+
+ /// 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.
+ bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID);
+
+ /// \brief Read all of the declarations lexically stored in a
+ /// declaration context.
+ ///
+ /// \param DC The declaration context whose declarations will be
+ /// read.
+ ///
+ /// \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.
+ ///
+ /// \returns true if there was an error while reading the
+ /// declarations for this declaration context.
+ virtual bool ReadDeclsLexicallyInContext(DeclContext *DC,
+ llvm::SmallVectorImpl<pch::DeclID> &Decls);
+
+ /// \brief Read all of the declarations visible from a declaration
+ /// context.
+ ///
+ /// \param DC The declaration context whose visible declarations
+ /// will be read.
+ ///
+ /// \param Decls A vector of visible declaration structures,
+ /// providing the mapping from each name visible in the declaration
+ /// context to the declaration IDs of declarations with that name.
+ ///
+ /// \returns true if there was an error while reading the
+ /// declarations for this declaration context.
+ ///
+ /// FIXME: Using this intermediate data structure results in an
+ /// extraneous copying of the data. Could we pass in a reference to
+ /// the StoredDeclsMap instead?
+ virtual bool ReadDeclsVisibleInContext(DeclContext *DC,
+ llvm::SmallVectorImpl<VisibleDeclaration> & Decls);
+
+ /// \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.
+ virtual void StartTranslationUnit(ASTConsumer *Consumer);
+
+ /// \brief Print some statistics about PCH usage.
+ virtual void PrintStats();
+
+ /// \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() { SemaObj = 0; }
+
+ /// \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.
+ virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd);
+ IdentifierInfo *get(llvm::StringRef Name) {
+ return get(Name.begin(), Name.end());
+ }
+
+ /// \brief Load the contents of the global method pool for a given
+ /// selector.
+ ///
+ /// \returns a pair of Objective-C methods lists containing the
+ /// instance and factory methods, respectively, with this selector.
+ virtual std::pair<ObjCMethodList, ObjCMethodList>
+ ReadMethodPool(Selector Sel);
+
+ void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
+ void SetGloballyVisibleDecls(IdentifierInfo *II,
+ const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
+ bool Nonrecursive = false);
+
+ /// \brief Report a diagnostic.
+ DiagnosticBuilder Diag(unsigned DiagID);
+
+ /// \brief Report a diagnostic.
+ DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+
+ IdentifierInfo *DecodeIdentifierInfo(unsigned Idx);
+
+ IdentifierInfo *GetIdentifierInfo(const RecordData &Record, unsigned &Idx) {
+ return DecodeIdentifierInfo(Record[Idx++]);
+ }
+
+ virtual IdentifierInfo *GetIdentifier(unsigned ID) {
+ return DecodeIdentifierInfo(ID);
+ }
+
+ /// \brief Read the source location entry with index ID.
+ virtual void ReadSLocEntry(unsigned ID);
+
+ Selector DecodeSelector(unsigned Idx);
+
+ virtual Selector GetSelector(uint32_t ID);
+ virtual uint32_t GetNumKnownSelectors();
+
+ Selector GetSelector(const RecordData &Record, unsigned &Idx) {
+ return DecodeSelector(Record[Idx++]);
+ }
+
+ /// \brief Read a declaration name.
+ DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx);
+
+ NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
+ unsigned &Idx);
+
+ /// \brief Read a source location.
+ SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
+ return SourceLocation::getFromRawEncoding(Record[Idx++]);
+ }
+
+ /// \brief Read a source range.
+ SourceRange ReadSourceRange(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, unsigned &Idx);
+
+ // \brief Read a string
+ std::string ReadString(const RecordData &Record, unsigned &Idx);
+
+ CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx);
+
+ /// \brief Reads attributes from the current stream position.
+ Attr *ReadAttributes();
+
+ /// \brief ReadDeclExpr - Reads an expression from the current decl cursor.
+ Expr *ReadDeclExpr();
+
+ /// \brief ReadTypeExpr - Reads an expression from the current type cursor.
+ Expr *ReadTypeExpr();
+
+ /// \brief Reads a statement from the specified cursor.
+ Stmt *ReadStmt(llvm::BitstreamCursor &Cursor);
+
+ /// \brief Read a statement from the current DeclCursor.
+ Stmt *ReadDeclStmt() {
+ return ReadStmt(DeclsCursor);
+ }
+
+ /// \brief Reads the macro record located at the given offset.
+ void ReadMacroRecord(uint64_t Offset);
+
+ /// \brief Read the set of macros defined by this external macro source.
+ virtual void ReadDefinedMacros();
+
+ /// \brief Retrieve the macro definition with the given ID.
+ MacroDefinition *getMacroDefinition(pch::IdentID ID);
+
+ /// \brief Retrieve the AST context that this PCH reader
+ /// supplements.
+ ASTContext *getContext() { return Context; }
+
+ // \brief Contains declarations that were loaded before we have
+ // access to a Sema object.
+ llvm::SmallVector<NamedDecl *, 16> PreloadedDecls;
+
+ /// \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 stream that this PCH reader is reading from.
+ llvm::BitstreamCursor &getStream() { return Stream; }
+ llvm::BitstreamCursor &getDeclsCursor() { return DeclsCursor; }
+
+ /// \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);
+
+ /// \brief Record that the given label statement has been
+ /// deserialized and has the given ID.
+ void RecordLabelStmt(LabelStmt *S, unsigned ID);
+
+ /// \brief Set the label of the given statement to the label
+ /// identified by ID.
+ ///
+ /// Depending on the order in which the label and other statements
+ /// referencing that label occur, this operation may complete
+ /// immediately (updating the statement) or it may queue the
+ /// statement to be back-patched later.
+ void SetLabelOf(GotoStmt *S, unsigned ID);
+
+ /// \brief Set the label of the given expression to the label
+ /// identified by ID.
+ ///
+ /// Depending on the order in which the label and other statements
+ /// referencing that label occur, this operation may complete
+ /// immediately (updating the statement) or it may queue the
+ /// statement to be back-patched later.
+ void SetLabelOf(AddrLabelExpr *S, unsigned ID);
+};
+
+/// \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/contrib/llvm/tools/clang/include/clang/Frontend/PCHWriter.h b/contrib/llvm/tools/clang/include/clang/Frontend/PCHWriter.h
new file mode 100644
index 0000000..85f53b9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/PCHWriter.h
@@ -0,0 +1,362 @@
+//===--- PCHWriter.h - Precompiled Headers 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 PCHWriter class, which writes a precompiled
+// header containing a serialized representation of a translation
+// unit.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_PCH_WRITER_H
+#define LLVM_CLANG_FRONTEND_PCH_WRITER_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Frontend/PCHBitCodes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include <map>
+#include <queue>
+
+namespace llvm {
+ class APFloat;
+ class APInt;
+ class BitstreamWriter;
+}
+
+namespace clang {
+
+class ASTContext;
+class NestedNameSpecifier;
+class CXXBaseSpecifier;
+class CXXBaseOrMemberInitializer;
+class LabelStmt;
+class MacroDefinition;
+class MemorizeStatCalls;
+class Preprocessor;
+class Sema;
+class SourceManager;
+class SwitchCase;
+class TargetInfo;
+
+/// 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 Writes a precompiled header containing the contents of a
+/// translation unit.
+///
+/// The PCHWriter 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 PCHReader class.
+class PCHWriter {
+public:
+ typedef llvm::SmallVector<uint64_t, 64> RecordData;
+
+private:
+ /// \brief The bitstream writer used to emit this precompiled header.
+ llvm::BitstreamWriter &Stream;
+
+ /// \brief Stores a declaration or a type to be written to the PCH 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 Map that provides the ID numbers of each declaration within
+ /// the output stream.
+ ///
+ /// 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 *, pch::DeclID> DeclIDs;
+
+ /// \brief Offset of each declaration in the bitstream, indexed by
+ /// the declaration's ID.
+ std::vector<uint32_t> DeclOffsets;
+
+ /// \brief Map that provides the ID numbers of each type within the
+ /// output stream.
+ ///
+ /// 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.
+ llvm::DenseMap<QualType, pch::TypeID, UnsafeQualTypeDenseMapInfo> TypeIDs;
+
+ /// \brief Offset of each type in the bitstream, indexed by
+ /// the type's ID.
+ std::vector<uint32_t> TypeOffsets;
+
+ /// \brief The type ID that will be assigned to the next new type.
+ pch::TypeID NextTypeID;
+
+ /// \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::DenseMap<const IdentifierInfo *, pch::IdentID> IdentifierIDs;
+
+ /// \brief Offsets of each of the identifier IDs into the identifier
+ /// table.
+ std::vector<uint32_t> IdentifierOffsets;
+
+ /// \brief Map that provides the ID numbers of each Selector.
+ llvm::DenseMap<Selector, pch::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 A vector of all Selectors (ordered by ID).
+ std::vector<Selector> SelVector;
+
+ /// \brief Offsets of each of the macro identifiers into the
+ /// bitstream.
+ ///
+ /// For each identifier that is associated with a macro, this map
+ /// provides the offset into the bitstream where that macro is
+ /// defined.
+ llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets;
+
+ /// \brief Mapping from macro definitions (as they occur in the preprocessing
+ /// record) to the index into the macro definitions table.
+ llvm::DenseMap<const MacroDefinition *, pch::IdentID> MacroDefinitions;
+
+ /// \brief Mapping from the macro definition indices in \c MacroDefinitions
+ /// to the corresponding offsets within the preprocessor block.
+ std::vector<uint32_t> MacroDefinitionOffsets;
+
+ /// \brief Declarations encountered that might be external
+ /// definitions.
+ ///
+ /// We keep track of external definitions (as well as tentative
+ /// definitions) as we are emitting declarations to the PCH
+ /// file. The PCH file contains a separate record for these external
+ /// definitions, which are provided to the AST consumer by the PCH
+ /// 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 EXTERNAL_DEFINITIONS
+ /// record.
+ llvm::SmallVector<uint64_t, 16> ExternalDefinitions;
+
+ /// \brief Statements that we've encountered while serializing a
+ /// declaration or type.
+ llvm::SmallVector<Stmt *, 8> StmtsToEmit;
+
+ /// \brief Mapping from SwitchCase statements to IDs.
+ std::map<SwitchCase *, unsigned> SwitchCaseIDs;
+
+ /// \brief Mapping from LabelStmt statements to IDs.
+ std::map<LabelStmt *, unsigned> LabelIDs;
+
+ /// \brief The number of statements written to the PCH file.
+ unsigned NumStatements;
+
+ /// \brief The number of macros written to the PCH file.
+ unsigned NumMacros;
+
+ /// \brief The number of lexical declcontexts written to the PCH
+ /// file.
+ unsigned NumLexicalDeclContexts;
+
+ /// \brief The number of visible declcontexts written to the PCH
+ /// file.
+ unsigned NumVisibleDeclContexts;
+
+ void WriteBlockInfoBlock();
+ void WriteMetadata(ASTContext &Context, const char *isysroot);
+ void WriteLanguageOptions(const LangOptions &LangOpts);
+ void WriteStatCache(MemorizeStatCalls &StatCalls, const char* isysroot);
+ void WriteSourceManagerBlock(SourceManager &SourceMgr,
+ const Preprocessor &PP,
+ const char* isysroot);
+ void WritePreprocessor(const Preprocessor &PP);
+ void WriteType(QualType T);
+ uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
+ uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
+
+ void WriteMethodPool(Sema &SemaRef);
+ void WriteIdentifierTable(Preprocessor &PP);
+ void WriteAttributeRecord(const Attr *Attr);
+
+ unsigned ParmVarDeclAbbrev;
+ void WriteDeclsBlockAbbrevs();
+ void WriteDecl(ASTContext &Context, Decl *D);
+
+public:
+ /// \brief Create a new precompiled header writer that outputs to
+ /// the given bitstream.
+ PCHWriter(llvm::BitstreamWriter &Stream);
+
+ /// \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 StatCalls the object that cached all of the stat() calls made while
+ /// searching for source files and headers.
+ ///
+ /// \param isysroot if non-NULL, write a relocatable PCH file whose headers
+ /// are relative to the given system root.
+ ///
+ /// \param PPRec Record of the preprocessing actions that occurred while
+ /// preprocessing this file, e.g., macro instantiations
+ void WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+ const char* isysroot);
+
+ /// \brief Emit a source location.
+ void AddSourceLocation(SourceLocation Loc, RecordData &Record);
+
+ /// \brief Emit a source range.
+ void AddSourceRange(SourceRange Range, RecordData &Record);
+
+ /// \brief Emit an integral value.
+ void AddAPInt(const llvm::APInt &Value, RecordData &Record);
+
+ /// \brief Emit a signed integral value.
+ void AddAPSInt(const llvm::APSInt &Value, RecordData &Record);
+
+ /// \brief Emit a floating-point value.
+ void AddAPFloat(const llvm::APFloat &Value, RecordData &Record);
+
+ /// \brief Emit a reference to an identifier.
+ void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
+
+ /// \brief Emit a Selector (which is a smart pointer reference).
+ void AddSelectorRef(Selector, RecordData &Record);
+
+ /// \brief Emit a CXXTemporary.
+ void AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record);
+
+ /// \brief Get the unique number used to refer to the given
+ /// identifier.
+ pch::IdentID getIdentifierRef(const IdentifierInfo *II);
+
+ /// \brief Retrieve the offset of the macro definition for the given
+ /// identifier.
+ ///
+ /// The identifier must refer to a macro.
+ uint64_t getMacroOffset(const IdentifierInfo *II) {
+ assert(MacroOffsets.find(II) != MacroOffsets.end() &&
+ "Identifier does not name a macro");
+ return MacroOffsets[II];
+ }
+
+ /// \brief Retrieve the ID number corresponding to the given macro
+ /// definition.
+ pch::IdentID getMacroDefinitionID(MacroDefinition *MD);
+
+ /// \brief Emit a reference to a type.
+ void AddTypeRef(QualType T, RecordData &Record);
+
+ /// \brief Emits a reference to a declarator info.
+ void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record);
+
+ /// \brief Emits a template argument location.
+ void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+ RecordData &Record);
+
+ /// \brief Emit a reference to a declaration.
+ void AddDeclRef(const Decl *D, RecordData &Record);
+
+ /// \brief Determine the declaration ID of an already-emitted
+ /// declaration.
+ pch::DeclID getDeclID(const Decl *D);
+
+ /// \brief Emit a declaration name.
+ void AddDeclarationName(DeclarationName Name, RecordData &Record);
+
+ /// \brief Emit a nested name specifier.
+ void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record);
+
+ /// \brief Add a string to the given record.
+ void AddString(const std::string &Str, RecordData &Record);
+
+ /// \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) { StmtsToEmit.push_back(S); }
+
+ /// \brief Write the given subexpression to the bitstream.
+ void WriteSubStmt(Stmt *S);
+
+ /// \brief Flush all of the statements and expressions that have
+ /// been added to the queue via AddStmt().
+ void FlushStmts();
+
+ /// \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);
+
+ /// \brief Retrieve the ID for the given label statement, which may
+ /// or may not have been emitted yet.
+ unsigned GetLabelID(LabelStmt *S);
+
+ unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PathDiagnosticClients.h b/contrib/llvm/tools/clang/include/clang/Frontend/PathDiagnosticClients.h
new file mode 100644
index 0000000..f8d2eeb
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/PathDiagnosticClients.h
@@ -0,0 +1,32 @@
+//===--- 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_FRONTEND_PATH_DIAGNOSTIC_CLIENTS_H
+#define LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLiENTS_H
+
+#include <string>
+
+namespace clang {
+
+class PathDiagnosticClient;
+class Preprocessor;
+
+PathDiagnosticClient*
+CreateHTMLDiagnosticClient(const std::string& prefix, const Preprocessor &PP);
+
+PathDiagnosticClient*
+CreatePlistDiagnosticClient(const std::string& prefix, const Preprocessor &PP,
+ PathDiagnosticClient *SubPD = 0);
+
+} // end clang namespace
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h
new file mode 100644
index 0000000..891359b
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h
@@ -0,0 +1,102 @@
+//===--- PreprocessorOptionms.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_PREPROCESSOROPTIONS_H_
+#define LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
+
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+ class MemoryBuffer;
+}
+
+namespace clang {
+
+class Preprocessor;
+class LangOptions;
+
+/// PreprocessorOptions - This class is used for passing the various options
+/// used in preprocessor initialization to InitializePreprocessor().
+class PreprocessorOptions {
+public:
+ std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
+ std::vector<std::string> Includes;
+ std::vector<std::string> MacroIncludes;
+
+ unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
+ /// and target specific predefines.
+
+ unsigned DetailedRecord : 1; /// Whether we should maintain a detailed
+ /// record of all macro definitions and
+ /// instantiations.
+
+ /// The implicit PCH included at the start of the translation unit, or empty.
+ std::string ImplicitPCHInclude;
+
+ /// 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 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, const llvm::MemoryBuffer *> >
+ RemappedFileBuffers;
+
+ typedef std::vector<std::pair<std::string, std::string> >::const_iterator
+ remapped_file_iterator;
+ remapped_file_iterator remapped_file_begin() const {
+ return RemappedFiles.begin();
+ }
+ remapped_file_iterator remapped_file_end() const {
+ return RemappedFiles.end();
+ }
+
+ typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >::
+ const_iterator remapped_file_buffer_iterator;
+ remapped_file_buffer_iterator remapped_file_buffer_begin() const {
+ return RemappedFileBuffers.begin();
+ }
+ remapped_file_buffer_iterator remapped_file_buffer_end() const {
+ return RemappedFileBuffers.end();
+ }
+
+public:
+ PreprocessorOptions() : UsePredefines(true), DetailedRecord(false) {}
+
+ void addMacroDef(llvm::StringRef Name) {
+ Macros.push_back(std::make_pair(Name, false));
+ }
+ void addMacroUndef(llvm::StringRef Name) {
+ Macros.push_back(std::make_pair(Name, true));
+ }
+ void addRemappedFile(llvm::StringRef From, llvm::StringRef To) {
+ RemappedFiles.push_back(std::make_pair(From, To));
+ }
+ void addRemappedFile(llvm::StringRef From, const llvm::MemoryBuffer * To) {
+ RemappedFileBuffers.push_back(std::make_pair(From, To));
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h
new file mode 100644
index 0000000..a712a3d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -0,0 +1,37 @@
+//===--- 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 ShowMacros : 1; ///< Print macro definitions.
+ unsigned ShowLineMarkers : 1; ///< Show #line markers.
+ unsigned ShowComments : 1; ///< Show comments.
+ unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
+
+public:
+ PreprocessorOutputOptions() {
+ ShowCPP = 1;
+ ShowMacros = 0;
+ ShowLineMarkers = 1;
+ ShowComments = 0;
+ ShowMacroComments = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/StmtXML.def b/contrib/llvm/tools/clang/include/clang/Frontend/StmtXML.def
new file mode 100644
index 0000000..f63761a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/StmtXML.def
@@ -0,0 +1,520 @@
+//===-- StmtXML.def - Metadata about Stmt XML 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 XML statement database structure as written in
+// <TranslationUnit> sub-nodes of the XML document.
+// The semantics of the attributes and enums are mostly self-documenting
+// by looking at the appropriate internally used functions and values.
+// The following macros are used:
+//
+// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+// statement of class CLASS where CLASS is a class name used internally by clang.
+// After a NODE_XML the definition of all (optional) attributes of that statement
+// node and possible sub-nodes follows.
+//
+// END_NODE_XML - Closes the attribute definition of the current node.
+//
+// ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a
+// string, which value uniquely identify that statement. Other nodes may refer
+// by reference attributes to this value (currently used only for Label).
+//
+// TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an
+// expression by a "type" attribute. FN is internally used by clang.
+//
+// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
+// used by clang. A boolean attribute have the values "0" or "1".
+//
+// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
+// a special handling. See the appropriate documentations.
+//
+// ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of
+// a statement in the source file(s).
+//
+// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
+// Optional attributes are omitted for boolean types, if the value is false,
+// for integral types, if the value is null and for strings,
+// if the value is the empty string. FN is internally used by clang.
+//
+// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+// is an enumeration defined with ENUM_XML macros immediately following after
+// that macro. An optional attribute is ommited, if the particular enum is the
+// empty string. FN is internally used by clang.
+//
+// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
+// internally used by clang.
+//
+// END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+// SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+// SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes.
+//
+// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
+// its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ATTRIBUTE_FILE_LOCATION_XML
+# define ATTRIBUTE_FILE_LOCATION_XML \
+ ATTRIBUTE_XML(getFilename(), "file") \
+ ATTRIBUTE_XML(getLine(), "line") \
+ ATTRIBUTE_XML(getColumn(), "col") \
+ ATTRIBUTE_OPT_XML(getFilename(), "endfile") \
+ ATTRIBUTE_OPT_XML(getLine(), "endline") \
+ ATTRIBUTE_OPT_XML(getColumn(), "endcol")
+#endif
+
+#ifndef TYPE_ATTRIBUTE_XML
+# define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
+#endif
+
+NODE_XML(Stmt, "Stmt_Unsupported") // fallback for unsupproted statements
+ ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(NullStmt, "NullStmt")
+ ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(CompoundStmt, "CompoundStmt")
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(size(), "num_stmts")
+ SUB_NODE_SEQUENCE_XML(Stmt)
+END_NODE_XML
+
+NODE_XML(CaseStmt, "CaseStmt") // case expr: body;
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Stmt) // body
+ SUB_NODE_XML(Expr) // expr
+ SUB_NODE_XML(Expr) // rhs expr in gc extension: case expr .. expr: body;
+END_NODE_XML
+
+NODE_XML(DefaultStmt, "DefaultStmt") // default: body;
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Stmt) // body
+END_NODE_XML
+
+NODE_XML(LabelStmt, "LabelStmt") // Label: body;
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getName(), "name") // string
+ SUB_NODE_XML(Stmt) // body
+END_NODE_XML
+
+NODE_XML(IfStmt, "IfStmt") // if (cond) stmt1; else stmt2;
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Expr) // cond
+ SUB_NODE_XML(Stmt) // stmt1
+ SUB_NODE_XML(Stmt) // stmt2
+END_NODE_XML
+
+NODE_XML(SwitchStmt, "SwitchStmt") // switch (cond) body;
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Expr) // cond
+ SUB_NODE_XML(Stmt) // body
+END_NODE_XML
+
+NODE_XML(WhileStmt, "WhileStmt") // while (cond) body;
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Expr) // cond
+ SUB_NODE_XML(Stmt) // body
+END_NODE_XML
+
+NODE_XML(DoStmt, "DoStmt") // do body while (cond);
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Expr) // cond
+ SUB_NODE_XML(Stmt) // body
+END_NODE_XML
+
+NODE_XML(ForStmt, "ForStmt") // for (init; cond; inc) body;
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Stmt) // init
+ SUB_NODE_XML(Expr) // cond
+ SUB_NODE_XML(Expr) // inc
+ SUB_NODE_XML(Stmt) // body
+END_NODE_XML
+
+NODE_XML(GotoStmt, "GotoStmt") // goto label;
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getLabel()->getName(), "name") // informal string
+ ATTRIBUTE_XML(getLabel(), "ref") // id string
+END_NODE_XML
+
+NODE_XML(IndirectGotoStmt, "IndirectGotoStmt") // goto expr;
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Expr) // expr
+END_NODE_XML
+
+NODE_XML(ContinueStmt, "ContinueStmt") // continue
+ ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(BreakStmt, "BreakStmt") // break
+ ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(ReturnStmt, "ReturnStmt") // return expr;
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(Expr) // expr
+END_NODE_XML
+
+NODE_XML(AsmStmt, "AsmStmt") // GNU inline-assembly statement extension
+ ATTRIBUTE_FILE_LOCATION_XML
+ // FIXME
+END_NODE_XML
+
+NODE_XML(DeclStmt, "DeclStmt") // a declaration statement
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_SEQUENCE_XML(Decl)
+END_NODE_XML
+
+// C++ statements
+NODE_XML(CXXTryStmt, "CXXTryStmt") // try CompoundStmt CXXCatchStmt1 CXXCatchStmt2 ..
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getNumHandlers(), "num_handlers")
+ SUB_NODE_XML(CompoundStmt)
+ SUB_NODE_SEQUENCE_XML(CXXCatchStmt)
+END_NODE_XML
+
+NODE_XML(CXXCatchStmt, "CXXCatchStmt") // catch (decl) Stmt
+ ATTRIBUTE_FILE_LOCATION_XML
+ SUB_NODE_XML(VarDecl)
+ SUB_NODE_XML(Stmt)
+END_NODE_XML
+
+// Expressions
+NODE_XML(PredefinedExpr, "PredefinedExpr")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_ENUM_XML(getIdentType(), "kind")
+ ENUM_XML(PredefinedExpr::Func, "__func__")
+ ENUM_XML(PredefinedExpr::Function, "__FUNCTION__")
+ ENUM_XML(PredefinedExpr::PrettyFunction, "__PRETTY_FUNCTION__")
+ END_ENUM_XML
+END_NODE_XML
+
+NODE_XML(DeclRefExpr, "DeclRefExpr") // an expression referring to a declared entity
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getDecl(), "ref") // id string of the declaration
+ ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // informal
+ //ATTRIBUTE_ENUM_XML(getDecl()->getKind(), "kind") // really needed here?
+END_NODE_XML
+
+NODE_XML(IntegerLiteral, "IntegerLiteral")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getValue(), "value") // (signed) integer
+END_NODE_XML
+
+NODE_XML(CharacterLiteral, "CharacterLiteral")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getValue(), "value") // unsigned
+END_NODE_XML
+
+NODE_XML(FloatingLiteral, "FloatingLiteral")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ // FIXME: output float as written in source (no approximation or the like)
+ //ATTRIBUTE_XML(getValueAsApproximateDouble(), "value") // float
+END_NODE_XML
+
+NODE_XML(StringLiteral, "StringLiteral")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_SPECIAL_XML(getStrData(), "value") // string, special handling for escaping needed
+ ATTRIBUTE_OPT_XML(isWide(), "is_wide") // boolean
+END_NODE_XML
+
+NODE_XML(UnaryOperator, "UnaryOperator") // op(expr) or (expr)op
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_ENUM_XML(getOpcode(), "kind")
+ ENUM_XML(UnaryOperator::PostInc, "postinc")
+ ENUM_XML(UnaryOperator::PostDec, "postdec")
+ ENUM_XML(UnaryOperator::PreInc, "preinc")
+ ENUM_XML(UnaryOperator::PreDec, "predec")
+ ENUM_XML(UnaryOperator::AddrOf, "addrof")
+ ENUM_XML(UnaryOperator::Deref, "deref")
+ ENUM_XML(UnaryOperator::Plus, "plus")
+ ENUM_XML(UnaryOperator::Minus, "minus")
+ ENUM_XML(UnaryOperator::Not, "not") // bitwise not
+ ENUM_XML(UnaryOperator::LNot, "lnot") // boolean not
+ ENUM_XML(UnaryOperator::Real, "__real")
+ ENUM_XML(UnaryOperator::Imag, "__imag")
+ ENUM_XML(UnaryOperator::Extension, "__extension__")
+ ENUM_XML(UnaryOperator::OffsetOf, "__builtin_offsetof")
+ END_ENUM_XML
+ SUB_NODE_XML(Expr) // expr
+END_NODE_XML
+
+NODE_XML(BinaryOperator, "BinaryOperator") // (expr1) op (expr2)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_ENUM_XML(getOpcode(), "kind")
+ ENUM_XML(BinaryOperator::PtrMemD , "ptrmemd")
+ ENUM_XML(BinaryOperator::PtrMemI , "ptrmemi")
+ ENUM_XML(BinaryOperator::Mul , "mul")
+ ENUM_XML(BinaryOperator::Div , "div")
+ ENUM_XML(BinaryOperator::Rem , "rem")
+ ENUM_XML(BinaryOperator::Add , "add")
+ ENUM_XML(BinaryOperator::Sub , "sub")
+ ENUM_XML(BinaryOperator::Shl , "shl")
+ ENUM_XML(BinaryOperator::Shr , "shr")
+ ENUM_XML(BinaryOperator::LT , "lt")
+ ENUM_XML(BinaryOperator::GT , "gt")
+ ENUM_XML(BinaryOperator::LE , "le")
+ ENUM_XML(BinaryOperator::GE , "ge")
+ ENUM_XML(BinaryOperator::EQ , "eq")
+ ENUM_XML(BinaryOperator::NE , "ne")
+ ENUM_XML(BinaryOperator::And , "and") // bitwise and
+ ENUM_XML(BinaryOperator::Xor , "xor")
+ ENUM_XML(BinaryOperator::Or , "or") // bitwise or
+ ENUM_XML(BinaryOperator::LAnd , "land") // boolean and
+ ENUM_XML(BinaryOperator::LOr , "lor") // boolean or
+ ENUM_XML(BinaryOperator::Assign , "assign")
+ ENUM_XML(BinaryOperator::MulAssign, "mulassign")
+ ENUM_XML(BinaryOperator::DivAssign, "divassign")
+ ENUM_XML(BinaryOperator::RemAssign, "remassign")
+ ENUM_XML(BinaryOperator::AddAssign, "addassign")
+ ENUM_XML(BinaryOperator::SubAssign, "subassign")
+ ENUM_XML(BinaryOperator::ShlAssign, "shlassign")
+ ENUM_XML(BinaryOperator::ShrAssign, "shrassign")
+ ENUM_XML(BinaryOperator::AndAssign, "andassign")
+ ENUM_XML(BinaryOperator::XorAssign, "xorassign")
+ ENUM_XML(BinaryOperator::OrAssign , "orassign")
+ ENUM_XML(BinaryOperator::Comma , "comma")
+ END_ENUM_XML
+ SUB_NODE_XML(Expr) // expr1
+ SUB_NODE_XML(Expr) // expr2
+END_NODE_XML
+
+// FIXME: is there a special class needed or is BinaryOperator sufficient?
+//NODE_XML(CompoundAssignOperator, "CompoundAssignOperator")
+
+NODE_XML(ConditionalOperator, "ConditionalOperator") // expr1 ? expr2 : expr3
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(Expr) // expr1
+ SUB_NODE_XML(Expr) // expr2
+ SUB_NODE_XML(Expr) // expr3
+END_NODE_XML
+
+NODE_XML(OffsetOfExpr, "OffsetOfExpr") // offsetof(basetype, components)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getTypeSourceInfo()->getType())
+ ATTRIBUTE_XML(getNumComponents(), "num_components")
+ SUB_NODE_SEQUENCE_XML(OffsetOfExpr::OffsetOfNode)
+END_NODE_XML
+
+NODE_XML(SizeOfAlignOfExpr, "SizeOfAlignOfExpr") // sizeof(expr) or alignof(expr)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(isSizeOf(), "is_sizeof")
+ ATTRIBUTE_XML(isArgumentType(), "is_type") // "1" if expr denotes a type
+ ATTRIBUTE_SPECIAL_XML(getArgumentType(), "type_ref") // optional, denotes the type of expr, if is_type=="1", special handling needed since getArgumentType() could assert
+ SUB_NODE_OPT_XML(Expr) // expr, if is_type=="0"
+END_NODE_XML
+
+NODE_XML(ArraySubscriptExpr, "ArraySubscriptExpr") // expr1[expr2]
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(Expr) // expr1
+ SUB_NODE_XML(Expr) // expr2
+END_NODE_XML
+
+NODE_XML(CallExpr, "CallExpr") // fnexpr(arg1, arg2, ...)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getNumArgs(), "num_args") // unsigned
+ SUB_NODE_XML(Expr) // fnexpr
+ SUB_NODE_SEQUENCE_XML(Expr) // arg1..argN
+END_NODE_XML
+
+NODE_XML(MemberExpr, "MemberExpr") // expr->F or expr.F
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(isArrow(), "is_deref")
+ ATTRIBUTE_XML(getMemberDecl(), "ref") // refers to F
+ ATTRIBUTE_XML(getMemberDecl()->getNameAsString(), "name") // informal
+ SUB_NODE_XML(Expr) // expr
+END_NODE_XML
+
+NODE_XML(CStyleCastExpr, "CStyleCastExpr") // (type)expr
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getTypeAsWritten(), "type_ref") // denotes the type as written in the source code
+ SUB_NODE_XML(Expr) // expr
+END_NODE_XML
+
+NODE_XML(ImplicitCastExpr, "ImplicitCastExpr")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(Expr)
+END_NODE_XML
+
+NODE_XML(CompoundLiteralExpr, "CompoundLiteralExpr") // [C99 6.5.2.5]
+ SUB_NODE_XML(Expr) // init
+END_NODE_XML
+
+NODE_XML(ExtVectorElementExpr, "ExtVectorElementExpr")
+ SUB_NODE_XML(Expr) // base
+END_NODE_XML
+
+NODE_XML(InitListExpr, "InitListExpr") // struct foo x = { expr1, { expr2, expr3 } };
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_OPT_XML(getInitializedFieldInUnion(), "field_ref") // if a union is initialized, this refers to the initialized union field id
+ ATTRIBUTE_XML(getNumInits(), "num_inits") // unsigned
+ SUB_NODE_SEQUENCE_XML(Expr) // expr1..exprN
+END_NODE_XML
+
+NODE_XML(DesignatedInitExpr, "DesignatedInitExpr")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(ImplicitValueInitExpr, "ImplicitValueInitExpr") // Implicit value initializations occur within InitListExpr
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(VAArgExpr, "VAArgExpr") // used for the builtin function __builtin_va_start(expr)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(Expr) // expr
+END_NODE_XML
+
+NODE_XML(ParenExpr, "ParenExpr") // this represents a parethesized expression "(expr)". Only formed if full location information is requested.
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(Expr) // expr
+END_NODE_XML
+
+// GNU Extensions
+NODE_XML(AddrLabelExpr, "AddrLabelExpr") // the GNU address of label extension, representing &&label.
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getLabel(), "ref") // id string
+ SUB_NODE_XML(LabelStmt) // expr
+END_NODE_XML
+
+NODE_XML(StmtExpr, "StmtExpr") // StmtExpr contains a single CompoundStmt node, which it evaluates and takes the value of the last subexpression.
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(CompoundStmt)
+END_NODE_XML
+
+NODE_XML(TypesCompatibleExpr, "TypesCompatibleExpr") // GNU builtin-in function __builtin_types_compatible_p
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getArgType1(), "type1_ref") // id of type1
+ ATTRIBUTE_XML(getArgType2(), "type2_ref") // id of type2
+END_NODE_XML
+
+NODE_XML(ChooseExpr, "ChooseExpr") // GNU builtin-in function __builtin_choose_expr(expr1, expr2, expr3)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(Expr) // expr1
+ SUB_NODE_XML(Expr) // expr2
+ SUB_NODE_XML(Expr) // expr3
+END_NODE_XML
+
+NODE_XML(GNUNullExpr, "GNUNullExpr") // GNU __null extension
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+// C++ Expressions
+NODE_XML(CXXOperatorCallExpr, "CXXOperatorCallExpr") // fnexpr(arg1, arg2, ...)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getNumArgs(), "num_args") // unsigned
+ SUB_NODE_XML(Expr) // fnexpr
+ SUB_NODE_SEQUENCE_XML(Expr) // arg1..argN
+END_NODE_XML
+
+NODE_XML(CXXNamedCastExpr, "CXXNamedCastExpr") // xxx_cast<type>(expr)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_ENUM_XML(getStmtClass(), "kind")
+ ENUM_XML(Stmt::CXXStaticCastExprClass, "static_cast")
+ ENUM_XML(Stmt::CXXDynamicCastExprClass, "dynamic_cast")
+ ENUM_XML(Stmt::CXXReinterpretCastExprClass, "reinterpret_cast")
+ ENUM_XML(Stmt::CXXConstCastExprClass, "const_cast")
+ END_ENUM_XML
+ ATTRIBUTE_XML(getTypeAsWritten(), "type_ref") // denotes the type as written in the source code
+ SUB_NODE_XML(Expr) // expr
+END_NODE_XML
+
+NODE_XML(CXXMemberCallExpr, "CXXMemberCallExpr") // fnexpr(arg1, arg2, ...)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getNumArgs(), "num_args") // unsigned
+ SUB_NODE_XML(Expr) // fnexpr
+ SUB_NODE_SEQUENCE_XML(Expr) // arg1..argN
+END_NODE_XML
+
+NODE_XML(CXXBoolLiteralExpr, "CXXBoolLiteralExpr")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getValue(), "value") // boolean
+END_NODE_XML
+
+NODE_XML(CXXNullPtrLiteralExpr, "CXXNullPtrLiteralExpr") // [C++0x 2.14.7] C++ Pointer Literal
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(CXXTypeidExpr, "CXXTypeidExpr") // typeid(expr)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(isTypeOperand(), "is_type") // "1" if expr denotes a type
+ ATTRIBUTE_SPECIAL_XML(getTypeOperand(), "type_ref") // optional, denotes the type of expr, if is_type=="1", special handling needed since getTypeOperand() could assert
+ SUB_NODE_OPT_XML(Expr) // expr, if is_type=="0"
+END_NODE_XML
+
+NODE_XML(CXXThisExpr, "CXXThisExpr") // this
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(CXXThrowExpr, "CXXThrowExpr") // throw (expr);
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(Expr) // NULL in case of "throw;"
+END_NODE_XML
+
+NODE_XML(CXXDefaultArgExpr, "CXXDefaultArgExpr")
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getType())
+ ATTRIBUTE_XML(getParam(), "ref") // id of the parameter declaration (the expression is a subnode of the declaration)
+END_NODE_XML
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML
+#undef END_NODE_XML
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h
new file mode 100644
index 0000000..380a1dd
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -0,0 +1,52 @@
+//===--- 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_TEXT_DIAGNOSTIC_BUFFER_H_
+#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_BUFFER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include <vector>
+
+namespace clang {
+
+class Preprocessor;
+class SourceManager;
+
+class TextDiagnosticBuffer : public DiagnosticClient {
+public:
+ typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
+ typedef DiagList::iterator iterator;
+ typedef DiagList::const_iterator const_iterator;
+private:
+ DiagList Errors, Warnings, 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 note_begin() const { return Notes.begin(); }
+ const_iterator note_end() const { return Notes.end(); }
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info);
+
+ /// FlushDiagnostics - Flush the buffered diagnostics to an given
+ /// diagnostic engine.
+ void FlushDiagnostics(Diagnostic &Diags) const;
+};
+
+} // end namspace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h
new file mode 100644
index 0000000..ec4392f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -0,0 +1,85 @@
+//===--- 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_TEXT_DIAGNOSTIC_PRINTER_H_
+#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace clang {
+class DiagnosticOptions;
+class LangOptions;
+class SourceManager;
+
+class TextDiagnosticPrinter : public DiagnosticClient {
+ llvm::raw_ostream &OS;
+ const LangOptions *LangOpts;
+ const DiagnosticOptions *DiagOpts;
+
+ SourceLocation LastWarningLoc;
+ FullSourceLoc LastLoc;
+ unsigned LastCaretDiagnosticWasNote : 1;
+ unsigned OwnsOutputStream : 1;
+
+ /// A string to prefix to error messages.
+ std::string Prefix;
+
+public:
+ TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags,
+ bool OwnsOutputStream = false);
+ virtual ~TextDiagnosticPrinter();
+
+ /// 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) {
+ LangOpts = &LO;
+ }
+
+ void EndSourceFile() {
+ LangOpts = 0;
+ }
+
+ void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM);
+
+ void HighlightRange(const SourceRange &R,
+ const SourceManager &SrcMgr,
+ unsigned LineNo, FileID FID,
+ std::string &CaretLine,
+ const std::string &SourceLine);
+
+ void EmitCaretDiagnostic(SourceLocation Loc,
+ SourceRange *Ranges, unsigned NumRanges,
+ const SourceManager &SM,
+ const FixItHint *Hints,
+ unsigned NumHints,
+ unsigned Columns,
+ unsigned OnMacroInst,
+ unsigned MacroSkipStart,
+ unsigned MacroSkipEnd);
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TypeXML.def b/contrib/llvm/tools/clang/include/clang/Frontend/TypeXML.def
new file mode 100644
index 0000000..069d718
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/TypeXML.def
@@ -0,0 +1,299 @@
+//===-- TypeXML.def - Metadata about Type XML 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 XML type info database as written in the
+// <ReferenceSection>/<Types> sub-nodes of the XML document. Type nodes
+// are referred by "type" reference attributes throughout the document.
+// A type node never contains sub-nodes.
+// The semantics of the attributes and enums are mostly self-documenting
+// by looking at the appropriate internally used functions and values.
+// The following macros are used:
+//
+// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+// type of class CLASS where CLASS is a class name used internally by clang.
+// After a NODE_XML the definition of all (optional) attributes of that type
+// node follows.
+//
+// END_NODE_XML - Closes the attribute definition of the current node.
+//
+// ID_ATTRIBUTE_XML - Each type node has an "id" attribute containing a
+// string, which value uniquely identify the type. Other nodes may refer
+// by "type" reference attributes to this value.
+//
+// TYPE_ATTRIBUTE_XML( FN ) - Type nodes may refer to the ids of other type
+// nodes by a "type" attribute. FN is internally used by clang.
+//
+// CONTEXT_ATTRIBUTE_XML( FN ) - Type nodes may refer to the ids of their
+// declaration contexts by a "context" attribute. FN is internally used by
+// clang.
+//
+// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
+// used by clang. A boolean attribute have the values "0" or "1".
+//
+// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
+// Optional attributes are omitted for boolean types, if the value is false,
+// for integral types, if the value is null and for strings,
+// if the value is the empty string. FN is internally used by clang.
+//
+// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+// is an enumeration defined with ENUM_XML macros immediately following after
+// that macro. An optional attribute is ommited, if the particular enum is the
+// empty string. FN is internally used by clang.
+//
+// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
+// internally used by clang.
+//
+// END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TYPE_ATTRIBUTE_XML
+# define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
+#endif
+
+NODE_XML(Type, "FIXME_Type")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getTypeClassName(), "unhandled_type_name")
+END_NODE_XML
+
+NODE_XML(QualType, "CvQualifiedType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getTypePtr()) // the qualified type, e.g. for 'T* const' it's 'T*'
+ ATTRIBUTE_OPT_XML(isLocalConstQualified(), "const") // boolean
+ ATTRIBUTE_OPT_XML(isLocalVolatileQualified(), "volatile") // boolean
+ ATTRIBUTE_OPT_XML(isLocalRestrictQualified(), "restrict") // boolean
+ ATTRIBUTE_OPT_XML(getObjCGCAttr(), "objc_gc") // Qualifiers::GC
+ ATTRIBUTE_OPT_XML(getAddressSpace(), "address_space") // unsigned
+END_NODE_XML
+
+NODE_XML(BuiltinType, "FundamentalType")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_ENUM_XML(getKind(), "kind")
+ ENUM_XML(BuiltinType::Void, "void")
+ ENUM_XML(BuiltinType::Bool, "bool")
+ ENUM_XML(BuiltinType::Char_U, "char") // not explicitely qualified char, depends on target platform
+ ENUM_XML(BuiltinType::Char_S, "char") // not explicitely qualified char, depends on target platform
+ ENUM_XML(BuiltinType::SChar, "signed char")
+ ENUM_XML(BuiltinType::Short, "short");
+ ENUM_XML(BuiltinType::Int, "int");
+ ENUM_XML(BuiltinType::Long, "long");
+ ENUM_XML(BuiltinType::LongLong, "long long");
+ ENUM_XML(BuiltinType::Int128, "__int128_t");
+ ENUM_XML(BuiltinType::UChar, "unsigned char");
+ ENUM_XML(BuiltinType::UShort, "unsigned short");
+ ENUM_XML(BuiltinType::UInt, "unsigned int");
+ ENUM_XML(BuiltinType::ULong, "unsigned long");
+ ENUM_XML(BuiltinType::ULongLong, "unsigned long long");
+ ENUM_XML(BuiltinType::UInt128, "__uint128_t");
+ ENUM_XML(BuiltinType::Float, "float");
+ ENUM_XML(BuiltinType::Double, "double");
+ ENUM_XML(BuiltinType::LongDouble, "long double");
+ ENUM_XML(BuiltinType::WChar, "wchar_t");
+ ENUM_XML(BuiltinType::Char16, "char16_t");
+ ENUM_XML(BuiltinType::Char32, "char32_t");
+ ENUM_XML(BuiltinType::NullPtr, "nullptr_t"); // This is the type of C++0x 'nullptr'.
+ ENUM_XML(BuiltinType::Overload, "overloaded");
+ ENUM_XML(BuiltinType::Dependent, "dependent");
+ END_ENUM_XML
+END_NODE_XML
+
+NODE_XML(PointerType, "PointerType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(LValueReferenceType, "ReferenceType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(RValueReferenceType, "ReferenceType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(FunctionNoProtoType, "FunctionNoProtoType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(FunctionProtoType, "FunctionType")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getResultType(), "result_type")
+ ATTRIBUTE_OPT_XML(isVariadic(), "variadic")
+END_NODE_XML
+
+NODE_XML(TypedefType, "Typedef")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getDecl()->getUnderlyingType())
+ ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string
+ CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(ComplexType, "ComplexType") // C99 complex types (_Complex float etc)
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getElementType())
+END_NODE_XML
+
+NODE_XML(BlockPointerType, "BlockPointerType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getPointeeType()) // alway refers to a function type
+END_NODE_XML
+
+NODE_XML(MemberPointerType, "MemberPointerType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getPointeeType())
+ ATTRIBUTE_XML(getClass(), "class_type") // refers to the class type id of which the pointee is a member
+END_NODE_XML
+
+NODE_XML(ConstantArrayType, "ArrayType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getElementType())
+ ATTRIBUTE_XML(getSize(), "size") // unsigned
+ ATTRIBUTE_ENUM_OPT_XML(getSizeModifier(), "size_modifier")
+ ENUM_XML(ArrayType::Normal, "")
+ ENUM_XML(ArrayType::Static, "static")
+ ENUM_XML(ArrayType::Star, "star")
+ END_ENUM_XML
+ ATTRIBUTE_OPT_XML(getIndexTypeCVRQualifiers(), "index_type_qualifier") // unsigned
+END_NODE_XML
+
+NODE_XML(IncompleteArrayType, "IncompleteArrayType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getElementType())
+END_NODE_XML
+
+NODE_XML(VariableArrayType, "VariableArrayType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getElementType())
+ // note: the size expression is print at the point of declaration
+END_NODE_XML
+
+NODE_XML(DependentSizedArrayType, "DependentSizedArrayType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getElementType())
+ // FIXME: how to deal with size expression?
+END_NODE_XML
+
+NODE_XML(VectorType, "VectorType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getElementType())
+ ATTRIBUTE_XML(getNumElements(), "size") // unsigned
+END_NODE_XML
+
+NODE_XML(ExtVectorType, "ExtVectorType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getElementType())
+ ATTRIBUTE_XML(getNumElements(), "size") // unsigned
+END_NODE_XML
+
+NODE_XML(TypeOfExprType, "TypeOfExprType")
+ ID_ATTRIBUTE_XML
+ // note: the typeof expression is print at the point of use
+END_NODE_XML
+
+NODE_XML(TypeOfType, "TypeOfType")
+ ID_ATTRIBUTE_XML
+ TYPE_ATTRIBUTE_XML(getUnderlyingType())
+END_NODE_XML
+
+
+NODE_XML(RecordType, "Record")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string
+ ATTRIBUTE_ENUM_XML(getDecl()->getTagKind(), "kind")
+ ENUM_XML(TTK_Struct, "struct")
+ ENUM_XML(TTK_Union, "union")
+ ENUM_XML(TTK_Class, "class")
+ END_ENUM_XML
+ CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(EnumType, "Enum")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string
+ CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(TemplateTypeParmType, "TemplateTypeParmType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(TemplateSpecializationType, "TemplateSpecializationType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(ElaboratedType, "ElaboratedType")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_ENUM_XML(getKeyword(), "keyword")
+ ENUM_XML(ETK_None, "none")
+ ENUM_XML(ETK_Typename, "typename")
+ ENUM_XML(ETK_Struct, "struct")
+ ENUM_XML(ETK_Union, "union")
+ ENUM_XML(ETK_Class, "class")
+ ENUM_XML(ETK_Enum, "enum")
+ END_ENUM_XML
+ TYPE_ATTRIBUTE_XML(getNamedType())
+END_NODE_XML
+
+NODE_XML(InjectedClassNameType, "InjectedClassNameType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(DependentNameType, "DependentNameType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(ObjCInterfaceType, "ObjCInterfaceType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(ObjCObjectPointerType, "ObjCObjectPointerType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(SubstTemplateTypeParmType, "SubstTemplateTypeParm")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(DependentSizedExtVectorType, "DependentSizedExtVector")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(UnresolvedUsingType, "UnresolvedUsing")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(DependentTypeOfExprType, "DependentTypeOfExpr")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(DecltypeType, "Decltype")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(DependentDecltypeType, "DependentDecltype")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML
+#undef TYPE_ATTRIBUTE_XML
+#undef CONTEXT_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ENUM_XML
+#undef END_ENUM_XML
+#undef END_NODE_XML
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h
new file mode 100644
index 0000000..c1d4831
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h
@@ -0,0 +1,93 @@
+//===--- 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 "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+class Triple;
+}
+
+namespace clang {
+class ASTConsumer;
+class Decl;
+class DependencyOutputOptions;
+class Diagnostic;
+class DiagnosticOptions;
+class HeaderSearch;
+class HeaderSearchOptions;
+class IdentifierTable;
+class LangOptions;
+class MinimalAction;
+class Preprocessor;
+class PreprocessorOptions;
+class PreprocessorOutputOptions;
+class SourceManager;
+class Stmt;
+class TargetInfo;
+class FrontendOptions;
+
+/// Normalize \arg File for use in a user defined #include directive (in the
+/// predefines buffer).
+std::string NormalizeDashIncludePath(llvm::StringRef File);
+
+/// 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 HeaderSearchOptions &HSOpts,
+ const FrontendOptions &FEOpts);
+
+/// ProcessWarningOptions - Initialize the diagnostic client and process the
+/// warning options specified on the command line.
+void ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts);
+
+/// DoPrintPreprocessedInput - Implement -E mode.
+void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS,
+ const PreprocessorOutputOptions &Opts);
+
+/// RewriteMacrosInInput - Implement -rewrite-macros mode.
+void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS);
+
+/// RewriteMacrosInInput - A simple test for the TokenRewriter class.
+void DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS);
+
+/// CreatePrintParserActionsAction - Return the actions implementation that
+/// implements the -parse-print-callbacks option.
+MinimalAction *CreatePrintParserActionsAction(Preprocessor &PP,
+ llvm::raw_ostream* OS);
+
+/// CheckDiagnostics - Gather the expected diagnostics and check them.
+bool CheckDiagnostics(Preprocessor &PP);
+
+/// AttachDependencyFileGen - Create a dependency file generator, and attach
+/// it to the given preprocessor. This takes ownership of the output stream.
+void AttachDependencyFileGen(Preprocessor &PP,
+ const DependencyOutputOptions &Opts);
+
+/// CacheTokens - Cache tokens for use with PCH. Note that this requires
+/// a seekable stream.
+void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS);
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticsClient.h b/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticsClient.h
new file mode 100644
index 0000000..6f45e49
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticsClient.h
@@ -0,0 +1,98 @@
+//===-- VerifyDiagnosticsClient.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_VERIFYDIAGNOSTICSCLIENT_H
+#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+
+class Diagnostic;
+class TextDiagnosticBuffer;
+
+/// VerifyDiagnosticsClient - 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:
+///
+/// expected-{error,warning,note}
+///
+/// to tag if it's an expected error 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:
+///
+/// int A = B; // expected-error {{use of undeclared identifier 'B'}}
+///
+/// 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.
+///
+/// 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:
+///
+/// void f(); // expected-note 2 {{previous declaration is here}}
+///
+/// Regex matching mode may be selected by appending '-re' to type. Example:
+///
+/// expected-error-re
+///
+/// Examples matching error: "variable has incomplete type 'struct s'"
+///
+/// // expected-error {{variable has incomplete type 'struct s'}}
+/// // expected-error {{variable has incomplete type}}
+///
+/// // expected-error-re {{variable has has type 'struct .'}}
+/// // expected-error-re {{variable has has type 'struct .*'}}
+/// // expected-error-re {{variable has has type 'struct (.*)'}}
+/// // expected-error-re {{variable has has type 'struct[[:space:]](.*)'}}
+///
+class VerifyDiagnosticsClient : public DiagnosticClient {
+public:
+ Diagnostic &Diags;
+ llvm::OwningPtr<DiagnosticClient> PrimaryClient;
+ llvm::OwningPtr<TextDiagnosticBuffer> Buffer;
+ Preprocessor *CurrentPreprocessor;
+ unsigned NumErrors;
+
+private:
+ void CheckDiagnostics();
+
+public:
+ /// Create a new verifying diagnostic client, which will issue errors to \arg
+ /// PrimaryClient when a diagnostic does not match what is expected (as
+ /// indicated in the source file). The verifying diagnostic client takes
+ /// ownership of \arg PrimaryClient.
+ VerifyDiagnosticsClient(Diagnostic &Diags, DiagnosticClient *PrimaryClient);
+ ~VerifyDiagnosticsClient();
+
+ virtual void BeginSourceFile(const LangOptions &LangOpts,
+ const Preprocessor *PP);
+
+ virtual void EndSourceFile();
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info);
+
+ /// HadErrors - Check if there were any mismatches in expected diagnostics.
+ bool HadErrors();
+};
+
+} // end namspace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h b/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h
new file mode 100644
index 0000000..fc18dae
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h
@@ -0,0 +1,174 @@
+//===--- ASTLocation.h - A <Decl, Stmt> pair --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// ASTLocation is Decl or a Stmt and its immediate Decl parent.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ASTLOCATION_H
+#define LLVM_CLANG_INDEX_ASTLOCATION_H
+
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace clang {
+ class Decl;
+ class Stmt;
+ class NamedDecl;
+
+namespace idx {
+ class TranslationUnit;
+
+/// \brief Represents a Decl or a Stmt and its immediate Decl parent. It's
+/// immutable.
+///
+/// ASTLocation is intended to be used as a "pointer" into the AST. It is either
+/// just a Decl, or a Stmt and its Decl parent. Since a single Stmt is devoid
+/// of context, its parent Decl provides all the additional missing information
+/// like the declaration context, ASTContext, etc.
+///
+class ASTLocation {
+public:
+ enum NodeKind {
+ N_Decl, N_NamedRef, N_Stmt, N_Type
+ };
+
+ struct NamedRef {
+ NamedDecl *ND;
+ SourceLocation Loc;
+
+ NamedRef() : ND(0) { }
+ NamedRef(NamedDecl *nd, SourceLocation loc) : ND(nd), Loc(loc) { }
+ };
+
+private:
+ llvm::PointerIntPair<Decl *, 2, NodeKind> ParentDecl;
+
+ union {
+ Decl *D;
+ Stmt *Stm;
+ struct {
+ NamedDecl *ND;
+ unsigned RawLoc;
+ } NDRef;
+ struct {
+ void *TyPtr;
+ void *Data;
+ } Ty;
+ };
+
+public:
+ ASTLocation() { }
+
+ explicit ASTLocation(const Decl *d)
+ : ParentDecl(const_cast<Decl*>(d), N_Decl), D(const_cast<Decl*>(d)) { }
+
+ ASTLocation(const Decl *parentDecl, const Stmt *stm)
+ : ParentDecl(const_cast<Decl*>(parentDecl), N_Stmt),
+ Stm(const_cast<Stmt*>(stm)) {
+ if (!stm) ParentDecl.setPointer(0);
+ }
+
+ ASTLocation(const Decl *parentDecl, NamedDecl *ndRef, SourceLocation loc)
+ : ParentDecl(const_cast<Decl*>(parentDecl), N_NamedRef) {
+ if (ndRef) {
+ NDRef.ND = ndRef;
+ NDRef.RawLoc = loc.getRawEncoding();
+ } else
+ ParentDecl.setPointer(0);
+ }
+
+ ASTLocation(const Decl *parentDecl, TypeLoc tyLoc)
+ : ParentDecl(const_cast<Decl*>(parentDecl), N_Type) {
+ if (tyLoc) {
+ Ty.TyPtr = tyLoc.getType().getAsOpaquePtr();
+ Ty.Data = tyLoc.getOpaqueData();
+ } else
+ ParentDecl.setPointer(0);
+ }
+
+ bool isValid() const { return ParentDecl.getPointer() != 0; }
+ bool isInvalid() const { return !isValid(); }
+
+ NodeKind getKind() const {
+ assert(isValid());
+ return (NodeKind)ParentDecl.getInt();
+ }
+
+ Decl *getParentDecl() const { return ParentDecl.getPointer(); }
+
+ Decl *AsDecl() const {
+ assert(getKind() == N_Decl);
+ return D;
+ }
+ Stmt *AsStmt() const {
+ assert(getKind() == N_Stmt);
+ return Stm;
+ }
+ NamedRef AsNamedRef() const {
+ assert(getKind() == N_NamedRef);
+ return NamedRef(NDRef.ND, SourceLocation::getFromRawEncoding(NDRef.RawLoc));
+ }
+ TypeLoc AsTypeLoc() const {
+ assert(getKind() == N_Type);
+ return TypeLoc(QualType::getFromOpaquePtr(Ty.TyPtr), Ty.Data);
+ }
+
+ Decl *dyn_AsDecl() const { return isValid() && getKind() == N_Decl ? D : 0; }
+ Stmt *dyn_AsStmt() const { return isValid() && getKind() == N_Stmt ? Stm : 0; }
+ NamedRef dyn_AsNamedRef() const {
+ return getKind() == N_Type ? AsNamedRef() : NamedRef();
+ }
+ TypeLoc dyn_AsTypeLoc() const {
+ return getKind() == N_Type ? AsTypeLoc() : TypeLoc();
+ }
+
+ bool isDecl() const { return isValid() && getKind() == N_Decl; }
+ bool isStmt() const { return isValid() && getKind() == N_Stmt; }
+ bool isNamedRef() const { return isValid() && getKind() == N_NamedRef; }
+ bool isType() const { return isValid() && getKind() == N_Type; }
+
+ /// \brief Returns the declaration that this ASTLocation references.
+ ///
+ /// If this points to a Decl, that Decl is returned.
+ /// If this points to an Expr that references a Decl, that Decl is returned,
+ /// otherwise it returns NULL.
+ Decl *getReferencedDecl();
+ const Decl *getReferencedDecl() const {
+ return const_cast<ASTLocation*>(this)->getReferencedDecl();
+ }
+
+ SourceRange getSourceRange() const;
+
+ void print(llvm::raw_ostream &OS) const;
+};
+
+/// \brief Like ASTLocation but also contains the TranslationUnit that the
+/// ASTLocation originated from.
+class TULocation : public ASTLocation {
+ TranslationUnit *TU;
+
+public:
+ TULocation(TranslationUnit *tu, ASTLocation astLoc)
+ : ASTLocation(astLoc), TU(tu) {
+ assert(tu && "Passed null translation unit");
+ }
+
+ TranslationUnit *getTU() const { return TU; }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/Analyzer.h b/contrib/llvm/tools/clang/include/clang/Index/Analyzer.h
new file mode 100644
index 0000000..f6b5465
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/Analyzer.h
@@ -0,0 +1,56 @@
+//===--- Analyzer.h - Analysis for indexing 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 declares the Analyzer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ANALYZER_H
+#define LLVM_CLANG_INDEX_ANALYZER_H
+
+namespace clang {
+ class Decl;
+ class ObjCMessageExpr;
+
+namespace idx {
+ class Program;
+ class IndexProvider;
+ class TULocationHandler;
+
+/// \brief Provides indexing information, like finding all references of an
+/// Entity across translation units.
+class Analyzer {
+ Program &Prog;
+ IndexProvider &Idxer;
+
+ Analyzer(const Analyzer&); // do not implement
+ Analyzer &operator=(const Analyzer &); // do not implement
+
+public:
+ explicit Analyzer(Program &prog, IndexProvider &idxer)
+ : Prog(prog), Idxer(idxer) { }
+
+ /// \brief Find all TULocations for declarations of the given Decl and pass
+ /// them to Handler.
+ void FindDeclarations(Decl *D, TULocationHandler &Handler);
+
+ /// \brief Find all TULocations for references of the given Decl and pass
+ /// them to Handler.
+ void FindReferences(Decl *D, TULocationHandler &Handler);
+
+ /// \brief Find methods that may respond to the given message and pass them
+ /// to Handler.
+ void FindObjCMethods(ObjCMessageExpr *MsgE, TULocationHandler &Handler);
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/CallGraph.h b/contrib/llvm/tools/clang/include/clang/Index/CallGraph.h
new file mode 100644
index 0000000..5edfe6f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/CallGraph.h
@@ -0,0 +1,146 @@
+//== CallGraph.cpp - Call graph 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 defined the CallGraph and CallGraphNode classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
+#define LLVM_CLANG_ANALYSIS_CALLGRAPH
+
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/Entity.h"
+#include "clang/Index/Program.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/STLExtras.h"
+#include <vector>
+#include <map>
+
+namespace clang {
+
+class CallGraphNode {
+ idx::Entity F;
+ typedef std::pair<idx::ASTLocation, CallGraphNode*> CallRecord;
+ std::vector<CallRecord> CalledFunctions;
+
+public:
+ CallGraphNode(idx::Entity f) : F(f) {}
+
+ typedef std::vector<CallRecord>::iterator iterator;
+ typedef std::vector<CallRecord>::const_iterator const_iterator;
+
+ iterator begin() { return CalledFunctions.begin(); }
+ iterator end() { return CalledFunctions.end(); }
+ const_iterator begin() const { return CalledFunctions.begin(); }
+ const_iterator end() const { return CalledFunctions.end(); }
+
+ void addCallee(idx::ASTLocation L, CallGraphNode *Node) {
+ CalledFunctions.push_back(std::make_pair(L, Node));
+ }
+
+ bool hasCallee() const { return begin() != end(); }
+
+ std::string getName() const { return F.getPrintableName(); }
+
+ Decl *getDecl(ASTContext &Ctx) const { return F.getDecl(Ctx); }
+};
+
+class CallGraph {
+ /// Program manages all Entities.
+ idx::Program Prog;
+
+ typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy;
+
+ /// FunctionMap owns all CallGraphNodes.
+ FunctionMapTy FunctionMap;
+
+ /// CallerCtx maps a caller to its ASTContext.
+ llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx;
+
+ /// Root node is the 'main' function or 0.
+ CallGraphNode *Root;
+
+ /// ExternalCallingNode has edges to all external functions.
+ CallGraphNode *ExternalCallingNode;
+
+public:
+ CallGraph();
+ ~CallGraph();
+
+ 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(); }
+
+ CallGraphNode *getRoot() { return Root; }
+
+ CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; }
+
+ void addTU(ASTContext &AST);
+
+ idx::Program &getProgram() { return Prog; }
+
+ CallGraphNode *getOrInsertFunction(idx::Entity F);
+
+ Decl *getDecl(CallGraphNode *Node);
+
+ void print(llvm::raw_ostream &os);
+ void dump();
+
+ void ViewCallGraph() const;
+};
+
+} // end clang namespace
+
+namespace llvm {
+
+template <> struct GraphTraits<clang::CallGraph> {
+ typedef clang::CallGraph GraphType;
+ typedef clang::CallGraphNode NodeType;
+
+ typedef std::pair<clang::idx::ASTLocation, NodeType*> CGNPairTy;
+ typedef std::pointer_to_unary_function<CGNPairTy, NodeType*> CGNDerefFun;
+
+ typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
+
+ static NodeType *getEntryNode(GraphType *CG) {
+ return CG->getExternalCallingNode();
+ }
+
+ static ChildIteratorType child_begin(NodeType *N) {
+ return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
+ }
+ static ChildIteratorType child_end(NodeType *N) {
+ return map_iterator(N->end(), CGNDerefFun(CGNDeref));
+ }
+
+ typedef std::pair<clang::idx::Entity, NodeType*> PairTy;
+ typedef std::pointer_to_unary_function<PairTy, NodeType*> DerefFun;
+
+ typedef mapped_iterator<GraphType::const_iterator, DerefFun> nodes_iterator;
+
+ static nodes_iterator nodes_begin(const GraphType &CG) {
+ return map_iterator(CG.begin(), DerefFun(CGDeref));
+ }
+ static nodes_iterator nodes_end(const GraphType &CG) {
+ return map_iterator(CG.end(), DerefFun(CGDeref));
+ }
+
+ static NodeType *CGNDeref(CGNPairTy P) { return P.second; }
+
+ static NodeType *CGDeref(PairTy P) { return P.second; }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/DeclReferenceMap.h b/contrib/llvm/tools/clang/include/clang/Index/DeclReferenceMap.h
new file mode 100644
index 0000000..73f2fe5
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/DeclReferenceMap.h
@@ -0,0 +1,50 @@
+//===--- DeclReferenceMap.h - Map Decls to their references -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// DeclReferenceMap creates a mapping from Decls to the ASTLocations that
+// reference them.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_DECLREFERENCEMAP_H
+#define LLVM_CLANG_INDEX_DECLREFERENCEMAP_H
+
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/STLExtras.h"
+#include <map>
+
+namespace clang {
+ class ASTContext;
+ class NamedDecl;
+
+namespace idx {
+
+/// \brief Maps NamedDecls with the ASTLocations that reference them.
+///
+/// References are mapped and retrieved using the canonical decls.
+class DeclReferenceMap {
+public:
+ explicit DeclReferenceMap(ASTContext &Ctx);
+
+ typedef std::multimap<NamedDecl*, ASTLocation> MapTy;
+ typedef pair_value_iterator<MapTy::iterator> astlocation_iterator;
+
+ astlocation_iterator refs_begin(NamedDecl *D) const;
+ astlocation_iterator refs_end(NamedDecl *D) const;
+ bool refs_empty(NamedDecl *D) const;
+
+private:
+ mutable MapTy Map;
+};
+
+} // end idx namespace
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/Entity.h b/contrib/llvm/tools/clang/include/clang/Index/Entity.h
new file mode 100644
index 0000000..c2aab62
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/Entity.h
@@ -0,0 +1,144 @@
+//===--- Entity.h - Cross-translation-unit "token" for decls ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Entity is a ASTContext-independent way to refer to declarations that are
+// visible across translation units.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ENTITY_H
+#define LLVM_CLANG_INDEX_ENTITY_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/DenseMap.h"
+#include <string>
+
+namespace clang {
+ class ASTContext;
+ class Decl;
+
+namespace idx {
+ class Program;
+ class EntityImpl;
+
+/// \brief A ASTContext-independent way to refer to declarations.
+///
+/// Entity is basically the link for declarations that are semantically the same
+/// in multiple ASTContexts. A client will convert a Decl into an Entity and
+/// later use that Entity to find the "same" Decl into another ASTContext.
+/// Declarations that are semantically the same and visible across translation
+/// units will be associated with the same Entity.
+///
+/// An Entity may also refer to declarations that cannot be visible across
+/// translation units, e.g. static functions with the same name in multiple
+/// translation units will be associated with different Entities.
+///
+/// Entities can be checked for equality but note that the same Program object
+/// should be used when getting Entities.
+///
+class Entity {
+ /// \brief Stores the Decl directly if it is not visible outside of its own
+ /// translation unit, otherwise it stores the associated EntityImpl.
+ llvm::PointerUnion<Decl *, EntityImpl *> Val;
+
+ explicit Entity(Decl *D);
+ explicit Entity(EntityImpl *impl) : Val(impl) { }
+ friend class EntityGetter;
+
+public:
+ Entity() { }
+
+ /// \brief Find the Decl that can be referred to by this entity.
+ Decl *getDecl(ASTContext &AST) const;
+
+ /// \brief If this Entity represents a declaration that is internal to its
+ /// translation unit, getInternalDecl() returns it.
+ Decl *getInternalDecl() const {
+ assert(isInternalToTU() && "This Entity is not internal!");
+ return Val.get<Decl *>();
+ }
+
+ /// \brief Get a printable name for debugging purpose.
+ std::string getPrintableName() const;
+
+ /// \brief Get an Entity associated with the given Decl.
+ /// \returns invalid Entity if an Entity cannot refer to this Decl.
+ static Entity get(Decl *D, Program &Prog);
+
+ /// \brief true if the Entity is not visible outside the trasnlation unit.
+ bool isInternalToTU() const {
+ assert(isValid() && "This Entity is not valid!");
+ return Val.is<Decl *>();
+ }
+
+ bool isValid() const { return !Val.isNull(); }
+ bool isInvalid() const { return !isValid(); }
+
+ void *getAsOpaquePtr() const { return Val.getOpaqueValue(); }
+ static Entity getFromOpaquePtr(void *Ptr) {
+ Entity Ent;
+ Ent.Val = llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue(Ptr);
+ return Ent;
+ }
+
+ friend bool operator==(const Entity &LHS, const Entity &RHS) {
+ return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr();
+ }
+
+ // For use in a std::map.
+ friend bool operator < (const Entity &LHS, const Entity &RHS) {
+ return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr();
+ }
+
+ // For use in DenseMap/DenseSet.
+ static Entity getEmptyMarker() {
+ Entity Ent;
+ Ent.Val =
+ llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-1);
+ return Ent;
+ }
+ static Entity getTombstoneMarker() {
+ Entity Ent;
+ Ent.Val =
+ llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-2);
+ return Ent;
+ }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that Entities can be used as keys in DenseMap and
+/// DenseSets.
+template<>
+struct DenseMapInfo<clang::idx::Entity> {
+ static inline clang::idx::Entity getEmptyKey() {
+ return clang::idx::Entity::getEmptyMarker();
+ }
+
+ static inline clang::idx::Entity getTombstoneKey() {
+ return clang::idx::Entity::getTombstoneMarker();
+ }
+
+ static unsigned getHashValue(clang::idx::Entity);
+
+ static inline bool
+ isEqual(clang::idx::Entity LHS, clang::idx::Entity RHS) {
+ return LHS == RHS;
+ }
+};
+
+template <>
+struct isPodLike<clang::idx::Entity> { static const bool value = true; };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/GlobalSelector.h b/contrib/llvm/tools/clang/include/clang/Index/GlobalSelector.h
new file mode 100644
index 0000000..9cd83a8
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/GlobalSelector.h
@@ -0,0 +1,100 @@
+//===--- GlobalSelector.h - Cross-translation-unit "token" for selectors --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// GlobalSelector is a ASTContext-independent way to refer to selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_GLOBALSELECTOR_H
+#define LLVM_CLANG_INDEX_GLOBALSELECTOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include <string>
+
+namespace clang {
+ class ASTContext;
+ class Selector;
+
+namespace idx {
+ class Program;
+
+/// \brief A ASTContext-independent way to refer to selectors.
+class GlobalSelector {
+ void *Val;
+
+ explicit GlobalSelector(void *val) : Val(val) { }
+
+public:
+ GlobalSelector() : Val(0) { }
+
+ /// \brief Get the ASTContext-specific selector.
+ Selector getSelector(ASTContext &AST) const;
+
+ bool isValid() const { return Val != 0; }
+ bool isInvalid() const { return !isValid(); }
+
+ /// \brief Get a printable name for debugging purpose.
+ std::string getPrintableName() const;
+
+ /// \brief Get a GlobalSelector for the ASTContext-specific selector.
+ static GlobalSelector get(Selector Sel, Program &Prog);
+
+ void *getAsOpaquePtr() const { return Val; }
+
+ static GlobalSelector getFromOpaquePtr(void *Ptr) {
+ return GlobalSelector(Ptr);
+ }
+
+ friend bool operator==(const GlobalSelector &LHS, const GlobalSelector &RHS) {
+ return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr();
+ }
+
+ // For use in a std::map.
+ friend bool operator< (const GlobalSelector &LHS, const GlobalSelector &RHS) {
+ return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr();
+ }
+
+ // For use in DenseMap/DenseSet.
+ static GlobalSelector getEmptyMarker() { return GlobalSelector((void*)-1); }
+ static GlobalSelector getTombstoneMarker() {
+ return GlobalSelector((void*)-2);
+ }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that GlobalSelectors can be used as keys in DenseMap
+/// and DenseSets.
+template<>
+struct DenseMapInfo<clang::idx::GlobalSelector> {
+ static inline clang::idx::GlobalSelector getEmptyKey() {
+ return clang::idx::GlobalSelector::getEmptyMarker();
+ }
+
+ static inline clang::idx::GlobalSelector getTombstoneKey() {
+ return clang::idx::GlobalSelector::getTombstoneMarker();
+ }
+
+ static unsigned getHashValue(clang::idx::GlobalSelector);
+
+ static inline bool
+ isEqual(clang::idx::GlobalSelector LHS, clang::idx::GlobalSelector RHS) {
+ return LHS == RHS;
+ }
+};
+
+template <>
+struct isPodLike<clang::idx::GlobalSelector> { static const bool value = true;};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/Handlers.h b/contrib/llvm/tools/clang/include/clang/Index/Handlers.h
new file mode 100644
index 0000000..655aef9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/Handlers.h
@@ -0,0 +1,81 @@
+//===--- Handlers.h - Interfaces for receiving information ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Abstract interfaces for receiving information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_HANDLERS_H
+#define LLVM_CLANG_INDEX_HANDLERS_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+namespace idx {
+ class Entity;
+ class TranslationUnit;
+ class TULocation;
+
+/// \brief Abstract interface for receiving Entities.
+class EntityHandler {
+public:
+ typedef Entity receiving_type;
+
+ virtual ~EntityHandler();
+ virtual void Handle(Entity Ent) = 0;
+};
+
+/// \brief Abstract interface for receiving TranslationUnits.
+class TranslationUnitHandler {
+public:
+ typedef TranslationUnit* receiving_type;
+
+ virtual ~TranslationUnitHandler();
+ virtual void Handle(TranslationUnit *TU) = 0;
+};
+
+/// \brief Abstract interface for receiving TULocations.
+class TULocationHandler {
+public:
+ typedef TULocation receiving_type;
+
+ virtual ~TULocationHandler();
+ virtual void Handle(TULocation TULoc) = 0;
+};
+
+/// \brief Helper for the Handler classes. Stores the objects into a vector.
+/// example:
+/// @code
+/// Storing<TranslationUnitHandler> TURes;
+/// IndexProvider.GetTranslationUnitsFor(Entity, TURes);
+/// for (Storing<TranslationUnitHandler>::iterator
+/// I = TURes.begin(), E = TURes.end(); I != E; ++I) { ....
+/// @endcode
+template <typename handler_type>
+class Storing : public handler_type {
+ typedef typename handler_type::receiving_type receiving_type;
+ typedef llvm::SmallVector<receiving_type, 8> StoreTy;
+ StoreTy Store;
+
+public:
+ virtual void Handle(receiving_type Obj) {
+ Store.push_back(Obj);
+ }
+
+ typedef typename StoreTy::const_iterator iterator;
+ iterator begin() const { return Store.begin(); }
+ iterator end() const { return Store.end(); }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/IndexProvider.h b/contrib/llvm/tools/clang/include/clang/Index/IndexProvider.h
new file mode 100644
index 0000000..187dd93
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/IndexProvider.h
@@ -0,0 +1,38 @@
+//===--- IndexProvider.h - Maps information to translation units -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Maps information to TranslationUnits.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXPROVIDER_H
+#define LLVM_CLANG_INDEX_INDEXPROVIDER_H
+
+namespace clang {
+
+namespace idx {
+ class Entity;
+ class TranslationUnitHandler;
+ class GlobalSelector;
+
+/// \brief Maps information to TranslationUnits.
+class IndexProvider {
+public:
+ virtual ~IndexProvider();
+ virtual void GetTranslationUnitsFor(Entity Ent,
+ TranslationUnitHandler &Handler) = 0;
+ virtual void GetTranslationUnitsFor(GlobalSelector Sel,
+ TranslationUnitHandler &Handler) = 0;
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/Indexer.h b/contrib/llvm/tools/clang/include/clang/Index/Indexer.h
new file mode 100644
index 0000000..361e729
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/Indexer.h
@@ -0,0 +1,64 @@
+//===--- Indexer.h - IndexProvider implementation ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// IndexProvider implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXER_H
+#define LLVM_CLANG_INDEX_INDEXER_H
+
+#include "clang/Index/IndexProvider.h"
+#include "clang/Index/Entity.h"
+#include "clang/Index/GlobalSelector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/DenseMap.h"
+#include <map>
+
+namespace clang {
+ class ASTContext;
+
+namespace idx {
+ class Program;
+ class TranslationUnit;
+
+/// \brief Maps information to TranslationUnits.
+class Indexer : public IndexProvider {
+public:
+ typedef llvm::SmallPtrSet<TranslationUnit *, 4> TUSetTy;
+ typedef llvm::DenseMap<ASTContext *, TranslationUnit *> CtxTUMapTy;
+ typedef std::map<Entity, TUSetTy> MapTy;
+ typedef std::map<GlobalSelector, TUSetTy> SelMapTy;
+
+ explicit Indexer(Program &prog) :
+ Prog(prog) { }
+
+ Program &getProgram() const { return Prog; }
+
+ /// \brief Find all Entities and map them to the given translation unit.
+ void IndexAST(TranslationUnit *TU);
+
+ virtual void GetTranslationUnitsFor(Entity Ent,
+ TranslationUnitHandler &Handler);
+ virtual void GetTranslationUnitsFor(GlobalSelector Sel,
+ TranslationUnitHandler &Handler);
+
+private:
+ Program &Prog;
+
+ MapTy Map;
+ CtxTUMapTy CtxTUMap;
+ SelMapTy SelMap;
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/Program.h b/contrib/llvm/tools/clang/include/clang/Index/Program.h
new file mode 100644
index 0000000..8039192
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/Program.h
@@ -0,0 +1,45 @@
+//===--- Program.h - Cross-translation unit 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 declares the idx::Program interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_PROGRAM_H
+#define LLVM_CLANG_INDEX_PROGRAM_H
+
+namespace clang {
+ class ASTContext;
+
+namespace idx {
+ class EntityHandler;
+
+/// \brief Top level object that owns and maintains information
+/// that is common across translation units.
+class Program {
+ void *Impl;
+
+ Program(const Program&); // do not implement
+ Program &operator=(const Program &); // do not implement
+ friend class Entity;
+ friend class GlobalSelector;
+
+public:
+ Program();
+ ~Program();
+
+ /// \brief Traverses the AST and passes all the entities to the Handler.
+ void FindEntities(ASTContext &Ctx, EntityHandler &Handler);
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/STLExtras.h b/contrib/llvm/tools/clang/include/clang/Index/STLExtras.h
new file mode 100644
index 0000000..a3693c6
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/STLExtras.h
@@ -0,0 +1,63 @@
+//===--- STLExtras.h - Helper STL related templates -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Helper templates for using with the STL.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_STLEXTRAS_H
+#define LLVM_CLANG_INDEX_STLEXTRAS_H
+
+namespace clang {
+
+namespace idx {
+
+/// \brief Wraps an iterator whose value_type is a pair, and provides
+/// pair's second object as the value.
+template <typename iter_type>
+class pair_value_iterator {
+ iter_type I;
+
+public:
+ typedef typename iter_type::value_type::second_type value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
+ typedef typename iter_type::iterator_category iterator_category;
+ typedef typename iter_type::difference_type difference_type;
+
+ pair_value_iterator() { }
+ pair_value_iterator(iter_type i) : I(i) { }
+
+ reference operator*() const { return I->second; }
+ pointer operator->() const { return &I->second; }
+
+ pair_value_iterator& operator++() {
+ ++I;
+ return *this;
+ }
+
+ pair_value_iterator operator++(int) {
+ pair_value_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool operator==(pair_value_iterator L, pair_value_iterator R) {
+ return L.I == R.I;
+ }
+ friend bool operator!=(pair_value_iterator L, pair_value_iterator R) {
+ return L.I != R.I;
+ }
+};
+
+} // end idx namespace
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/SelectorMap.h b/contrib/llvm/tools/clang/include/clang/Index/SelectorMap.h
new file mode 100644
index 0000000..be01702
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/SelectorMap.h
@@ -0,0 +1,57 @@
+//===--- SelectorMap.h - Maps selectors to methods and messages -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// SelectorMap creates a mapping from selectors to ObjC method declarations
+// and ObjC message expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_SELECTORMAP_H
+#define LLVM_CLANG_INDEX_SELECTORMAP_H
+
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/STLExtras.h"
+#include "clang/Basic/IdentifierTable.h"
+#include <map>
+
+namespace clang {
+ class ASTContext;
+ class ObjCMethodDecl;
+
+namespace idx {
+
+/// \brief Maps NamedDecls with the ASTLocations that reference them.
+///
+/// References are mapped and retrieved using the canonical decls.
+class SelectorMap {
+public:
+ explicit SelectorMap(ASTContext &Ctx);
+
+ typedef std::multimap<Selector, ObjCMethodDecl *> SelMethMapTy;
+ typedef std::multimap<Selector, ASTLocation> SelRefMapTy;
+
+ typedef pair_value_iterator<SelMethMapTy::iterator> method_iterator;
+ typedef pair_value_iterator<SelRefMapTy::iterator> astlocation_iterator;
+
+ method_iterator methods_begin(Selector Sel) const;
+ method_iterator methods_end(Selector Sel) const;
+
+ astlocation_iterator refs_begin(Selector Sel) const;
+ astlocation_iterator refs_end(Selector Sel) const;
+
+private:
+ mutable SelMethMapTy SelMethMap;
+ mutable SelRefMapTy SelRefMap;
+};
+
+} // end idx namespace
+
+} // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h b/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h
new file mode 100644
index 0000000..bf9e78f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h
@@ -0,0 +1,37 @@
+//===--- TranslationUnit.h - Interface for a translation unit ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Abstract interface for a translation unit.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_TRANSLATIONUNIT_H
+#define LLVM_CLANG_INDEX_TRANSLATIONUNIT_H
+
+namespace clang {
+ class ASTContext;
+
+namespace idx {
+ class DeclReferenceMap;
+ class SelectorMap;
+
+/// \brief Abstract interface for a translation unit.
+class TranslationUnit {
+public:
+ virtual ~TranslationUnit();
+ virtual ASTContext &getASTContext() = 0;
+ virtual DeclReferenceMap &getDeclReferenceMap() = 0;
+ virtual SelectorMap &getSelectorMap() = 0;
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Index/Utils.h b/contrib/llvm/tools/clang/include/clang/Index/Utils.h
new file mode 100644
index 0000000..f8e01f7
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Index/Utils.h
@@ -0,0 +1,36 @@
+//===--- Utils.h - Misc utilities for indexing-----------------------------===//
+//
+// 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 indexing related
+// functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_UTILS_H
+#define LLVM_CLANG_INDEX_UTILS_H
+
+namespace clang {
+ class ASTContext;
+ class SourceLocation;
+
+namespace idx {
+ class ASTLocation;
+
+/// \brief Returns the ASTLocation that a source location points to.
+///
+/// \returns the resolved ASTLocation or an invalid ASTLocation if the source
+/// location could not be resolved.
+ASTLocation ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc,
+ ASTLocation *LastLoc = 0);
+
+} // end namespace idx
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h b/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h
new file mode 100644
index 0000000..64687a1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h
@@ -0,0 +1,134 @@
+//===--- 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/SourceManager.h"
+
+namespace llvm {
+ class StringRef;
+}
+namespace clang {
+class HeaderMap;
+class DirectoryEntry;
+class FileEntry;
+class HeaderSearch;
+
+/// 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;
+
+ /// UserSupplied - True if this is a user-supplied directory.
+ ///
+ bool UserSupplied : 1;
+
+ /// LookupType - This indicates whether this DirectoryLookup object is a
+ /// normal directory, a framework, or a headermap.
+ unsigned LookupType : 2;
+public:
+ /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
+ /// 'dir'.
+ DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
+ bool isUser, bool isFramework)
+ : DirCharacteristic(DT), UserSupplied(isUser),
+ LookupType(isFramework ? LT_Framework : LT_NormalDir) {
+ u.Dir = dir;
+ }
+
+ /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
+ /// 'map'.
+ DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
+ bool isUser)
+ : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap) {
+ 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 : 0; }
+
+ /// getFrameworkDir - Return the directory that this framework refers to.
+ ///
+ const DirectoryEntry *getFrameworkDir() const {
+ return isFramework() ? u.Dir : 0;
+ }
+
+ /// getHeaderMap - Return the directory that this entry refers to.
+ ///
+ const HeaderMap *getHeaderMap() const { return isHeaderMap() ? u.Map : 0; }
+
+ /// 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; }
+
+ /// DirCharacteristic - The type of directory this is, one of the DirType enum
+ /// values.
+ SrcMgr::CharacteristicKind getDirCharacteristic() const {
+ return (SrcMgr::CharacteristicKind)DirCharacteristic;
+ }
+
+ /// isUserSupplied - True if this is a user-supplied directory.
+ ///
+ bool isUserSupplied() const { return UserSupplied; }
+
+
+ /// LookupFile - Lookup the specified file in this search path, returning it
+ /// if it exists or returning null if not.
+ const FileEntry *LookupFile(llvm::StringRef Filename, HeaderSearch &HS) const;
+
+private:
+ const FileEntry *DoFrameworkLookup(llvm::StringRef Filename,
+ HeaderSearch &HS) const;
+
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/ExternalPreprocessorSource.h b/contrib/llvm/tools/clang/include/clang/Lex/ExternalPreprocessorSource.h
new file mode 100644
index 0000000..af5c389
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/ExternalPreprocessorSource.h
@@ -0,0 +1,34 @@
+//===- 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_EXTERNAL_PREPROCESSOR_SOURCE_H
+#define LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
+
+namespace clang {
+
+/// \brief Abstract interface for external sources of preprocessor
+/// information.
+///
+/// This abstract class allows an external sources (such as the \c PCHReader)
+/// to provide additional macro definitions.
+class ExternalPreprocessorSource {
+public:
+ virtual ~ExternalPreprocessorSource();
+
+ /// \brief Read the set of macros defined by this external macro source.
+ virtual void ReadDefinedMacros() = 0;
+};
+
+}
+
+#endif // LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h
new file mode 100644
index 0000000..9837e29
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h
@@ -0,0 +1,67 @@
+//===--- 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
+
+namespace llvm {
+ class MemoryBuffer;
+ class StringRef;
+}
+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&); // DO NOT IMPLEMENT
+ void operator=(const HeaderMap&); // DO NOT IMPLEMENT
+
+ const llvm::MemoryBuffer *FileBuffer;
+ bool NeedsBSwap;
+
+ HeaderMap(const llvm::MemoryBuffer *File, bool BSwap)
+ : FileBuffer(File), NeedsBSwap(BSwap) {
+ }
+public:
+ ~HeaderMap();
+
+ /// 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);
+
+ /// LookupFile - Check to see if the specified relative filename is located in
+ /// this HeaderMap. If so, open it and return its FileEntry.
+ const FileEntry *LookupFile(llvm::StringRef Filename, FileManager &FM) 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/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h
new file mode 100644
index 0000000..978585c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h
@@ -0,0 +1,235 @@
+//===--- 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 "llvm/ADT/StringMap.h"
+#include <vector>
+
+namespace clang {
+
+class ExternalIdentifierLookup;
+class FileEntry;
+class FileManager;
+class IdentifierInfo;
+
+/// HeaderFileInfo - The preprocessor keeps track of this information for each
+/// file that is #included.
+struct HeaderFileInfo {
+ /// isImport - True if this is a #import'd or #pragma once file.
+ bool isImport : 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;
+
+ /// NumIncludes - This is the number of times the file has been included
+ /// already.
+ unsigned short NumIncludes;
+
+ /// ControllingMacro - 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 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;
+
+ HeaderFileInfo()
+ : isImport(false), DirInfo(SrcMgr::C_User),
+ NumIncludes(0), ControllingMacro(0), ControllingMacroID(0) {}
+
+ /// \brief Retrieve the controlling macro for this header file, if
+ /// any.
+ const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
+};
+
+/// HeaderSearch - This class encapsulates the information needed to find the
+/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
+class HeaderSearch {
+ FileManager &FileMgr;
+
+ /// #include search path information. Requests for #include "x" search the
+ /// directory of the #including file first, then each directory in SearchDirs
+ /// consequtively. Requests for <x> search the current dir first, then each
+ /// directory in SearchDirs, starting at SystemDirIdx, consequtively. If
+ /// NoCurDirSearch is true, then the check for the file in the current
+ /// directory is supressed.
+ std::vector<DirectoryLookup> SearchDirs;
+ unsigned SystemDirIdx;
+ bool NoCurDirSearch;
+
+ /// FileInfo - This contains all of the preprocessor-specific data about files
+ /// that are included. The vector is indexed by the FileEntry's UID.
+ ///
+ std::vector<HeaderFileInfo> FileInfo;
+
+ /// LookupFileCache - This is keeps track of each lookup performed by
+ /// LookupFile. The first part of the value is the 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. The second value is the entry in SearchDirs that satisfied the
+ /// query.
+ llvm::StringMap<std::pair<unsigned, unsigned> > LookupFileCache;
+
+
+ /// FrameworkMap - This is a collection mapping a framework or subframework
+ /// name like "Carbon" to the Carbon.framework directory.
+ llvm::StringMap<const DirectoryEntry *> FrameworkMap;
+
+ /// 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 Entity used to resolve the identifier IDs of controlling
+ /// macros into IdentifierInfo pointers, as needed.
+ ExternalIdentifierLookup *ExternalLookup;
+
+ // Various statistics we track for performance analysis.
+ unsigned NumIncluded;
+ unsigned NumMultiIncludeFileOptzn;
+ unsigned NumFrameworkLookups, NumSubFrameworkLookups;
+
+ // HeaderSearch doesn't support default or copy construction.
+ explicit HeaderSearch();
+ explicit HeaderSearch(const HeaderSearch&);
+ void operator=(const HeaderSearch&);
+public:
+ HeaderSearch(FileManager &FM);
+ ~HeaderSearch();
+
+ FileManager &getFileMgr() const { return FileMgr; }
+
+ /// SetSearchPaths - Interface for setting the file search paths.
+ ///
+ void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
+ unsigned systemDirIdx, bool noCurDirSearch) {
+ SearchDirs = dirs;
+ SystemDirIdx = systemDirIdx;
+ NoCurDirSearch = noCurDirSearch;
+ //LookupFileCache.clear();
+ }
+
+ /// ClearFileInfo - Forget everything we know about headers so far.
+ void ClearFileInfo() {
+ FileInfo.clear();
+ }
+
+ void SetExternalLookup(ExternalIdentifierLookup *EIL) {
+ ExternalLookup = EIL;
+ }
+
+ /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+ /// return null on failure. isAngled indicates whether the file reference is
+ /// a <> reference. If successful, this returns 'UsedDir', the
+ /// DirectoryLookup member the file was found in, or null if not applicable.
+ /// If CurDir is non-null, the file was found in the specified directory
+ /// search location. This is used to implement #include_next. CurFileEnt, if
+ /// non-null, indicates where the #including file is, in case a relative
+ /// search is needed.
+ const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled,
+ const DirectoryLookup *FromDir,
+ const DirectoryLookup *&CurDir,
+ const FileEntry *CurFileEnt);
+
+ /// LookupSubframeworkHeader - 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(llvm::StringRef Filename,
+ const FileEntry *RelativeFileEnt);
+
+ /// LookupFrameworkCache - Look up the specified framework name in our
+ /// framework cache, returning the DirectoryEntry it is in if we know,
+ /// otherwise, return null.
+ const DirectoryEntry *&LookupFrameworkCache(llvm::StringRef FWName) {
+ return FrameworkMap.GetOrCreateValue(FWName).getValue();
+ }
+
+ /// ShouldEnterIncludeFile - 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(const FileEntry *File, bool isImport);
+
+
+ /// getFileDirFlavor - 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;
+ }
+
+ /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
+ /// due to #pragma once.
+ void MarkFileIncludeOnce(const FileEntry *File) {
+ getFileInfo(File).isImport = true;
+ }
+
+ /// MarkFileSystemHeader - 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;
+ }
+
+ /// IncrementIncludeCount - Increment the count for the number of times the
+ /// specified FileEntry has been entered.
+ void IncrementIncludeCount(const FileEntry *File) {
+ ++getFileInfo(File).NumIncludes;
+ }
+
+ /// SetFileControllingMacro - 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;
+ }
+
+ /// CreateHeaderMap - This method returns a HeaderMap for the specified
+ /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
+ const HeaderMap *CreateHeaderMap(const FileEntry *FE);
+
+ void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
+
+ typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator;
+ header_file_iterator header_file_begin() const { return FileInfo.begin(); }
+ header_file_iterator header_file_end() const { return FileInfo.end(); }
+ unsigned header_file_size() const { return FileInfo.size(); }
+
+ // Used by PCHReader.
+ void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
+
+ void PrintStats();
+private:
+
+ /// getFileInfo - Return the HeaderFileInfo structure for the specified
+ /// FileEntry.
+ HeaderFileInfo &getFileInfo(const FileEntry *FE);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h
new file mode 100644
index 0000000..2d941e4
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- 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_DIAGNOSTICLEX_H
+#define LLVM_CLANG_DIAGNOSTICLEX_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+ namespace diag {
+ enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,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/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h b/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h
new file mode 100644
index 0000000..6a6e319
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h
@@ -0,0 +1,384 @@
+//===--- 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_LEXER_H
+#define LLVM_CLANG_LEXER_H
+
+#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+#include <vector>
+#include <cassert>
+
+namespace clang {
+class Diagnostic;
+class SourceManager;
+class Preprocessor;
+class DiagnosticBuilder;
+
+/// 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 {
+ //===--------------------------------------------------------------------===//
+ // 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 Features; // Features enabled by this language (cache).
+ bool Is_PragmaLexer : 1; // True if lexer for _Pragma handling.
+ bool IsInConflictMarker : 1; // True if in a VCS conflict marker '<<<<<<<'
+
+ //===--------------------------------------------------------------------===//
+ // 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;
+
+ Lexer(const Lexer&); // DO NOT IMPLEMENT
+ void operator=(const Lexer&); // DO NOT IMPLEMENT
+ 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 'LexRawToken'. This lexer assumes that the text
+ /// range will outlive it, so it doesn't take ownership of it.
+ Lexer(SourceLocation FileLoc, const LangOptions &Features,
+ 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 'LexRawToken'. 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 &Features);
+
+ /// 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 InstantiationLocStart,
+ SourceLocation InstantiationLocEnd,
+ unsigned TokLen, Preprocessor &PP);
+
+
+ /// getFeatures - Return the language features currently enabled. NOTE: this
+ /// lexer modifies features as a file is parsed!
+ const LangOptions &getFeatures() const { return Features; }
+
+ /// 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; }
+
+ /// Lex - Return the next token in the file. If this is the end of file, it
+ /// return the tok::eof token. Return true if an error occurred and
+ /// compilation should terminate, false if normal. This implicitly involves
+ /// the preprocessor.
+ void Lex(Token &Result) {
+ // Start a new token.
+ Result.startToken();
+
+ // NOTE, any changes here should also change code after calls to
+ // Preprocessor::HandleDirective
+ if (IsAtStartOfLine) {
+ Result.setFlag(Token::StartOfLine);
+ IsAtStartOfLine = false;
+ }
+
+ // Get a token. Note that this may delete the current lexer if the end of
+ // file is reached.
+ LexTokenInternal(Result);
+ }
+
+ /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma.
+ bool isPragmaLexer() const { return Is_PragmaLexer; }
+
+ /// IndirectLex - An indirect call to 'Lex' that can be invoked via
+ /// the PreprocessorLexer interface.
+ void IndirectLex(Token &Result) { Lex(Result); }
+
+ /// 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) &&
+ "Can only enable whitespace retention in raw mode");
+ 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;
+ }
+
+ const char *getBufferStart() const { return BufferStart; }
+
+ /// ReadToEndOfLine - Read the rest of the current preprocessor line as an
+ /// uninterpreted string. This switches the lexer out of directive mode.
+ std::string ReadToEndOfLine();
+
+
+ /// 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() { 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(const std::string &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(llvm::SmallVectorImpl<char> &Str);
+
+ /// 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);
+
+ //===--------------------------------------------------------------------===//
+ // Internal implementation interfaces.
+private:
+
+ /// LexTokenInternal - Internal interface to lex a preprocessing token. Called
+ /// by Lex.
+ ///
+ void LexTokenInternal(Token &Result);
+
+ /// 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.
+public:
+
+ // 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;
+ }
+
+private:
+ /// 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 = 0);
+public:
+
+ /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
+ /// emit a warning.
+ static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
+ const LangOptions &Features) {
+ // 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, Features);
+ }
+
+ /// 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);
+private:
+
+ /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
+ /// diagnostic.
+ static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
+ const LangOptions &Features);
+
+ //===--------------------------------------------------------------------===//
+ // Other lexer functions.
+
+ // Helper functions to lex the remainder of a token of the specific type.
+ void LexIdentifier (Token &Result, const char *CurPtr);
+ void LexNumericConstant (Token &Result, const char *CurPtr);
+ void LexStringLiteral (Token &Result, const char *CurPtr,bool Wide);
+ void LexAngledStringLiteral(Token &Result, const char *CurPtr);
+ void LexCharConstant (Token &Result, const char *CurPtr);
+ bool LexEndOfFile (Token &Result, const char *CurPtr);
+
+ bool SkipWhitespace (Token &Result, const char *CurPtr);
+ bool SkipBCPLComment (Token &Result, const char *CurPtr);
+ bool SkipBlockComment (Token &Result, const char *CurPtr);
+ bool SaveBCPLComment (Token &Result, const char *CurPtr);
+
+ bool IsStartOfConflictMarker(const char *CurPtr);
+ bool HandleEndOfConflictMarker(const char *CurPtr);
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h b/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h
new file mode 100644
index 0000000..ba46fb1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h
@@ -0,0 +1,172 @@
+//===--- 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 CLANG_LITERALSUPPORT_H
+#define CLANG_LITERALSUPPORT_H
+
+#include <string>
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/System/DataTypes.h"
+
+namespace clang {
+
+class Diagnostic;
+class Preprocessor;
+class Token;
+class SourceLocation;
+class TargetInfo;
+
+/// 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;
+
+public:
+ NumericLiteralParser(const char *begin, const char *end,
+ SourceLocation Loc, Preprocessor &PP);
+ bool hadError;
+ bool isUnsigned;
+ bool isLong; // This is *not* set for long long.
+ bool isLongLong;
+ bool isFloat; // 1.0f
+ bool isImaginary; // 1.0i
+ bool isMicrosoftInteger; // 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 hasSuffix() const {
+ return SuffixBegin != ThisTokEnd;
+ }
+
+ 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);
+
+ /// 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 && isxdigit(*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')))
+ 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))
+ 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'))
+ ptr++;
+ return ptr;
+ }
+
+};
+
+/// CharLiteralParser - Perform interpretation and semantic analysis of a
+/// character literal.
+class CharLiteralParser {
+ uint64_t Value;
+ bool IsWide;
+ bool IsMultiChar;
+ bool HadError;
+public:
+ CharLiteralParser(const char *begin, const char *end,
+ SourceLocation Loc, Preprocessor &PP);
+
+ bool hadError() const { return HadError; }
+ bool isWide() const { return IsWide; }
+ bool isMultiChar() const { return IsMultiChar; }
+ uint64_t getValue() const { return Value; }
+};
+
+/// 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 {
+ Preprocessor &PP;
+
+ unsigned MaxTokenLength;
+ unsigned SizeBound;
+ unsigned wchar_tByteWidth;
+ llvm::SmallString<512> ResultBuf;
+ char *ResultPtr; // cursor
+public:
+ StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+ Preprocessor &PP, bool Complain = true);
+ bool hadError;
+ bool AnyWide;
+ bool Pascal;
+
+ const char *GetString() { return &ResultBuf[0]; }
+ unsigned GetStringLength() const { return ResultPtr-&ResultBuf[0]; }
+
+ unsigned GetNumStringChars() const {
+ if (AnyWide)
+ return GetStringLength() / wchar_tByteWidth;
+ return GetStringLength();
+ }
+ /// 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.
+ static unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo,
+ Preprocessor &PP, bool Complain = true);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h
new file mode 100644
index 0000000..5887041
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h
@@ -0,0 +1,218 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MacroInfo interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MACROINFO_H
+#define LLVM_CLANG_MACROINFO_H
+
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+#include <cassert>
+
+namespace clang {
+ class Preprocessor;
+
+/// MacroInfo - Each identifier that is #define'd has an instance of this class
+/// associated with it, used to implement macro expansion.
+class MacroInfo {
+ //===--------------------------------------------------------------------===//
+ // State set when the macro is defined.
+
+ /// Location - This is the place the macro is defined.
+ SourceLocation Location;
+ /// EndLocation - The location of the last token in the macro.
+ SourceLocation EndLocation;
+
+ /// Arguments - The list of arguments for a function-like macro. This can be
+ /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this
+ /// includes the __VA_ARGS__ identifier on the list.
+ IdentifierInfo **ArgumentList;
+ unsigned NumArguments;
+
+ /// ReplacementTokens - This is the list of tokens that the macro is defined
+ /// to.
+ llvm::SmallVector<Token, 8> ReplacementTokens;
+
+ /// IsFunctionLike - True if this macro is a function-like macro, false if it
+ /// is an object-like macro.
+ bool IsFunctionLike : 1;
+
+ /// IsC99Varargs - 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;
+
+ /// IsGNUVarargs - 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;
+
+ /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
+ /// it has not yet been redefined or undefined.
+ bool IsBuiltinMacro : 1;
+
+private:
+ //===--------------------------------------------------------------------===//
+ // State that changes as the macro is used.
+
+ /// IsDisabled - True if we have started an expansion of this macro already.
+ /// This disbles recursive expansion, which would be quite bad for things like
+ /// #define A A.
+ bool IsDisabled : 1;
+
+ /// IsUsed - 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;
+
+ ~MacroInfo() {
+ assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
+ }
+
+public:
+ MacroInfo(SourceLocation DefLoc);
+
+ /// FreeArgumentList - Free the argument list of the macro, restoring it to a
+ /// state where it can be reused for other devious purposes.
+ void FreeArgumentList(llvm::BumpPtrAllocator &PPAllocator) {
+ PPAllocator.Deallocate(ArgumentList);
+ ArgumentList = 0;
+ NumArguments = 0;
+ }
+
+ /// Destroy - destroy this MacroInfo object.
+ void Destroy(llvm::BumpPtrAllocator &PPAllocator) {
+ FreeArgumentList(PPAllocator);
+ this->~MacroInfo();
+ }
+
+ /// getDefinitionLoc - Return the location that the macro was defined at.
+ ///
+ SourceLocation getDefinitionLoc() const { return Location; }
+
+ /// setDefinitionEndLoc - Set the location of the last token in the macro.
+ ///
+ void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; }
+ /// getDefinitionEndLoc - Return the location of the last token in the macro.
+ ///
+ SourceLocation getDefinitionEndLoc() const { return EndLocation; }
+
+ /// isIdenticalTo - Return true if the specified macro definition is equal to
+ /// this macro in spelling, arguments, and whitespace. This is used to emit
+ /// duplicate definition warnings. This implements the rules in C99 6.10.3.
+ bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const;
+
+ /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
+ ///
+ void setIsBuiltinMacro(bool Val = true) {
+ IsBuiltinMacro = Val;
+ }
+
+ /// setIsUsed - Set the value of the IsUsed flag.
+ ///
+ void setIsUsed(bool Val) {
+ IsUsed = Val;
+ }
+
+ /// setArgumentList - Set the specified list of identifiers as the argument
+ /// list for this macro.
+ void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
+ llvm::BumpPtrAllocator &PPAllocator) {
+ assert(ArgumentList == 0 && NumArguments == 0 &&
+ "Argument list already set!");
+ if (NumArgs == 0) return;
+
+ NumArguments = NumArgs;
+ ArgumentList = PPAllocator.Allocate<IdentifierInfo*>(NumArgs);
+ for (unsigned i = 0; i != NumArgs; ++i)
+ ArgumentList[i] = List[i];
+ }
+
+ /// 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; }
+
+ /// getArgumentNum - Return the argument number of the specified identifier,
+ /// or -1 if the identifier is not a formal argument identifier.
+ int getArgumentNum(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; }
+
+ /// isBuiltinMacro - Return true if this macro is a builtin macro, such as
+ /// __LINE__, which requires processing before expansion.
+ bool isBuiltinMacro() const { return IsBuiltinMacro; }
+
+ /// isUsed - Return false if this macro is defined in the main file and has
+ /// not yet been used.
+ bool isUsed() const { return IsUsed; }
+
+ /// getNumTokens - 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 llvm::SmallVector<Token, 8>::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(); }
+
+ /// AddTokenToBody - Add the specified token to the replacement text for the
+ /// macro.
+ void AddTokenToBody(const Token &Tok) {
+ ReplacementTokens.push_back(Tok);
+ }
+
+ /// isEnabled - 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;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/MultipleIncludeOpt.h b/contrib/llvm/tools/clang/include/clang/Lex/MultipleIncludeOpt.h
new file mode 100644
index 0000000..5d5d673
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/MultipleIncludeOpt.h
@@ -0,0 +1,130 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MultipleIncludeOpt interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+#define LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+
+namespace clang {
+class IdentifierInfo;
+
+/// MultipleIncludeOpt - This class 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;
+
+ /// 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;
+public:
+ MultipleIncludeOpt() {
+ ReadAnyTokens = false;
+ DidMacroExpansion = false;
+ TheMacro = 0;
+ }
+
+ /// Invalidate - Permenantly 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;
+ TheMacro = 0;
+ }
+
+ /// 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; }
+
+ // If a token is read, remember that we have seen a side-effect in this file.
+ void ReadToken() { ReadAnyTokens = true; }
+
+ /// 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; }
+
+ /// EnterTopLevelIFNDEF - When entering a top-level #ifndef directive (or the
+ /// "#if !defined" equivalent) without any preceding tokens, this method is
+ /// called.
+ ///
+ /// 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) {
+ // 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;
+ TheMacro = M;
+ }
+
+ /// EnterTopLevelConditional - This is 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();
+ }
+
+ /// ExitTopLevelConditional - This method is 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;
+ }
+
+ /// GetControllingMacroAtEndOfFile - 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 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h
new file mode 100644
index 0000000..d74124e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h
@@ -0,0 +1,148 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PPCallbacks interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
+#define LLVM_CLANG_LEX_PPCALLBACKS_H
+
+#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Basic/SourceLocation.h"
+#include <string>
+
+namespace clang {
+ class SourceLocation;
+ class Token;
+ class IdentifierInfo;
+ class MacroInfo;
+
+/// PPCallbacks - 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
+ };
+
+ /// FileChanged - This callback is invoked whenever a source file is
+ /// entered or exited. The SourceLocation indicates the new location, and
+ /// EnteringFile indicates whether this is because we are entering a new
+ /// #include'd file (when true) or whether we're exiting one because we ran
+ /// off the end (when false).
+ virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+ SrcMgr::CharacteristicKind FileType) {
+ }
+
+ /// FileSkipped - This callback is invoked whenever a source file is
+ /// skipped as the result of header guard optimization. ParentFile
+ /// is the file that #includes the skipped file. FilenameTok is the
+ /// token in ParentFile that indicates the skipped file.
+ virtual void FileSkipped(const FileEntry &ParentFile,
+ const Token &FilenameTok,
+ SrcMgr::CharacteristicKind FileType) {
+ }
+
+ /// EndOfMainFile - This callback is invoked when the end of the main file is
+ /// reach, no subsequent callbacks will be made.
+ virtual void EndOfMainFile() {
+ }
+
+ /// Ident - This callback is invoked when a #ident or #sccs directive is read.
+ ///
+ virtual void Ident(SourceLocation Loc, const std::string &str) {
+ }
+
+ /// PragmaComment - This callback is invoked when a #pragma comment directive
+ /// is read.
+ ///
+ virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+ const std::string &Str) {
+ }
+
+ /// MacroExpands - This is called by
+ /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
+ /// found.
+ virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
+ }
+
+ /// MacroDefined - This hook is called whenever a macro definition is seen.
+ virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) {
+ }
+
+ /// MacroUndefined - This hook is called whenever a macro #undef is seen.
+ /// MI is released immediately following this callback.
+ virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) {
+ }
+};
+
+/// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
+class PPChainedCallbacks : public PPCallbacks {
+ PPCallbacks *First, *Second;
+
+public:
+ PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
+ : First(_First), Second(_Second) {}
+ ~PPChainedCallbacks() {
+ delete Second;
+ delete First;
+ }
+
+ virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+ SrcMgr::CharacteristicKind FileType) {
+ First->FileChanged(Loc, Reason, FileType);
+ Second->FileChanged(Loc, Reason, FileType);
+ }
+
+ virtual void FileSkipped(const FileEntry &ParentFile,
+ const Token &FilenameTok,
+ SrcMgr::CharacteristicKind FileType) {
+ First->FileSkipped(ParentFile, FilenameTok, FileType);
+ Second->FileSkipped(ParentFile, FilenameTok, FileType);
+ }
+
+ virtual void EndOfMainFile() {
+ First->EndOfMainFile();
+ Second->EndOfMainFile();
+ }
+
+ virtual void Ident(SourceLocation Loc, const std::string &str) {
+ First->Ident(Loc, str);
+ Second->Ident(Loc, str);
+ }
+
+ virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+ const std::string &Str) {
+ First->PragmaComment(Loc, Kind, Str);
+ Second->PragmaComment(Loc, Kind, Str);
+ }
+
+ virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
+ First->MacroExpands(Id, MI);
+ Second->MacroExpands(Id, MI);
+ }
+
+ virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) {
+ First->MacroDefined(II, MI);
+ Second->MacroDefined(II, MI);
+ }
+
+ virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) {
+ First->MacroUndefined(II, MI);
+ Second->MacroUndefined(II, MI);
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h
new file mode 100644
index 0000000..e96a8c5
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h
@@ -0,0 +1,104 @@
+//===--- 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_PTHLEXER_H
+#define LLVM_CLANG_PTHLEXER_H
+
+#include "clang/Lex/PreprocessorLexer.h"
+#include <vector>
+
+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&); // DO NOT IMPLEMENT
+ void operator=(const PTHLexer&); // DO NOT IMPLEMENT
+
+ /// ReadToken - Used by PTHLexer to read tokens TokBuf.
+ void ReadToken(Token& T);
+
+ /// 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() {}
+
+ /// Lex - Return the next token.
+ void 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) { Lex(Result); }
+
+ /// getSourceLocation - Return a source location for the token in
+ /// the current file.
+ SourceLocation getSourceLocation();
+
+ /// SkipBlock - Used by Preprocessor to skip the current conditional block.
+ bool SkipBlock();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h b/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h
new file mode 100644
index 0000000..5e8a4f1
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h
@@ -0,0 +1,140 @@
+//===--- 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_PTHMANAGER_H
+#define LLVM_CLANG_PTHMANAGER_H
+
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+#include <string>
+
+namespace llvm {
+ class MemoryBuffer;
+}
+
+namespace clang {
+
+class FileEntry;
+class PTHLexer;
+class Diagnostic;
+class StatSysCallCache;
+
+class PTHManager : public IdentifierInfoLookup {
+ friend class PTHLexer;
+
+ /// The memory mapped PTH file.
+ const llvm::MemoryBuffer* Buf;
+
+ /// Alloc - Allocator used for IdentifierInfo objects.
+ llvm::BumpPtrAllocator Alloc;
+
+ /// IdMap - A lazily generated cache mapping from persistent identifiers to
+ /// IdentifierInfo*.
+ IdentifierInfo** PerIDCache;
+
+ /// FileLookup - Abstract data structure used for mapping between files
+ /// and token data in the PTH file.
+ void* 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().
+ void* 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(const llvm::MemoryBuffer* buf, void* fileLookup,
+ const unsigned char* idDataTable, IdentifierInfo** perIDCache,
+ void* stringIdLookup, unsigned numIds,
+ const unsigned char* spellingBase, const char *originalSourceFile);
+
+ // Do not implement.
+ PTHManager();
+ void operator=(const PTHManager&);
+
+ /// 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 = 9 };
+
+ ~PTHManager();
+
+ /// 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(llvm::StringRef Name);
+
+ /// 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(const std::string& file, Diagnostic &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 StatSysCallCache 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.
+ StatSysCallCache *createStatCache();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h b/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h
new file mode 100644
index 0000000..ef367fe
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h
@@ -0,0 +1,90 @@
+//===--- 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_PRAGMA_H
+#define LLVM_CLANG_PRAGMA_H
+
+#include <cassert>
+#include <vector>
+
+namespace clang {
+ class Preprocessor;
+ class Token;
+ class IdentifierInfo;
+ class PragmaNamespace;
+
+/// 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 {
+ const IdentifierInfo *Name;
+public:
+ PragmaHandler(const IdentifierInfo *name) : Name(name) {}
+ virtual ~PragmaHandler();
+
+ const IdentifierInfo *getName() const { return Name; }
+ virtual void HandlePragma(Preprocessor &PP, 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 0; }
+};
+
+/// 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 the list of handlers in this namespace.
+ ///
+ std::vector<PragmaHandler*> Handlers;
+public:
+ PragmaNamespace(const IdentifierInfo *Name) : PragmaHandler(Name) {}
+ virtual ~PragmaNamespace();
+
+ /// FindHandler - Check to see if there is already a handler for the
+ /// specified name. If not, return the handler for the null identifier 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(const IdentifierInfo *Name,
+ bool IgnoreNull = true) const;
+
+ /// AddPragma - Add a pragma to this namespace.
+ ///
+ void AddPragma(PragmaHandler *Handler) {
+ Handlers.push_back(Handler);
+ }
+
+ /// RemovePragmaHandler - Remove the given handler from the
+ /// namespace.
+ void RemovePragmaHandler(PragmaHandler *Handler);
+
+ bool IsEmpty() {
+ return Handlers.empty();
+ }
+
+ virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+
+ virtual PragmaNamespace *getIfNamespace() { return this; }
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h
new file mode 100644
index 0000000..ef28af9
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h
@@ -0,0 +1,274 @@
+//===--- 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/Lex/PPCallbacks.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+
+namespace clang {
+ class IdentifierInfo;
+ class PreprocessingRecord;
+}
+
+/// \brief Allocates memory within a Clang preprocessing record.
+void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
+ unsigned alignment = 8) throw();
+
+/// \brief Frees memory allocated in a Clang preprocessing record.
+void operator delete(void* ptr, clang::PreprocessingRecord& PR,
+ unsigned) throw();
+
+namespace clang {
+ class MacroDefinition;
+
+ /// \brief Base class that describes a preprocessed entity, which may be a
+ /// preprocessor directive or macro instantiation.
+ class PreprocessedEntity {
+ public:
+ /// \brief The kind of preprocessed entity an object describes.
+ enum EntityKind {
+ /// \brief A macro instantiation.
+ MacroInstantiationKind,
+
+ /// \brief A preprocessing directive whose kind is not specified.
+ ///
+ /// This kind will be used for any preprocessing directive that does not
+ /// have a more specific kind within the \c DirectiveKind enumeration.
+ PreprocessingDirectiveKind,
+
+ /// \brief A macro definition.
+ MacroDefinitionKind,
+
+ FirstPreprocessingDirective = PreprocessingDirectiveKind,
+ LastPreprocessingDirective = MacroDefinitionKind
+ };
+
+ 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) { }
+
+ 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 { return Range; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const PreprocessedEntity *) { return true; }
+
+ // 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) throw() {
+ return ::operator new(bytes, PR, alignment);
+ }
+
+ void* operator new(size_t bytes, void* mem) throw() {
+ return mem;
+ }
+
+ void operator delete(void* ptr, PreprocessingRecord& PR,
+ unsigned alignment) throw() {
+ return ::operator delete(ptr, PR, alignment);
+ }
+
+ void operator delete(void*, std::size_t) throw() { }
+ void operator delete(void*, void*) throw() { }
+
+ private:
+ // Make vanilla 'new' and 'delete' illegal for preprocessed entities.
+ void* operator new(size_t bytes) throw();
+ void operator delete(void* data) throw();
+ };
+
+ /// \brief Records the location of a macro instantiation.
+ class MacroInstantiation : public PreprocessedEntity {
+ /// \brief The name of the macro being instantiation.
+ IdentifierInfo *Name;
+
+ /// \brief The definition of this macro.
+ MacroDefinition *Definition;
+
+ public:
+ MacroInstantiation(IdentifierInfo *Name, SourceRange Range,
+ MacroDefinition *Definition)
+ : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name),
+ Definition(Definition) { }
+
+ /// \brief The name of the macro being instantiated.
+ IdentifierInfo *getName() const { return Name; }
+
+ /// \brief The definition of the macro being instantiated.
+ MacroDefinition *getDefinition() const { return Definition; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const PreprocessedEntity *PE) {
+ return PE->getKind() == MacroInstantiationKind;
+ }
+ static bool classof(const MacroInstantiation *) { return true; }
+
+ };
+
+ /// \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;
+ }
+ static bool classof(const PreprocessingDirective *) { return true; }
+ };
+
+ /// \brief Record the location of a macro definition.
+ class MacroDefinition : public PreprocessingDirective {
+ /// \brief The name of the macro being defined.
+ const IdentifierInfo *Name;
+
+ /// \brief The location of the macro name in the macro definition.
+ SourceLocation Location;
+
+ public:
+ explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location,
+ SourceRange Range)
+ : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name),
+ Location(Location) { }
+
+ /// \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 Location; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const PreprocessedEntity *PE) {
+ return PE->getKind() == MacroDefinitionKind;
+ }
+ static bool classof(const MacroDefinition *) { return true; }
+ };
+
+ /// \brief An abstract class that should be subclassed by any external source
+ /// of preprocessing record entries.
+ class ExternalPreprocessingRecordSource {
+ public:
+ virtual ~ExternalPreprocessingRecordSource();
+
+ /// \brief Read any preallocated preprocessed entities from the external
+ /// source.
+ virtual void ReadPreprocessedEntities() = 0;
+ };
+
+ /// \brief A record of the steps taken while preprocessing a source file,
+ /// including the various preprocessing directives processed, macros
+ /// instantiated, etc.
+ class PreprocessingRecord : public PPCallbacks {
+ /// \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 Mapping from MacroInfo structures to their definitions.
+ llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
+
+ /// \brief External source of preprocessed entities.
+ ExternalPreprocessingRecordSource *ExternalSource;
+
+ /// \brief The number of preallocated entities (that are known to the
+ /// external source).
+ unsigned NumPreallocatedEntities;
+
+ /// \brief Whether we have already loaded all of the preallocated entities.
+ mutable bool LoadedPreallocatedEntities;
+
+ void MaybeLoadPreallocatedEntities() const ;
+
+ public:
+ PreprocessingRecord();
+
+ /// \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) { }
+
+ // Iteration over the preprocessed entities.
+ typedef std::vector<PreprocessedEntity *>::iterator iterator;
+ typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;
+ iterator begin(bool OnlyLocalEntities = false);
+ iterator end(bool OnlyLocalEntities = false);
+ const_iterator begin(bool OnlyLocalEntities = false) const;
+ const_iterator end(bool OnlyLocalEntities = false) const;
+
+ /// \brief Add a new preprocessed entity to this record.
+ void addPreprocessedEntity(PreprocessedEntity *Entity);
+
+ /// \brief Set the external source for preprocessed entities.
+ void SetExternalSource(ExternalPreprocessingRecordSource &Source,
+ unsigned NumPreallocatedEntities);
+
+ /// \brief Set the preallocated entry at the given index to the given
+ /// preprocessed entity.
+ void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity);
+
+ /// \brief Register a new macro definition.
+ void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
+
+ /// \brief Retrieve the preprocessed entity at the given index.
+ PreprocessedEntity *getPreprocessedEntity(unsigned Index) {
+ assert(Index < PreprocessedEntities.size() &&
+ "Out-of-bounds preprocessed entity");
+ return PreprocessedEntities[Index];
+ }
+
+ /// \brief Retrieve the macro definition that corresponds to the given
+ /// \c MacroInfo.
+ MacroDefinition *findMacroDefinition(const MacroInfo *MI);
+
+ virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
+ virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
+ virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI);
+ };
+} // end namespace clang
+
+inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
+ unsigned alignment) throw() {
+ return PR.Allocate(bytes, alignment);
+}
+
+inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
+ unsigned) throw() {
+ PR.Deallocate(ptr);
+}
+
+#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h
new file mode 100644
index 0000000..f01b3af
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h
@@ -0,0 +1,939 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Preprocessor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
+#define LLVM_CLANG_LEX_PREPROCESSOR_H
+
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/TokenLexer.h"
+#include "clang/Lex/PTHManager.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+
+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 DirectoryLookup;
+class PreprocessingRecord;
+
+/// Preprocessor - This object 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 {
+ Diagnostic *Diags;
+ LangOptions Features;
+ const TargetInfo &Target;
+ FileManager &FileMgr;
+ SourceManager &SourceMgr;
+ ScratchBuffer *ScratchBuf;
+ HeaderSearch &HeaderInfo;
+
+ /// \brief External source of macros.
+ ExternalPreprocessorSource *ExternalSource;
+
+ /// PTH - An optional PTHManager object used for getting tokens from
+ /// a token cache rather than lexing the original source file.
+ llvm::OwningPtr<PTHManager> PTH;
+
+ /// BP - 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__VA_ARGS__; // _Pragma, __VA_ARGS__
+ IdentifierInfo *Ident__has_feature; // __has_feature
+ IdentifierInfo *Ident__has_builtin; // __has_builtin
+ IdentifierInfo *Ident__has_include; // __has_include
+ IdentifierInfo *Ident__has_include_next; // __has_include_next
+
+ SourceLocation DATELoc, TIMELoc;
+ unsigned CounterValue; // Next __COUNTER__ value.
+
+ enum {
+ /// MaxIncludeStackDepth - Maximum depth of #includes.
+ MaxAllowedIncludeStackDepth = 200
+ };
+
+ // State that is set before the preprocessor begins.
+ bool KeepComments : 1;
+ bool KeepMacroComments : 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;
+
+ /// DisableMacroExpansion - True if macro expansion is disabled.
+ bool DisableMacroExpansion : 1;
+
+ /// \brief Whether we have already loaded macros from the external source.
+ mutable bool ReadMacrosFromExternalSource : 1;
+
+ /// Identifiers - This is mapping/lookup information for all identifiers in
+ /// the program, including program keywords.
+ mutable IdentifierTable Identifiers;
+
+ /// Selectors - This table contains all the selectors in the program. Unlike
+ /// IdentifierTable above, this table *isn't* populated by the preprocessor.
+ /// It is declared/instantiated here because it's role/lifetime is
+ /// conceptually similar 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 fo the preprocessor.
+ SelectorTable Selectors;
+
+ /// BuiltinInfo - Information about builtins.
+ Builtin::Context BuiltinInfo;
+
+ /// PragmaHandlers - This tracks all of the pragmas that the client registered
+ /// with this preprocessor.
+ PragmaNamespace *PragmaHandlers;
+
+ /// \brief Tracks all of the comment handlers that the client registered
+ /// with this preprocessor.
+ std::vector<CommentHandler *> CommentHandlers;
+
+ /// \brief The file that we're performing code-completion for, if any.
+ const FileEntry *CodeCompletionFile;
+
+ /// CurLexer - This is 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.
+ llvm::OwningPtr<Lexer> CurLexer;
+
+ /// CurPTHLexer - This is 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.
+ llvm::OwningPtr<PTHLexer> CurPTHLexer;
+
+ /// CurPPLexer - This is 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;
+
+ /// CurLookup - 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 *CurDirLookup;
+
+ /// CurTokenLexer - This is the current macro we are expanding, if we are
+ /// expanding a macro. One of CurLexer and CurTokenLexer must be null.
+ llvm::OwningPtr<TokenLexer> CurTokenLexer;
+
+ /// IncludeMacroStack - This keeps track of the stack of files currently
+ /// #included, and macros currently being expanded from, not counting
+ /// CurLexer/CurTokenLexer.
+ struct IncludeStackInfo {
+ Lexer *TheLexer;
+ PTHLexer *ThePTHLexer;
+ PreprocessorLexer *ThePPLexer;
+ TokenLexer *TheTokenLexer;
+ const DirectoryLookup *TheDirLookup;
+
+ IncludeStackInfo(Lexer *L, PTHLexer* P, PreprocessorLexer* PPL,
+ TokenLexer* TL, const DirectoryLookup *D)
+ : TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL), TheTokenLexer(TL),
+ TheDirLookup(D) {}
+ };
+ std::vector<IncludeStackInfo> IncludeMacroStack;
+
+ /// Callbacks - These are actions invoked when some preprocessor activity is
+ /// encountered (e.g. a file is #included, etc).
+ PPCallbacks *Callbacks;
+
+ /// Macros - For each IdentifierInfo with 'HasMacro' set, we keep a mapping
+ /// to the actual definition of the macro.
+ llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
+
+ /// MICache - A "freelist" of MacroInfo objects that can be reused for quick
+ /// allocation.
+ /// FIXME: why not use a singly linked list?
+ std::vector<MacroInfo*> MICache;
+
+ /// MacroArgCache - This is a "freelist" of MacroArg objects that can be
+ /// reused for quick allocation.
+ MacroArgs *MacroArgCache;
+ friend class MacroArgs;
+
+ // Various statistics we track for performance analysis.
+ unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
+ unsigned NumIf, NumElse, NumEndif;
+ unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
+ unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
+ unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
+ unsigned NumSkipped;
+
+ /// Predefines - This string is the predefined macros that preprocessor
+ /// should use from the command line etc.
+ std::string Predefines;
+
+ /// TokenLexerCache - Cache macro expanders to reduce malloc traffic.
+ enum { TokenLexerCacheSize = 8 };
+ unsigned NumCachedTokenLexers;
+ TokenLexer *TokenLexerCache[TokenLexerCacheSize];
+
+ /// \brief A record of the macro definitions and instantiations that
+ /// occurred during preprocessing.
+ ///
+ /// This is an optional side structure that can be enabled with
+ /// \c createPreprocessingRecord() prior to preprocessing.
+ PreprocessingRecord *Record;
+
+private: // Cached tokens state.
+ typedef llvm::SmallVector<Token, 1> CachedTokensTy;
+
+ /// CachedTokens - Cached tokens are stored here when we do backtracking or
+ /// lookahead. They are "lexed" by the CachingLex() method.
+ CachedTokensTy CachedTokens;
+
+ /// CachedLexPos - 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;
+
+ /// BacktrackPositions - 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;
+
+public:
+ Preprocessor(Diagnostic &diags, const LangOptions &opts,
+ const TargetInfo &target,
+ SourceManager &SM, HeaderSearch &Headers,
+ IdentifierInfoLookup *IILookup = 0,
+ bool OwnsHeaderSearch = false);
+
+ ~Preprocessor();
+
+ Diagnostic &getDiagnostics() const { return *Diags; }
+ void setDiagnostics(Diagnostic &D) { Diags = &D; }
+
+ const LangOptions &getLangOptions() const { return Features; }
+ const TargetInfo &getTargetInfo() const { return Target; }
+ FileManager &getFileManager() const { return FileMgr; }
+ SourceManager &getSourceManager() const { return SourceMgr; }
+ HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
+
+ IdentifierTable &getIdentifierTable() { 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;
+ }
+
+ /// SetCommentRetentionState - Control whether or not the preprocessor retains
+ /// comments in output.
+ void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
+ this->KeepComments = KeepComments | KeepMacroComments;
+ this->KeepMacroComments = KeepMacroComments;
+ }
+
+ bool getCommentRetentionState() const { return KeepComments; }
+
+ /// isCurrentLexer - Return true if we are lexing directly from the specified
+ /// lexer.
+ bool isCurrentLexer(const PreprocessorLexer *L) const {
+ return CurPPLexer == L;
+ }
+
+ /// getCurrentLexer - 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; }
+
+ /// getCurrentFileLexer - 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;
+
+ /// getPPCallbacks/addPPCallbacks - Accessors for preprocessor callbacks.
+ /// Note that this class takes ownership of any PPCallbacks object given to
+ /// it.
+ PPCallbacks *getPPCallbacks() const { return Callbacks; }
+ void addPPCallbacks(PPCallbacks *C) {
+ if (Callbacks)
+ C = new PPChainedCallbacks(C, Callbacks);
+ Callbacks = C;
+ }
+
+ /// getMacroInfo - Given an identifier, return the MacroInfo it is #defined to
+ /// or null if it isn't #define'd.
+ MacroInfo *getMacroInfo(IdentifierInfo *II) const {
+ return II->hasMacroDefinition() ? Macros.find(II)->second : 0;
+ }
+
+ /// setMacroInfo - Specify a macro for this identifier.
+ ///
+ void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
+
+ /// macro_iterator/macro_begin/macro_end - This allows you to walk the current
+ /// state of the macro table. This visits every currently-defined macro.
+ typedef llvm::DenseMap<IdentifierInfo*,
+ MacroInfo*>::const_iterator macro_iterator;
+ macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
+ macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+
+ const std::string &getPredefines() const { return Predefines; }
+ /// setPredefines - 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(const std::string &P) { Predefines = P; }
+
+ /// getIdentifierInfo - Return information about the specified preprocessor
+ /// identifier token. The version of this method that takes two character
+ /// pointers is preferred unless the identifier is already available as a
+ /// string (this avoids allocation and copying of memory to construct an
+ /// std::string).
+ IdentifierInfo *getIdentifierInfo(llvm::StringRef Name) const {
+ return &Identifiers.get(Name);
+ }
+
+ /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
+ /// If '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(const char *Namespace, PragmaHandler *Handler);
+
+ /// RemovePragmaHandler - Remove the specific pragma handler from
+ /// the preprocessor. If \arg Namespace is non-null, then it should
+ /// be the namespace that \arg Handler was added to. It is an error
+ /// to remove a handler that has not been registered.
+ void RemovePragmaHandler(const char *Namespace, PragmaHandler *Handler);
+
+ /// \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 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();
+
+ /// EnterMainSourceFile - Enter the specified FileID as the main source file,
+ /// which implicitly adds the builtin defines etc.
+ void EnterMainSourceFile();
+
+ /// EndSourceFile - Inform the preprocessor callbacks that processing is
+ /// complete.
+ void EndSourceFile();
+
+ /// EnterSourceFile - Add a source file to the top of the include stack and
+ /// start lexing tokens from it instead of the current buffer. Emit an error
+ /// and don't enter the file on error.
+ void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+ SourceLocation Loc);
+
+ /// EnterMacro - Add a Macro to the top of the include stack and start lexing
+ /// tokens from it instead of the current buffer. Args specifies the
+ /// tokens input to a function-like macro.
+ ///
+ /// 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, MacroArgs *Args);
+
+ /// EnterTokenStream - Add a "macro" context to the top of the include stack,
+ /// which will cause the lexer to start returning the specified tokens.
+ ///
+ /// If 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 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 new[] and
+ /// must be freed.
+ ///
+ void EnterTokenStream(const Token *Toks, unsigned NumToks,
+ bool DisableMacroExpansion, bool OwnsTokens);
+
+ /// RemoveTopOfLexerStack - 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();
+
+ /// EnableBacktrackAtThisPos - 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();
+
+ /// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
+ void CommitBacktrackedTokens();
+
+ /// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
+ /// EnableBacktrackAtThisPos() was previously called.
+ void Backtrack();
+
+ /// isBacktrackEnabled - True if EnableBacktrackAtThisPos() was called and
+ /// caching of tokens is on.
+ bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
+
+ /// Lex - To lex a token from the preprocessor, just pull a token from the
+ /// current lexer or macro object.
+ void Lex(Token &Result) {
+ if (CurLexer)
+ CurLexer->Lex(Result);
+ else if (CurPTHLexer)
+ CurPTHLexer->Lex(Result);
+ else if (CurTokenLexer)
+ CurTokenLexer->Lex(Result);
+ else
+ CachingLex(Result);
+ }
+
+ /// LexNonComment - 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);
+ }
+
+ /// LexUnexpandedToken - This is just like Lex, but this 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;
+ }
+
+ /// LookAhead - This 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);
+ }
+
+ /// RevertCachedTokens - 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;
+ }
+
+ /// EnterToken - 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);
+ }
+
+ /// AnnotateCachedTokens - 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);
+ }
+
+ /// \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;
+ }
+
+ /// \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 this source location refers into the file
+ /// for which we are performing code completion.
+ bool isCodeCompletionFile(SourceLocation FileLoc) const;
+
+ /// Diag - 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) {
+ return Diags->Report(FullSourceLoc(Loc, getSourceManager()), DiagID);
+ }
+
+ DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) {
+ return Diags->Report(FullSourceLoc(Tok.getLocation(), getSourceManager()),
+ DiagID);
+ }
+
+ /// 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.
+ ///
+ /// \param Invalid If non-NULL, will be set \c true if an error occurs.
+ std::string getSpelling(const Token &Tok, bool *Invalid = 0) const;
+
+ /// 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 &Features,
+ bool *Invalid = 0);
+
+ /// 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.
+ unsigned getSpelling(const Token &Tok, const char *&Buffer,
+ bool *Invalid = 0) const;
+
+ /// getSpelling - This method is used to 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.
+ llvm::StringRef getSpelling(const Token &Tok,
+ llvm::SmallVectorImpl<char> &Buffer,
+ bool *Invalid = 0) const;
+
+ /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
+ /// with length 1, return the character.
+ char getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
+ bool *Invalid = 0) 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);
+ }
+
+ /// CreateString - 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 instantiation point of the token.
+ void CreateString(const char *Buf, unsigned Len,
+ Token &Tok, SourceLocation SourceLoc = 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);
+
+ /// DumpToken - 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;
+
+ /// AdvanceToTokenCharacter - 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);
+
+ /// IncrementPasteCounter - 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();
+
+ /// HandleMicrosoftCommentPaste - 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.
+
+ /// LookUpIdentifierInfo - Given a tok::identifier token, look up the
+ /// identifier information for the token and install it into the token.
+ IdentifierInfo *LookUpIdentifierInfo(Token &Identifier,
+ const char *BufPtr = 0) const;
+
+ /// HandleIdentifier - This callback is 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').
+ void HandleIdentifier(Token &Identifier);
+
+
+ /// HandleEndOfFile - This callback is 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);
+
+ /// HandleEndOfTokenLexer - This callback is invoked when the current
+ /// TokenLexer hits the end of its token stream.
+ bool HandleEndOfTokenLexer(Token &Result);
+
+ /// HandleDirective - This callback is 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);
+
+ /// CheckEndOfDirective - Ensure that the next token is a tok::eom token. If
+ /// not, emit a diagnostic and consume up until the eom. If EnableMacros is
+ /// true, then we consider macros that expand to zero tokens as being ok.
+ void CheckEndOfDirective(const char *Directive, bool EnableMacros = false);
+
+ /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
+ /// current line until the tok::eom token is found.
+ void DiscardUntilEndOfDirective();
+
+ /// SawDateOrTime - This 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; }
+
+ /// AllocateMacroInfo - Allocate a new MacroInfo object with the provide
+ /// SourceLocation.
+ MacroInfo* AllocateMacroInfo(SourceLocation L);
+
+ /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
+ /// checked and spelled filename, e.g. as an operand of #include. This returns
+ /// true if the input filename was in <>'s or false if it were in ""'s. 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.
+ bool GetIncludeFilenameSpelling(SourceLocation Loc,llvm::StringRef &Filename);
+
+ /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+ /// return null on failure. isAngled indicates whether the file reference is
+ /// for system #include's or not (i.e. using <> instead of "").
+ const FileEntry *LookupFile(llvm::StringRef Filename,
+ bool isAngled, const DirectoryLookup *FromDir,
+ const DirectoryLookup *&CurDir);
+
+ /// GetCurLookup - 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; }
+
+ /// isInPrimaryFile - Return true if we're in the top-level file, not in a
+ /// #include.
+ bool isInPrimaryFile() const;
+
+ /// ConcatenateIncludeName - 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:
+ /// #define FOO <a/b.h>
+ /// #include FOO
+ /// because in this case, "<a/b.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 EOM marker.
+ bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer);
+
+private:
+
+ void PushIncludeMacroStack() {
+ IncludeMacroStack.push_back(IncludeStackInfo(CurLexer.take(),
+ CurPTHLexer.take(),
+ CurPPLexer,
+ CurTokenLexer.take(),
+ CurDirLookup));
+ CurPPLexer = 0;
+ }
+
+ void PopIncludeMacroStack() {
+ CurLexer.reset(IncludeMacroStack.back().TheLexer);
+ CurPTHLexer.reset(IncludeMacroStack.back().ThePTHLexer);
+ CurPPLexer = IncludeMacroStack.back().ThePPLexer;
+ CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer);
+ CurDirLookup = IncludeMacroStack.back().TheDirLookup;
+ IncludeMacroStack.pop_back();
+ }
+
+ /// ReleaseMacroInfo - Release the specified MacroInfo. This memory will
+ /// be reused for allocating new MacroInfo objects.
+ void ReleaseMacroInfo(MacroInfo* MI);
+
+ /// ReadMacroName - Lex and validate a macro name, which occurs after a
+ /// #define or #undef. This emits a diagnostic, sets the token kind to eom,
+ /// and discards the rest of the macro line if the macro name is invalid.
+ void ReadMacroName(Token &MacroNameTok, char isDefineUndef = 0);
+
+ /// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
+ /// definition has just been read. Lex the rest of the arguments and the
+ /// closing ), updating MI with what we learn. Return true if an error occurs
+ /// parsing the arg list.
+ bool ReadMacroDefinitionArgList(MacroInfo *MI);
+
+ /// SkipExcludedConditionalBlock - 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
+ /// FoundNonSkipPortion is true, then we have already emitted code for part of
+ /// this #if directive, so #else/#elif blocks should never be entered. If
+ /// 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);
+
+ /// PTHSkipExcludedConditionalBlock - A fast PTH version of
+ /// SkipExcludedConditionalBlock.
+ void PTHSkipExcludedConditionalBlock();
+
+ /// EvaluateDirectiveExpression - 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);
+
+ /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
+ /// #pragma GCC poison/system_header/dependency and #pragma once.
+ void RegisterBuiltinPragmas();
+
+ /// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
+ /// identifier table.
+ void RegisterBuiltinMacros();
+
+ /// HandleMacroExpandedIdentifier - If an identifier token is read that is to
+ /// be expanded as a macro, handle it and return the next token as 'Tok'. If
+ /// the macro should not be expanded return true, otherwise return false.
+ bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI);
+
+ /// isNextPPTokenLParen - 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();
+
+ /// ReadFunctionLikeMacroArgs - After reading "MACRO(", this method is
+ /// invoked to read all of the formal arguments specified for the macro
+ /// invocation. This returns null on error.
+ MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
+ SourceLocation &InstantiationEnd);
+
+ /// ExpandBuiltinMacro - 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);
+
+ /// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
+ /// return the first token after the directive. The _Pragma token has just
+ /// been read into 'Tok'.
+ void Handle_Pragma(Token &Tok);
+
+ /// EnterSourceFileWithLexer - 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);
+
+ /// EnterSourceFileWithPTH - 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);
+
+ /// IsFileLexer - 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 != 0;
+ }
+
+ static bool IsFileLexer(const IncludeStackInfo& I) {
+ return IsFileLexer(I.TheLexer, I.ThePPLexer);
+ }
+
+ bool IsFileLexer() const {
+ return IsFileLexer(CurLexer.get(), CurPPLexer);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Caching stuff.
+ void CachingLex(Token &Result);
+ bool InCachingLexMode() const { return CurPPLexer == 0 && CurTokenLexer == 0;}
+ 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);
+
+ // File inclusion.
+ void HandleIncludeDirective(Token &Tok,
+ const DirectoryLookup *LookupFrom = 0,
+ bool isImport = false);
+ void HandleIncludeNextDirective(Token &Tok);
+ void HandleIncludeMacrosDirective(Token &Tok);
+ void HandleImportDirective(Token &Tok);
+
+ // Macro handling.
+ void HandleDefineDirective(Token &Tok);
+ 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();
+public:
+ void HandlePragmaOnce(Token &OnceTok);
+ void HandlePragmaMark();
+ void HandlePragmaPoison(Token &PoisonTok);
+ void HandlePragmaSystemHeader(Token &SysHeaderTok);
+ void HandlePragmaDependency(Token &DependencyTok);
+ void HandlePragmaComment(Token &CommentTok);
+ // 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 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/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h
new file mode 100644
index 0000000..477a213
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h
@@ -0,0 +1,162 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PreprocessorLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PreprocessorLexer_H
+#define LLVM_CLANG_PreprocessorLexer_H
+
+#include "clang/Lex/MultipleIncludeOpt.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+
+namespace clang {
+
+class FileEntry;
+class Preprocessor;
+
+class PreprocessorLexer {
+protected:
+ Preprocessor *PP; // Preprocessor object controlling lexing.
+
+ /// The SourceManager FileID corresponding to the file being lexed.
+ const FileID FID;
+
+ //===--------------------------------------------------------------------===//
+ // Context-specific lexing flags set by the preprocessor.
+ //===--------------------------------------------------------------------===//
+
+ /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns
+ /// '\n' into a tok::eom token.
+ bool ParsingPreprocessorDirective;
+
+ /// ParsingFilename - True after #include: this turns <xx> into a
+ /// tok::angle_string_literal token.
+ bool ParsingFilename;
+
+ /// LexingRawMode - True if in raw mode: This flag 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;
+
+ /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file
+ /// idiom for the multiple-include optimization.
+ MultipleIncludeOpt MIOpt;
+
+ /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks
+ /// we are currently in.
+ llvm::SmallVector<PPConditionalInfo, 4> ConditionalStack;
+
+ PreprocessorLexer(const PreprocessorLexer&); // DO NOT IMPLEMENT
+ void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT
+ friend class Preprocessor;
+
+ PreprocessorLexer(Preprocessor *pp, FileID fid)
+ : PP(pp), FID(fid), ParsingPreprocessorDirective(false),
+ ParsingFilename(false), LexingRawMode(false) {}
+
+ PreprocessorLexer()
+ : PP(0),
+ ParsingPreprocessorDirective(false),
+ ParsingFilename(false),
+ LexingRawMode(false) {}
+
+ virtual ~PreprocessorLexer() {}
+
+ virtual void IndirectLex(Token& Result) = 0;
+
+ /// getSourceLocation - 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.back();
+ ConditionalStack.pop_back();
+ return false;
+ }
+
+ /// peekConditionalLevel - Return the top of the conditional stack. 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.
+
+ /// LexIncludeFilename - 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 EOM token.
+ void LexIncludeFilename(Token &Result);
+
+ /// setParsingPreprocessorDirective - Inform the lexer whether or not
+ /// we are currently lexing a preprocessor directive.
+ void setParsingPreprocessorDirective(bool f) {
+ ParsingPreprocessorDirective = f;
+ }
+
+ /// isLexingRawMode - Return true if this lexer is in raw mode or not.
+ bool isLexingRawMode() const { return LexingRawMode; }
+
+ /// getPP - 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;
+ }
+
+ /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
+ /// getFileID(), this only works for lexers with attached preprocessors.
+ const FileEntry *getFileEntry() const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/ScratchBuffer.h b/contrib/llvm/tools/clang/include/clang/Lex/ScratchBuffer.h
new file mode 100644
index 0000000..f03515f
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/ScratchBuffer.h
@@ -0,0 +1,45 @@
+//===--- 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_SCRATCHBUFFER_H
+#define LLVM_CLANG_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/contrib/llvm/tools/clang/include/clang/Lex/Token.h b/contrib/llvm/tools/clang/include/clang/Lex/Token.h
new file mode 100644
index 0000000..b5dde9a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/Token.h
@@ -0,0 +1,257 @@
+//===--- 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_TOKEN_H
+#define LLVM_CLANG_TOKEN_H
+
+#include "clang/Basic/TemplateKinds.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/OperatorKinds.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.
+ SourceLocation 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.
+ /// Other:
+ /// This is null.
+ void *PtrData;
+
+ /// Kind - The actual flavor of token this is.
+ ///
+ unsigned char Kind; // DON'T make Kind a 'tok::TokenKind';
+ // MSVC will treat it as a signed char and
+ // TokenKinds > 127 won't be handled correctly.
+
+ /// Flags - Bits we track about this token, members of the TokenFlags enum.
+ unsigned char Flags;
+public:
+
+ // Various flags set per token:
+ enum TokenFlags {
+ StartOfLine = 0x01, // At start of line or only after whitespace.
+ LeadingSpace = 0x02, // Whitespace exists before this token.
+ DisableExpand = 0x04, // This identifier may never be macro expanded.
+ NeedsCleaning = 0x08 // Contained an escaped newline or trigraph.
+ };
+
+ tok::TokenKind getKind() const { return (tok::TokenKind)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 == (unsigned) K; }
+ bool isNot(tok::TokenKind K) const { return Kind != (unsigned) K; }
+
+ /// isLiteral - Return true if this is a "literal", like a numeric
+ /// constant, string, etc.
+ bool isLiteral() const {
+ return is(tok::numeric_constant) || is(tok::char_constant) ||
+ is(tok::string_literal) || is(tok::wide_string_literal) ||
+ is(tok::angle_string_literal);
+ }
+
+ bool isAnnotation() const {
+ return is(tok::annot_typename) ||
+ is(tok::annot_cxxscope) ||
+ is(tok::annot_template_id);
+ }
+
+ /// getLocation - Return a source location identifier for the specified
+ /// offset in the current file.
+ SourceLocation getLocation() const { return Loc; }
+ unsigned getLength() const {
+ assert(!isAnnotation() && "Annotation tokens have no length field");
+ return UintData;
+ }
+
+ void setLocation(SourceLocation L) { Loc = L; }
+ 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);
+ }
+ void setAnnotationEndLoc(SourceLocation L) {
+ assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
+ UintData = L.getRawEncoding();
+ }
+
+ SourceLocation getLastLoc() const {
+ return isAnnotation() ? getAnnotationEndLoc() : getLocation();
+ }
+
+ /// getAnnotationRange - 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( (tok::TokenKind) Kind);
+ }
+
+ /// startToken - Reset all flags to cleared.
+ ///
+ void startToken() {
+ Kind = tok::unknown;
+ Flags = 0;
+ PtrData = 0;
+ Loc = SourceLocation();
+ }
+
+ IdentifierInfo *getIdentifierInfo() const {
+ assert(!isAnnotation() && "Used IdentInfo on annotation token!");
+ if (isLiteral()) return 0;
+ return (IdentifierInfo*) PtrData;
+ }
+ void setIdentifierInfo(IdentifierInfo *II) {
+ PtrData = (void*) II;
+ }
+
+ /// 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 = (void*)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;
+ }
+
+ /// setFlag - Set the specified flag.
+ void setFlag(TokenFlags Flag) {
+ Flags |= Flag;
+ }
+
+ /// clearFlag - Unset the specified flag.
+ void clearFlag(TokenFlags Flag) {
+ Flags &= ~Flag;
+ }
+
+ /// getFlags - Return the internal represtation of the flags.
+ /// Only intended for low-level operations such as writing tokens to
+ // disk.
+ unsigned getFlags() const {
+ return Flags;
+ }
+
+ /// setFlagValue - 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; }
+
+ /// hasLeadingSpace - Return true if this token has whitespace before it.
+ ///
+ bool hasLeadingSpace() const { return (Flags & LeadingSpace) ? true : false; }
+
+ /// isExpandDisabled - 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;
+ }
+
+ /// isObjCAtKeyword - Return true if we have an ObjC keyword identifier.
+ bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const;
+
+ /// getObjCKeywordID - Return the ObjC keyword kind.
+ tok::ObjCKeywordKind getObjCKeywordID() const;
+
+ /// needsCleaning - Return true if this token has trigraphs or escaped
+ /// newlines in it.
+ ///
+ bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; }
+};
+
+/// PPConditionalInfo - Information about the conditional stack (#if directives)
+/// currently active.
+struct PPConditionalInfo {
+ /// IfLoc - Location where the conditional started.
+ ///
+ SourceLocation IfLoc;
+
+ /// WasSkipping - True if this was contained in a skipping directive, e.g.
+ /// in a "#if 0" block.
+ bool WasSkipping;
+
+ /// FoundNonSkip - True if we have emitted tokens already, and now we're in
+ /// an #else block or something. Only useful in Skipping blocks.
+ bool FoundNonSkip;
+
+ /// FoundElse - True if we've seen a #else in this block. If so,
+ /// #elif/#else directives are not allowed.
+ bool FoundElse;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/TokenConcatenation.h b/contrib/llvm/tools/clang/include/clang/Lex/TokenConcatenation.h
new file mode 100644
index 0000000..094990a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/TokenConcatenation.h
@@ -0,0 +1,75 @@
+//===--- 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 CLANG_LEX_TOKEN_CONCATENATION_H
+#define CLANG_LEX_TOKEN_CONCATENATION_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:
+ /// StartsWithL - Return true if the spelling of this token starts with 'L'.
+ bool StartsWithL(const Token &Tok) const;
+
+ /// IsIdentifierL - Return true if the spelling of this token is literally
+ /// 'L'.
+ bool IsIdentifierL(const Token &Tok) const;
+ };
+ } // end clang namespace
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h
new file mode 100644
index 0000000..3f13e9c
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h
@@ -0,0 +1,154 @@
+//===--- 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_TOKENLEXER_H
+#define LLVM_CLANG_TOKENLEXER_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+ class MacroInfo;
+ class Preprocessor;
+ class Token;
+ class MacroArgs;
+
+/// TokenLexer - This implements a lexer that returns token 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 scratch buffer allocated from
+ /// the preprocessor's bump pointer allocator, or some other buffer that we
+ /// may or may not own (depending on OwnsTokens).
+ const Token *Tokens;
+
+ /// NumTokens - This is the length of the Tokens array.
+ ///
+ unsigned NumTokens;
+
+ /// CurToken - This is the next token that Lex will return.
+ ///
+ unsigned CurToken;
+
+ /// InstantiateLocStart/End - The source location range where this macro was
+ /// instantiated.
+ SourceLocation InstantiateLocStart, InstantiateLocEnd;
+
+ /// 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;
+
+ /// 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&); // DO NOT IMPLEMENT
+ void operator=(const TokenLexer&); // DO NOT IMPLEMENT
+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, MacroArgs *ActualArgs,
+ Preprocessor &pp)
+ : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
+ Init(Tok, ILEnd, 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, 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(0), ActualArgs(0), 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.
+ void Lex(Token &Tok);
+
+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 instantiated buffer. Handle this by returning the
+ /// first token on the next line.
+ void HandleMicrosoftCommentPaste(Token &Tok);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Makefile b/contrib/llvm/tools/clang/include/clang/Makefile
new file mode 100644
index 0000000..6abe375
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Makefile
@@ -0,0 +1,31 @@
+LEVEL = ../../../..
+DIRS := AST Basic Driver
+
+include $(LEVEL)/Makefile.common
+
+install-local::
+ $(Echo) Installing Clang include files
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
+ $(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include/clang" ; then \
+ cd $(PROJ_SRC_ROOT)/tools/clang/include && \
+ for hdr in `find clang -type f '!' '(' -name '*~' \
+ -o -name '.#*' -o -name '*.in' -o -name '*.txt' \
+ -o -name 'Makefile' -o -name '*.td' -o -name '*.orig' ')' -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 'Makefile' ')' -print \
+ | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
+ $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
+ done ; \
+ fi
+endif
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Action.h b/contrib/llvm/tools/clang/include/clang/Parse/Action.h
new file mode 100644
index 0000000..e21da81
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/Action.h
@@ -0,0 +1,3122 @@
+//===--- Action.h - Parser Action 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 Action and EmptyAction interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_ACTION_H
+#define LLVM_CLANG_PARSE_ACTION_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TemplateKinds.h"
+#include "clang/Basic/TypeTraits.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Ownership.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+ // Semantic.
+ class DeclSpec;
+ class ObjCDeclSpec;
+ class CXXScopeSpec;
+ class Declarator;
+ class AttributeList;
+ struct FieldDeclarator;
+ // Parse.
+ class Scope;
+ class Action;
+ class Selector;
+ class Designation;
+ class InitListDesignations;
+ // Lex.
+ class Preprocessor;
+ class Token;
+
+ // We can re-use the low bit of expression, statement, base, and
+ // member-initializer pointers for the "invalid" flag of
+ // ActionResult.
+ template<> struct IsResultPtrLowBitFree<0> { static const bool value = true;};
+ template<> struct IsResultPtrLowBitFree<1> { static const bool value = true;};
+ template<> struct IsResultPtrLowBitFree<3> { static const bool value = true;};
+ template<> struct IsResultPtrLowBitFree<4> { static const bool value = true;};
+ template<> struct IsResultPtrLowBitFree<5> { static const bool value = true;};
+
+/// Action - As the parser reads the input file and recognizes the productions
+/// of the grammar, it invokes methods on this class to turn the parsed input
+/// into something useful: e.g. a parse tree.
+///
+/// The callback methods that this class provides are phrased as actions that
+/// the parser has just done or is about to do when the method is called. They
+/// are not requests that the actions module do the specified action.
+///
+/// All of the methods here are optional except getTypeName() and
+/// isCurrentClassName(), which must be specified in order for the
+/// parse to complete accurately. The MinimalAction class does this
+/// bare-minimum of tracking to implement this functionality.
+class Action : public ActionBase {
+public:
+ /// Out-of-line virtual destructor to provide home for this class.
+ virtual ~Action();
+
+ // Types - Though these don't actually enforce strong typing, they document
+ // what types are required to be identical for the actions.
+ typedef ActionBase::ExprTy ExprTy;
+ typedef ActionBase::StmtTy StmtTy;
+
+ /// Expr/Stmt/Type/BaseResult - Provide a unique type to wrap
+ /// ExprTy/StmtTy/TypeTy/BaseTy, providing strong typing and
+ /// allowing for failure.
+ typedef ActionResult<0> ExprResult;
+ typedef ActionResult<1> StmtResult;
+ typedef ActionResult<2> TypeResult;
+ typedef ActionResult<3> BaseResult;
+ typedef ActionResult<4> MemInitResult;
+ typedef ActionResult<5, DeclPtrTy> DeclResult;
+
+ /// Same, but with ownership.
+ typedef ASTOwningResult<&ActionBase::DeleteExpr> OwningExprResult;
+ typedef ASTOwningResult<&ActionBase::DeleteStmt> OwningStmtResult;
+ // Note that these will replace ExprResult and StmtResult when the transition
+ // is complete.
+
+ /// Single expressions or statements as arguments.
+#if !defined(DISABLE_SMART_POINTERS)
+ typedef ASTOwningResult<&ActionBase::DeleteExpr> ExprArg;
+ typedef ASTOwningResult<&ActionBase::DeleteStmt> StmtArg;
+#else
+ typedef ASTOwningPtr<&ActionBase::DeleteExpr> ExprArg;
+ typedef ASTOwningPtr<&ActionBase::DeleteStmt> StmtArg;
+#endif
+
+ /// Multiple expressions or statements as arguments.
+ typedef ASTMultiPtr<&ActionBase::DeleteExpr> MultiExprArg;
+ typedef ASTMultiPtr<&ActionBase::DeleteStmt> MultiStmtArg;
+ typedef ASTMultiPtr<&ActionBase::DeleteTemplateParams> MultiTemplateParamsArg;
+
+ class FullExprArg {
+ public:
+ FullExprArg(ActionBase &actions) : Expr(actions) { }
+
+ // FIXME: The const_cast here is ugly. RValue references would make this
+ // much nicer (or we could duplicate a bunch of the move semantics
+ // emulation code from Ownership.h).
+ FullExprArg(const FullExprArg& Other)
+ : Expr(move(const_cast<FullExprArg&>(Other).Expr)) {}
+
+ FullExprArg &operator=(const FullExprArg& Other) {
+ Expr.operator=(move(const_cast<FullExprArg&>(Other).Expr));
+ return *this;
+ }
+
+ OwningExprResult release() {
+ return move(Expr);
+ }
+
+ ExprArg* operator->() {
+ return &Expr;
+ }
+
+ private:
+ // FIXME: No need to make the entire Action class a friend when it's just
+ // Action::FullExpr that needs access to the constructor below.
+ friend class Action;
+
+ explicit FullExprArg(ExprArg expr)
+ : Expr(move(expr)) {}
+
+ ExprArg Expr;
+ };
+
+ template<typename T>
+ FullExprArg MakeFullExpr(T &Arg) {
+ return FullExprArg(ActOnFinishFullExpr(move(Arg)));
+ }
+
+ // Utilities for Action implementations to return smart results.
+
+ OwningExprResult ExprError() { return OwningExprResult(*this, true); }
+ OwningStmtResult StmtError() { return OwningStmtResult(*this, true); }
+
+ OwningExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
+ OwningStmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
+
+ OwningExprResult ExprEmpty() { return OwningExprResult(*this, false); }
+ OwningStmtResult StmtEmpty() { return OwningStmtResult(*this, false); }
+
+ /// Statistics.
+ virtual void PrintStats() const {}
+
+ /// getDeclName - Return a pretty name for the specified decl if possible, or
+ /// an empty string if not. This is used for pretty crash reporting.
+ virtual std::string getDeclName(DeclPtrTy D) { return ""; }
+
+ //===--------------------------------------------------------------------===//
+ // Declaration Tracking Callbacks.
+ //===--------------------------------------------------------------------===//
+
+ typedef uintptr_t ParsingDeclStackState;
+
+ /// PushParsingDeclaration - Notes that the parser has begun
+ /// processing a declaration of some sort. Guaranteed to be matched
+ /// by a call to PopParsingDeclaration with the value returned by
+ /// this method.
+ virtual ParsingDeclStackState PushParsingDeclaration() {
+ return ParsingDeclStackState();
+ }
+
+ /// PopParsingDeclaration - Notes that the parser has completed
+ /// processing a declaration of some sort. The decl will be empty
+ /// if the declaration didn't correspond to a full declaration (or
+ /// if the actions module returned an empty decl for it).
+ virtual void PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy D) {
+ }
+
+ /// ConvertDeclToDeclGroup - If the parser has one decl in a context where it
+ /// needs a decl group, it calls this to convert between the two
+ /// representations.
+ virtual DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
+ return DeclGroupPtrTy();
+ }
+
+ /// getTypeName - Return non-null if the specified identifier is a type name
+ /// in the current scope.
+ ///
+ /// \param II the identifier for which we are performing name lookup
+ ///
+ /// \param NameLoc the location of the identifier
+ ///
+ /// \param S the scope in which this name lookup occurs
+ ///
+ /// \param SS if non-NULL, the C++ scope specifier that precedes the
+ /// identifier
+ ///
+ /// \param isClassName whether this is a C++ class-name production, in
+ /// which we can end up referring to a member of an unknown specialization
+ /// that we know (from the grammar) is supposed to be a type. For example,
+ /// this occurs when deriving from "std::vector<T>::allocator_type", where T
+ /// is a template parameter.
+ ///
+ /// \param ObjectType if we're checking whether an identifier is a type
+ /// within a C++ member access expression, this will be the type of the
+ ///
+ /// \returns the type referred to by this identifier, or NULL if the type
+ /// does not name an identifier.
+ virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+ Scope *S, CXXScopeSpec *SS = 0,
+ bool isClassName = false,
+ TypeTy *ObjectType = 0) = 0;
+
+ /// isTagName() - This method is called *for error recovery purposes only*
+ /// to determine if the specified name is a valid tag name ("struct foo"). If
+ /// so, this returns the TST for the tag corresponding to it (TST_enum,
+ /// TST_union, TST_struct, TST_class). This is used to diagnose cases in C
+ /// where the user forgot to specify the tag.
+ virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S) {
+ return DeclSpec::TST_unspecified;
+ }
+
+ /// \brief Action called as part of error recovery when the parser has
+ /// determined that the given name must refer to a type, but
+ /// \c getTypeName() did not return a result.
+ ///
+ /// This callback permits the action to give a detailed diagnostic when an
+ /// unknown type name is encountered and, potentially, to try to recover
+ /// by producing a new type in \p SuggestedType.
+ ///
+ /// \param II the name that should be a type.
+ ///
+ /// \param IILoc the location of the name in the source.
+ ///
+ /// \param S the scope in which name lookup was performed.
+ ///
+ /// \param SS if non-NULL, the C++ scope specifier that preceded the name.
+ ///
+ /// \param SuggestedType if the action sets this type to a non-NULL type,
+ /// the parser will recovery by consuming the type name token and then
+ /// pretending that the given type was the type it parsed.
+ ///
+ /// \returns true if a diagnostic was emitted, false otherwise. When false,
+ /// the parser itself will emit a generic "unknown type name" diagnostic.
+ virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
+ SourceLocation IILoc,
+ Scope *S,
+ CXXScopeSpec *SS,
+ TypeTy *&SuggestedType) {
+ return false;
+ }
+
+ /// isCurrentClassName - Return true if the specified name is the
+ /// name of the innermost C++ class type currently being defined.
+ virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
+ const CXXScopeSpec *SS = 0) = 0;
+
+ /// \brief Determine whether the given name refers to a template.
+ ///
+ /// This callback is used by the parser after it has seen a '<' to determine
+ /// whether the given name refers to a template and, if so, what kind of
+ /// template.
+ ///
+ /// \param S the scope in which the name occurs.
+ ///
+ /// \param SS the C++ nested-name-specifier that precedes the template name,
+ /// if any.
+ ///
+ /// \param Name the name that we are querying to determine whether it is
+ /// a template.
+ ///
+ /// \param ObjectType if we are determining whether the given name is a
+ /// template name in the context of a member access expression (e.g.,
+ /// \c p->X<int>), this is the type of the object referred to by the
+ /// member access (e.g., \c p).
+ ///
+ /// \param EnteringContext whether we are potentially entering the context
+ /// referred to by the nested-name-specifier \p SS, which allows semantic
+ /// analysis to look into uninstantiated templates.
+ ///
+ /// \param Template if the name does refer to a template, the declaration
+ /// of the template that the name refers to.
+ ///
+ /// \param MemberOfUnknownSpecialization Will be set true if the resulting
+ /// member would be a member of an unknown specialization, in which case this
+ /// lookup cannot possibly pass at this time.
+ ///
+ /// \returns the kind of template that this name refers to.
+ virtual TemplateNameKind isTemplateName(Scope *S,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ TypeTy *ObjectType,
+ bool EnteringContext,
+ TemplateTy &Template,
+ bool &MemberOfUnknownSpecialization) = 0;
+
+ /// \brief Action called as part of error recovery when the parser has
+ /// determined that the given name must refer to a template, but
+ /// \c isTemplateName() did not return a result.
+ ///
+ /// This callback permits the action to give a detailed diagnostic when an
+ /// unknown template name is encountered and, potentially, to try to recover
+ /// by producing a new template in \p SuggestedTemplate.
+ ///
+ /// \param II the name that should be a template.
+ ///
+ /// \param IILoc the location of the name in the source.
+ ///
+ /// \param S the scope in which name lookup was performed.
+ ///
+ /// \param SS the C++ scope specifier that preceded the name.
+ ///
+ /// \param SuggestedTemplate if the action sets this template to a non-NULL,
+ /// template, the parser will recover by consuming the template name token
+ /// and the template argument list that follows.
+ ///
+ /// \param SuggestedTemplateKind as input, the kind of template that we
+ /// expect (e.g., \c TNK_Type_template or \c TNK_Function_template). If the
+ /// action provides a suggested template, this should be set to the kind of
+ /// template.
+ ///
+ /// \returns true if a diagnostic was emitted, false otherwise. When false,
+ /// the parser itself will emit a generic "unknown template name" diagnostic.
+ virtual bool DiagnoseUnknownTemplateName(const IdentifierInfo &II,
+ SourceLocation IILoc,
+ Scope *S,
+ const CXXScopeSpec *SS,
+ TemplateTy &SuggestedTemplate,
+ TemplateNameKind &SuggestedKind) {
+ return false;
+ }
+
+ /// \brief Determine whether the given name refers to a non-type nested name
+ /// specifier, e.g., the name of a namespace or namespace alias.
+ ///
+ /// This actual is used in the parsing of pseudo-destructor names to
+ /// distinguish a nested-name-specifier and a "type-name ::" when we
+ /// see the token sequence "X :: ~".
+ virtual bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
+ SourceLocation IdLoc,
+ IdentifierInfo &II,
+ TypeTy *ObjectType) {
+ return false;
+ }
+
+ /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
+ /// global scope ('::').
+ virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
+ SourceLocation CCLoc) {
+ return 0;
+ }
+
+ /// \brief Parsed an identifier followed by '::' in a C++
+ /// nested-name-specifier.
+ ///
+ /// \param S the scope in which the nested-name-specifier was parsed.
+ ///
+ /// \param SS the nested-name-specifier that precedes the identifier. For
+ /// example, if we are parsing "foo::bar::", \p SS will describe the "foo::"
+ /// that has already been parsed.
+ ///
+ /// \param IdLoc the location of the identifier we have just parsed (e.g.,
+ /// the "bar" in "foo::bar::".
+ ///
+ /// \param CCLoc the location of the '::' at the end of the
+ /// nested-name-specifier.
+ ///
+ /// \param II the identifier that represents the scope that this
+ /// nested-name-specifier refers to, e.g., the "bar" in "foo::bar::".
+ ///
+ /// \param ObjectType if this nested-name-specifier occurs as part of a
+ /// C++ member access expression such as "x->Base::f", the type of the base
+ /// object (e.g., *x in the example, if "x" were a pointer).
+ ///
+ /// \param EnteringContext if true, then we intend to immediately enter the
+ /// context of this nested-name-specifier, e.g., for an out-of-line
+ /// definition of a class member.
+ ///
+ /// \returns a CXXScopeTy* object representing the C++ scope.
+ virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
+ CXXScopeSpec &SS,
+ SourceLocation IdLoc,
+ SourceLocation CCLoc,
+ IdentifierInfo &II,
+ TypeTy *ObjectType,
+ bool EnteringContext) {
+ return 0;
+ }
+
+ /// IsInvalidUnlessNestedName - This method is used for error recovery
+ /// purposes to determine whether the specified identifier is only valid as
+ /// a nested name specifier, for example a namespace name. It is
+ /// conservatively correct to always return false from this method.
+ ///
+ /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
+ virtual bool IsInvalidUnlessNestedName(Scope *S,
+ CXXScopeSpec &SS,
+ IdentifierInfo &II,
+ TypeTy *ObjectType,
+ bool EnteringContext) {
+ return false;
+ }
+
+ /// ActOnCXXNestedNameSpecifier - Called during parsing of a
+ /// nested-name-specifier that involves a template-id, e.g.,
+ /// "foo::bar<int, float>::", and now we need to build a scope
+ /// specifier. \p SS is empty or the previously parsed nested-name
+ /// part ("foo::"), \p Type is the already-parsed class template
+ /// specialization (or other template-id that names a type), \p
+ /// TypeRange is the source range where the type is located, and \p
+ /// CCLoc is the location of the trailing '::'.
+ virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
+ const CXXScopeSpec &SS,
+ TypeTy *Type,
+ SourceRange TypeRange,
+ SourceLocation CCLoc) {
+ return 0;
+ }
+
+ /// ShouldEnterDeclaratorScope - Called when a C++ scope specifier
+ /// is parsed as part of a declarator-id to determine whether a scope
+ /// should be entered.
+ ///
+ /// \param S the current scope
+ /// \param SS the scope being entered
+ /// \param isFriendDeclaration whether this is a friend declaration
+ virtual bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+ return false;
+ }
+
+ /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
+ /// scope or nested-name-specifier) is parsed as 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.
+ /// \returns true if an error occurred, false otherwise.
+ virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS) {
+ return false;
+ }
+
+ /// 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.
+ virtual 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.
+ virtual void ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+ }
+
+ /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+ /// initializer for the declaration 'Dcl'.
+ virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+ }
+
+ /// ActOnDeclarator - This callback is invoked when a declarator is parsed and
+ /// 'Init' specifies the initializer if any. This is for things like:
+ /// "int X = 4" or "typedef int foo".
+ ///
+ virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnParamDeclarator - This callback is invoked when a parameter
+ /// declarator is parsed. This callback only occurs for functions
+ /// with prototypes. S is the function prototype scope for the
+ /// parameters (C++ [basic.scope.proto]).
+ virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D) {
+ return DeclPtrTy();
+ }
+
+ /// \brief Parsed an exception object declaration within an Objective-C
+ /// @catch statement.
+ virtual DeclPtrTy ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
+ return DeclPtrTy();
+ }
+
+ /// AddInitializerToDecl - This action is called immediately after
+ /// ActOnDeclarator (when an initializer is present). The code is factored
+ /// this way to make sure we are able to handle the following:
+ /// void func() { int xx = xx; }
+ /// This allows ActOnDeclarator to register "xx" prior to parsing the
+ /// initializer. The declaration above should still result in a warning,
+ /// since the reference to "xx" is uninitialized.
+ virtual void AddInitializerToDecl(DeclPtrTy Dcl, ExprArg Init) {
+ return;
+ }
+
+ /// SetDeclDeleted - This action is called immediately after ActOnDeclarator
+ /// if =delete is parsed. C++0x [dcl.fct.def]p10
+ /// Note that this can be called even for variable declarations. It's the
+ /// action's job to reject it.
+ virtual void SetDeclDeleted(DeclPtrTy Dcl, SourceLocation DelLoc) {
+ return;
+ }
+
+ /// ActOnUninitializedDecl - This action is called immediately after
+ /// ActOnDeclarator (when an initializer is *not* present).
+ /// If TypeContainsUndeducedAuto is true, then the type of the declarator
+ /// has an undeduced 'auto' type somewhere.
+ virtual void ActOnUninitializedDecl(DeclPtrTy Dcl,
+ bool TypeContainsUndeducedAuto) {
+ return;
+ }
+
+ /// \brief Note that the given declaration had an initializer that could not
+ /// be parsed.
+ virtual void ActOnInitializerError(DeclPtrTy Dcl) {
+ return;
+ }
+
+ /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
+ /// gives the actions implementation a chance to process the group as a whole.
+ virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec& DS,
+ DeclPtrTy *Group,
+ unsigned NumDecls) {
+ return DeclGroupPtrTy();
+ }
+
+
+ /// @brief Indicates that all K&R-style parameter declarations have
+ /// been parsed prior to a function definition.
+ /// @param S The function prototype scope.
+ /// @param D The function declarator.
+ virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
+ SourceLocation LocAfterDecls) {
+ }
+
+ /// ActOnStartOfFunctionDef - This is called at the start of a function
+ /// definition, instead of calling ActOnDeclarator. The Declarator includes
+ /// information about formal arguments that are part of this function.
+ virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
+ // Default to ActOnDeclarator.
+ return ActOnStartOfFunctionDef(FnBodyScope,
+ ActOnDeclarator(FnBodyScope, D));
+ }
+
+ /// ActOnStartOfFunctionDef - This is called at the start of a function
+ /// definition, after the FunctionDecl has already been created.
+ virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+ return D;
+ }
+
+ virtual void ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
+ return;
+ }
+
+ /// ActOnFinishFunctionBody - This is called when a function body has
+ /// completed parsing. Decl is returned by ParseStartOfFunctionDef.
+ virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body) {
+ return Decl;
+ }
+
+ virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc,
+ ExprArg AsmString) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnPopScope - This callback is called immediately before the specified
+ /// scope is popped and deleted.
+ virtual void ActOnPopScope(SourceLocation Loc, Scope *S) {}
+
+ /// ActOnTranslationUnitScope - This callback is called once, immediately
+ /// after creating the translation unit scope (in Parser::Initialize).
+ virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {}
+
+ /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+ /// no declarator (e.g. "struct foo;") is parsed.
+ virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S,
+ AccessSpecifier Access,
+ DeclSpec &DS) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnStartLinkageSpecification - Parsed the beginning of a C++
+ /// linkage specification, including the language and (if present)
+ /// the '{'. ExternLoc is the location of the 'extern', LangLoc is
+ /// the location of the language string literal, which is provided
+ /// by Lang/StrSize. LBraceLoc, if valid, provides the location of
+ /// the '{' brace. Otherwise, this linkage specification does not
+ /// have any braces.
+ virtual DeclPtrTy ActOnStartLinkageSpecification(Scope *S,
+ SourceLocation ExternLoc,
+ SourceLocation LangLoc,
+ llvm::StringRef Lang,
+ SourceLocation LBraceLoc) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnFinishLinkageSpecification - Completely the definition of
+ /// the C++ linkage specification LinkageSpec. If RBraceLoc is
+ /// valid, it's the position of the closing '}' brace in a linkage
+ /// specification that uses braces.
+ virtual DeclPtrTy ActOnFinishLinkageSpecification(Scope *S,
+ DeclPtrTy LinkageSpec,
+ SourceLocation RBraceLoc) {
+ return LinkageSpec;
+ }
+
+ /// ActOnEndOfTranslationUnit - This is called at the very end of the
+ /// translation unit when EOF is reached and all but the top-level scope is
+ /// popped.
+ virtual void ActOnEndOfTranslationUnit() {}
+
+ //===--------------------------------------------------------------------===//
+ // Type Parsing Callbacks.
+ //===--------------------------------------------------------------------===//
+
+ /// ActOnTypeName - A type-name (type-id in C++) was parsed.
+ virtual TypeResult ActOnTypeName(Scope *S, Declarator &D) {
+ return TypeResult();
+ }
+
+ 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;'
+ };
+
+ /// \brief The parser has encountered a tag (e.g., "class X") that should be
+ /// turned into a declaration by the action module.
+ ///
+ /// \param S the scope in which this tag occurs.
+ ///
+ /// \param TagSpec an instance of DeclSpec::TST, indicating what kind of tag
+ /// this is (struct/union/enum/class).
+ ///
+ /// \param TUK how the tag we have encountered is being used, which
+ /// can be a reference to a (possibly pre-existing) tag, a
+ /// declaration of that tag, or the beginning of a definition of
+ /// that tag.
+ ///
+ /// \param KWLoc the location of the "struct", "class", "union", or "enum"
+ /// keyword.
+ ///
+ /// \param SS C++ scope specifier that precedes the name of the tag, e.g.,
+ /// the "std::" in "class std::type_info".
+ ///
+ /// \param Name the name of the tag, e.g., "X" in "struct X". This parameter
+ /// may be NULL, to indicate an anonymous class/struct/union/enum type.
+ ///
+ /// \param NameLoc the location of the name of the tag.
+ ///
+ /// \param Attr the set of attributes that appertain to the tag.
+ ///
+ /// \param AS when this tag occurs within a C++ class, provides the
+ /// current access specifier (AS_public, AS_private, AS_protected).
+ /// Otherwise, it will be AS_none.
+ ///
+ /// \param TemplateParameterLists the set of C++ template parameter lists
+ /// that apply to this tag, if the tag is a declaration or definition (see
+ /// the \p TK parameter). The action module is responsible for determining,
+ /// based on the template parameter lists and the scope specifier, whether
+ /// the declared tag is a class template or not.
+ ///
+ /// \param OwnedDecl the callee should set this flag true when the returned
+ /// declaration is "owned" by this reference. Ownership is handled entirely
+ /// by the action module.
+ ///
+ /// \returns the declaration to which this tag refers.
+ virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+ SourceLocation KWLoc, CXXScopeSpec &SS,
+ IdentifierInfo *Name, SourceLocation NameLoc,
+ AttributeList *Attr, AccessSpecifier AS,
+ MultiTemplateParamsArg TemplateParameterLists,
+ bool &OwnedDecl, bool &IsDependent) {
+ return DeclPtrTy();
+ }
+
+ /// Acts on a reference to a dependent tag name. This arises in
+ /// cases like:
+ ///
+ /// template <class T> class A;
+ /// template <class T> class B {
+ /// friend class A<T>::M; // here
+ /// };
+ ///
+ /// \param TagSpec an instance of DeclSpec::TST corresponding to the
+ /// tag specifier.
+ ///
+ /// \param TUK the tag use kind (either TUK_Friend or TUK_Reference)
+ ///
+ /// \param SS the scope specifier (always defined)
+ virtual TypeResult ActOnDependentTag(Scope *S,
+ unsigned TagSpec,
+ TagUseKind TUK,
+ const CXXScopeSpec &SS,
+ IdentifierInfo *Name,
+ SourceLocation KWLoc,
+ SourceLocation NameLoc) {
+ return TypeResult();
+ }
+
+ /// Act on @defs() element found when parsing a structure. ClassName is the
+ /// name of the referenced class.
+ virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
+ IdentifierInfo *ClassName,
+ llvm::SmallVectorImpl<DeclPtrTy> &Decls) {}
+ virtual DeclPtrTy ActOnField(Scope *S, DeclPtrTy TagD,
+ SourceLocation DeclStart,
+ Declarator &D, ExprTy *BitfieldWidth) {
+ return DeclPtrTy();
+ }
+
+ virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart,
+ DeclPtrTy IntfDecl,
+ Declarator &D, ExprTy *BitfieldWidth,
+ tok::ObjCKeywordKind visibility) {
+ return DeclPtrTy();
+ }
+
+ virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclPtrTy TagDecl,
+ DeclPtrTy *Fields, unsigned NumFields,
+ 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).
+ virtual void ActOnTagStartDefinition(Scope *S, DeclPtrTy TagDecl) { }
+
+ /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
+ /// C++ record definition's base-specifiers clause and are starting its
+ /// member declarations.
+ virtual void ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagDecl,
+ SourceLocation LBraceLoc) { }
+
+ /// ActOnTagFinishDefinition - Invoked once we have finished parsing
+ /// the definition of a tag (enumeration, class, struct, or union).
+ ///
+ /// The scope is the scope of the tag definition.
+ virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
+ SourceLocation RBraceLoc) { }
+
+ /// ActOnTagDefinitionError - Invoked if there's an unrecoverable
+ /// error parsing the definition of a tag.
+ ///
+ /// The scope is the scope of the tag definition.
+ virtual void ActOnTagDefinitionError(Scope *S, DeclPtrTy TagDecl) { }
+
+ virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl,
+ DeclPtrTy LastEnumConstant,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ SourceLocation EqualLoc, ExprTy *Val) {
+ return DeclPtrTy();
+ }
+ virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
+ SourceLocation RBraceLoc, DeclPtrTy EnumDecl,
+ DeclPtrTy *Elements, unsigned NumElements,
+ Scope *S, AttributeList *AttrList) {}
+
+ //===--------------------------------------------------------------------===//
+ // Statement Parsing Callbacks.
+ //===--------------------------------------------------------------------===//
+
+ virtual OwningStmtResult ActOnNullStmt(SourceLocation SemiLoc) {
+ return StmtEmpty();
+ }
+
+ virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
+ MultiStmtArg Elts,
+ bool isStmtExpr) {
+ return StmtEmpty();
+ }
+ virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ return StmtEmpty();
+ }
+
+ virtual void ActOnForEachDeclStmt(DeclGroupPtrTy Decl) {
+ }
+
+ virtual OwningStmtResult ActOnExprStmt(FullExprArg Expr) {
+ return OwningStmtResult(*this, Expr->release());
+ }
+
+ /// ActOnCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
+ /// which can specify an RHS value. The sub-statement of the case is
+ /// specified in a separate action.
+ virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprArg LHSVal,
+ SourceLocation DotDotDotLoc,
+ ExprArg RHSVal,
+ SourceLocation ColonLoc) {
+ return StmtEmpty();
+ }
+
+ /// ActOnCaseStmtBody - This installs a statement as the body of a case.
+ virtual void ActOnCaseStmtBody(StmtTy *CaseStmt, StmtArg SubStmt) {}
+
+ virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
+ SourceLocation ColonLoc,
+ StmtArg SubStmt, Scope *CurScope){
+ return StmtEmpty();
+ }
+
+ virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc,
+ IdentifierInfo *II,
+ SourceLocation ColonLoc,
+ StmtArg SubStmt) {
+ return StmtEmpty();
+ }
+
+ /// \brief Parsed an "if" statement.
+ ///
+ /// \param IfLoc the location of the "if" keyword.
+ ///
+ /// \param CondVal if the "if" condition was parsed as an expression,
+ /// the expression itself.
+ ///
+ /// \param CondVar if the "if" condition was parsed as a condition variable,
+ /// the condition variable itself.
+ ///
+ /// \param ThenVal the "then" statement.
+ ///
+ /// \param ElseLoc the location of the "else" keyword.
+ ///
+ /// \param ElseVal the "else" statement.
+ virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
+ FullExprArg CondVal,
+ DeclPtrTy CondVar,
+ StmtArg ThenVal,
+ SourceLocation ElseLoc,
+ StmtArg ElseVal) {
+ return StmtEmpty();
+ }
+
+ /// \brief Parsed the start of a "switch" statement.
+ ///
+ /// \param SwitchLoc The location of the "switch" keyword.
+ ///
+ /// \param Cond if the "switch" condition was parsed as an expression,
+ /// the expression itself.
+ ///
+ /// \param CondVar if the "switch" condition was parsed as a condition
+ /// variable, the condition variable itself.
+ virtual OwningStmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
+ ExprArg Cond,
+ DeclPtrTy CondVar) {
+ return StmtEmpty();
+ }
+
+ virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
+ StmtArg Switch, StmtArg Body) {
+ return StmtEmpty();
+ }
+
+ /// \brief Parsed a "while" statement.
+ ///
+ /// \param Cond if the "while" condition was parsed as an expression,
+ /// the expression itself.
+ ///
+ /// \param CondVar if the "while" condition was parsed as a condition
+ /// variable, the condition variable itself.
+ ///
+ /// \param Body the body of the "while" loop.
+ virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
+ FullExprArg Cond, DeclPtrTy CondVar,
+ StmtArg Body) {
+ return StmtEmpty();
+ }
+ virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
+ SourceLocation WhileLoc,
+ SourceLocation CondLParen,
+ ExprArg Cond,
+ SourceLocation CondRParen) {
+ return StmtEmpty();
+ }
+
+ /// \brief Parsed a "for" statement.
+ ///
+ /// \param ForLoc the location of the "for" keyword.
+ ///
+ /// \param LParenLoc the location of the left parentheses.
+ ///
+ /// \param First the statement used to initialize the for loop.
+ ///
+ /// \param Second the condition to be checked during each iteration, if
+ /// that condition was parsed as an expression.
+ ///
+ /// \param SecondArg the condition variable to be checked during each
+ /// iterator, if that condition was parsed as a variable declaration.
+ ///
+ /// \param Third the expression that will be evaluated to "increment" any
+ /// values prior to the next iteration.
+ ///
+ /// \param RParenLoc the location of the right parentheses.
+ ///
+ /// \param Body the body of the "body" loop.
+ virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
+ SourceLocation LParenLoc,
+ StmtArg First, FullExprArg Second,
+ DeclPtrTy SecondVar, FullExprArg Third,
+ SourceLocation RParenLoc,
+ StmtArg Body) {
+ return StmtEmpty();
+ }
+
+ virtual OwningStmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
+ SourceLocation LParenLoc,
+ StmtArg First, ExprArg Second,
+ SourceLocation RParenLoc, StmtArg Body) {
+ return StmtEmpty();
+ }
+ virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc,
+ SourceLocation LabelLoc,
+ IdentifierInfo *LabelII) {
+ return StmtEmpty();
+ }
+ virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
+ SourceLocation StarLoc,
+ ExprArg DestExp) {
+ return StmtEmpty();
+ }
+ virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
+ Scope *CurScope) {
+ return StmtEmpty();
+ }
+ virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc,
+ Scope *CurScope) {
+ return StmtEmpty();
+ }
+ virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
+ ExprArg RetValExp) {
+ return StmtEmpty();
+ }
+ virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+ bool IsSimple,
+ bool IsVolatile,
+ unsigned NumOutputs,
+ unsigned NumInputs,
+ IdentifierInfo **Names,
+ MultiExprArg Constraints,
+ MultiExprArg Exprs,
+ ExprArg AsmString,
+ MultiExprArg Clobbers,
+ SourceLocation RParenLoc,
+ bool MSAsm = false) {
+ return StmtEmpty();
+ }
+
+ // Objective-c statements
+
+ /// \brief Parsed an Objective-C @catch statement.
+ ///
+ /// \param AtLoc The location of the '@' starting the '@catch'.
+ ///
+ /// \param RParen The location of the right parentheses ')' after the
+ /// exception variable.
+ ///
+ /// \param Parm The variable that will catch the exception. Will be NULL if
+ /// this is a @catch(...) block.
+ ///
+ /// \param Body The body of the @catch block.
+ virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
+ SourceLocation RParen,
+ DeclPtrTy Parm, StmtArg Body) {
+ return StmtEmpty();
+ }
+
+ /// \brief Parsed an Objective-C @finally statement.
+ ///
+ /// \param AtLoc The location of the '@' starting the '@finally'.
+ ///
+ /// \param Body The body of the @finally block.
+ virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
+ StmtArg Body) {
+ return StmtEmpty();
+ }
+
+ /// \brief Parsed an Objective-C @try-@catch-@finally statement.
+ ///
+ /// \param AtLoc The location of the '@' starting '@try'.
+ ///
+ /// \param Try The body of the '@try' statement.
+ ///
+ /// \param CatchStmts The @catch statements.
+ ///
+ /// \param Finally The @finally statement.
+ virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
+ StmtArg Try,
+ MultiStmtArg CatchStmts,
+ StmtArg Finally) {
+ return StmtEmpty();
+ }
+
+ virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
+ ExprArg Throw,
+ Scope *CurScope) {
+ return StmtEmpty();
+ }
+
+ virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
+ ExprArg SynchExpr,
+ StmtArg SynchBody) {
+ return StmtEmpty();
+ }
+
+ // C++ Statements
+ virtual DeclPtrTy ActOnExceptionDeclarator(Scope *S, Declarator &D) {
+ return DeclPtrTy();
+ }
+
+ virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
+ DeclPtrTy ExceptionDecl,
+ StmtArg HandlerBlock) {
+ return StmtEmpty();
+ }
+
+ virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
+ StmtArg TryBlock,
+ MultiStmtArg Handlers) {
+ return StmtEmpty();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Expression Parsing Callbacks.
+ //===--------------------------------------------------------------------===//
+
+ /// \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++0x [expr]p8), such as a constant expression
+ /// or the subexpression of \c sizeof, where the type or the value 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 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 may be potentially evaluated or it may
+ /// be unevaluated, but it is impossible to tell from the lexical context.
+ /// This evaluation context is used primary for the operand of the C++
+ /// \c typeid expression, whose argument is potentially evaluated only when
+ /// it is an lvalue of polymorphic class type (C++ [basic.def.odr]p2).
+ PotentiallyPotentiallyEvaluated
+ };
+
+ /// \brief The parser is entering a new expression evaluation context.
+ ///
+ /// \param NewContext is the new expression evaluation context.
+ virtual void
+ PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) { }
+
+ /// \brief The parser is exiting an expression evaluation context.
+ virtual void
+ PopExpressionEvaluationContext() { }
+
+ // Primary Expressions.
+
+ /// \brief Retrieve the source range that corresponds to the given
+ /// expression.
+ virtual SourceRange getExprRange(ExprTy *E) const {
+ return SourceRange();
+ }
+
+ /// \brief Parsed an id-expression (C++) or identifier (C) in expression
+ /// context, e.g., the expression "x" that refers to a variable named "x".
+ ///
+ /// \param S the scope in which this id-expression or identifier occurs.
+ ///
+ /// \param SS the C++ nested-name-specifier that qualifies the name of the
+ /// value, e.g., "std::" in "std::sort".
+ ///
+ /// \param Name the name to which the id-expression refers. In C, this will
+ /// always be an identifier. In C++, it may also be an overloaded operator,
+ /// destructor name (if there is a nested-name-specifier), or template-id.
+ ///
+ /// \param HasTrailingLParen whether the next token following the
+ /// id-expression or identifier is a left parentheses ('(').
+ ///
+ /// \param IsAddressOfOperand whether the token that precedes this
+ /// id-expression or identifier was an ampersand ('&'), indicating that
+ /// we will be taking the address of this expression.
+ virtual OwningExprResult ActOnIdExpression(Scope *S,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ bool HasTrailingLParen,
+ bool IsAddressOfOperand) {
+ return ExprEmpty();
+ }
+
+ virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
+ tok::TokenKind Kind) {
+ return ExprEmpty();
+ }
+ virtual OwningExprResult ActOnCharacterConstant(const Token &) {
+ return ExprEmpty();
+ }
+ virtual OwningExprResult ActOnNumericConstant(const Token &) {
+ return ExprEmpty();
+ }
+
+ /// ActOnStringLiteral - The specified tokens were lexed as pasted string
+ /// fragments (e.g. "foo" "bar" L"baz").
+ virtual OwningExprResult ActOnStringLiteral(const Token *Toks,
+ unsigned NumToks) {
+ return ExprEmpty();
+ }
+
+ virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
+ ExprArg Val) {
+ return move(Val); // Default impl returns operand.
+ }
+
+ virtual OwningExprResult ActOnParenOrParenListExpr(SourceLocation L,
+ SourceLocation R,
+ MultiExprArg Val,
+ TypeTy *TypeOfCast=0) {
+ return ExprEmpty();
+ }
+
+ // Postfix Expressions.
+ virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
+ tok::TokenKind Kind,
+ ExprArg Input) {
+ return ExprEmpty();
+ }
+ virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base,
+ SourceLocation LLoc,
+ ExprArg Idx,
+ SourceLocation RLoc) {
+ return ExprEmpty();
+ }
+
+ /// \brief Parsed a member access expresion (C99 6.5.2.3, C++ [expr.ref])
+ /// of the form \c x.m or \c p->m.
+ ///
+ /// \param S the scope in which the member access expression occurs.
+ ///
+ /// \param Base the class or pointer to class into which this member
+ /// access expression refers, e.g., \c x in \c x.m.
+ ///
+ /// \param OpLoc the location of the "." or "->" operator.
+ ///
+ /// \param OpKind the kind of member access operator, which will be either
+ /// tok::arrow ("->") or tok::period (".").
+ ///
+ /// \param SS in C++, the nested-name-specifier that precedes the member
+ /// name, if any.
+ ///
+ /// \param Member the name of the member that we are referring to. In C,
+ /// this will always store an identifier; in C++, we may also have operator
+ /// names, conversion function names, destructors, and template names.
+ ///
+ /// \param ObjCImpDecl the Objective-C implementation declaration.
+ /// FIXME: Do we really need this?
+ ///
+ /// \param HasTrailingLParen whether this member name is immediately followed
+ /// by a left parentheses ('(').
+ virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Member,
+ DeclPtrTy ObjCImpDecl,
+ bool HasTrailingLParen) {
+ return ExprEmpty();
+ }
+
+ /// 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. There are guaranteed to be one fewer commas than arguments,
+ /// unless there are zero arguments.
+ virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn,
+ SourceLocation LParenLoc,
+ MultiExprArg Args,
+ SourceLocation *CommaLocs,
+ SourceLocation RParenLoc) {
+ return ExprEmpty();
+ }
+
+ // Unary Operators. 'Tok' is the token for the operator.
+ virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+ tok::TokenKind Op, ExprArg Input) {
+ return ExprEmpty();
+ }
+ virtual OwningExprResult
+ ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
+ void *TyOrEx, const SourceRange &ArgRange) {
+ return ExprEmpty();
+ }
+
+ virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParen,
+ TypeTy *Ty,
+ SourceLocation RParen,
+ ExprArg Op) {
+ return ExprEmpty();
+ }
+ virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc,
+ MultiExprArg InitList,
+ SourceLocation RParenLoc) {
+ return ExprEmpty();
+ }
+ /// @brief Parsed a C99 designated initializer.
+ ///
+ /// @param Desig Contains the designation with one or more designators.
+ ///
+ /// @param Loc The location of the '=' or ':' prior to the
+ /// initialization expression.
+ ///
+ /// @param GNUSyntax If true, then this designated initializer used
+ /// the deprecated GNU syntax @c fieldname:foo or @c [expr]foo rather
+ /// than the C99 syntax @c .fieldname=foo or @c [expr]=foo.
+ ///
+ /// @param Init The value that the entity (or entities) described by
+ /// the designation will be initialized with.
+ virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
+ SourceLocation Loc,
+ bool GNUSyntax,
+ OwningExprResult Init) {
+ return ExprEmpty();
+ }
+
+ virtual OwningExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+ TypeTy *Ty, SourceLocation RParenLoc,
+ ExprArg Op) {
+ return ExprEmpty();
+ }
+
+ virtual bool TypeIsVectorType(TypeTy *Ty) {
+ return false;
+ }
+
+ virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
+ tok::TokenKind Kind,
+ ExprArg LHS, ExprArg RHS) {
+ return ExprEmpty();
+ }
+
+ /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
+ /// in the case of a the GNU conditional expr extension.
+ virtual OwningExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
+ SourceLocation ColonLoc,
+ ExprArg Cond, ExprArg LHS,
+ ExprArg RHS) {
+ return ExprEmpty();
+ }
+
+ //===---------------------- GNU Extension Expressions -------------------===//
+
+ virtual OwningExprResult ActOnAddrLabel(SourceLocation OpLoc,
+ SourceLocation LabLoc,
+ IdentifierInfo *LabelII) { // "&&foo"
+ return ExprEmpty();
+ }
+
+ virtual OwningExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtArg SubStmt,
+ SourceLocation RPLoc) { // "({..})"
+ return ExprEmpty();
+ }
+
+ // __builtin_offsetof(type, identifier(.identifier|[expr])*)
+ struct OffsetOfComponent {
+ SourceLocation LocStart, LocEnd;
+ bool isBrackets; // true if [expr], false if .ident
+ union {
+ IdentifierInfo *IdentInfo;
+ ExprTy *E;
+ } U;
+ };
+
+ virtual OwningExprResult ActOnBuiltinOffsetOf(Scope *S,
+ SourceLocation BuiltinLoc,
+ SourceLocation TypeLoc,
+ TypeTy *Arg1,
+ OffsetOfComponent *CompPtr,
+ unsigned NumComponents,
+ SourceLocation RParenLoc) {
+ return ExprEmpty();
+ }
+
+ // __builtin_types_compatible_p(type1, type2)
+ virtual OwningExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+ TypeTy *arg1, TypeTy *arg2,
+ SourceLocation RPLoc) {
+ return ExprEmpty();
+ }
+ // __builtin_choose_expr(constExpr, expr1, expr2)
+ virtual OwningExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
+ ExprArg cond, ExprArg expr1,
+ ExprArg expr2, SourceLocation RPLoc){
+ return ExprEmpty();
+ }
+
+ // __builtin_va_arg(expr, type)
+ virtual OwningExprResult ActOnVAArg(SourceLocation BuiltinLoc,
+ ExprArg expr, TypeTy *type,
+ SourceLocation RPLoc) {
+ return ExprEmpty();
+ }
+
+ /// ActOnGNUNullExpr - Parsed the GNU __null expression, the token
+ /// for which is at position TokenLoc.
+ virtual OwningExprResult ActOnGNUNullExpr(SourceLocation TokenLoc) {
+ return ExprEmpty();
+ }
+
+ //===------------------------- "Block" Extension ------------------------===//
+
+ /// ActOnBlockStart - This callback is invoked when a block literal is
+ /// started. The result pointer is passed into the block finalizers.
+ virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {}
+
+ /// ActOnBlockArguments - This callback allows processing of block arguments.
+ /// If there are no arguments, this is still invoked.
+ virtual void ActOnBlockArguments(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.
+ virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {}
+
+ /// ActOnBlockStmtExpr - This is called when the body of a block statement
+ /// literal was successfully completed. ^(int x){...}
+ virtual OwningExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc,
+ StmtArg Body,
+ Scope *CurScope) {
+ return ExprEmpty();
+ }
+
+ //===------------------------- C++ Declarations -------------------------===//
+
+ /// ActOnStartNamespaceDef - This is called at the start of a namespace
+ /// definition.
+ virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
+ IdentifierInfo *Ident,
+ SourceLocation LBrace,
+ AttributeList *AttrList) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnFinishNamespaceDef - This callback is called after a namespace is
+ /// exited. Decl is returned by ActOnStartNamespaceDef.
+ virtual void ActOnFinishNamespaceDef(DeclPtrTy Dcl, SourceLocation RBrace) {
+ return;
+ }
+
+ /// ActOnUsingDirective - This is called when using-directive is parsed.
+ virtual DeclPtrTy ActOnUsingDirective(Scope *CurScope,
+ SourceLocation UsingLoc,
+ SourceLocation NamespcLoc,
+ CXXScopeSpec &SS,
+ SourceLocation IdentLoc,
+ IdentifierInfo *NamespcName,
+ AttributeList *AttrList);
+
+ /// ActOnNamespaceAliasDef - This is called when a namespace alias definition
+ /// is parsed.
+ virtual DeclPtrTy ActOnNamespaceAliasDef(Scope *CurScope,
+ SourceLocation NamespaceLoc,
+ SourceLocation AliasLoc,
+ IdentifierInfo *Alias,
+ CXXScopeSpec &SS,
+ SourceLocation IdentLoc,
+ IdentifierInfo *Ident) {
+ return DeclPtrTy();
+ }
+
+ /// \brief Parsed a C++ using-declaration.
+ ///
+ /// This callback will be invoked when the parser has parsed a C++
+ /// using-declaration, e.g.,
+ ///
+ /// \code
+ /// namespace std {
+ /// template<typename T, typename Alloc> class vector;
+ /// }
+ ///
+ /// using std::vector; // using-declaration here
+ /// \endcode
+ ///
+ /// \param CurScope the scope in which this using declaration was parsed.
+ ///
+ /// \param AS the currently-active access specifier.
+ ///
+ /// \param HasUsingKeyword true if this was declared with an
+ /// explicit 'using' keyword (i.e. if this is technically a using
+ /// declaration, not an access declaration)
+ ///
+ /// \param UsingLoc the location of the 'using' keyword.
+ ///
+ /// \param SS the nested-name-specifier that precedes the name.
+ ///
+ /// \param Name the name to which the using declaration refers.
+ ///
+ /// \param AttrList attributes applied to this using declaration, if any.
+ ///
+ /// \param IsTypeName whether this using declaration started with the
+ /// 'typename' keyword. FIXME: This will eventually be split into a
+ /// separate action.
+ ///
+ /// \param TypenameLoc the location of the 'typename' keyword, if present
+ ///
+ /// \returns a representation of the using declaration.
+ virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
+ AccessSpecifier AS,
+ bool HasUsingKeyword,
+ SourceLocation UsingLoc,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ AttributeList *AttrList,
+ bool IsTypeName,
+ SourceLocation TypenameLoc);
+
+ /// ActOnParamDefaultArgument - Parse default argument for function parameter
+ virtual void ActOnParamDefaultArgument(DeclPtrTy param,
+ SourceLocation EqualLoc,
+ ExprArg defarg) {
+ }
+
+ /// ActOnParamUnparsedDefaultArgument - We've seen a default
+ /// argument for a function parameter, but we can't parse it yet
+ /// because we're inside a class definition. Note that this default
+ /// argument will be parsed later.
+ virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
+ SourceLocation EqualLoc,
+ SourceLocation ArgLoc) { }
+
+ /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
+ /// the default argument for the parameter param failed.
+ virtual void ActOnParamDefaultArgumentError(DeclPtrTy param) { }
+
+ /// AddCXXDirectInitializerToDecl - This action is called immediately after
+ /// ActOnDeclarator, when a C++ direct initializer is present.
+ /// e.g: "int x(1);"
+ virtual void AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
+ SourceLocation LParenLoc,
+ MultiExprArg Exprs,
+ SourceLocation *CommaLocs,
+ SourceLocation RParenLoc) {
+ return;
+ }
+
+ /// \brief Called when we re-enter a template parameter scope.
+ ///
+ /// This action occurs when we are going to parse an member
+ /// function's default arguments or inline definition after the
+ /// outermost class definition has been completed, and when one or
+ /// more of the class definitions enclosing the member function is a
+ /// template. The "entity" in the given scope will be set as it was
+ /// when we entered the scope of the template initially, and should
+ /// be used to, e.g., reintroduce the names of template parameters
+ /// into the current scope so that they can be found by name lookup.
+ ///
+ /// \param S The (new) template parameter scope.
+ ///
+ /// \param Template the class template declaration whose template
+ /// parameters should be reintroduced into the current scope.
+ virtual void ActOnReenterTemplateScope(Scope *S, DeclPtrTy Template) {
+ }
+
+ /// ActOnStartDelayedMemberDeclarations - We have completed parsing
+ /// a C++ class, and we are about to start parsing any parts of
+ /// member declarations that could not be parsed earlier. Enter
+ /// the appropriate record scope.
+ virtual void ActOnStartDelayedMemberDeclarations(Scope *S,
+ DeclPtrTy Record) {
+ }
+
+ /// ActOnStartDelayedCXXMethodDeclaration - We have completed
+ /// parsing a top-level (non-nested) C++ class, and we are now
+ /// parsing those parts of the given Method declaration that could
+ /// not be parsed earlier (C++ [class.mem]p2), such as default
+ /// arguments. This action should enter the scope of the given
+ /// Method declaration as if we had just parsed the qualified method
+ /// name. However, it should not bring the parameters into scope;
+ /// that will be performed by ActOnDelayedCXXMethodParameter.
+ virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S,
+ DeclPtrTy Method) {
+ }
+
+ /// ActOnDelayedCXXMethodParameter - We've already started a delayed
+ /// C++ method declaration. We're (re-)introducing the given
+ /// function parameter into scope for use in parsing later parts of
+ /// the method declaration. For example, we could see an
+ /// ActOnParamDefaultArgument event for this parameter.
+ virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy Param) {
+ }
+
+ /// ActOnFinishDelayedCXXMethodDeclaration - We have finished
+ /// processing the delayed method declaration for Method. The method
+ /// declaration is now considered finished. There may be a separate
+ /// ActOnStartOfFunctionDef action later (not necessarily
+ /// immediately!) for this method, if it was also defined inside the
+ /// class body.
+ virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S,
+ DeclPtrTy Method) {
+ }
+
+ /// ActOnFinishDelayedMemberDeclarations - We have finished parsing
+ /// a C++ class, and we are about to start parsing any parts of
+ /// member declarations that could not be parsed earlier. Enter the
+ /// appropriate record scope.
+ virtual void ActOnFinishDelayedMemberDeclarations(Scope *S,
+ DeclPtrTy Record) {
+ }
+
+ /// ActOnStaticAssertDeclaration - Parse a C++0x static_assert declaration.
+ virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+ ExprArg AssertExpr,
+ ExprArg AssertMessageExpr) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnFriendFunctionDecl - Parsed a friend function declarator.
+ /// The name is actually a slight misnomer, because the declarator
+ /// is not necessarily a function declarator.
+ virtual DeclPtrTy ActOnFriendFunctionDecl(Scope *S,
+ Declarator &D,
+ bool IsDefinition,
+ MultiTemplateParamsArg TParams) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnFriendTypeDecl - Parsed a friend type declaration.
+ virtual DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+ MultiTemplateParamsArg TParams) {
+ return DeclPtrTy();
+ }
+
+ //===------------------------- C++ Expressions --------------------------===//
+
+ /// \brief Parsed a destructor name or pseudo-destructor name.
+ ///
+ /// \returns the type being destructed.
+ virtual TypeTy *getDestructorName(SourceLocation TildeLoc,
+ IdentifierInfo &II, SourceLocation NameLoc,
+ Scope *S, CXXScopeSpec &SS,
+ TypeTy *ObjectType,
+ bool EnteringContext) {
+ return getTypeName(II, NameLoc, S, &SS, false, ObjectType);
+ }
+
+
+ /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+ virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
+ tok::TokenKind Kind,
+ SourceLocation LAngleBracketLoc,
+ TypeTy *Ty,
+ SourceLocation RAngleBracketLoc,
+ SourceLocation LParenLoc,
+ ExprArg Op,
+ SourceLocation RParenLoc) {
+ return ExprEmpty();
+ }
+
+ /// ActOnCXXTypeidOfType - Parse typeid( type-id ).
+ virtual OwningExprResult ActOnCXXTypeid(SourceLocation OpLoc,
+ SourceLocation LParenLoc, bool isType,
+ void *TyOrExpr,
+ SourceLocation RParenLoc) {
+ return ExprEmpty();
+ }
+
+ /// ActOnCXXThis - Parse the C++ 'this' pointer.
+ virtual OwningExprResult ActOnCXXThis(SourceLocation ThisLoc) {
+ return ExprEmpty();
+ }
+
+ /// ActOnCXXBoolLiteral - Parse {true,false} literals.
+ virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
+ tok::TokenKind Kind) {
+ return ExprEmpty();
+ }
+
+ /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+ virtual OwningExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc) {
+ return ExprEmpty();
+ }
+
+ /// ActOnCXXThrow - Parse throw expressions.
+ virtual OwningExprResult ActOnCXXThrow(SourceLocation OpLoc, ExprArg Op) {
+ return ExprEmpty();
+ }
+
+ /// 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()").
+ virtual OwningExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
+ TypeTy *TypeRep,
+ SourceLocation LParenLoc,
+ MultiExprArg Exprs,
+ SourceLocation *CommaLocs,
+ SourceLocation RParenLoc) {
+ return ExprEmpty();
+ }
+
+ /// \brief Parsed a condition declaration in a C++ if, switch, or while
+ /// statement.
+ ///
+ /// This callback will be invoked after parsing the declaration of "x" in
+ ///
+ /// \code
+ /// if (int x = f()) {
+ /// // ...
+ /// }
+ /// \endcode
+ ///
+ /// \param S the scope of the if, switch, or while statement.
+ ///
+ /// \param D the declarator that that describes the variable being declared.
+ virtual DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
+ return DeclResult();
+ }
+
+ /// \brief Parsed an expression that will be handled as the condition in
+ /// an if/while/for statement.
+ ///
+ /// This routine handles the conversion of the expression to 'bool'.
+ ///
+ /// \param S The scope in which the expression occurs.
+ ///
+ /// \param Loc The location of the construct that requires the conversion to
+ /// a boolean value.
+ ///
+ /// \param SubExpr The expression that is being converted to bool.
+ virtual OwningExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+ ExprArg SubExpr) {
+ return move(SubExpr);
+ }
+
+ /// ActOnCXXNew - Parsed a C++ 'new' expression. UseGlobal is true if the
+ /// new was qualified (::new). In a full new like
+ /// @code new (p1, p2) type(c1, c2) @endcode
+ /// the p1 and p2 expressions will be in PlacementArgs and the c1 and c2
+ /// expressions in ConstructorArgs. The type is passed as a declarator.
+ virtual OwningExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
+ SourceLocation PlacementLParen,
+ MultiExprArg PlacementArgs,
+ SourceLocation PlacementRParen,
+ bool ParenTypeId, Declarator &D,
+ SourceLocation ConstructorLParen,
+ MultiExprArg ConstructorArgs,
+ SourceLocation ConstructorRParen) {
+ return ExprEmpty();
+ }
+
+ /// ActOnCXXDelete - Parsed a C++ 'delete' expression. UseGlobal is true if
+ /// the delete was qualified (::delete). ArrayForm is true if the array form
+ /// was used (delete[]).
+ virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
+ bool UseGlobal, bool ArrayForm,
+ ExprArg Operand) {
+ return ExprEmpty();
+ }
+
+ virtual OwningExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+ SourceLocation KWLoc,
+ SourceLocation LParen,
+ TypeTy *Ty,
+ SourceLocation RParen) {
+ return ExprEmpty();
+ }
+
+ /// \brief Invoked when the parser is starting to parse a C++ member access
+ /// expression such as x.f or x->f.
+ ///
+ /// \param S the scope in which the member access expression occurs.
+ ///
+ /// \param Base the expression in which a member is being accessed, e.g., the
+ /// "x" in "x.f".
+ ///
+ /// \param OpLoc the location of the member access operator ("." or "->")
+ ///
+ /// \param OpKind the kind of member access operator ("." or "->")
+ ///
+ /// \param ObjectType originally NULL. The action should fill in this type
+ /// with the type into which name lookup should look to find the member in
+ /// the member access expression.
+ ///
+ /// \param MayBePseudoDestructor Originally false. The action should
+ /// set this true if the expression may end up being a
+ /// pseudo-destructor expression, indicating to the parser that it
+ /// shoudl be parsed as a pseudo-destructor rather than as a member
+ /// access expression. Note that this should apply both when the
+ /// object type is a scalar and when the object type is dependent.
+ ///
+ /// \returns the (possibly modified) \p Base expression
+ virtual OwningExprResult ActOnStartCXXMemberReference(Scope *S,
+ ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ TypeTy *&ObjectType,
+ bool &MayBePseudoDestructor) {
+ return ExprEmpty();
+ }
+
+ /// \brief Parsed a C++ pseudo-destructor expression or a dependent
+ /// member access expression that has the same syntactic form as a
+ /// pseudo-destructor expression.
+ ///
+ /// \param S The scope in which the member access expression occurs.
+ ///
+ /// \param Base The expression in which a member is being accessed, e.g., the
+ /// "x" in "x.f".
+ ///
+ /// \param OpLoc The location of the member access operator ("." or "->")
+ ///
+ /// \param OpKind The kind of member access operator ("." or "->")
+ ///
+ /// \param SS The nested-name-specifier that precedes the type names
+ /// in the grammar. Note that this nested-name-specifier will not
+ /// cover the last "type-name ::" in the grammar, because it isn't
+ /// necessarily a nested-name-specifier.
+ ///
+ /// \param FirstTypeName The type name that follows the optional
+ /// nested-name-specifier but precedes the '::', e.g., the first
+ /// type-name in "type-name :: type-name". This type name may be
+ /// empty. This will be either an identifier or a template-id.
+ ///
+ /// \param CCLoc The location of the '::' in "type-name ::
+ /// typename". May be invalid, if there is no \p FirstTypeName.
+ ///
+ /// \param TildeLoc The location of the '~'.
+ ///
+ /// \param SecondTypeName The type-name following the '~', which is
+ /// the name of the type being destroyed. This will be either an
+ /// identifier or a template-id.
+ ///
+ /// \param HasTrailingLParen Whether the next token in the stream is
+ /// a left parentheses.
+ virtual OwningExprResult ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ CXXScopeSpec &SS,
+ UnqualifiedId &FirstTypeName,
+ SourceLocation CCLoc,
+ SourceLocation TildeLoc,
+ UnqualifiedId &SecondTypeName,
+ bool HasTrailingLParen) {
+ return ExprEmpty();
+ }
+
+ /// ActOnFinishFullExpr - Called whenever a full expression has been parsed.
+ /// (C++ [intro.execution]p12).
+ virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr) {
+ return move(Expr);
+ }
+
+ //===---------------------------- C++ Classes ---------------------------===//
+ /// ActOnBaseSpecifier - Parsed a base specifier
+ virtual BaseResult ActOnBaseSpecifier(DeclPtrTy classdecl,
+ SourceRange SpecifierRange,
+ bool Virtual, AccessSpecifier Access,
+ TypeTy *basetype,
+ SourceLocation BaseLoc) {
+ return BaseResult();
+ }
+
+ virtual void ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
+ unsigned NumBases) {
+ }
+
+ /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
+ /// declarator is parsed. 'AS' is the access specifier, 'BitfieldWidth'
+ /// specifies the bitfield width if there is one and 'Init' specifies the
+ /// initializer if any. 'Deleted' is true if there's a =delete
+ /// specifier on the function.
+ virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
+ Declarator &D,
+ MultiTemplateParamsArg TemplateParameterLists,
+ ExprTy *BitfieldWidth,
+ ExprTy *Init,
+ bool IsDefinition,
+ bool Deleted = false) {
+ return DeclPtrTy();
+ }
+
+ virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorDecl,
+ Scope *S,
+ CXXScopeSpec &SS,
+ IdentifierInfo *MemberOrBase,
+ TypeTy *TemplateTypeTy,
+ SourceLocation IdLoc,
+ SourceLocation LParenLoc,
+ ExprTy **Args, unsigned NumArgs,
+ SourceLocation *CommaLocs,
+ SourceLocation RParenLoc) {
+ return true;
+ }
+
+ /// ActOnMemInitializers - This is invoked when all of the member
+ /// initializers of a constructor have been parsed. ConstructorDecl
+ /// is the function declaration (which will be a C++ constructor in
+ /// a well-formed program), ColonLoc is the location of the ':' that
+ /// starts the constructor initializer, and MemInit/NumMemInits
+ /// contains the individual member (and base) initializers.
+ /// AnyErrors will be true if there were any invalid member initializers
+ /// that are not represented in the list.
+ virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
+ SourceLocation ColonLoc,
+ MemInitTy **MemInits, unsigned NumMemInits,
+ bool AnyErrors){
+ }
+
+ virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {}
+
+ /// ActOnFinishCXXMemberSpecification - Invoked after all member declarators
+ /// are parsed but *before* parsing of inline method definitions.
+ virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
+ DeclPtrTy TagDecl,
+ SourceLocation LBrac,
+ SourceLocation RBrac,
+ AttributeList *AttrList) {
+ }
+
+ //===---------------------------C++ Templates----------------------------===//
+
+ /// ActOnTypeParameter - Called when a C++ template type parameter
+ /// (e.g., "typename T") has been parsed. Typename specifies whether
+ /// the keyword "typename" was used to declare the type parameter
+ /// (otherwise, "class" was used), ellipsis specifies whether this is a
+ /// C++0x parameter pack, EllipsisLoc specifies the start of the ellipsis,
+ /// and KeyLoc is the location of the "class" or "typename" keyword.
+ // ParamName is the name of the parameter (NULL indicates an unnamed template
+ // parameter) and ParamNameLoc is the location of the parameter name (if any)
+ /// If the type parameter has a default argument, it will be added
+ /// later via ActOnTypeParameterDefault. Depth and Position provide
+ /// the number of enclosing templates (see
+ /// ActOnTemplateParameterList) and the number of previous
+ /// parameters within this template parameter list.
+ virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+ SourceLocation EllipsisLoc,
+ SourceLocation KeyLoc,
+ IdentifierInfo *ParamName,
+ SourceLocation ParamNameLoc,
+ unsigned Depth, unsigned Position) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnTypeParameterDefault - Adds a default argument (the type
+ /// Default) to the given template type parameter (TypeParam).
+ virtual void ActOnTypeParameterDefault(DeclPtrTy TypeParam,
+ SourceLocation EqualLoc,
+ SourceLocation DefaultLoc,
+ TypeTy *Default) {
+ }
+
+ /// ActOnNonTypeTemplateParameter - Called when a C++ non-type
+ /// template parameter (e.g., "int Size" in "template<int Size>
+ /// class Array") has been parsed. S is the current scope and D is
+ /// the parsed declarator. Depth and Position provide the number of
+ /// enclosing templates (see
+ /// ActOnTemplateParameterList) and the number of previous
+ /// parameters within this template parameter list.
+ virtual DeclPtrTy ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+ unsigned Depth,
+ unsigned Position) {
+ return DeclPtrTy();
+ }
+
+ /// \brief Adds a default argument to the given non-type template
+ /// parameter.
+ virtual void ActOnNonTypeTemplateParameterDefault(DeclPtrTy TemplateParam,
+ SourceLocation EqualLoc,
+ ExprArg Default) {
+ }
+
+ /// ActOnTemplateTemplateParameter - Called when a C++ template template
+ /// parameter (e.g., "int T" in "template<template <typename> class T> class
+ /// Array") has been parsed. TmpLoc is the location of the "template" keyword,
+ /// TemplateParams is the sequence of parameters required by the template,
+ /// ParamName is the name of the parameter (null if unnamed), and ParamNameLoc
+ /// is the source location of the identifier (if given).
+ virtual DeclPtrTy ActOnTemplateTemplateParameter(Scope *S,
+ SourceLocation TmpLoc,
+ TemplateParamsTy *Params,
+ IdentifierInfo *ParamName,
+ SourceLocation ParamNameLoc,
+ unsigned Depth,
+ unsigned Position) {
+ return DeclPtrTy();
+ }
+
+ /// \brief Adds a default argument to the given template template
+ /// parameter.
+ virtual void ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParam,
+ SourceLocation EqualLoc,
+ const ParsedTemplateArgument &Default) {
+ }
+
+ /// ActOnTemplateParameterList - Called when a complete template
+ /// parameter list has been parsed, e.g.,
+ ///
+ /// @code
+ /// export template<typename T, T Size>
+ /// @endcode
+ ///
+ /// Depth is the number of enclosing template parameter lists. This
+ /// value does not include templates from outer scopes. For example:
+ ///
+ /// @code
+ /// template<typename T> // depth = 0
+ /// class A {
+ /// template<typename U> // depth = 0
+ /// class B;
+ /// };
+ ///
+ /// template<typename T> // depth = 0
+ /// template<typename U> // depth = 1
+ /// class A<T>::B { ... };
+ /// @endcode
+ ///
+ /// ExportLoc, if valid, is the position of the "export"
+ /// keyword. Otherwise, "export" was not specified.
+ /// TemplateLoc is the position of the template keyword, LAngleLoc
+ /// is the position of the left angle bracket, and RAngleLoc is the
+ /// position of the corresponding right angle bracket.
+ /// Params/NumParams provides the template parameters that were
+ /// parsed as part of the template-parameter-list.
+ virtual TemplateParamsTy *
+ ActOnTemplateParameterList(unsigned Depth,
+ SourceLocation ExportLoc,
+ SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ DeclPtrTy *Params, unsigned NumParams,
+ SourceLocation RAngleLoc) {
+ return 0;
+ }
+
+ /// \brief Form a type from a template and a list of template
+ /// arguments.
+ ///
+ /// This action merely forms the type for the template-id, possibly
+ /// checking well-formedness of the template arguments. It does not
+ /// imply the declaration of any entity.
+ ///
+ /// \param Template A template whose specialization results in a
+ /// type, e.g., a class template or template template parameter.
+ virtual TypeResult ActOnTemplateIdType(TemplateTy Template,
+ SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation RAngleLoc) {
+ return TypeResult();
+ }
+
+ /// \brief Note that a template ID was used with a tag.
+ ///
+ /// \param Type The result of ActOnTemplateIdType.
+ ///
+ /// \param TUK Either TUK_Reference or TUK_Friend. Declarations and
+ /// definitions are interpreted as explicit instantiations or
+ /// specializations.
+ ///
+ /// \param TagSpec The tag keyword that was provided as part of the
+ /// elaborated-type-specifier; either class, struct, union, or enum.
+ ///
+ /// \param TagLoc The location of the tag keyword.
+ virtual TypeResult ActOnTagTemplateIdType(TypeResult Type,
+ TagUseKind TUK,
+ DeclSpec::TST TagSpec,
+ SourceLocation TagLoc) {
+ return TypeResult();
+ }
+
+ /// \brief Form a dependent template name.
+ ///
+ /// This action forms a dependent template name given the template
+ /// name and its (presumably dependent) scope specifier. For
+ /// example, given "MetaFun::template apply", the scope specifier \p
+ /// SS will be "MetaFun::", \p TemplateKWLoc contains the location
+ /// of the "template" keyword, and "apply" is the \p Name.
+ ///
+ /// \param TemplateKWLoc the location of the "template" keyword (if any).
+ ///
+ /// \param SS the nested-name-specifier that precedes the "template" keyword
+ /// or the template name. If the dependent template name occurs in
+ /// a member access expression, e.g., "x.template f<T>", this
+ /// nested-name-specifier will be empty.
+ ///
+ /// \param Name the name of the template.
+ ///
+ /// \param ObjectType if this dependent template name occurs in the
+ /// context of a member access expression, the type of the object being
+ /// accessed.
+ ///
+ /// \param EnteringContext whether we are entering the context of this
+ /// template.
+ virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ TypeTy *ObjectType,
+ bool EnteringContext) {
+ return TemplateTy();
+ }
+
+ /// \brief Process the declaration or definition of an explicit
+ /// class template specialization or a class template partial
+ /// specialization.
+ ///
+ /// This routine is invoked when an explicit class template
+ /// specialization or a class template partial specialization is
+ /// declared or defined, to introduce the (partial) specialization
+ /// and produce a declaration for it. In the following example,
+ /// ActOnClassTemplateSpecialization will be invoked for the
+ /// declarations at both A and B:
+ ///
+ /// \code
+ /// template<typename T> class X;
+ /// template<> class X<int> { }; // A: explicit specialization
+ /// template<typename T> class X<T*> { }; // B: partial specialization
+ /// \endcode
+ ///
+ /// Note that it is the job of semantic analysis to determine which
+ /// of the two cases actually occurred in the source code, since
+ /// they are parsed through the same path. The formulation of the
+ /// template parameter lists describes which case we are in.
+ ///
+ /// \param S the current scope
+ ///
+ /// \param TagSpec whether this declares a class, struct, or union
+ /// (template)
+ ///
+ /// \param TUK whether this is a declaration or a definition
+ ///
+ /// \param KWLoc the location of the 'class', 'struct', or 'union'
+ /// keyword.
+ ///
+ /// \param SS the scope specifier preceding the template-id
+ ///
+ /// \param Template the declaration of the class template that we
+ /// are specializing.
+ ///
+ /// \param Attr attributes on the specialization
+ ///
+ /// \param TemplateParameterLists the set of template parameter
+ /// lists that apply to this declaration. In a well-formed program,
+ /// the number of template parameter lists will be one more than the
+ /// number of template-ids in the scope specifier. However, it is
+ /// common for users to provide the wrong number of template
+ /// parameter lists (such as a missing \c template<> prior to a
+ /// specialization); the parser does not check this condition.
+ virtual DeclResult
+ ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
+ SourceLocation KWLoc,
+ CXXScopeSpec &SS,
+ TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation RAngleLoc,
+ AttributeList *Attr,
+ MultiTemplateParamsArg TemplateParameterLists) {
+ return DeclResult();
+ }
+
+ /// \brief Invoked when a declarator that has one or more template parameter
+ /// lists has been parsed.
+ ///
+ /// This action is similar to ActOnDeclarator(), except that the declaration
+ /// being created somehow involves a template, e.g., it is a template
+ /// declaration or specialization.
+ virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
+ MultiTemplateParamsArg TemplateParameterLists,
+ Declarator &D) {
+ return DeclPtrTy();
+ }
+
+ /// \brief Invoked when the parser is beginning to parse a function template
+ /// or function template specialization definition.
+ virtual DeclPtrTy ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+ MultiTemplateParamsArg TemplateParameterLists,
+ Declarator &D) {
+ return DeclPtrTy();
+ }
+
+ /// \brief Process the explicit instantiation of a class template
+ /// specialization.
+ ///
+ /// This routine is invoked when an explicit instantiation of a
+ /// class template specialization is encountered. In the following
+ /// example, ActOnExplicitInstantiation will be invoked to force the
+ /// instantiation of X<int>:
+ ///
+ /// \code
+ /// template<typename T> class X { /* ... */ };
+ /// template class X<int>; // explicit instantiation
+ /// \endcode
+ ///
+ /// \param S the current scope
+ ///
+ /// \param ExternLoc the location of the 'extern' keyword that specifies that
+ /// this is an extern template (if any).
+ ///
+ /// \param TemplateLoc the location of the 'template' keyword that
+ /// specifies that this is an explicit instantiation.
+ ///
+ /// \param TagSpec whether this declares a class, struct, or union
+ /// (template).
+ ///
+ /// \param KWLoc the location of the 'class', 'struct', or 'union'
+ /// keyword.
+ ///
+ /// \param SS the scope specifier preceding the template-id.
+ ///
+ /// \param Template the declaration of the class template that we
+ /// are instantiation.
+ ///
+ /// \param LAngleLoc the location of the '<' token in the template-id.
+ ///
+ /// \param TemplateArgs the template arguments used to form the
+ /// template-id.
+ ///
+ /// \param TemplateArgLocs the locations of the template arguments.
+ ///
+ /// \param RAngleLoc the location of the '>' token in the template-id.
+ ///
+ /// \param Attr attributes that apply to this instantiation.
+ virtual 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) {
+ return DeclResult();
+ }
+
+ /// \brief Process the explicit instantiation of a member class of a
+ /// class template specialization.
+ ///
+ /// This routine is invoked when an explicit instantiation of a
+ /// member class of a class template specialization is
+ /// encountered. In the following example,
+ /// ActOnExplicitInstantiation will be invoked to force the
+ /// instantiation of X<int>::Inner:
+ ///
+ /// \code
+ /// template<typename T> class X { class Inner { /* ... */}; };
+ /// template class X<int>::Inner; // explicit instantiation
+ /// \endcode
+ ///
+ /// \param S the current scope
+ ///
+ /// \param ExternLoc the location of the 'extern' keyword that specifies that
+ /// this is an extern template (if any).
+ ///
+ /// \param TemplateLoc the location of the 'template' keyword that
+ /// specifies that this is an explicit instantiation.
+ ///
+ /// \param TagSpec whether this declares a class, struct, or union
+ /// (template).
+ ///
+ /// \param KWLoc the location of the 'class', 'struct', or 'union'
+ /// keyword.
+ ///
+ /// \param SS the scope specifier preceding the template-id.
+ ///
+ /// \param Template the declaration of the class template that we
+ /// are instantiation.
+ ///
+ /// \param LAngleLoc the location of the '<' token in the template-id.
+ ///
+ /// \param TemplateArgs the template arguments used to form the
+ /// template-id.
+ ///
+ /// \param TemplateArgLocs the locations of the template arguments.
+ ///
+ /// \param RAngleLoc the location of the '>' token in the template-id.
+ ///
+ /// \param Attr attributes that apply to this instantiation.
+ virtual DeclResult
+ ActOnExplicitInstantiation(Scope *S,
+ SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ unsigned TagSpec,
+ SourceLocation KWLoc,
+ CXXScopeSpec &SS,
+ IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ AttributeList *Attr) {
+ return DeclResult();
+ }
+
+ /// \brief Process the explicit instantiation of a function template or a
+ /// member of a class template.
+ ///
+ /// This routine is invoked when an explicit instantiation of a
+ /// function template or member function of a class template specialization
+ /// is encountered. In the following example,
+ /// ActOnExplicitInstantiation will be invoked to force the
+ /// instantiation of X<int>:
+ ///
+ /// \code
+ /// template<typename T> void f(T);
+ /// template void f(int); // explicit instantiation
+ /// \endcode
+ ///
+ /// \param S the current scope
+ ///
+ /// \param ExternLoc the location of the 'extern' keyword that specifies that
+ /// this is an extern template (if any).
+ ///
+ /// \param TemplateLoc the location of the 'template' keyword that
+ /// specifies that this is an explicit instantiation.
+ ///
+ /// \param D the declarator describing the declaration to be implicitly
+ /// instantiated.
+ virtual DeclResult ActOnExplicitInstantiation(Scope *S,
+ SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ Declarator &D) {
+ return DeclResult();
+ }
+
+
+ /// \brief Called when the parser has parsed a C++ typename
+ /// specifier that ends in an identifier, e.g., "typename T::type".
+ ///
+ /// \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.
+ virtual TypeResult
+ ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+ const IdentifierInfo &II, SourceLocation IdLoc) {
+ return TypeResult();
+ }
+
+ /// \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 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 Ty the type that the typename specifier refers to.
+ virtual TypeResult
+ ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+ SourceLocation TemplateLoc, TypeTy *Ty) {
+ return TypeResult();
+ }
+
+ //===----------------------- Obj-C Declarations -------------------------===//
+
+ // ActOnStartClassInterface - this action is called immediately after parsing
+ // the prologue for a class interface (before parsing the instance
+ // variables). Instance variables are processed by ActOnFields().
+ virtual DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassLoc,
+ IdentifierInfo *SuperName,
+ SourceLocation SuperLoc,
+ const DeclPtrTy *ProtoRefs,
+ unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs,
+ SourceLocation EndProtoLoc,
+ AttributeList *AttrList) {
+ return DeclPtrTy();
+ }
+
+ /// ActOnCompatiblityAlias - this action is called after complete parsing of
+ /// @compaatibility_alias declaration. It sets up the alias relationships.
+ virtual DeclPtrTy ActOnCompatiblityAlias(
+ SourceLocation AtCompatibilityAliasLoc,
+ IdentifierInfo *AliasName, SourceLocation AliasLocation,
+ IdentifierInfo *ClassName, SourceLocation ClassLocation) {
+ return DeclPtrTy();
+ }
+
+ // ActOnStartProtocolInterface - this action is called immdiately after
+ // parsing the prologue for a protocol interface.
+ virtual DeclPtrTy ActOnStartProtocolInterface(SourceLocation AtProtoLoc,
+ IdentifierInfo *ProtocolName,
+ SourceLocation ProtocolLoc,
+ const DeclPtrTy *ProtoRefs,
+ unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs,
+ SourceLocation EndProtoLoc,
+ AttributeList *AttrList) {
+ return DeclPtrTy();
+ }
+ // ActOnStartCategoryInterface - this action is called immdiately after
+ // parsing the prologue for a category interface.
+ virtual DeclPtrTy ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassLoc,
+ IdentifierInfo *CategoryName,
+ SourceLocation CategoryLoc,
+ const DeclPtrTy *ProtoRefs,
+ unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs,
+ SourceLocation EndProtoLoc) {
+ return DeclPtrTy();
+ }
+ // ActOnStartClassImplementation - this action is called immdiately after
+ // parsing the prologue for a class implementation. Instance variables are
+ // processed by ActOnFields().
+ virtual DeclPtrTy ActOnStartClassImplementation(
+ SourceLocation AtClassImplLoc,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassLoc,
+ IdentifierInfo *SuperClassname,
+ SourceLocation SuperClassLoc) {
+ return DeclPtrTy();
+ }
+ // ActOnStartCategoryImplementation - this action is called immdiately after
+ // parsing the prologue for a category implementation.
+ virtual DeclPtrTy ActOnStartCategoryImplementation(
+ SourceLocation AtCatImplLoc,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassLoc,
+ IdentifierInfo *CatName,
+ SourceLocation CatLoc) {
+ return DeclPtrTy();
+ }
+ // ActOnPropertyImplDecl - called for every property implementation
+ virtual DeclPtrTy ActOnPropertyImplDecl(
+ Scope *S,
+ SourceLocation AtLoc, // location of the @synthesize/@dynamic
+ SourceLocation PropertyNameLoc, // location for the property name
+ bool ImplKind, // true for @synthesize, false for
+ // @dynamic
+ DeclPtrTy ClassImplDecl, // class or category implementation
+ IdentifierInfo *propertyId, // name of property
+ IdentifierInfo *propertyIvar) { // name of the ivar
+ return DeclPtrTy();
+ }
+
+ struct ObjCArgInfo {
+ IdentifierInfo *Name;
+ SourceLocation NameLoc;
+ // The Type is null if no type was specified, and the DeclSpec is invalid
+ // in this case.
+ TypeTy *Type;
+ ObjCDeclSpec DeclSpec;
+
+ /// ArgAttrs - Attribute list for this argument.
+ AttributeList *ArgAttrs;
+ };
+
+ // ActOnMethodDeclaration - called for all method declarations.
+ virtual DeclPtrTy ActOnMethodDeclaration(
+ SourceLocation BeginLoc, // location of the + or -.
+ SourceLocation EndLoc, // location of the ; or {.
+ tok::TokenKind MethodType, // tok::minus for instance, tok::plus for class.
+ DeclPtrTy ClassDecl, // class this methods belongs to.
+ ObjCDeclSpec &ReturnQT, // for return type's in inout etc.
+ TypeTy *ReturnType, // the method return type.
+ Selector Sel, // a unique name for the method.
+ ObjCArgInfo *ArgInfo, // ArgInfo: Has 'Sel.getNumArgs()' entries.
+ DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
+ AttributeList *MethodAttrList, // optional
+ // tok::objc_not_keyword, tok::objc_optional, tok::objc_required
+ tok::ObjCKeywordKind impKind,
+ bool isVariadic = false) {
+ return DeclPtrTy();
+ }
+ // ActOnAtEnd - called to mark the @end. For declarations (interfaces,
+ // protocols, categories), the parser passes all methods/properties.
+ // For class implementations, these values default to 0. For implementations,
+ // methods are processed incrementally (by ActOnMethodDeclaration above).
+ virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd,
+ DeclPtrTy classDecl,
+ DeclPtrTy *allMethods = 0,
+ unsigned allNum = 0,
+ DeclPtrTy *allProperties = 0,
+ unsigned pNum = 0,
+ DeclGroupPtrTy *allTUVars = 0,
+ unsigned tuvNum = 0) {
+ }
+ // ActOnProperty - called to build one property AST
+ virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
+ FieldDeclarator &FD, ObjCDeclSpec &ODS,
+ Selector GetterSel, Selector SetterSel,
+ DeclPtrTy ClassCategory,
+ bool *OverridingProperty,
+ tok::ObjCKeywordKind MethodImplKind) {
+ return DeclPtrTy();
+ }
+
+ virtual OwningExprResult
+ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
+ IdentifierInfo &propertyName,
+ SourceLocation receiverNameLoc,
+ SourceLocation propertyNameLoc) {
+ return ExprEmpty();
+ }
+
+ /// \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
+ };
+
+ /// \brief Determine the kind of Objective-C message send that we will be
+ /// performing based on the identifier given.
+ ///
+ /// This action determines how a message send that starts with [
+ /// identifier (followed by another identifier) will be parsed,
+ /// e.g., as a class message, instance message, super message. The
+ /// result depends on the meaning of the given identifier. If the
+ /// identifier is unknown, the action should indicate that the
+ /// message is an instance message.
+ ///
+ /// By default, this routine applies syntactic disambiguation and uses
+ /// \c getTypeName() to determine whether the identifier refers to a type.
+ /// However, \c Action subclasses may override this routine to improve
+ /// error recovery.
+ ///
+ /// \param S The scope in which the message send occurs.
+ ///
+ /// \param Name The identifier following the '['.
+ ///
+ /// \param NameLoc The location of the identifier.
+ ///
+ /// \param IsSuper Whether the name is the pseudo-keyword "super".
+ ///
+ /// \param HasTrailingDot Whether the name is followed by a period.
+ ///
+ /// \param ReceiverType If this routine returns \c ObjCClassMessage,
+ /// this argument will be set to the receiver type.
+ ///
+ /// \returns The kind of message send.
+ virtual ObjCMessageKind getObjCMessageKind(Scope *S,
+ IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ bool IsSuper,
+ bool HasTrailingDot,
+ TypeTy *&ReceiverType);
+
+ /// \brief Parsed a message send to 'super'.
+ ///
+ /// \param S The scope in which the message send occurs.
+ /// \param SuperLoc The location of the 'super' keyword.
+ /// \param Sel The selector to which the message is being sent.
+ /// \param LBracLoc The location of the opening square bracket ']'.
+ /// \param SelectorLoc The location of the first identifier in the selector.
+ /// \param RBrac The location of the closing square bracket ']'.
+ /// \param Args The message arguments.
+ virtual OwningExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
+ Selector Sel,
+ SourceLocation LBracLoc,
+ SourceLocation SelectorLoc,
+ SourceLocation RBracLoc,
+ MultiExprArg Args) {
+ return OwningExprResult(*this);
+ }
+
+ /// \brief Parsed a message send to a class.
+ ///
+ /// \param S The scope in which the message send occurs.
+ /// \param Receiver The type of the class receiving the message.
+ /// \param Sel The selector to which the message is being sent.
+ /// \param LBracLoc The location of the opening square bracket ']'.
+ /// \param SelectorLoc The location of the first identifier in the selector.
+ /// \param RBrac The location of the closing square bracket ']'.
+ /// \param Args The message arguments.
+ virtual OwningExprResult ActOnClassMessage(Scope *S,
+ TypeTy *Receiver,
+ Selector Sel,
+ SourceLocation LBracLoc,
+ SourceLocation SelectorLoc,
+ SourceLocation RBracLoc,
+ MultiExprArg Args) {
+ return OwningExprResult(*this);
+ }
+
+ /// \brief Parsed a message send to an object instance.
+ ///
+ /// \param S The scope in which the message send occurs.
+ /// \param Receiver The expression that computes the receiver object.
+ /// \param Sel The selector to which the message is being sent.
+ /// \param LBracLoc The location of the opening square bracket ']'.
+ /// \param SelectorLoc The location of the first identifier in the selector.
+ /// \param RBrac The location of the closing square bracket ']'.
+ /// \param Args The message arguments.
+ virtual OwningExprResult ActOnInstanceMessage(Scope *S,
+ ExprArg Receiver,
+ Selector Sel,
+ SourceLocation LBracLoc,
+ SourceLocation SelectorLoc,
+ SourceLocation RBracLoc,
+ MultiExprArg Args) {
+ return OwningExprResult(*this);
+ }
+
+ virtual DeclPtrTy ActOnForwardClassDeclaration(
+ SourceLocation AtClassLoc,
+ IdentifierInfo **IdentList,
+ SourceLocation *IdentLocs,
+ unsigned NumElts) {
+ return DeclPtrTy();
+ }
+ virtual DeclPtrTy ActOnForwardProtocolDeclaration(
+ SourceLocation AtProtocolLoc,
+ const IdentifierLocPair*IdentList,
+ unsigned NumElts,
+ AttributeList *AttrList) {
+ return DeclPtrTy();
+ }
+
+ /// FindProtocolDeclaration - This routine looks up protocols and
+ /// issues error if they are not declared. It returns list of valid
+ /// protocols found.
+ virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
+ const IdentifierLocPair *ProtocolId,
+ unsigned NumProtocols,
+ llvm::SmallVectorImpl<DeclPtrTy> &ResProtos) {
+ }
+
+ //===----------------------- Obj-C Expressions --------------------------===//
+
+ virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
+ ExprTy **Strings,
+ unsigned NumStrings) {
+ return ExprResult();
+ }
+
+ virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
+ SourceLocation EncLoc,
+ SourceLocation LParenLoc,
+ TypeTy *Ty,
+ SourceLocation RParenLoc) {
+ return ExprResult();
+ }
+
+ virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
+ SourceLocation AtLoc,
+ SourceLocation SelLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc) {
+ return ExprResult();
+ }
+
+ virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
+ SourceLocation AtLoc,
+ SourceLocation ProtoLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc) {
+ return ExprResult();
+ }
+
+ //===---------------------------- Pragmas -------------------------------===//
+
+ enum PragmaOptionsAlignKind {
+ POAK_Natural, // #pragma options align=natural
+ 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={...}.
+ virtual void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
+ SourceLocation PragmaLoc,
+ SourceLocation KindLoc) {
+ return;
+ }
+
+ 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])
+ };
+
+ /// ActOnPragmaPack - Called on well formed #pragma pack(...).
+ virtual void ActOnPragmaPack(PragmaPackKind Kind,
+ IdentifierInfo *Name,
+ ExprTy *Alignment,
+ SourceLocation PragmaLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc) {
+ return;
+ }
+
+ /// ActOnPragmaUnused - Called on well formed #pragma unused(...).
+ virtual void ActOnPragmaUnused(const Token *Identifiers,
+ unsigned NumIdentifiers, Scope *CurScope,
+ SourceLocation PragmaLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc) {
+ return;
+ }
+
+ /// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
+ virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName,
+ SourceLocation PragmaLoc,
+ SourceLocation WeakNameLoc) {
+ return;
+ }
+
+ /// ActOnPragmaWeakAlias - Called on well formed #pragma weak ident = ident.
+ virtual void ActOnPragmaWeakAlias(IdentifierInfo* WeakName,
+ IdentifierInfo* AliasName,
+ SourceLocation PragmaLoc,
+ SourceLocation WeakNameLoc,
+ SourceLocation AliasNameLoc) {
+ return;
+ }
+
+ /// \name Code completion actions
+ ///
+ /// These actions are used to signal that a code-completion token has been
+ /// found at a point in the grammar where the Action implementation is
+ /// likely to be able to provide a list of possible completions, e.g.,
+ /// after the "." or "->" of a member access expression.
+ ///
+ /// \todo Code completion for designated field initializers
+ /// \todo Code completion for call arguments after a function template-id
+ /// \todo Code completion within a call expression, object construction, etc.
+ /// \todo Code completion within a template argument list.
+ /// \todo Code completion for attributes.
+ //@{
+
+ /// \brief Describes the context in which code completion occurs.
+ enum CodeCompletionContext {
+ /// \brief Code completion occurs at top-level or namespace context.
+ CCC_Namespace,
+ /// \brief Code completion occurs within a class, struct, or union.
+ CCC_Class,
+ /// \brief Code completion occurs within an Objective-C interface, protocol,
+ /// or category.
+ CCC_ObjCInterface,
+ /// \brief Code completion occurs within an Objective-C implementation or
+ /// category implementation
+ CCC_ObjCImplementation,
+ /// \brief Code completion occurs within the list of instance variables
+ /// in an Objective-C interface, protocol, category, or implementation.
+ CCC_ObjCInstanceVariableList,
+ /// \brief Code completion occurs following one or more template
+ /// headers.
+ CCC_Template,
+ /// \brief Code completion occurs following one or more template
+ /// headers within a class.
+ CCC_MemberTemplate,
+ /// \brief Code completion occurs within an expression.
+ CCC_Expression,
+ /// \brief Code completion occurs within a statement, which may
+ /// also be an expression or a declaration.
+ CCC_Statement,
+ /// \brief Code completion occurs at the beginning of the
+ /// initialization statement (or expression) in a for loop.
+ CCC_ForInit,
+ /// \brief Code completion occurs within the condition of an if,
+ /// while, switch, or for statement.
+ CCC_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.
+ CCC_RecoveryInFunction
+ };
+
+ /// \brief Code completion for an ordinary name that occurs within the given
+ /// scope.
+ ///
+ /// \param S the scope in which the name occurs.
+ ///
+ /// \param CompletionContext the context in which code completion
+ /// occurs.
+ virtual void CodeCompleteOrdinaryName(Scope *S,
+ CodeCompletionContext CompletionContext) { }
+
+ /// \brief Code completion for a member access expression.
+ ///
+ /// This code completion action is invoked when the code-completion token
+ /// is found after the "." or "->" of a member access expression.
+ ///
+ /// \param S the scope in which the member access expression occurs.
+ ///
+ /// \param Base the base expression (e.g., the x in "x.foo") of the member
+ /// access.
+ ///
+ /// \param OpLoc the location of the "." or "->" operator.
+ ///
+ /// \param IsArrow true when the operator is "->", false when it is ".".
+ virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
+ SourceLocation OpLoc,
+ bool IsArrow) { }
+
+ /// \brief Code completion for a reference to a tag.
+ ///
+ /// This code completion action is invoked when the code-completion
+ /// token is found after a tag keyword (struct, union, enum, or class).
+ ///
+ /// \param S the scope in which the tag reference occurs.
+ ///
+ /// \param TagSpec an instance of DeclSpec::TST, indicating what kind of tag
+ /// this is (struct/union/enum/class).
+ virtual void CodeCompleteTag(Scope *S, unsigned TagSpec) { }
+
+ /// \brief Code completion for a case statement.
+ ///
+ /// \brief S the scope in which the case statement occurs.
+ virtual void CodeCompleteCase(Scope *S) { }
+
+ /// \brief Code completion for a call.
+ ///
+ /// \brief S the scope in which the call occurs.
+ ///
+ /// \param Fn the expression describing the function being called.
+ ///
+ /// \param Args the arguments to the function call (so far).
+ ///
+ /// \param NumArgs the number of arguments in \p Args.
+ virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
+ ExprTy **Args, unsigned NumArgs) { }
+
+ /// \brief Code completion for a C++ nested-name-specifier that precedes a
+ /// qualified-id of some form.
+ ///
+ /// This code completion action is invoked when the code-completion token
+ /// is found after the "::" of a nested-name-specifier.
+ ///
+ /// \param S the scope in which the nested-name-specifier occurs.
+ ///
+ /// \param SS the scope specifier ending with "::".
+ ///
+ /// \parame EnteringContext whether we're entering the context of this
+ /// scope specifier.
+ virtual void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
+ bool EnteringContext) { }
+
+ /// \brief Code completion for a C++ "using" declaration or directive.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the "using" keyword.
+ ///
+ /// \param S the scope in which the "using" occurs.
+ virtual void CodeCompleteUsing(Scope *S) { }
+
+ /// \brief Code completion for a C++ using directive.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "using namespace".
+ ///
+ /// \param S the scope in which the "using namespace" occurs.
+ virtual void CodeCompleteUsingDirective(Scope *S) { }
+
+ /// \brief Code completion for a C++ namespace declaration or namespace
+ /// alias declaration.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "namespace".
+ ///
+ /// \param S the scope in which the "namespace" token occurs.
+ virtual void CodeCompleteNamespaceDecl(Scope *S) { }
+
+ /// \brief Code completion for a C++ namespace alias declaration.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "namespace identifier = ".
+ ///
+ /// \param S the scope in which the namespace alias declaration occurs.
+ virtual void CodeCompleteNamespaceAliasDecl(Scope *S) { }
+
+ /// \brief Code completion for an operator name.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the keyword "operator".
+ ///
+ /// \param S the scope in which the operator keyword occurs.
+ virtual void CodeCompleteOperatorName(Scope *S) { }
+
+ /// \brief Code completion after the '@' at the top level.
+ ///
+ /// \param S the scope in which the '@' occurs.
+ ///
+ /// \param ObjCImpDecl the Objective-C implementation or category
+ /// implementation.
+ ///
+ /// \param InInterface whether we are in an Objective-C interface or
+ /// protocol.
+ virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
+ bool InInterface) { }
+
+ /// \brief Code completion after the '@' in the list of instance variables.
+ virtual void CodeCompleteObjCAtVisibility(Scope *S) { }
+
+ /// \brief Code completion after the '@' in a statement.
+ virtual void CodeCompleteObjCAtStatement(Scope *S) { }
+
+ /// \brief Code completion after the '@' in an expression.
+ virtual void CodeCompleteObjCAtExpression(Scope *S) { }
+
+ /// \brief Code completion for an ObjC property decl.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the left paren.
+ ///
+ /// \param S the scope in which the operator keyword occurs.
+ virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { }
+
+ /// \brief Code completion for the getter of an Objective-C property
+ /// declaration.
+ ///
+ /// This code completion action is invoked when the code-completion
+ /// token is found after the "getter = " in a property declaration.
+ ///
+ /// \param S the scope in which the property is being declared.
+ ///
+ /// \param ClassDecl the Objective-C class or category in which the property
+ /// is being defined.
+ ///
+ /// \param Methods the set of methods declared thus far within \p ClassDecl.
+ ///
+ /// \param NumMethods the number of methods in \p Methods
+ virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods) {
+ }
+
+ /// \brief Code completion for the setter of an Objective-C property
+ /// declaration.
+ ///
+ /// This code completion action is invoked when the code-completion
+ /// token is found after the "setter = " in a property declaration.
+ ///
+ /// \param S the scope in which the property is being declared.
+ ///
+ /// \param ClassDecl the Objective-C class or category in which the property
+ /// is being defined.
+ ///
+ /// \param Methods the set of methods declared thus far within \p ClassDecl.
+ ///
+ /// \param NumMethods the number of methods in \p Methods
+ virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods) {
+ }
+
+ /// \brief Code completion for an ObjC message expression that sends
+ /// a message to the superclass.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the class name and after each argument.
+ ///
+ /// \param S The scope in which the message expression occurs.
+ /// \param SuperLoc The location of the 'super' keyword.
+ /// \param SelIdents The identifiers that describe the selector (thus far).
+ /// \param NumSelIdents The number of identifiers in \p SelIdents.
+ virtual void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) { }
+
+ /// \brief Code completion for an ObjC message expression that refers to
+ /// a class method.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the class name and after each argument.
+ ///
+ /// \param S The scope in which the message expression occurs.
+ /// \param Receiver The type of the class that is receiving a message.
+ /// \param SelIdents The identifiers that describe the selector (thus far).
+ /// \param NumSelIdents The number of identifiers in \p SelIdents.
+ virtual void CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) { }
+
+ /// \brief Code completion for an ObjC message expression that refers to
+ /// an instance method.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the receiver expression and after each argument.
+ ///
+ /// \param S the scope in which the operator keyword occurs.
+ /// \param Receiver an expression for the receiver of the message.
+ /// \param SelIdents the identifiers that describe the selector (thus far).
+ /// \param NumSelIdents the number of identifiers in \p SelIdents.
+ virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) { }
+
+ /// \brief Code completion for a list of protocol references in Objective-C,
+ /// such as P1 and P2 in \c id<P1,P2>.
+ ///
+ /// This code completion action is invoked prior to each identifier
+ /// in the protocol list.
+ ///
+ /// \param Protocols the set of protocols that have already been parsed.
+ ///
+ /// \param NumProtocols the number of protocols that have already been
+ /// parsed.
+ virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
+ unsigned NumProtocols) { }
+
+ /// \brief Code completion for a protocol declaration or definition, after
+ /// the @protocol but before any identifier.
+ ///
+ /// \param S the scope in which the protocol declaration occurs.
+ virtual void CodeCompleteObjCProtocolDecl(Scope *S) { }
+
+ /// \brief Code completion for an Objective-C interface, after the
+ /// @interface but before any identifier.
+ virtual void CodeCompleteObjCInterfaceDecl(Scope *S) { }
+
+ /// \brief Code completion for the superclass of an Objective-C
+ /// interface, after the ':'.
+ ///
+ /// \param S the scope in which the interface declaration occurs.
+ ///
+ /// \param ClassName the name of the class being defined.
+ virtual void CodeCompleteObjCSuperclass(Scope *S,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassNameLoc) {
+ }
+
+ /// \brief Code completion for an Objective-C implementation, after the
+ /// @implementation but before any identifier.
+ virtual void CodeCompleteObjCImplementationDecl(Scope *S) { }
+
+ /// \brief Code completion for the category name in an Objective-C interface
+ /// declaration.
+ ///
+ /// This code completion action is invoked after the '(' that indicates
+ /// a category name within an Objective-C interface declaration.
+ virtual void CodeCompleteObjCInterfaceCategory(Scope *S,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassNameLoc) {
+ }
+
+ /// \brief Code completion for the category name in an Objective-C category
+ /// implementation.
+ ///
+ /// This code completion action is invoked after the '(' that indicates
+ /// the category name within an Objective-C category implementation.
+ virtual void CodeCompleteObjCImplementationCategory(Scope *S,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassNameLoc) {
+ }
+
+ /// \brief Code completion for the property names when defining an
+ /// Objective-C property.
+ ///
+ /// This code completion action is invoked after @synthesize or @dynamic and
+ /// after each "," within one of those definitions.
+ virtual void CodeCompleteObjCPropertyDefinition(Scope *S,
+ DeclPtrTy ObjCImpDecl) {
+ }
+
+ /// \brief Code completion for the instance variable name that should
+ /// follow an '=' when synthesizing an Objective-C property.
+ ///
+ /// This code completion action is invoked after each '=' that occurs within
+ /// an @synthesized definition.
+ virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
+ IdentifierInfo *PropertyName,
+ DeclPtrTy ObjCImpDecl) {
+ }
+
+ /// \brief Code completion for an Objective-C method declaration or
+ /// definition, which may occur within an interface, category,
+ /// extension, protocol, or implementation thereof (where applicable).
+ ///
+ /// This code completion action is invoked after the "-" or "+" that
+ /// starts a method declaration or definition, and after the return
+ /// type such a declaration (e.g., "- (id)").
+ ///
+ /// \param S The scope in which the completion occurs.
+ ///
+ /// \param IsInstanceMethod Whether this is an instance method
+ /// (introduced with '-'); otherwise, it's a class method
+ /// (introduced with '+').
+ ///
+ /// \param ReturnType If non-NULL, the specified return type of the method
+ /// being declared or defined.
+ ///
+ /// \param IDecl The interface, category, protocol, or
+ /// implementation, or category implementation in which this method
+ /// declaration or definition occurs.
+ virtual void CodeCompleteObjCMethodDecl(Scope *S,
+ bool IsInstanceMethod,
+ TypeTy *ReturnType,
+ DeclPtrTy IDecl) {
+ }
+ //@}
+};
+
+/// MinimalAction - Minimal actions are used by light-weight clients of the
+/// parser that do not need name resolution or significant semantic analysis to
+/// be performed. The actions implemented here are in the form of unresolved
+/// identifiers. By using a simpler interface than the SemanticAction class,
+/// the parser doesn't have to build complex data structures and thus runs more
+/// quickly.
+class MinimalAction : public Action {
+ /// 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;
+ IdentifierTable &Idents;
+ Preprocessor &PP;
+ void *TypeNameInfoTablePtr;
+public:
+ MinimalAction(Preprocessor &pp);
+ ~MinimalAction();
+
+ /// getTypeName - This looks at the IdentifierInfo::FETokenInfo field to
+ /// determine whether the name is a typedef or not in this scope.
+ ///
+ /// \param II the identifier for which we are performing name lookup
+ ///
+ /// \param NameLoc the location of the identifier
+ ///
+ /// \param S the scope in which this name lookup occurs
+ ///
+ /// \param SS if non-NULL, the C++ scope specifier that precedes the
+ /// identifier
+ ///
+ /// \param isClassName whether this is a C++ class-name production, in
+ /// which we can end up referring to a member of an unknown specialization
+ /// that we know (from the grammar) is supposed to be a type. For example,
+ /// this occurs when deriving from "std::vector<T>::allocator_type", where T
+ /// is a template parameter.
+ ///
+ /// \returns the type referred to by this identifier, or NULL if the type
+ /// does not name an identifier.
+ virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+ Scope *S, CXXScopeSpec *SS,
+ bool isClassName = false,
+ TypeTy *ObjectType = 0);
+
+ /// isCurrentClassName - Always returns false, because MinimalAction
+ /// does not support C++ classes with constructors.
+ virtual bool isCurrentClassName(const IdentifierInfo& II, Scope *S,
+ const CXXScopeSpec *SS);
+
+ virtual TemplateNameKind isTemplateName(Scope *S,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ TypeTy *ObjectType,
+ bool EnteringContext,
+ TemplateTy &Template,
+ bool &MemberOfUnknownSpecialization);
+
+
+ /// ActOnDeclarator - If this is a typedef declarator, we modify the
+ /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
+ /// popped.
+ virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D);
+
+ /// ActOnPopScope - When a scope is popped, if any typedefs are now
+ /// out-of-scope, they are removed from the IdentifierInfo::FETokenInfo field.
+ virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
+ virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
+
+ virtual DeclPtrTy ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
+ IdentifierInfo **IdentList,
+ SourceLocation *SLocs,
+ unsigned NumElts);
+
+ virtual DeclPtrTy ActOnStartClassInterface(SourceLocation interLoc,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassLoc,
+ IdentifierInfo *SuperName,
+ SourceLocation SuperLoc,
+ const DeclPtrTy *ProtoRefs,
+ unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs,
+ SourceLocation EndProtoLoc,
+ AttributeList *AttrList);
+};
+
+/// PrettyStackTraceActionsDecl - If a crash occurs in the parser while parsing
+/// something related to a virtualized decl, include that virtualized decl in
+/// the stack trace.
+class PrettyStackTraceActionsDecl : public llvm::PrettyStackTraceEntry {
+ Action::DeclPtrTy TheDecl;
+ SourceLocation Loc;
+ Action &Actions;
+ SourceManager &SM;
+ const char *Message;
+public:
+ PrettyStackTraceActionsDecl(Action::DeclPtrTy Decl, SourceLocation L,
+ Action &actions, SourceManager &sm,
+ const char *Msg)
+ : TheDecl(Decl), Loc(L), Actions(actions), SM(sm), Message(Msg) {}
+
+ virtual void print(llvm::raw_ostream &OS) const;
+};
+
+/// \brief RAII object that enters a new expression evaluation context.
+class EnterExpressionEvaluationContext {
+ /// \brief The action object.
+ Action &Actions;
+
+public:
+ EnterExpressionEvaluationContext(Action &Actions,
+ Action::ExpressionEvaluationContext NewContext)
+ : Actions(Actions) {
+ Actions.PushExpressionEvaluationContext(NewContext);
+ }
+
+ ~EnterExpressionEvaluationContext() {
+ Actions.PopExpressionEvaluationContext();
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/AttributeList.h b/contrib/llvm/tools/clang/include/clang/Parse/AttributeList.h
new file mode 100644
index 0000000..1e6d3ab
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/AttributeList.h
@@ -0,0 +1,227 @@
+//===--- AttributeList.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 AttributeList class interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ATTRLIST_H
+#define LLVM_CLANG_ATTRLIST_H
+
+#include "clang/Parse/Ownership.h"
+#include "clang/Basic/SourceLocation.h"
+#include <cassert>
+
+namespace clang {
+ class IdentifierInfo;
+ class Action;
+
+/// AttributeList - Represents GCC's __attribute__ declaration. There are
+/// 4 forms of this construct...they are:
+///
+/// 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 {
+ IdentifierInfo *AttrName;
+ SourceLocation AttrLoc;
+ IdentifierInfo *ScopeName;
+ SourceLocation ScopeLoc;
+ IdentifierInfo *ParmName;
+ SourceLocation ParmLoc;
+ ActionBase::ExprTy **Args;
+ unsigned NumArgs;
+ AttributeList *Next;
+ bool DeclspecAttribute, CXX0XAttribute;
+ mutable bool Invalid; /// True if already diagnosed as invalid.
+ AttributeList(const AttributeList &); // DO NOT IMPLEMENT
+ void operator=(const AttributeList &); // DO NOT IMPLEMENT
+public:
+ AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc,
+ IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+ IdentifierInfo *ParmName, SourceLocation ParmLoc,
+ ActionBase::ExprTy **args, unsigned numargs,
+ AttributeList *Next, bool declspec = false, bool cxx0x = false);
+ ~AttributeList();
+
+ enum Kind { // Please keep this list alphabetized.
+ AT_IBAction, // Clang-specific.
+ AT_IBOutlet, // Clang-specific.
+ AT_IBOutletCollection, // Clang-specific.
+ AT_address_space,
+ AT_alias,
+ AT_aligned,
+ AT_always_inline,
+ AT_analyzer_noreturn,
+ AT_annotate,
+ AT_base_check,
+ AT_blocks,
+ AT_carries_dependency,
+ AT_cdecl,
+ AT_cleanup,
+ AT_const,
+ AT_constructor,
+ AT_deprecated,
+ AT_destructor,
+ AT_dllexport,
+ AT_dllimport,
+ AT_ext_vector_type,
+ AT_fastcall,
+ AT_final,
+ AT_format,
+ AT_format_arg,
+ AT_gnu_inline,
+ AT_hiding,
+ AT_malloc,
+ AT_mode,
+ AT_nodebug,
+ AT_noinline,
+ AT_no_instrument_function,
+ AT_nonnull,
+ AT_noreturn,
+ AT_nothrow,
+ AT_nsobject,
+ AT_objc_exception,
+ AT_override,
+ AT_cf_returns_not_retained, // Clang-specific.
+ AT_cf_returns_retained, // Clang-specific.
+ AT_ns_returns_not_retained, // Clang-specific.
+ AT_ns_returns_retained, // Clang-specific.
+ AT_objc_gc,
+ AT_overloadable, // Clang-specific.
+ AT_packed,
+ AT_pure,
+ AT_regparm,
+ AT_section,
+ AT_sentinel,
+ AT_stdcall,
+ AT_thiscall,
+ AT_transparent_union,
+ AT_unavailable,
+ AT_unused,
+ AT_used,
+ AT_vector_size,
+ AT_visibility,
+ AT_warn_unused_result,
+ AT_weak,
+ AT_weakref,
+ AT_weak_import,
+ AT_reqd_wg_size,
+ IgnoredAttribute,
+ UnknownAttribute
+ };
+
+ IdentifierInfo *getName() const { return AttrName; }
+ SourceLocation getLoc() const { return AttrLoc; }
+
+ bool hasScope() const { return ScopeName; }
+ IdentifierInfo *getScopeName() const { return ScopeName; }
+ SourceLocation getScopeLoc() const { return ScopeLoc; }
+
+ IdentifierInfo *getParameterName() const { return ParmName; }
+
+ bool isDeclspecAttribute() const { return DeclspecAttribute; }
+ bool isCXX0XAttribute() const { return CXX0XAttribute; }
+
+ bool isInvalid() const { return Invalid; }
+ void setInvalid(bool b = true) const { Invalid = b; }
+
+ Kind getKind() const { return getKind(getName()); }
+ static Kind getKind(const IdentifierInfo *Name);
+
+ AttributeList *getNext() const { return Next; }
+ void setNext(AttributeList *N) { Next = N; }
+
+ /// getNumArgs - Return the number of actual arguments to this attribute.
+ unsigned getNumArgs() const { return NumArgs; }
+
+ /// getArg - Return the specified argument.
+ ActionBase::ExprTy *getArg(unsigned Arg) const {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return Args[Arg];
+ }
+
+ class arg_iterator {
+ ActionBase::ExprTy** X;
+ unsigned Idx;
+ public:
+ arg_iterator(ActionBase::ExprTy** x, unsigned idx) : X(x), Idx(idx) {}
+
+ arg_iterator& operator++() {
+ ++Idx;
+ return *this;
+ }
+
+ bool operator==(const arg_iterator& I) const {
+ assert (X == I.X &&
+ "compared arg_iterators are for different argument lists");
+ return Idx == I.Idx;
+ }
+
+ bool operator!=(const arg_iterator& I) const {
+ return !operator==(I);
+ }
+
+ ActionBase::ExprTy* operator*() const {
+ return X[Idx];
+ }
+
+ unsigned getArgNum() const {
+ return Idx+1;
+ }
+ };
+
+ arg_iterator arg_begin() const {
+ return arg_iterator(Args, 0);
+ }
+
+ arg_iterator arg_end() const {
+ return arg_iterator(Args, NumArgs);
+ }
+};
+
+/// addAttributeLists - Add two AttributeLists together
+/// The right-hand list is appended to the left-hand list, if any
+/// A pointer to the joined list is returned.
+/// Note: the lists are not left unmodified.
+inline AttributeList* addAttributeLists (AttributeList *Left,
+ AttributeList *Right) {
+ if (!Left)
+ return Right;
+
+ AttributeList *next = Left, *prev;
+ do {
+ prev = next;
+ next = next->getNext();
+ } while (next);
+ prev->setNext(Right);
+ return Left;
+}
+
+/// CXX0XAttributeList - A wrapper around a C++0x attribute list.
+/// Stores, in addition to the list proper, whether or not an actual list was
+/// (as opposed to an empty list, which may be ill-formed in some places) and
+/// the source range of the list.
+struct CXX0XAttributeList {
+ AttributeList *AttrList;
+ SourceRange Range;
+ bool HasAttr;
+ CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
+ : AttrList(attrList), Range(range), HasAttr (hasAttr) {
+ }
+ CXX0XAttributeList ()
+ : AttrList(0), Range(), HasAttr(false) {
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/DeclSpec.h b/contrib/llvm/tools/clang/include/clang/Parse/DeclSpec.h
new file mode 100644
index 0000000..9c19a67
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/DeclSpec.h
@@ -0,0 +1,1323 @@
+//===--- SemaDeclSpec.h - Declaration Specifier Semantic Analys -*- 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 for Declaration Specifiers and Declarators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_DECLSPEC_H
+#define LLVM_CLANG_PARSE_DECLSPEC_H
+
+#include "clang/Parse/AttributeList.h"
+#include "clang/Lex/Token.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+ class LangOptions;
+ class Diagnostic;
+ class IdentifierInfo;
+ class Preprocessor;
+ class Declarator;
+ struct TemplateIdAnnotation;
+
+/// CXXScopeSpec - 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, idenified 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;
+ void *ScopeRep;
+
+public:
+ CXXScopeSpec() : Range(), ScopeRep() { }
+
+ const SourceRange &getRange() const { return Range; }
+ void setRange(const 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(); }
+
+ ActionBase::CXXScopeTy *getScopeRep() const { return ScopeRep; }
+ void setScopeRep(ActionBase::CXXScopeTy *S) { ScopeRep = S; }
+
+ /// 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 occured during parsing of the scope specifier.
+ bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; }
+ /// A scope specifier is present, and it refers to a real scope.
+ bool isValid() const { return isNotEmpty() && ScopeRep != 0; }
+
+ /// Deprecated. Some call sites intend isNotEmpty() while others intend
+ /// isValid().
+ bool isSet() const { return ScopeRep != 0; }
+
+ void clear() {
+ Range = SourceRange();
+ ScopeRep = 0;
+ }
+};
+
+/// DeclSpec - This class captures information about "declaration specifiers",
+/// which encompasses storage-class-specifiers, type-specifiers,
+/// type-qualifiers, and function-specifiers.
+class DeclSpec {
+public:
+ // 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 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_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_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_auto = clang::TST_auto;
+ 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
+ };
+
+ /// 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;
+ bool SCS_thread_specified : 1;
+
+ // type-specifier
+ /*TSW*/unsigned TypeSpecWidth : 2;
+ /*TSC*/unsigned TypeSpecComplex : 2;
+ /*TSS*/unsigned TypeSpecSign : 2;
+ /*TST*/unsigned TypeSpecType : 5;
+ bool TypeAltiVecVector : 1;
+ bool TypeAltiVecPixel : 1;
+ bool TypeSpecOwned : 1;
+
+ // type-qualifiers
+ unsigned TypeQualifiers : 3; // Bitwise OR of TQ.
+
+ // function-specifier
+ bool FS_inline_specified : 1;
+ bool FS_virtual_specified : 1;
+ bool FS_explicit_specified : 1;
+
+ // friend-specifier
+ bool Friend_specified : 1;
+
+ // constexpr-specifier
+ bool Constexpr_specified : 1;
+
+ /*SCS*/unsigned StorageClassSpecAsWritten : 3;
+
+ /// TypeRep - This contains action-specific information about a specific TST.
+ /// For example, for a typedef or struct, it might contain the declaration for
+ /// these.
+ void *TypeRep;
+
+ // attributes.
+ AttributeList *AttrList;
+
+ // Scope specifier for the type spec, if applicable.
+ CXXScopeSpec TypeScope;
+
+ // List of protocol qualifiers for objective-c classes. Used for
+ // protocol-qualified interfaces "NString<foo>" and protocol-qualified id
+ // "id<foo>".
+ const ActionBase::DeclPtrTy *ProtocolQualifiers;
+ unsigned NumProtocolQualifiers;
+ SourceLocation ProtocolLAngleLoc;
+ SourceLocation *ProtocolLocs;
+
+ // SourceLocation info. These are null if the item wasn't specified or if
+ // the setting was synthesized.
+ SourceRange Range;
+
+ SourceLocation StorageClassSpecLoc, SCS_threadLoc;
+ SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
+ SourceRange TypeofParensRange;
+ SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
+ SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc;
+ SourceLocation FriendLoc, ConstexprLoc;
+
+ WrittenBuiltinSpecs writtenBS;
+ void SaveWrittenBuiltinSpecs();
+ void SaveStorageSpecifierAsWritten() {
+ StorageClassSpecAsWritten = StorageClassSpec;
+ }
+
+ DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT
+ void operator=(const DeclSpec&); // DO NOT IMPLEMENT
+public:
+
+ DeclSpec()
+ : StorageClassSpec(SCS_unspecified),
+ SCS_thread_specified(false),
+ TypeSpecWidth(TSW_unspecified),
+ TypeSpecComplex(TSC_unspecified),
+ TypeSpecSign(TSS_unspecified),
+ TypeSpecType(TST_unspecified),
+ TypeAltiVecVector(false),
+ TypeAltiVecPixel(false),
+ TypeSpecOwned(false),
+ TypeQualifiers(TSS_unspecified),
+ FS_inline_specified(false),
+ FS_virtual_specified(false),
+ FS_explicit_specified(false),
+ Friend_specified(false),
+ Constexpr_specified(false),
+ StorageClassSpecAsWritten(SCS_unspecified),
+ TypeRep(0),
+ AttrList(0),
+ ProtocolQualifiers(0),
+ NumProtocolQualifiers(0),
+ ProtocolLocs(0),
+ writtenBS() {
+ }
+ ~DeclSpec() {
+ delete AttrList;
+ delete [] ProtocolQualifiers;
+ delete [] ProtocolLocs;
+ }
+ // storage-class-specifier
+ SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; }
+ bool isThreadSpecified() const { return SCS_thread_specified; }
+
+ SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
+ SourceLocation getThreadSpecLoc() const { return SCS_threadLoc; }
+
+ void ClearStorageClassSpecs() {
+ StorageClassSpec = DeclSpec::SCS_unspecified;
+ SCS_thread_specified = false;
+ StorageClassSpecLoc = SourceLocation();
+ SCS_threadLoc = 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 isTypeSpecOwned() const { return TypeSpecOwned; }
+ void *getTypeRep() const { return TypeRep; }
+ CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
+ const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
+
+ const SourceRange &getSourceRange() const { return Range; }
+ 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; }
+
+ SourceRange getTypeofParensRange() const { return TypeofParensRange; }
+ void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
+
+ /// getSpecifierName - Turn a type-specifier-type into a string like "_Bool"
+ /// or "union".
+ static const char *getSpecifierName(DeclSpec::TST T);
+ 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);
+
+ // 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; }
+
+ // function-specifier
+ bool isInlineSpecified() const { return FS_inline_specified; }
+ SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; }
+
+ 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; }
+
+ void ClearFunctionSpecs() {
+ FS_inline_specified = false;
+ FS_inlineLoc = SourceLocation();
+ FS_virtual_specified = false;
+ FS_virtualLoc = SourceLocation();
+ FS_explicit_specified = false;
+ FS_explicitLoc = SourceLocation();
+ }
+
+ /// hasTypeSpecifier - 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;
+ }
+
+ /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
+ /// DeclSpec includes.
+ ///
+ unsigned getParsedSpecifiers() const;
+
+ SCS getStorageClassSpecAsWritten() const {
+ return (SCS)StorageClassSpecAsWritten;
+ }
+
+ /// 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(SCS S, SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ 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, void *Rep = 0, bool Owned = false);
+ bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID);
+ bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID);
+ bool SetTypeSpecError();
+ void UpdateTypeRep(void *Rep) { TypeRep = 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 SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+
+ bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+
+ bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+
+ bool isFriendSpecified() const { return Friend_specified; }
+ SourceLocation getFriendSpecLoc() const { return FriendLoc; }
+
+ bool isConstexprSpecified() const { return Constexpr_specified; }
+ SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
+
+ /// AddAttributes - contatenates two attribute lists.
+ /// The GCC attribute syntax allows for the following:
+ ///
+ /// short __attribute__(( unused, deprecated ))
+ /// int __attribute__(( may_alias, aligned(16) )) var;
+ ///
+ /// This declares 4 attributes using 2 lists. The following syntax is
+ /// also allowed and equivalent to the previous declaration.
+ ///
+ /// short __attribute__((unused)) __attribute__((deprecated))
+ /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
+ ///
+ void AddAttributes(AttributeList *alist) {
+ AttrList = addAttributeLists(AttrList, alist);
+ }
+ void SetAttributes(AttributeList *AL) { AttrList = AL; }
+ const AttributeList *getAttributes() const { return AttrList; }
+ AttributeList *getAttributes() { return AttrList; }
+
+ /// TakeAttributes - Return the current attribute list and remove them from
+ /// the DeclSpec so that it doesn't own them.
+ AttributeList *TakeAttributes() {
+ AttributeList *AL = AttrList;
+ AttrList = 0;
+ return AL;
+ }
+
+ typedef const ActionBase::DeclPtrTy *ProtocolQualifierListTy;
+ ProtocolQualifierListTy getProtocolQualifiers() const {
+ return ProtocolQualifiers;
+ }
+ SourceLocation *getProtocolLocs() const { return ProtocolLocs; }
+ unsigned getNumProtocolQualifiers() const {
+ return NumProtocolQualifiers;
+ }
+ SourceLocation getProtocolLAngleLoc() const { return ProtocolLAngleLoc; }
+ void setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos, unsigned NP,
+ SourceLocation *ProtoLocs,
+ SourceLocation LAngleLoc);
+
+ /// 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(Diagnostic &D, Preprocessor &PP);
+
+ const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
+ return writtenBS;
+ }
+
+ /// isMissingDeclaratorOk - This checks if this DeclSpec can stand alone,
+ /// without a Declarator. Only tag declspecs can stand alone.
+ bool isMissingDeclaratorOk();
+};
+
+/// ObjCDeclSpec - This class captures information about
+/// "declaration specifiers" specific to objective-c
+class ObjCDeclSpec {
+public:
+ /// ObjCDeclQualifier - Qualifier used on types in method declarations
+ enum ObjCDeclQualifier {
+ DQ_None = 0x0,
+ DQ_In = 0x1,
+ DQ_Inout = 0x2,
+ DQ_Out = 0x4,
+ DQ_Bycopy = 0x8,
+ DQ_Byref = 0x10,
+ DQ_Oneway = 0x20
+ };
+
+ /// 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
+ };
+
+
+ ObjCDeclSpec()
+ : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
+ GetterName(0), SetterName(0) { }
+ ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
+ void setObjCDeclQualifier(ObjCDeclQualifier DQVal) {
+ objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal);
+ }
+
+ ObjCPropertyAttributeKind getPropertyAttributes() const {
+ return ObjCPropertyAttributeKind(PropertyAttributes);
+ }
+ void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) {
+ PropertyAttributes =
+ (ObjCPropertyAttributeKind)(PropertyAttributes | PRVal);
+ }
+
+ 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 mutially exclusive. So perhaps
+ // we can put them in a union to reflect their mutual exclusiveness
+ // (space saving is negligible).
+ ObjCDeclQualifier objcDeclQualifier : 6;
+
+ // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
+ unsigned PropertyAttributes : 8;
+ IdentifierInfo *GetterName; // getter name of NULL if no getter
+ IdentifierInfo *SetterName; // setter name of NULL if no setter
+};
+
+/// \brief Represents a C++ unqualified-id that has been parsed.
+class UnqualifiedId {
+private:
+ const UnqualifiedId &operator=(const UnqualifiedId &); // DO NOT IMPLEMENT
+
+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
+ } Kind;
+
+ /// \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 {
+ /// \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];
+ } OperatorFunctionId;
+
+ /// \brief When Kind == IK_ConversionFunctionId, the type that the
+ /// conversion function names.
+ ActionBase::TypeTy *ConversionFunctionId;
+
+ /// \brief When Kind == IK_ConstructorName, the class-name of the type
+ /// whose constructor is being referenced.
+ ActionBase::TypeTy *ConstructorName;
+
+ /// \brief When Kind == IK_DestructorName, the type referred to by the
+ /// class-name.
+ ActionBase::TypeTy *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(0) { }
+
+ /// \brief Do not use this copy constructor. It is temporary, and only
+ /// exists because we are holding FieldDeclarators in a SmallVector when we
+ /// don't actually need them.
+ ///
+ /// FIXME: Kill this copy constructor.
+ UnqualifiedId(const UnqualifiedId &Other)
+ : Kind(IK_Identifier), Identifier(Other.Identifier),
+ StartLocation(Other.StartLocation), EndLocation(Other.EndLocation) {
+ assert(Other.Kind == IK_Identifier && "Cannot copy non-identifiers");
+ }
+
+ /// \brief Destroy this unqualified-id.
+ ~UnqualifiedId() { clear(); }
+
+ /// \brief Clear out this unqualified-id, setting it to default (invalid)
+ /// state.
+ void clear();
+
+ /// \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; }
+
+ /// \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,
+ ActionBase::TypeTy *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(ActionBase::TypeTy *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, ActionBase::TypeTy *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 {
+ return SourceRange(StartLocation, EndLocation);
+ }
+};
+
+/// CachedTokens - A set of tokens that has been cached for later
+/// parsing.
+typedef llvm::SmallVector<Token, 4> CachedTokens;
+
+/// DeclaratorChunk - 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
+ } Kind;
+
+ /// Loc - The place where this type was defined.
+ SourceLocation Loc;
+ /// EndLoc - If valid, the place where this chunck ends.
+ SourceLocation EndLoc;
+
+ struct PointerTypeInfo {
+ /// The type qualifiers: const/volatile/restrict.
+ unsigned TypeQuals : 3;
+ AttributeList *AttrList;
+ void destroy() {
+ delete AttrList;
+ }
+ };
+
+ struct ReferenceTypeInfo {
+ /// The type qualifier: restrict. [GNU] C++ extension
+ bool HasRestrict : 1;
+ /// True if this is an lvalue reference, false if it's an rvalue reference.
+ bool LValueRef : 1;
+ AttributeList *AttrList;
+ void destroy() {
+ delete AttrList;
+ }
+ };
+
+ struct ArrayTypeInfo {
+ /// The type qualifiers for the array: const/volatile/restrict.
+ unsigned TypeQuals : 3;
+
+ /// 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.
+ ActionBase::ExprTy *NumElts;
+ void destroy() {}
+ };
+
+ /// ParamInfo - An array of paraminfo objects is allocated whenever a function
+ /// declarator is parsed. There are two interesting styles of arguments 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;
+ ActionBase::DeclPtrTy 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,
+ ActionBase::DeclPtrTy param,
+ CachedTokens *DefArgTokens = 0)
+ : Ident(ident), IdentLoc(iloc), Param(param),
+ DefaultArgTokens(DefArgTokens) {}
+ };
+
+ struct TypeAndRange {
+ ActionBase::TypeTy *Ty;
+ SourceRange Range;
+ };
+
+ struct FunctionTypeInfo {
+ /// hasPrototype - This is true if the function had at least one typed
+ /// argument. If the function is () or (a,b,c), then it has no prototype,
+ /// and is treated as a K&R-style function.
+ bool 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.
+ bool isVariadic : 1;
+
+ /// The type qualifiers: const/volatile/restrict.
+ /// The qualifier bitmask values are the same as in QualType.
+ unsigned TypeQuals : 3;
+
+ /// hasExceptionSpec - True if the function has an exception specification.
+ bool hasExceptionSpec : 1;
+
+ /// hasAnyExceptionSpec - True if the function has a throw(...) specifier.
+ bool hasAnyExceptionSpec : 1;
+
+ /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
+ bool DeleteArgInfo : 1;
+
+ /// When isVariadic is true, the location of the ellipsis in the source.
+ unsigned EllipsisLoc;
+
+ /// NumArgs - This is the number of formal arguments provided for the
+ /// declarator.
+ unsigned NumArgs;
+
+ /// NumExceptions - This is the number of types in the exception-decl, if
+ /// the function has one.
+ unsigned NumExceptions;
+
+ /// ThrowLoc - When hasExceptionSpec is true, the location of the throw
+ /// keyword introducing the spec.
+ unsigned ThrowLoc;
+
+ /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
+ /// describe the arguments for this function declarator. This is null if
+ /// there are no arguments specified.
+ ParamInfo *ArgInfo;
+
+ /// Exceptions - This is a pointer to a new[]'d array of TypeAndRange
+ /// objects that contain the types in the function's exception
+ /// specification and their locations.
+ TypeAndRange *Exceptions;
+
+ /// freeArgs - reset the argument list to having zero arguments. This is
+ /// used in various places for error recovery.
+ void freeArgs() {
+ if (DeleteArgInfo) {
+ delete[] ArgInfo;
+ DeleteArgInfo = false;
+ }
+ NumArgs = 0;
+ }
+
+ void destroy() {
+ if (DeleteArgInfo)
+ delete[] ArgInfo;
+ delete[] Exceptions;
+ }
+
+ SourceLocation getEllipsisLoc() const {
+ return SourceLocation::getFromRawEncoding(EllipsisLoc);
+ }
+ SourceLocation getThrowLoc() const {
+ return SourceLocation::getFromRawEncoding(ThrowLoc);
+ }
+ };
+
+ struct BlockPointerTypeInfo {
+ /// For now, sema will catch these as invalid.
+ /// The type qualifiers: const/volatile/restrict.
+ unsigned TypeQuals : 3;
+ AttributeList *AttrList;
+ void destroy() {
+ delete AttrList;
+ }
+ };
+
+ struct MemberPointerTypeInfo {
+ /// The type qualifiers: const/volatile/restrict.
+ unsigned TypeQuals : 3;
+ AttributeList *AttrList;
+ // 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() {
+ delete AttrList;
+ Scope().~CXXScopeSpec();
+ }
+ };
+
+ union {
+ PointerTypeInfo Ptr;
+ ReferenceTypeInfo Ref;
+ ArrayTypeInfo Arr;
+ FunctionTypeInfo Fun;
+ BlockPointerTypeInfo Cls;
+ MemberPointerTypeInfo Mem;
+ };
+
+ void destroy() {
+ switch (Kind) {
+ default: assert(0 && "Unknown decl type!");
+ 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();
+ }
+ }
+
+ /// getAttrs - If there are attributes applied to this declaratorchunk, return
+ /// them.
+ const AttributeList *getAttrs() const {
+ switch (Kind) {
+ default: assert(0 && "Unknown declarator kind!");
+ case Pointer: return Ptr.AttrList;
+ case Reference: return Ref.AttrList;
+ case MemberPointer: return Mem.AttrList;
+ case Array: return 0;
+ case Function: return 0;
+ case BlockPointer: return Cls.AttrList;
+ }
+ }
+
+
+ /// getPointer - Return a DeclaratorChunk for a pointer.
+ ///
+ static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
+ AttributeList *AL) {
+ DeclaratorChunk I;
+ I.Kind = Pointer;
+ I.Loc = Loc;
+ I.Ptr.TypeQuals = TypeQuals;
+ I.Ptr.AttrList = AL;
+ return I;
+ }
+
+ /// getReference - Return a DeclaratorChunk for a reference.
+ ///
+ static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
+ AttributeList *AL, 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 = AL;
+ return I;
+ }
+
+ /// getArray - Return a DeclaratorChunk for an array.
+ ///
+ static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic,
+ bool isStar, void *NumElts,
+ SourceLocation LBLoc, SourceLocation RBLoc) {
+ DeclaratorChunk I;
+ I.Kind = Array;
+ I.Loc = LBLoc;
+ I.EndLoc = RBLoc;
+ 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 isVariadic,
+ SourceLocation EllipsisLoc,
+ ParamInfo *ArgInfo, unsigned NumArgs,
+ unsigned TypeQuals, bool hasExceptionSpec,
+ SourceLocation ThrowLoc,
+ bool hasAnyExceptionSpec,
+ ActionBase::TypeTy **Exceptions,
+ SourceRange *ExceptionRanges,
+ unsigned NumExceptions,
+ SourceLocation LPLoc, SourceLocation RPLoc,
+ Declarator &TheDeclarator);
+
+ /// getBlockPointer - Return a DeclaratorChunk for a block.
+ ///
+ static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc,
+ AttributeList *AL) {
+ DeclaratorChunk I;
+ I.Kind = BlockPointer;
+ I.Loc = Loc;
+ I.Cls.TypeQuals = TypeQuals;
+ I.Cls.AttrList = AL;
+ return I;
+ }
+
+ static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
+ unsigned TypeQuals,
+ SourceLocation Loc,
+ AttributeList *AL) {
+ DeclaratorChunk I;
+ I.Kind = MemberPointer;
+ I.Loc = Loc;
+ I.Mem.TypeQuals = TypeQuals;
+ I.Mem.AttrList = AL;
+ new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
+ return I;
+ }
+};
+
+/// Declarator - 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.
+ 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.
+ CXXCatchContext, // C++ catch exception-declaration
+ BlockLiteralContext // Block literal declarator.
+ };
+
+private:
+ const DeclSpec &DS;
+ CXXScopeSpec SS;
+ UnqualifiedId Name;
+ SourceRange Range;
+
+ /// Context - 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.
+ llvm::SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
+
+ /// InvalidType - Set by Sema::GetTypeForDeclarator().
+ bool InvalidType : 1;
+
+ /// GroupingParens - Set by Parser::ParseParenDeclarator().
+ bool GroupingParens : 1;
+
+ /// AttrList - Attributes.
+ AttributeList *AttrList;
+
+ /// AsmLabel - The asm label, if specified.
+ ActionBase::ExprTy *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;
+
+ /// Extension - true if the declaration is preceded by __extension__.
+ bool Extension : 1;
+
+ 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), AttrList(0), AsmLabel(0),
+ InlineParamsUsed(false), Extension(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); }
+
+ /// 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; }
+
+ /// getSourceRange - Get the source range that spans this declarator.
+ const SourceRange &getSourceRange() const { return Range; }
+
+ 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) {
+ const SourceRange &SR = DS.getSourceRange();
+ if (Range.getBegin().isInvalid())
+ Range.setBegin(SR.getBegin());
+ if (!SR.getEnd().isInvalid())
+ Range.setEnd(SR.getEnd());
+ }
+
+ /// clear - 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();
+ delete AttrList;
+ AttrList = 0;
+ AsmLabel = 0;
+ InlineParamsUsed = false;
+ }
+
+ /// 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 {
+ return Context == TypeNameContext || Context == PrototypeContext ||
+ Context == TemplateParamContext || Context == CXXCatchContext ||
+ Context == BlockLiteralContext;
+ }
+
+ /// 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 {
+ return Context != TypeNameContext && Context != BlockLiteralContext;
+ }
+
+ /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be
+ /// followed by a C++ direct initializer, e.g. "int x(1);".
+ bool mayBeFollowedByCXXDirectInit() const {
+ return !hasGroupingParens() &&
+ (Context == FileContext ||
+ Context == BlockContext ||
+ Context == ForContext);
+ }
+
+ /// 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 0;
+ }
+ 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, SourceLocation EndLoc) {
+ DeclTypeInfo.push_back(TI);
+ if (!EndLoc.isInvalid())
+ SetRangeEnd(EndLoc);
+ }
+
+ /// getNumTypeObjects() - 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];
+ }
+
+ void DropFirstTypeObject()
+ {
+ assert(!DeclTypeInfo.empty() && "No type chunks to drop.");
+ DeclTypeInfo.front().destroy();
+ DeclTypeInfo.erase(DeclTypeInfo.begin());
+ }
+
+ /// isFunctionDeclarator - Once this declarator is fully parsed and formed,
+ /// this method returns true if the identifier is a function declarator.
+ bool isFunctionDeclarator() const {
+ return !DeclTypeInfo.empty() &&
+ DeclTypeInfo[0].Kind == DeclaratorChunk::Function;
+ }
+
+ /// AddAttributes - simply adds the attribute list to the 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 AddAttributes(AttributeList *alist, SourceLocation LastLoc) {
+ AttrList = addAttributeLists(AttrList, alist);
+
+ if (!LastLoc.isInvalid())
+ SetRangeEnd(LastLoc);
+ }
+
+ const AttributeList *getAttributes() const { return AttrList; }
+ AttributeList *getAttributes() { return AttrList; }
+
+ /// hasAttributes - do we contain any attributes?
+ bool hasAttributes() const {
+ if (getAttributes() || getDeclSpec().getAttributes()) return true;
+ for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
+ if (getTypeObject(i).getAttrs())
+ return true;
+ return false;
+ }
+
+ void setAsmLabel(ActionBase::ExprTy *E) { AsmLabel = E; }
+ ActionBase::ExprTy *getAsmLabel() const { return AsmLabel; }
+
+ void setExtension(bool Val = true) { Extension = Val; }
+ bool getExtension() const { return Extension; }
+
+ 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; }
+};
+
+/// FieldDeclarator - This little struct is used to capture information about
+/// structure field declarators, which is basically just a bitfield size.
+struct FieldDeclarator {
+ Declarator D;
+ ActionBase::ExprTy *BitfieldSize;
+ explicit FieldDeclarator(DeclSpec &DS) : D(DS, Declarator::MemberContext) {
+ BitfieldSize = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Designator.h b/contrib/llvm/tools/clang/include/clang/Parse/Designator.h
new file mode 100644
index 0000000..255af59
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/Designator.h
@@ -0,0 +1,239 @@
+//===--- 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 in the parser and
+// is the input to Actions module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_DESIGNATOR_H
+#define LLVM_CLANG_PARSE_DESIGNATOR_H
+
+#include "clang/Parse/Action.h"
+
+namespace clang {
+
+/// Designator - 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 {
+ ActionBase::ExprTy *Index;
+ unsigned LBracketLoc;
+ mutable unsigned RBracketLoc;
+ };
+ struct ArrayRangeDesignatorInfo {
+ ActionBase::ExprTy *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);
+ }
+
+ ActionBase::ExprTy *getArrayIndex() const {
+ assert(isArrayDesignator() && "Invalid accessor");
+ return ArrayInfo.Index;
+ }
+
+ ActionBase::ExprTy *getArrayRangeStart() const {
+ assert(isArrayRangeDesignator() && "Invalid accessor");
+ return ArrayRangeInfo.Start;
+ }
+ ActionBase::ExprTy *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(ActionBase::ExprTy *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(ActionBase::ExprTy *Start,
+ ActionBase::ExprTy *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(Action &Actions) {
+ switch (Kind) {
+ case FieldDesignator: return;
+ case ArrayDesignator:
+ ArrayInfo.Index = 0;
+ return;
+ case ArrayRangeDesignator:
+ ArrayRangeInfo.Start = 0;
+ ArrayRangeInfo.End = 0;
+ return;
+ }
+ }
+
+ /// FreeExprs - Release any unclaimed memory for the expressions in this
+ /// designator.
+ void FreeExprs(Action &Actions) {
+ switch (Kind) {
+ case FieldDesignator: return; // nothing to free.
+ case ArrayDesignator:
+ Actions.DeleteExpr(getArrayIndex());
+ return;
+ case ArrayRangeDesignator:
+ Actions.DeleteExpr(getArrayRangeStart());
+ Actions.DeleteExpr(getArrayRangeEnd());
+ return;
+ }
+ }
+};
+
+
+/// Designation - Represent a full designation, which is a sequence of
+/// designators. This class is mostly a helper for InitListDesignations.
+class Designation {
+ /// InitIndex - The index of the initializer expression this is for. For
+ /// example, if the initializer were "{ A, .foo=B, C }" a Designation would
+ /// exist with InitIndex=1, because element #1 has a designation.
+ unsigned InitIndex;
+
+ /// Designators - The actual designators for this initializer.
+ llvm::SmallVector<Designator, 2> Designators;
+
+ Designation(unsigned Idx) : InitIndex(Idx) {}
+public:
+ Designation() : InitIndex(4000) {}
+
+ /// 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(Action &Actions) {
+ for (unsigned i = 0, e = Designators.size(); i != e; ++i)
+ Designators[i].ClearExprs(Actions);
+ }
+
+ /// FreeExprs - Release any unclaimed memory for the expressions in this
+ /// designation.
+ void FreeExprs(Action &Actions) {
+ for (unsigned i = 0, e = Designators.size(); i != e; ++i)
+ Designators[i].FreeExprs(Actions);
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Ownership.h b/contrib/llvm/tools/clang/include/clang/Parse/Ownership.h
new file mode 100644
index 0000000..e9a20b7
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/Ownership.h
@@ -0,0 +1,845 @@
+//===--- 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_PARSE_OWNERSHIP_H
+#define LLVM_CLANG_PARSE_OWNERSHIP_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+//===----------------------------------------------------------------------===//
+// OpaquePtr
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+ class ActionBase;
+
+ /// OpaquePtr - 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 UID
+ /// template argument is used to make sure that "Decl" pointers are not
+ /// compatible with "Type" pointers for example.
+ template<int UID>
+ class OpaquePtr {
+ void *Ptr;
+ public:
+ OpaquePtr() : Ptr(0) {}
+
+ template <typename T>
+ T* getAs() const {
+ return llvm::PointerLikeTypeTraits<T*>::getFromVoidPointer(Ptr);
+ }
+
+ template <typename T>
+ T getAsVal() const {
+ return llvm::PointerLikeTypeTraits<T>::getFromVoidPointer(Ptr);
+ }
+
+ void *get() const { return Ptr; }
+
+ template<typename T>
+ static OpaquePtr make(T P) {
+ OpaquePtr R; R.set(P); return R;
+ }
+
+ template<typename T>
+ void set(T P) {
+ Ptr = llvm::PointerLikeTypeTraits<T>::getAsVoidPointer(P);
+ }
+
+ operator bool() const { return Ptr != 0; }
+ };
+}
+
+namespace llvm {
+ template <int UID>
+ class PointerLikeTypeTraits<clang::OpaquePtr<UID> > {
+ public:
+ static inline void *getAsVoidPointer(clang::OpaquePtr<UID> P) {
+ // FIXME: Doesn't work? return P.getAs< void >();
+ return P.get();
+ }
+ static inline clang::OpaquePtr<UID> getFromVoidPointer(void *P) {
+ return clang::OpaquePtr<UID>::make(P);
+ }
+ enum { NumLowBitsAvailable = 3 };
+ };
+}
+
+
+
+// -------------------------- About Move Emulation -------------------------- //
+// The smart pointer classes in this file attempt to emulate move semantics
+// as they appear in C++0x with rvalue references. Since C++03 doesn't have
+// rvalue references, some tricks are needed to get similar results.
+// Move semantics in C++0x have the following properties:
+// 1) "Moving" means transferring the value of an object to another object,
+// similar to copying, but without caring what happens to the old object.
+// In particular, this means that the new object can steal the old object's
+// resources instead of creating a copy.
+// 2) Since moving can modify the source object, it must either be explicitly
+// requested by the user, or the modifications must be unnoticeable.
+// 3) As such, C++0x moving is only allowed in three contexts:
+// * By explicitly using std::move() to request it.
+// * From a temporary object, since that object cannot be accessed
+// afterwards anyway, thus making the state unobservable.
+// * On function return, since the object is not observable afterwards.
+//
+// To sum up: moving from a named object should only be possible with an
+// explicit std::move(), or on function return. Moving from a temporary should
+// be implicitly done. Moving from a const object is forbidden.
+//
+// The emulation is not perfect, and has the following shortcomings:
+// * move() is not in namespace std.
+// * move() is required on function return.
+// * There are difficulties with implicit conversions.
+// * Microsoft's compiler must be given the /Za switch to successfully compile.
+//
+// -------------------------- Implementation -------------------------------- //
+// The move emulation relies on the peculiar reference binding semantics of
+// C++03: as a rule, a non-const reference may not bind to a temporary object,
+// except for the implicit object parameter in a member function call, which
+// can refer to a temporary even when not being const.
+// The moveable object has five important functions to facilitate moving:
+// * A private, unimplemented constructor taking a non-const reference to its
+// own class. This constructor serves a two-fold purpose.
+// - It prevents the creation of a copy constructor that takes a const
+// reference. Temporaries would be able to bind to the argument of such a
+// constructor, and that would be bad.
+// - Named objects will bind to the non-const reference, but since it's
+// private, this will fail to compile. This prevents implicit moving from
+// named objects.
+// There's also a copy assignment operator for the same purpose.
+// * An implicit, non-const conversion operator to a special mover type. This
+// type represents the rvalue reference of C++0x. Being a non-const member,
+// its implicit this parameter can bind to temporaries.
+// * A constructor that takes an object of this mover type. This constructor
+// performs the actual move operation. There is an equivalent assignment
+// operator.
+// There is also a free move() function that takes a non-const reference to
+// an object and returns a temporary. Internally, this function uses explicit
+// constructor calls to move the value from the referenced object to the return
+// value.
+//
+// There are now three possible scenarios of use.
+// * Copying from a const object. Constructor overload resolution will find the
+// non-const copy constructor, and the move constructor. The first is not
+// viable because the const object cannot be bound to the non-const reference.
+// The second fails because the conversion to the mover object is non-const.
+// Moving from a const object fails as intended.
+// * Copying from a named object. Constructor overload resolution will select
+// the non-const copy constructor, but fail as intended, because this
+// constructor is private.
+// * Copying from a temporary. Constructor overload resolution cannot select
+// the non-const copy constructor, because the temporary cannot be bound to
+// the non-const reference. It thus selects the move constructor. The
+// temporary can be bound to the implicit this parameter of the conversion
+// operator, because of the special binding rule. Construction succeeds.
+// Note that the Microsoft compiler, as an extension, allows binding
+// temporaries against non-const references. The compiler thus selects the
+// non-const copy constructor and fails, because the constructor is private.
+// Passing /Za (disable extensions) disables this behaviour.
+// The free move() function is used to move from a named object.
+//
+// Note that when passing an object of a different type (the classes below
+// have OwningResult and OwningPtr, which should be mixable), you get a problem.
+// Argument passing and function return use copy initialization rules. The
+// effect of this is that, when the source object is not already of the target
+// type, the compiler will first seek a way to convert the source object to the
+// target type, and only then attempt to copy the resulting object. This means
+// that when passing an OwningResult where an OwningPtr is expected, the
+// compiler will first seek a conversion from OwningResult to OwningPtr, then
+// copy the OwningPtr. The resulting conversion sequence is:
+// OwningResult object -> ResultMover -> OwningResult argument to
+// OwningPtr(OwningResult) -> OwningPtr -> PtrMover -> final OwningPtr
+// This conversion sequence is too complex to be allowed. Thus the special
+// move_* functions, which help the compiler out with some explicit
+// conversions.
+
+// Flip this switch to measure performance impact of the smart pointers.
+// #define DISABLE_SMART_POINTERS
+
+namespace llvm {
+ template<>
+ class PointerLikeTypeTraits<clang::ActionBase*> {
+ typedef clang::ActionBase* PT;
+ public:
+ static inline void *getAsVoidPointer(PT P) { return P; }
+ static inline PT getFromVoidPointer(void *P) {
+ return static_cast<PT>(P);
+ }
+ enum { NumLowBitsAvailable = 2 };
+ };
+}
+
+namespace clang {
+ // 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<unsigned UID>
+ struct IsResultPtrLowBitFree {
+ static const bool value = false;
+ };
+
+ /// ActionBase - A small part split from Action because of the horrible
+ /// definition order dependencies between Action and the smart pointers.
+ class ActionBase {
+ public:
+ /// Out-of-line virtual destructor to provide home for this class.
+ virtual ~ActionBase();
+
+ // Types - Though these don't actually enforce strong typing, they document
+ // what types are required to be identical for the actions.
+ typedef OpaquePtr<0> DeclPtrTy;
+ typedef OpaquePtr<1> DeclGroupPtrTy;
+ typedef OpaquePtr<2> TemplateTy;
+ typedef void AttrTy;
+ typedef void BaseTy;
+ typedef void MemInitTy;
+ typedef void ExprTy;
+ typedef void StmtTy;
+ typedef void TemplateParamsTy;
+ typedef void CXXScopeTy;
+ typedef void TypeTy; // FIXME: Change TypeTy to use OpaquePtr<N>.
+
+ /// 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<unsigned UID,
+ typename PtrTy = void*,
+ bool CompressInvalid = IsResultPtrLowBitFree<UID>::value>
+ class ActionResult {
+ PtrTy Val;
+ bool Invalid;
+
+ public:
+ ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
+ template<typename ActualExprTy>
+ ActionResult(ActualExprTy val) : Val(val), Invalid(false) {}
+ ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
+
+ PtrTy get() const { return Val; }
+ void set(PtrTy V) { Val = V; }
+ bool isInvalid() const { return Invalid; }
+
+ 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<unsigned UID, typename PtrTy>
+ class ActionResult<UID, 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)) { }
+
+ template<typename ActualExprTy>
+ ActionResult(ActualExprTy *val) {
+ PtrTy V(val);
+ void *VP = PtrTraits::getAsVoidPointer(V);
+ PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+ assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+ }
+
+ 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) { }
+
+ PtrTy get() const {
+ void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
+ return PtrTraits::getFromVoidPointer(VP);
+ }
+
+ void set(PtrTy V) {
+ void *VP = PtrTraits::getAsVoidPointer(V);
+ PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+ assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+ }
+
+ bool isInvalid() const { return PtrWithInvalid & 0x01; }
+
+ 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;
+ }
+ };
+
+ /// Deletion callbacks - Since the parser doesn't know the concrete types of
+ /// the AST nodes being generated, it must do callbacks to delete objects
+ /// when recovering from errors. These are in ActionBase because the smart
+ /// pointers need access to them.
+ virtual void DeleteExpr(ExprTy *E) {}
+ virtual void DeleteStmt(StmtTy *S) {}
+ virtual void DeleteTemplateParams(TemplateParamsTy *P) {}
+ };
+
+ /// ASTDestroyer - The type of an AST node destruction function pointer.
+ typedef void (ActionBase::*ASTDestroyer)(void *);
+
+ /// For the transition phase: translate from an ASTDestroyer to its
+ /// ActionResult UID.
+ template <ASTDestroyer Destroyer> struct DestroyerToUID;
+ template <> struct DestroyerToUID<&ActionBase::DeleteExpr> {
+ static const unsigned UID = 0;
+ };
+ template <> struct DestroyerToUID<&ActionBase::DeleteStmt> {
+ static const unsigned UID = 1;
+ };
+ /// ASTOwningResult - A moveable smart pointer for AST nodes that also
+ /// has an extra flag to indicate an additional success status.
+ template <ASTDestroyer Destroyer> class ASTOwningResult;
+
+ /// ASTMultiPtr - A moveable smart pointer to multiple AST nodes. Only owns
+ /// the individual pointers, not the array holding them.
+ template <ASTDestroyer Destroyer> class ASTMultiPtr;
+
+#if !defined(DISABLE_SMART_POINTERS)
+ namespace moving {
+ /// Move emulation helper for ASTOwningResult. NEVER EVER use this class
+ /// directly if you don't know what you're doing.
+ template <ASTDestroyer Destroyer>
+ class ASTResultMover {
+ ASTOwningResult<Destroyer> &Moved;
+
+ public:
+ ASTResultMover(ASTOwningResult<Destroyer> &moved) : Moved(moved) {}
+
+ ASTOwningResult<Destroyer> * operator ->() { return &Moved; }
+ };
+
+ /// Move emulation helper for ASTMultiPtr. NEVER EVER use this class
+ /// directly if you don't know what you're doing.
+ template <ASTDestroyer Destroyer>
+ class ASTMultiMover {
+ ASTMultiPtr<Destroyer> &Moved;
+
+ public:
+ ASTMultiMover(ASTMultiPtr<Destroyer> &moved) : Moved(moved) {}
+
+ ASTMultiPtr<Destroyer> * operator ->() { return &Moved; }
+
+ /// Reset the moved object's internal structures.
+ void release();
+ };
+ }
+#else
+
+ /// Kept only as a type-safe wrapper for a void pointer, when smart pointers
+ /// are disabled. When they are enabled, ASTOwningResult takes over.
+ template <ASTDestroyer Destroyer>
+ class ASTOwningPtr {
+ void *Node;
+
+ public:
+ explicit ASTOwningPtr(ActionBase &) : Node(0) {}
+ ASTOwningPtr(ActionBase &, void *node) : Node(node) {}
+ // Normal copying operators are defined implicitly.
+ ASTOwningPtr(const ASTOwningResult<Destroyer> &o);
+
+ ASTOwningPtr & operator =(void *raw) {
+ Node = raw;
+ return *this;
+ }
+
+ /// Access to the raw pointer.
+ void * get() const { return Node; }
+
+ /// Release the raw pointer.
+ void * take() {
+ return Node;
+ }
+
+ /// Take outside ownership of the raw pointer and cast it down.
+ template<typename T>
+ T *takeAs() {
+ return static_cast<T*>(Node);
+ }
+
+ /// Alias for interface familiarity with unique_ptr.
+ void * release() {
+ return take();
+ }
+ };
+#endif
+
+ // Important: There are two different implementations of
+ // ASTOwningResult below, depending on whether
+ // DISABLE_SMART_POINTERS is defined. If you make changes that
+ // affect the interface, be sure to compile and test both ways!
+
+#if !defined(DISABLE_SMART_POINTERS)
+ template <ASTDestroyer Destroyer>
+ class ASTOwningResult {
+ llvm::PointerIntPair<ActionBase*, 1, bool> ActionInv;
+ void *Ptr;
+
+ friend class moving::ASTResultMover<Destroyer>;
+
+#if !(defined(_MSC_VER) && _MSC_VER >= 1600)
+ ASTOwningResult(ASTOwningResult&); // DO NOT IMPLEMENT
+ ASTOwningResult& operator =(ASTOwningResult&); // DO NOT IMPLEMENT
+#endif
+
+ void destroy() {
+ if (Ptr) {
+ assert(ActionInv.getPointer() &&
+ "Smart pointer has node but no action.");
+ (ActionInv.getPointer()->*Destroyer)(Ptr);
+ Ptr = 0;
+ }
+ }
+
+ public:
+ typedef ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID> DumbResult;
+
+ explicit ASTOwningResult(ActionBase &actions, bool invalid = false)
+ : ActionInv(&actions, invalid), Ptr(0) {}
+ ASTOwningResult(ActionBase &actions, void *node)
+ : ActionInv(&actions, false), Ptr(node) {}
+ ASTOwningResult(ActionBase &actions, const DumbResult &res)
+ : ActionInv(&actions, res.isInvalid()), Ptr(res.get()) {}
+ /// Move from another owning result
+ ASTOwningResult(moving::ASTResultMover<Destroyer> mover)
+ : ActionInv(mover->ActionInv),
+ Ptr(mover->Ptr) {
+ mover->Ptr = 0;
+ }
+
+ ~ASTOwningResult() {
+ destroy();
+ }
+
+ /// Move assignment from another owning result
+ ASTOwningResult &operator=(moving::ASTResultMover<Destroyer> mover) {
+ destroy();
+ ActionInv = mover->ActionInv;
+ Ptr = mover->Ptr;
+ mover->Ptr = 0;
+ return *this;
+ }
+
+#if defined(_MSC_VER) && _MSC_VER >= 1600
+ // Emulated move semantics don't work with msvc.
+ ASTOwningResult(ASTOwningResult &&mover)
+ : ActionInv(mover.ActionInv),
+ Ptr(mover.Ptr) {
+ mover.Ptr = 0;
+ }
+ ASTOwningResult &operator=(ASTOwningResult &&mover) {
+ *this = moving::ASTResultMover<Destroyer>(mover);
+ return *this;
+ }
+#endif
+
+ /// Assignment from a raw pointer. Takes ownership - beware!
+ ASTOwningResult &operator=(void *raw) {
+ destroy();
+ Ptr = raw;
+ ActionInv.setInt(false);
+ return *this;
+ }
+
+ /// Assignment from an ActionResult. Takes ownership - beware!
+ ASTOwningResult &operator=(const DumbResult &res) {
+ destroy();
+ Ptr = res.get();
+ ActionInv.setInt(res.isInvalid());
+ return *this;
+ }
+
+ /// Access to the raw pointer.
+ void *get() const { return Ptr; }
+
+ bool isInvalid() const { return ActionInv.getInt(); }
+
+ /// Does this point to a usable AST node? To be usable, the node must be
+ /// valid and non-null.
+ bool isUsable() const { return !isInvalid() && get(); }
+
+ /// Take outside ownership of the raw pointer.
+ void *take() {
+ if (isInvalid())
+ return 0;
+ void *tmp = Ptr;
+ Ptr = 0;
+ return tmp;
+ }
+
+ /// Take outside ownership of the raw pointer and cast it down.
+ template<typename T>
+ T *takeAs() {
+ return static_cast<T*>(take());
+ }
+
+ /// Alias for interface familiarity with unique_ptr.
+ void *release() { return take(); }
+
+ /// Pass ownership to a classical ActionResult.
+ DumbResult result() {
+ if (isInvalid())
+ return true;
+ return take();
+ }
+
+ /// Move hook
+ operator moving::ASTResultMover<Destroyer>() {
+ return moving::ASTResultMover<Destroyer>(*this);
+ }
+ };
+#else
+ template <ASTDestroyer Destroyer>
+ class ASTOwningResult {
+ public:
+ typedef ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID> DumbResult;
+
+ private:
+ DumbResult Result;
+
+ public:
+ explicit ASTOwningResult(ActionBase &actions, bool invalid = false)
+ : Result(invalid) { }
+ ASTOwningResult(ActionBase &actions, void *node) : Result(node) { }
+ ASTOwningResult(ActionBase &actions, const DumbResult &res) : Result(res) { }
+ // Normal copying semantics are defined implicitly.
+ ASTOwningResult(const ASTOwningPtr<Destroyer> &o) : Result(o.get()) { }
+
+ /// Assignment from a raw pointer. Takes ownership - beware!
+ ASTOwningResult & operator =(void *raw) {
+ Result = raw;
+ return *this;
+ }
+
+ /// Assignment from an ActionResult. Takes ownership - beware!
+ ASTOwningResult & operator =(const DumbResult &res) {
+ Result = res;
+ return *this;
+ }
+
+ /// Access to the raw pointer.
+ void * get() const { return Result.get(); }
+
+ bool isInvalid() const { return Result.isInvalid(); }
+
+ /// Does this point to a usable AST node? To be usable, the node must be
+ /// valid and non-null.
+ bool isUsable() const { return !Result.isInvalid() && get(); }
+
+ /// Take outside ownership of the raw pointer.
+ void * take() {
+ return Result.get();
+ }
+
+ /// Take outside ownership of the raw pointer and cast it down.
+ template<typename T>
+ T *takeAs() {
+ return static_cast<T*>(take());
+ }
+
+ /// Alias for interface familiarity with unique_ptr.
+ void * release() { return take(); }
+
+ /// Pass ownership to a classical ActionResult.
+ DumbResult result() { return Result; }
+ };
+#endif
+
+ template <ASTDestroyer Destroyer>
+ class ASTMultiPtr {
+#if !defined(DISABLE_SMART_POINTERS)
+ ActionBase &Actions;
+#endif
+ void **Nodes;
+ unsigned Count;
+
+#if !defined(DISABLE_SMART_POINTERS)
+ friend class moving::ASTMultiMover<Destroyer>;
+
+#if defined(_MSC_VER)
+ // Last tested with Visual Studio 2008.
+ // Visual C++ appears to have a bug where it does not recognise
+ // the return value from ASTMultiMover<Destroyer>::opeator-> as
+ // being a pointer to ASTMultiPtr. However, the diagnostics
+ // suggest it has the right name, simply that the pointer type
+ // is not convertible to itself.
+ // Either way, a classic C-style hard cast resolves any issue.
+ static ASTMultiPtr* hack(moving::ASTMultiMover<Destroyer> & source) {
+ return (ASTMultiPtr*)source.operator->();
+ }
+#endif
+
+ ASTMultiPtr(ASTMultiPtr&); // DO NOT IMPLEMENT
+ // Reference member prevents copy assignment.
+
+ void destroy() {
+ assert((Count == 0 || Nodes) && "No nodes when count is not zero.");
+ for (unsigned i = 0; i < Count; ++i) {
+ if (Nodes[i])
+ (Actions.*Destroyer)(Nodes[i]);
+ }
+ }
+#endif
+
+ public:
+#if !defined(DISABLE_SMART_POINTERS)
+ explicit ASTMultiPtr(ActionBase &actions)
+ : Actions(actions), Nodes(0), Count(0) {}
+ ASTMultiPtr(ActionBase &actions, void **nodes, unsigned count)
+ : Actions(actions), Nodes(nodes), Count(count) {}
+ /// Move constructor
+ ASTMultiPtr(moving::ASTMultiMover<Destroyer> mover)
+#if defined(_MSC_VER)
+ // Apply the visual C++ hack supplied above.
+ // Last tested with Visual Studio 2008.
+ : Actions(hack(mover)->Actions), Nodes(hack(mover)->Nodes), Count(hack(mover)->Count) {
+#else
+ : Actions(mover->Actions), Nodes(mover->Nodes), Count(mover->Count) {
+#endif
+ mover.release();
+ }
+#else
+ // Normal copying implicitly defined
+ explicit ASTMultiPtr(ActionBase &) : Nodes(0), Count(0) {}
+ ASTMultiPtr(ActionBase &, void **nodes, unsigned count)
+ : Nodes(nodes), Count(count) {}
+ // Fake mover in Parse/AstGuard.h needs this:
+ ASTMultiPtr(void **nodes, unsigned count) : Nodes(nodes), Count(count) {}
+#endif
+
+#if !defined(DISABLE_SMART_POINTERS)
+ /// Move assignment
+ ASTMultiPtr & operator =(moving::ASTMultiMover<Destroyer> mover) {
+ destroy();
+ Nodes = mover->Nodes;
+ Count = mover->Count;
+ mover.release();
+ return *this;
+ }
+#endif
+
+ /// Access to the raw pointers.
+ void ** get() const { return Nodes; }
+
+ /// Access to the count.
+ unsigned size() const { return Count; }
+
+ void ** release() {
+#if !defined(DISABLE_SMART_POINTERS)
+ void **tmp = Nodes;
+ Nodes = 0;
+ Count = 0;
+ return tmp;
+#else
+ return Nodes;
+#endif
+ }
+
+#if !defined(DISABLE_SMART_POINTERS)
+ /// Move hook
+ operator moving::ASTMultiMover<Destroyer>() {
+ return moving::ASTMultiMover<Destroyer>(*this);
+ }
+#endif
+ };
+
+ class ParsedTemplateArgument;
+
+ class ASTTemplateArgsPtr {
+#if !defined(DISABLE_SMART_POINTERS)
+ ActionBase &Actions;
+#endif
+ ParsedTemplateArgument *Args;
+ mutable unsigned Count;
+
+#if !defined(DISABLE_SMART_POINTERS)
+ void destroy();
+#endif
+
+ public:
+ ASTTemplateArgsPtr(ActionBase &actions, ParsedTemplateArgument *args,
+ unsigned count) :
+#if !defined(DISABLE_SMART_POINTERS)
+ Actions(actions),
+#endif
+ Args(args), Count(count) { }
+
+ // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
+ ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) :
+#if !defined(DISABLE_SMART_POINTERS)
+ Actions(Other.Actions),
+#endif
+ Args(Other.Args), Count(Other.Count) {
+#if !defined(DISABLE_SMART_POINTERS)
+ Other.Count = 0;
+#endif
+ }
+
+ // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
+ ASTTemplateArgsPtr& operator=(ASTTemplateArgsPtr &Other) {
+#if !defined(DISABLE_SMART_POINTERS)
+ Actions = Other.Actions;
+#endif
+ Args = Other.Args;
+ Count = Other.Count;
+#if !defined(DISABLE_SMART_POINTERS)
+ Other.Count = 0;
+#endif
+ return *this;
+ }
+
+#if !defined(DISABLE_SMART_POINTERS)
+ ~ASTTemplateArgsPtr() { destroy(); }
+#endif
+
+ ParsedTemplateArgument *getArgs() const { return Args; }
+ unsigned size() const { return Count; }
+
+ void reset(ParsedTemplateArgument *args, unsigned count) {
+#if !defined(DISABLE_SMART_POINTERS)
+ destroy();
+#endif
+ Args = args;
+ Count = count;
+ }
+
+ const ParsedTemplateArgument &operator[](unsigned Arg) const;
+
+ ParsedTemplateArgument *release() const {
+#if !defined(DISABLE_SMART_POINTERS)
+ Count = 0;
+#endif
+ return Args;
+ }
+ };
+
+ /// \brief A small vector that owns a set of AST nodes.
+ template <ASTDestroyer Destroyer, unsigned N = 8>
+ class ASTOwningVector : public llvm::SmallVector<void *, N> {
+#if !defined(DISABLE_SMART_POINTERS)
+ ActionBase &Actions;
+ bool Owned;
+#endif
+
+ ASTOwningVector(ASTOwningVector &); // do not implement
+ ASTOwningVector &operator=(ASTOwningVector &); // do not implement
+
+ public:
+ explicit ASTOwningVector(ActionBase &Actions)
+#if !defined(DISABLE_SMART_POINTERS)
+ : Actions(Actions), Owned(true)
+#endif
+ { }
+
+#if !defined(DISABLE_SMART_POINTERS)
+ ~ASTOwningVector() {
+ if (!Owned)
+ return;
+
+ for (unsigned I = 0, Last = this->size(); I != Last; ++I)
+ (Actions.*Destroyer)((*this)[I]);
+ }
+#endif
+
+ void **take() {
+#if !defined(DISABLE_SMART_POINTERS)
+ Owned = false;
+#endif
+ return &this->front();
+ }
+
+ template<typename T> T **takeAs() { return (T**)take(); }
+
+#if !defined(DISABLE_SMART_POINTERS)
+ ActionBase &getActions() const { return Actions; }
+#endif
+ };
+
+ /// A SmallVector of statements, with stack size 32 (as that is the only one
+ /// used.)
+ typedef ASTOwningVector<&ActionBase::DeleteStmt, 32> StmtVector;
+ /// A SmallVector of expressions, with stack size 12 (the maximum used.)
+ typedef ASTOwningVector<&ActionBase::DeleteExpr, 12> ExprVector;
+
+ template <ASTDestroyer Destroyer, unsigned N> inline
+ ASTMultiPtr<Destroyer> move_arg(ASTOwningVector<Destroyer, N> &vec) {
+#if !defined(DISABLE_SMART_POINTERS)
+ return ASTMultiPtr<Destroyer>(vec.getActions(), vec.take(), vec.size());
+#else
+ return ASTMultiPtr<Destroyer>(vec.take(), vec.size());
+#endif
+ }
+
+#if !defined(DISABLE_SMART_POINTERS)
+
+ // Out-of-line implementations due to definition dependencies
+
+ template <ASTDestroyer Destroyer> inline
+ void moving::ASTMultiMover<Destroyer>::release() {
+ Moved.Nodes = 0;
+ Moved.Count = 0;
+ }
+
+ // Move overloads.
+
+ template <ASTDestroyer Destroyer> inline
+ ASTOwningResult<Destroyer> move(ASTOwningResult<Destroyer> &ptr) {
+ return ASTOwningResult<Destroyer>(moving::ASTResultMover<Destroyer>(ptr));
+ }
+
+ template <ASTDestroyer Destroyer> inline
+ ASTMultiPtr<Destroyer> move(ASTMultiPtr<Destroyer> &ptr) {
+ return ASTMultiPtr<Destroyer>(moving::ASTMultiMover<Destroyer>(ptr));
+ }
+
+#else
+
+ template <ASTDestroyer Destroyer> inline
+ ASTOwningPtr<Destroyer>::ASTOwningPtr(const ASTOwningResult<Destroyer> &o)
+ : Node(o.get()) { }
+
+ // These versions are hopefully no-ops.
+ template <ASTDestroyer Destroyer> inline
+ ASTOwningResult<Destroyer>& move(ASTOwningResult<Destroyer> &ptr) {
+ return ptr;
+ }
+
+ template <ASTDestroyer Destroyer> inline
+ ASTOwningPtr<Destroyer>& move(ASTOwningPtr<Destroyer> &ptr) {
+ return ptr;
+ }
+
+ template <ASTDestroyer Destroyer> inline
+ ASTMultiPtr<Destroyer>& move(ASTMultiPtr<Destroyer> &ptr) {
+ return ptr;
+ }
+#endif
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h
new file mode 100644
index 0000000..d7c5eee
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- 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_DIAGNOSTICPARSE_H
+#define LLVM_CLANG_DIAGNOSTICPARSE_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+ namespace diag {
+ enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,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/contrib/llvm/tools/clang/include/clang/Parse/Parser.h b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h
new file mode 100644
index 0000000..8081c24
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h
@@ -0,0 +1,1503 @@
+//===--- 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/Specifiers.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/Action.h"
+#include "clang/Parse/DeclSpec.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <stack>
+#include <list>
+
+namespace clang {
+ class AttributeList;
+ struct CXX0XAttributeList;
+ class PragmaHandler;
+ class Scope;
+ class DiagnosticBuilder;
+ class Parser;
+ class PragmaUnusedHandler;
+ class ColonProtectionRAIIObject;
+
+/// PrettyStackTraceParserEntry - If a crash happens while the parser is active,
+/// an entry is printed for it.
+class PrettyStackTraceParserEntry : public llvm::PrettyStackTraceEntry {
+ const Parser &P;
+public:
+ PrettyStackTraceParserEntry(const Parser &p) : P(p) {}
+ virtual void print(llvm::raw_ostream &OS) const;
+};
+
+/// 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 // .*, ->*
+ };
+}
+
+/// 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 {
+ friend class PragmaUnusedHandler;
+ friend class ColonProtectionRAIIObject;
+ PrettyStackTraceParserEntry CrashInfo;
+
+ 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. This refers to the common base class between MinimalActions
+ /// and SemaActions for those uses that don't matter.
+ Action &Actions;
+
+ Scope *CurScope;
+ Diagnostic &Diags;
+
+ /// ScopeCache - Cache scopes to reduce malloc traffic.
+ enum { ScopeCacheSize = 16 };
+ unsigned NumCachedScopes;
+ Scope *ScopeCache[ScopeCacheSize];
+
+ /// Ident_super - IdentifierInfo for "super", to support fast
+ /// comparison.
+ IdentifierInfo *Ident_super;
+ /// Ident_vector and Ident_pixel - cached IdentifierInfo's for
+ /// "vector" and "pixel" fast comparison. Only present if
+ /// AltiVec enabled.
+ IdentifierInfo *Ident_vector;
+ IdentifierInfo *Ident_pixel;
+
+ llvm::OwningPtr<PragmaHandler> OptionsHandler;
+ llvm::OwningPtr<PragmaHandler> PackHandler;
+ llvm::OwningPtr<PragmaHandler> UnusedHandler;
+ llvm::OwningPtr<PragmaHandler> WeakHandler;
+
+ /// 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;
+
+ /// The "depth" of the template parameters currently being parsed.
+ unsigned TemplateParameterDepth;
+
+public:
+ Parser(Preprocessor &PP, Action &Actions);
+ ~Parser();
+
+ const LangOptions &getLang() const { return PP.getLangOptions(); }
+ const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
+ Preprocessor &getPreprocessor() const { return PP; }
+ Action &getActions() const { return Actions; }
+
+ const Token &getCurToken() const { return Tok; }
+
+ // Type forwarding. All of these are statically 'void*', but they may all be
+ // different actual classes based on the actions in place.
+ typedef Action::ExprTy ExprTy;
+ typedef Action::StmtTy StmtTy;
+ typedef Action::DeclPtrTy DeclPtrTy;
+ typedef Action::DeclGroupPtrTy DeclGroupPtrTy;
+ typedef Action::TypeTy TypeTy;
+ typedef Action::BaseTy BaseTy;
+ typedef Action::MemInitTy MemInitTy;
+ typedef Action::CXXScopeTy CXXScopeTy;
+ typedef Action::TemplateParamsTy TemplateParamsTy;
+ typedef Action::TemplateTy TemplateTy;
+
+ typedef llvm::SmallVector<TemplateParamsTy *, 4> TemplateParameterLists;
+
+ typedef Action::ExprResult ExprResult;
+ typedef Action::StmtResult StmtResult;
+ typedef Action::BaseResult BaseResult;
+ typedef Action::MemInitResult MemInitResult;
+ typedef Action::TypeResult TypeResult;
+
+ typedef Action::OwningExprResult OwningExprResult;
+ typedef Action::OwningStmtResult OwningStmtResult;
+
+ typedef Action::ExprArg ExprArg;
+ typedef Action::MultiStmtArg MultiStmtArg;
+ typedef Action::FullExprArg FullExprArg;
+
+ /// Adorns a ExprResult with Actions to make it an OwningExprResult
+ OwningExprResult Owned(ExprResult res) {
+ return OwningExprResult(Actions, res);
+ }
+ /// Adorns a StmtResult with Actions to make it an OwningStmtResult
+ OwningStmtResult Owned(StmtResult res) {
+ return OwningStmtResult(Actions, res);
+ }
+
+ OwningExprResult ExprError() { return OwningExprResult(Actions, true); }
+ OwningStmtResult StmtError() { return OwningStmtResult(Actions, true); }
+
+ OwningExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
+ OwningStmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
+
+ OwningExprResult ExprEmpty() { return OwningExprResult(Actions, false); }
+
+ // Parsing methods.
+
+ /// ParseTranslationUnit - All in one method that initializes parses, and
+ /// shuts down the parser.
+ void ParseTranslationUnit();
+
+ /// Initialize - Warm up the parser.
+ ///
+ void Initialize();
+
+ /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
+ /// the EOF was encountered.
+ bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
+
+ DeclGroupPtrTy RetrievePendingObjCImpDecl();
+
+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.getKind() == tok::string_literal ||
+ Tok.getKind() == tok::wide_string_literal;
+ }
+
+ /// ConsumeToken - Consume the current 'peek token' and lex the next one.
+ /// This does not work with all kinds of tokens: strings and specific other
+ /// tokens must be consumed with custom methods below. This returns the
+ /// location of the consumed token.
+ SourceLocation ConsumeToken() {
+ assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
+ !isTokenBrace() &&
+ "Should consume special tokens with Consume*Token");
+ if (Tok.is(tok::code_completion)) {
+ CodeCompletionRecovery();
+ return ConsumeCodeCompletionToken();
+ }
+
+ PrevTokLocation = Tok.getLocation();
+ PP.Lex(Tok);
+ return PrevTokLocation;
+ }
+
+ /// 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() {
+ if (isTokenParen())
+ return ConsumeParen();
+ else if (isTokenBracket())
+ return ConsumeBracket();
+ else if (isTokenBrace())
+ return ConsumeBrace();
+ else if (isTokenStringLiteral())
+ return ConsumeStringToken();
+ else
+ 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 should be called to consume the code-completion token once
+ /// a code-completion action has already been invoked.
+ 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 within having
+ /// matched specific position in the grammar, provide code-completion results
+ /// based on context.
+ void CodeCompletionRecovery();
+
+ /// 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);
+ }
+
+ /// NextToken - This peeks ahead one token and returns it without
+ /// consuming it.
+ const Token &NextToken() {
+ return PP.LookAhead(0);
+ }
+
+ /// TryAnnotateTypeOrScopeToken - If the current token position is on a
+ /// typename (possibly qualified in C++) or a C++ scope specifier not followed
+ /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
+ /// with a single annotation token representing the typename or C++ scope
+ /// respectively.
+ /// This simplifies handling of C++ scope specifiers and allows efficient
+ /// backtracking without the need to re-parse and resolve nested-names and
+ /// typenames.
+ /// It will mainly be called when we expect to treat identifiers as typenames
+ /// (if they are typenames). For example, in C we do not expect identifiers
+ /// inside expressions to be treated as typenames so it will not be called
+ /// for expressions in C.
+ ///
+ /// This returns true if the token was annotated.
+ bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false);
+
+ /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but
+ /// only annotates C++ scope specifiers. This returns true if there
+ /// was an unrecoverable error.
+ bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+
+ /// 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 (!getLang().AltiVec ||
+ (Tok.getIdentifierInfo() != Ident_vector &&
+ 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 (!getLang().AltiVec ||
+ Tok.getIdentifierInfo() != Ident_vector) return false;
+ return TryAltiVecVectorTokenOutOfLine();
+ }
+
+ bool TryAltiVecVectorTokenOutOfLine();
+ bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID,
+ bool &isInvalid);
+
+ /// 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;
+ bool isActive;
+
+ public:
+ explicit TentativeParsingAction(Parser& p) : P(p) {
+ PrevTok = P.Tok;
+ P.PP.EnableBacktrackAtThisPos();
+ isActive = true;
+ }
+ void Commit() {
+ assert(isActive && "Parsing action was finished!");
+ P.PP.CommitBacktrackedTokens();
+ isActive = false;
+ }
+ void Revert() {
+ assert(isActive && "Parsing action was finished!");
+ P.PP.Backtrack();
+ P.Tok = PrevTok;
+ isActive = false;
+ }
+ ~TentativeParsingAction() {
+ assert(!isActive && "Forgot to call Commit or Revert!");
+ }
+ };
+
+
+ /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
+ /// this helper function matches and consumes the specified RHS token if
+ /// present. If not present, it emits the specified diagnostic indicating
+ /// that the parser failed to match the RHS of the token at LHSLoc. LHSName
+ /// should be the name of the unmatched LHS token. This returns the location
+ /// of the consumed token.
+ SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
+ SourceLocation LHSLoc);
+
+ /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
+ /// input. If so, it is consumed and false is returned.
+ ///
+ /// If the input is malformed, this emits the specified diagnostic. Next, if
+ /// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
+ /// returned.
+ bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
+ const char *DiagMsg = "",
+ tok::TokenKind SkipToTok = tok::unknown);
+
+ //===--------------------------------------------------------------------===//
+ // 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&); // do not implement
+ ParseScope& operator=(const ParseScope&); // do not implement
+
+ 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 ManageScope is true (the default). If
+ // ManageScope is false, this object does nothing.
+ ParseScope(Parser *Self, unsigned ScopeFlags, bool ManageScope = true)
+ : Self(Self) {
+ if (ManageScope)
+ Self->EnterScope(ScopeFlags);
+ else
+ this->Self = 0;
+ }
+
+ // Exit - Exit the scope associated with this object now, rather
+ // than waiting until the object is destroyed.
+ void Exit() {
+ if (Self) {
+ Self->ExitScope();
+ Self = 0;
+ }
+ }
+
+ ~ParseScope() {
+ Exit();
+ }
+ };
+
+ /// EnterScope - Start a new scope.
+ void EnterScope(unsigned ScopeFlags);
+
+ /// ExitScope - Pop a scope off the scope stack.
+ void ExitScope();
+
+ //===--------------------------------------------------------------------===//
+ // Diagnostic Emission and Error recovery.
+
+public:
+ DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+ DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
+
+private:
+ void SuggestParentheses(SourceLocation Loc, unsigned DK,
+ SourceRange ParenRange);
+
+ /// SkipUntil - Read tokens until we get to the specified token, then consume
+ /// it (unless DontConsume is true). Because we cannot guarantee that the
+ /// token will ever occur, this skips to the next token, or to some likely
+ /// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
+ /// character.
+ ///
+ /// If SkipUntil finds the specified token, it returns true, otherwise it
+ /// returns false.
+ bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
+ bool DontConsume = false) {
+ return SkipUntil(&T, 1, StopAtSemi, DontConsume);
+ }
+ bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
+ bool DontConsume = false) {
+ tok::TokenKind TokArray[] = {T1, T2};
+ return SkipUntil(TokArray, 2, StopAtSemi, DontConsume);
+ }
+ bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
+ bool StopAtSemi = true, bool DontConsume = false);
+
+ //===--------------------------------------------------------------------===//
+ // Lexing and parsing of C++ inline methods.
+
+ struct LexedMethod {
+ Action::DeclPtrTy D;
+ CachedTokens Toks;
+
+ /// \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;
+
+ explicit LexedMethod(Action::DeclPtrTy MD) : D(MD), TemplateScope(false) {}
+ };
+
+ /// 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(Action::DeclPtrTy P,
+ CachedTokens *Toks = 0)
+ : Param(P), Toks(Toks) { }
+
+ /// Param - The parameter declaration for this parameter.
+ Action::DeclPtrTy 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 {
+ explicit LateParsedMethodDeclaration(Action::DeclPtrTy M)
+ : Method(M), TemplateScope(false) { }
+
+ /// Method - The method declaration.
+ Action::DeclPtrTy 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.
+ llvm::SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
+ };
+
+ /// LateParsedMethodDecls - During parsing of a top (non-nested) C++
+ /// class, its method declarations that contain parts that won't be
+ /// parsed until after the definiton is completed (C++ [class.mem]p2),
+ /// the method declarations will be stored here with the tokens that
+ /// will be parsed to create those entities.
+ typedef std::list<LateParsedMethodDeclaration> LateParsedMethodDecls;
+
+ /// LexedMethodsForTopClass - During parsing of a top (non-nested) C++ class,
+ /// its inline method definitions and the inline method definitions of its
+ /// nested classes are lexed and stored here.
+ typedef std::list<LexedMethod> LexedMethodsForTopClass;
+
+ /// \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(DeclPtrTy TagOrTemplate, bool TopLevelClass)
+ : TopLevelClass(TopLevelClass), TemplateScope(false),
+ 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 The class or class template whose definition we are parsing.
+ DeclPtrTy TagOrTemplate;
+
+ /// MethodDecls - Method declarations that contain pieces whose
+ /// parsing will be delayed until the class is fully defined.
+ LateParsedMethodDecls MethodDecls;
+
+ /// MethodDefs - Methods whose definitions will be parsed once the
+ /// class has been fully defined.
+ LexedMethodsForTopClass MethodDefs;
+
+ /// \brief Nested classes inside this class.
+ llvm::SmallVector<ParsingClass*, 4> NestedClasses;
+ };
+
+ /// \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 inform the actions that we're
+ /// currently parsing a declaration. This is active when parsing a
+ /// variable's initializer, but not when parsing the body of a
+ /// class or function definition.
+ class ParsingDeclRAIIObject {
+ Action &Actions;
+ Action::ParsingDeclStackState State;
+ bool Popped;
+
+ public:
+ ParsingDeclRAIIObject(Parser &P) : Actions(P.Actions) {
+ push();
+ }
+
+ ~ParsingDeclRAIIObject() {
+ abort();
+ }
+
+ /// Resets the RAII object for a new declaration.
+ void reset() {
+ abort();
+ push();
+ }
+
+ /// Signals that the context was completed without an appropriate
+ /// declaration being parsed.
+ void abort() {
+ pop(DeclPtrTy());
+ }
+
+ void complete(DeclPtrTy D) {
+ assert(!Popped && "ParsingDeclaration has already been popped!");
+ pop(D);
+ }
+
+ private:
+ void push() {
+ State = Actions.PushParsingDeclaration();
+ Popped = false;
+ }
+
+ void pop(DeclPtrTy D) {
+ if (!Popped) {
+ Actions.PopParsingDeclaration(State, D);
+ Popped = true;
+ }
+ }
+ };
+
+ /// A class for parsing a DeclSpec.
+ class ParsingDeclSpec : public DeclSpec {
+ ParsingDeclRAIIObject ParsingRAII;
+
+ public:
+ ParsingDeclSpec(Parser &P) : ParsingRAII(P) {
+ }
+
+ void complete(DeclPtrTy D) {
+ ParsingRAII.complete(D);
+ }
+
+ void abort() {
+ ParsingRAII.abort();
+ }
+ };
+
+ /// A class for parsing a declarator.
+ class ParsingDeclarator : public Declarator {
+ ParsingDeclRAIIObject ParsingRAII;
+
+ public:
+ ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C)
+ : Declarator(DS, C), ParsingRAII(P) {
+ }
+
+ const ParsingDeclSpec &getDeclSpec() const {
+ return static_cast<const ParsingDeclSpec&>(Declarator::getDeclSpec());
+ }
+
+ ParsingDeclSpec &getMutableDeclSpec() const {
+ return const_cast<ParsingDeclSpec&>(getDeclSpec());
+ }
+
+ void clear() {
+ Declarator::clear();
+ ParsingRAII.reset();
+ }
+
+ void complete(DeclPtrTy D) {
+ ParsingRAII.complete(D);
+ }
+ };
+
+ /// \brief RAII object used to
+ class ParsingClassDefinition {
+ Parser &P;
+ bool Popped;
+
+ public:
+ ParsingClassDefinition(Parser &P, DeclPtrTy TagOrTemplate, bool TopLevelClass)
+ : P(P), Popped(false) {
+ P.PushParsingClass(TagOrTemplate, TopLevelClass);
+ }
+
+ /// \brief Pop this class of the stack.
+ void Pop() {
+ assert(!Popped && "Nested class has already been popped");
+ Popped = true;
+ P.PopParsingClass();
+ }
+
+ ~ParsingClassDefinition() {
+ if (!Popped)
+ P.PopParsingClass();
+ }
+ };
+
+ /// \brief Contains information about any template-specific
+ /// information that has been parsed prior to parsing declaration
+ /// specifiers.
+ struct ParsedTemplateInfo {
+ ParsedTemplateInfo()
+ : Kind(NonTemplate), TemplateParams(0), 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(0),
+ 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;
+ };
+
+ void PushParsingClass(DeclPtrTy TagOrTemplate, bool TopLevelClass);
+ void DeallocateParsedClasses(ParsingClass *Class);
+ void PopParsingClass();
+
+ DeclPtrTy ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
+ const ParsedTemplateInfo &TemplateInfo);
+ void ParseLexedMethodDeclarations(ParsingClass &Class);
+ void ParseLexedMethodDefs(ParsingClass &Class);
+ 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.
+ DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr);
+ bool isDeclarationAfterDeclarator();
+ bool isStartOfFunctionDefinition();
+ DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
+ AccessSpecifier AS = AS_none);
+ DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
+ AttributeList *Attr,
+ AccessSpecifier AS = AS_none);
+
+ DeclPtrTy ParseFunctionDefinition(ParsingDeclarator &D,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+ void ParseKNRParamDeclarations(Declarator &D);
+ // EndLoc, if non-NULL, is filled with the location of the last token of
+ // the simple-asm.
+ OwningExprResult ParseSimpleAsm(SourceLocation *EndLoc = 0);
+ OwningExprResult ParseAsmStringLiteral();
+
+ // Objective-C External Declarations
+ DeclPtrTy ParseObjCAtDirectives();
+ DeclPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
+ DeclPtrTy ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
+ AttributeList *prefixAttrs = 0);
+ void ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
+ tok::ObjCKeywordKind visibility,
+ SourceLocation atLoc);
+ bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &P,
+ llvm::SmallVectorImpl<SourceLocation> &PLocs,
+ bool WarnOnDeclarations,
+ SourceLocation &LAngleLoc,
+ SourceLocation &EndProtoLoc);
+ void ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
+ tok::ObjCKeywordKind contextKey);
+ DeclPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
+ AttributeList *prefixAttrs = 0);
+
+ DeclPtrTy ObjCImpDecl;
+ llvm::SmallVector<DeclPtrTy, 4> PendingObjCImpDecl;
+
+ DeclPtrTy ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
+ DeclPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
+ DeclPtrTy ParseObjCAtAliasDeclaration(SourceLocation atLoc);
+ DeclPtrTy ParseObjCPropertySynthesize(SourceLocation atLoc);
+ DeclPtrTy 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_NumQuals
+ };
+ IdentifierInfo *ObjCTypeQuals[objc_NumQuals];
+
+ bool isTokIdentifier_in() const;
+
+ TypeTy *ParseObjCTypeName(ObjCDeclSpec &DS);
+ void ParseObjCMethodRequirement();
+ DeclPtrTy ParseObjCMethodPrototype(DeclPtrTy classOrCat,
+ tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
+ DeclPtrTy ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
+ DeclPtrTy classDecl,
+ tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
+ void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods, unsigned NumMethods);
+
+ DeclPtrTy ParseObjCMethodDefinition();
+
+ //===--------------------------------------------------------------------===//
+ // C99 6.5: Expressions.
+
+ OwningExprResult ParseExpression();
+ OwningExprResult ParseConstantExpression();
+ // Expr that doesn't include commas.
+ OwningExprResult ParseAssignmentExpression();
+
+ OwningExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
+
+ OwningExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
+
+ OwningExprResult ParseRHSOfBinaryExpression(OwningExprResult LHS,
+ prec::Level MinPrec);
+ OwningExprResult ParseCastExpression(bool isUnaryExpression,
+ bool isAddressOfOperand,
+ bool &NotCastExpr,
+ TypeTy *TypeOfCast);
+ OwningExprResult ParseCastExpression(bool isUnaryExpression,
+ bool isAddressOfOperand = false,
+ TypeTy *TypeOfCast = 0);
+ OwningExprResult ParsePostfixExpressionSuffix(OwningExprResult LHS);
+ OwningExprResult ParseSizeofAlignofExpression();
+ OwningExprResult ParseBuiltinPrimaryExpression();
+
+ OwningExprResult ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
+ bool &isCastExpr,
+ TypeTy *&CastTy,
+ SourceRange &CastRange);
+
+ static const unsigned ExprListSize = 12;
+ typedef llvm::SmallVector<ExprTy*, ExprListSize> ExprListTy;
+ typedef llvm::SmallVector<SourceLocation, ExprListSize> CommaLocsTy;
+
+ /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
+ bool ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs,
+ void (Action::*Completer)(Scope *S, void *Data,
+ ExprTy **Args,
+ unsigned NumArgs) = 0,
+ void *Data = 0);
+
+ /// 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>
+ };
+ OwningExprResult ParseParenExpression(ParenParseOption &ExprType,
+ bool stopIfCastExpr,
+ TypeTy *TypeOfCast,
+ TypeTy *&CastTy,
+ SourceLocation &RParenLoc);
+
+ OwningExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
+ TypeTy *&CastTy,
+ SourceLocation LParenLoc,
+ SourceLocation &RParenLoc);
+
+ OwningExprResult ParseCompoundLiteralExpression(TypeTy *Ty,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc);
+
+ OwningExprResult ParseStringLiteralExpression();
+
+ //===--------------------------------------------------------------------===//
+ // C++ Expressions
+ OwningExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
+
+ bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
+ TypeTy *ObjectType,
+ bool EnteringContext,
+ bool *MayBePseudoDestructor = 0);
+
+ //===--------------------------------------------------------------------===//
+ // C++ 5.2p1: C++ Casts
+ OwningExprResult ParseCXXCasts();
+
+ //===--------------------------------------------------------------------===//
+ // C++ 5.2p1: C++ Type Identification
+ OwningExprResult ParseCXXTypeid();
+
+ //===--------------------------------------------------------------------===//
+ // C++ 5.2.4: C++ Pseudo-Destructor Expressions
+ OwningExprResult ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ CXXScopeSpec &SS,
+ Action::TypeTy *ObjectType);
+
+ //===--------------------------------------------------------------------===//
+ // C++ 9.3.2: C++ 'this' pointer
+ OwningExprResult ParseCXXThis();
+
+ //===--------------------------------------------------------------------===//
+ // C++ 15: C++ Throw Expression
+ OwningExprResult ParseThrowExpression();
+ // EndLoc is filled with the location of the last token of the specification.
+ bool ParseExceptionSpecification(SourceLocation &EndLoc,
+ llvm::SmallVector<TypeTy*, 2> &Exceptions,
+ llvm::SmallVector<SourceRange, 2> &Ranges,
+ bool &hasAnyExceptionSpec);
+
+ //===--------------------------------------------------------------------===//
+ // C++ 2.13.5: C++ Boolean Literals
+ OwningExprResult ParseCXXBoolLiteral();
+
+ //===--------------------------------------------------------------------===//
+ // C++ 5.2.3: Explicit type conversion (functional notation)
+ OwningExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
+
+ bool isCXXSimpleTypeSpecifier() const;
+
+ /// 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(ExprListTy &Exprs, Declarator &D);
+ void ParseDirectNewDeclarator(Declarator &D);
+ OwningExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
+ OwningExprResult ParseCXXDeleteExpression(bool UseGlobal,
+ SourceLocation Start);
+
+ //===--------------------------------------------------------------------===//
+ // C++ if/switch/while condition expression.
+ bool ParseCXXCondition(OwningExprResult &ExprResult, DeclPtrTy &DeclResult,
+ SourceLocation Loc, bool ConvertToBoolean);
+
+ //===--------------------------------------------------------------------===//
+ // C++ types
+
+ //===--------------------------------------------------------------------===//
+ // C99 6.7.8: Initialization.
+
+ /// ParseInitializer
+ /// initializer: [C99 6.7.8]
+ /// assignment-expression
+ /// '{' ...
+ OwningExprResult ParseInitializer() {
+ if (Tok.isNot(tok::l_brace))
+ return ParseAssignmentExpression();
+ return ParseBraceInitializer();
+ }
+ OwningExprResult ParseBraceInitializer();
+ OwningExprResult ParseInitializerWithPotentialDesignator();
+
+ //===--------------------------------------------------------------------===//
+ // clang Expressions
+
+ OwningExprResult ParseBlockLiteralExpression(); // ^{...}
+
+ //===--------------------------------------------------------------------===//
+ // Objective-C Expressions
+ OwningExprResult ParseObjCAtExpression(SourceLocation AtLocation);
+ OwningExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
+ OwningExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
+ OwningExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
+ OwningExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
+ OwningExprResult ParseObjCMessageExpression();
+ OwningExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
+ SourceLocation SuperLoc,
+ TypeTy *ReceiverType,
+ ExprArg ReceiverExpr);
+ OwningExprResult ParseAssignmentExprWithObjCMessageExprStart(
+ SourceLocation LBracloc, SourceLocation SuperLoc,
+ TypeTy *ReceiverType, ExprArg ReceiverExpr);
+ bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
+
+ //===--------------------------------------------------------------------===//
+ // C99 6.8: Statements and Blocks.
+
+ OwningStmtResult ParseStatement() {
+ return ParseStatementOrDeclaration(true);
+ }
+ OwningStmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
+ OwningStmtResult ParseLabeledStatement(AttributeList *Attr);
+ OwningStmtResult ParseCaseStatement(AttributeList *Attr);
+ OwningStmtResult ParseDefaultStatement(AttributeList *Attr);
+ OwningStmtResult ParseCompoundStatement(AttributeList *Attr,
+ bool isStmtExpr = false);
+ OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
+ bool ParseParenExprOrCondition(OwningExprResult &ExprResult,
+ DeclPtrTy &DeclResult,
+ SourceLocation Loc,
+ bool ConvertToBoolean);
+ OwningStmtResult ParseIfStatement(AttributeList *Attr);
+ OwningStmtResult ParseSwitchStatement(AttributeList *Attr);
+ OwningStmtResult ParseWhileStatement(AttributeList *Attr);
+ OwningStmtResult ParseDoStatement(AttributeList *Attr);
+ OwningStmtResult ParseForStatement(AttributeList *Attr);
+ OwningStmtResult ParseGotoStatement(AttributeList *Attr);
+ OwningStmtResult ParseContinueStatement(AttributeList *Attr);
+ OwningStmtResult ParseBreakStatement(AttributeList *Attr);
+ OwningStmtResult ParseReturnStatement(AttributeList *Attr);
+ OwningStmtResult ParseAsmStatement(bool &msAsm);
+ OwningStmtResult FuzzyParseMicrosoftAsmStatement();
+ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
+ llvm::SmallVectorImpl<ExprTy *> &Constraints,
+ llvm::SmallVectorImpl<ExprTy *> &Exprs);
+
+ //===--------------------------------------------------------------------===//
+ // C++ 6: Statements and Blocks
+
+ OwningStmtResult ParseCXXTryBlock(AttributeList *Attr);
+ OwningStmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
+ OwningStmtResult ParseCXXCatchBlock();
+
+ //===--------------------------------------------------------------------===//
+ // Objective-C Statements
+
+ OwningStmtResult ParseObjCAtStatement(SourceLocation atLoc);
+ OwningStmtResult ParseObjCTryStmt(SourceLocation atLoc);
+ OwningStmtResult ParseObjCThrowStmt(SourceLocation atLoc);
+ OwningStmtResult ParseObjCSynchronizedStmt(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_top_level // top-level/namespace declaration context
+ };
+
+ DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd,
+ CXX0XAttributeList Attr);
+ DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
+ SourceLocation &DeclEnd,
+ AttributeList *Attr,
+ bool RequireSemi);
+ DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
+ bool AllowFunctionDefinitions,
+ SourceLocation *DeclEnd = 0);
+ DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+ DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
+ DeclPtrTy ParseFunctionTryBlock(DeclPtrTy Decl);
+
+ bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
+ const ParsedTemplateInfo &TemplateInfo,
+ AccessSpecifier AS);
+ DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context);
+ void ParseDeclarationSpecifiers(DeclSpec &DS,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+ AccessSpecifier AS = AS_none,
+ DeclSpecContext DSC = DSC_normal);
+ bool ParseOptionalTypeSpecifier(DeclSpec &DS, bool &isInvalid,
+ const char *&PrevSpec,
+ unsigned &DiagID,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+ bool SuppressDeclarations = false);
+
+ void ParseSpecifierQualifierList(DeclSpec &DS);
+
+ void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
+
+ void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), AccessSpecifier AS = AS_none);
+ void ParseEnumBody(SourceLocation StartLoc, DeclPtrTy TagDecl);
+ void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
+ DeclPtrTy TagDecl);
+
+ struct FieldCallback {
+ virtual DeclPtrTy invoke(FieldDeclarator &Field) = 0;
+ virtual ~FieldCallback() {}
+
+ private:
+ virtual void _anchor();
+ };
+ struct ObjCPropertyCallback;
+
+ void ParseStructDeclaration(DeclSpec &DS, FieldCallback &Callback);
+
+ bool isDeclarationSpecifier();
+ 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;
+
+ /// isDeclarationStatement - Disambiguates between a declaration or an
+ /// expression statement, when parsing function bodies.
+ /// Returns true for declaration, false for expression.
+ bool isDeclarationStatement() {
+ if (getLang().CPlusPlus)
+ return isCXXDeclarationStatement();
+ return isDeclarationSpecifier();
+ }
+
+ /// isSimpleDeclaration - Disambiguates between a declaration or an
+ /// expression, mainly used for the C 'clause-1' or the C++
+ // 'for-init-statement' part of a 'for' statement.
+ /// Returns true for declaration, false for expression.
+ bool isSimpleDeclaration() {
+ if (getLang().CPlusPlus)
+ return isCXXSimpleDeclaration();
+ return isDeclarationSpecifier();
+ }
+
+ /// \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();
+
+ /// \brief Specifies the context in which type-id/expression
+ /// disambiguation will occur.
+ enum TentativeCXXTypeIdContext {
+ TypeIdInParens,
+ 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 (getLang().CPlusPlus)
+ return isCXXTypeId(TypeIdInParens, isAmbiguous);
+ isAmbiguous = false;
+ return isTypeSpecifierQualifier();
+ }
+ bool isTypeIdInParens() {
+ bool isAmbiguous;
+ return isTypeIdInParens(isAmbiguous);
+ }
+
+ /// 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();
+
+ /// 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. If 'warnIfAmbiguous' is true a warning will be emitted to
+ /// indicate that the parens were disambiguated as function declarator.
+ /// 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 warnIfAmbiguous);
+
+ /// 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.
+ /// This is a class instead of a simple enum because the implicit enum-to-bool
+ /// conversions may cause subtle bugs.
+ class TPResult {
+ enum Result {
+ TPR_true,
+ TPR_false,
+ TPR_ambiguous,
+ TPR_error
+ };
+ Result Res;
+ TPResult(Result result) : Res(result) {}
+ public:
+ static TPResult True() { return TPR_true; }
+ static TPResult False() { return TPR_false; }
+ static TPResult Ambiguous() { return TPR_ambiguous; }
+ static TPResult Error() { return TPR_error; }
+
+ bool operator==(const TPResult &RHS) const { return Res == RHS.Res; }
+ bool operator!=(const TPResult &RHS) const { return Res != RHS.Res; }
+ };
+
+ /// 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.
+ /// Doesn't consume tokens.
+ TPResult isCXXDeclarationSpecifier();
+
+ // "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 TryParseDeclarationSpecifier();
+ TPResult TryParseSimpleDeclaration();
+ TPResult TryParseTypeofSpecifier();
+ TPResult TryParseInitDeclaratorList();
+ TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
+ TPResult TryParseParameterDeclarationClause();
+ TPResult TryParseFunctionDeclarator();
+ TPResult TryParseBracketDeclarator();
+
+ TypeResult ParseTypeName(SourceRange *Range = 0);
+ void ParseBlockId();
+ // EndLoc, if non-NULL, is filled with the location of the last token of
+ // the attribute list.
+ CXX0XAttributeList ParseCXX0XAttributes(SourceLocation *EndLoc = 0);
+ AttributeList *ParseGNUAttributes(SourceLocation *EndLoc = 0);
+ AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0);
+ AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0);
+ void ParseTypeofSpecifier(DeclSpec &DS);
+ void ParseDecltypeSpecifier(DeclSpec &DS);
+
+ OwningExprResult ParseCXX0XAlignArgument(SourceLocation Start);
+
+ /// 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.CurScope, SS))
+ EnteredScope = true;
+ }
+
+ ~DeclaratorScopeObj() {
+ if (EnteredScope) {
+ assert(SS.isSet() && "C++ scope was cleared ?");
+ P.Actions.ActOnCXXExitDeclaratorScope(P.CurScope, 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);
+ void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
+ bool CXX0XAttributesAllowed = true);
+ void ParseDirectDeclarator(Declarator &D);
+ void ParseParenDeclarator(Declarator &D);
+ void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
+ AttributeList *AttrList = 0,
+ bool RequiresArg = false);
+ void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
+ IdentifierInfo *FirstIdent,
+ SourceLocation FirstIdentLoc,
+ Declarator &D);
+ void ParseBracketDeclarator(Declarator &D);
+
+ //===--------------------------------------------------------------------===//
+ // C++ 7: Declarations [dcl.dcl]
+
+ bool isCXX0XAttributeSpecifier(bool FullLookahead = false,
+ tok::TokenKind *After = 0);
+
+ DeclPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd);
+ DeclPtrTy ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
+ DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context,
+ SourceLocation &DeclEnd,
+ CXX0XAttributeList Attrs);
+ DeclPtrTy ParseUsingDirective(unsigned Context, SourceLocation UsingLoc,
+ SourceLocation &DeclEnd,
+ AttributeList *Attr);
+ DeclPtrTy ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc,
+ SourceLocation &DeclEnd,
+ AccessSpecifier AS = AS_none);
+ DeclPtrTy ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
+ DeclPtrTy ParseNamespaceAlias(SourceLocation NamespaceLoc,
+ SourceLocation AliasLoc, IdentifierInfo *Alias,
+ SourceLocation &DeclEnd);
+
+ //===--------------------------------------------------------------------===//
+ // C++ 9: classes [class] and C structs/unions.
+ TypeResult ParseClassName(SourceLocation &EndLocation,
+ CXXScopeSpec *SS = 0);
+ void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
+ DeclSpec &DS,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+ AccessSpecifier AS = AS_none,
+ bool SuppressDeclarations = false);
+ void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
+ DeclPtrTy TagDecl);
+ void ParseCXXClassMemberDeclaration(AccessSpecifier AS,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+ void ParseConstructorInitializer(DeclPtrTy ConstructorDecl);
+ MemInitResult ParseMemInitializer(DeclPtrTy ConstructorDecl);
+ void HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
+ DeclPtrTy ThisDecl);
+
+ //===--------------------------------------------------------------------===//
+ // C++ 10: Derived classes [class.derived]
+ void ParseBaseClause(DeclPtrTy ClassDecl);
+ BaseResult ParseBaseSpecifier(DeclPtrTy ClassDecl);
+ AccessSpecifier getAccessSpecifierIfPresent() const;
+
+ bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
+ IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ bool EnteringContext,
+ TypeTy *ObjectType,
+ UnqualifiedId &Id,
+ bool AssumeTemplateId,
+ SourceLocation TemplateKWLoc);
+ bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
+ TypeTy *ObjectType,
+ UnqualifiedId &Result);
+ bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
+ bool AllowDestructorName,
+ bool AllowConstructorName,
+ TypeTy *ObjectType,
+ UnqualifiedId &Result);
+
+ //===--------------------------------------------------------------------===//
+ // C++ 14: Templates [temp]
+ typedef llvm::SmallVector<DeclPtrTy, 4> TemplateParameterList;
+
+ // C++ 14.1: Template Parameters [temp.param]
+ DeclPtrTy ParseDeclarationStartingWithTemplate(unsigned Context,
+ SourceLocation &DeclEnd,
+ AccessSpecifier AS = AS_none);
+ DeclPtrTy ParseTemplateDeclarationOrSpecialization(unsigned Context,
+ SourceLocation &DeclEnd,
+ AccessSpecifier AS);
+ DeclPtrTy ParseSingleDeclarationAfterTemplate(
+ unsigned Context,
+ const ParsedTemplateInfo &TemplateInfo,
+ SourceLocation &DeclEnd,
+ AccessSpecifier AS=AS_none);
+ bool ParseTemplateParameters(unsigned Depth,
+ TemplateParameterList &TemplateParams,
+ SourceLocation &LAngleLoc,
+ SourceLocation &RAngleLoc);
+ bool ParseTemplateParameterList(unsigned Depth,
+ TemplateParameterList &TemplateParams);
+ bool isStartOfTemplateTypeParameter();
+ DeclPtrTy ParseTemplateParameter(unsigned Depth, unsigned Position);
+ DeclPtrTy ParseTypeParameter(unsigned Depth, unsigned Position);
+ DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
+ DeclPtrTy ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
+ // C++ 14.3: Template arguments [temp.arg]
+ typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
+
+ bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ const CXXScopeSpec *SS,
+ bool ConsumeLastToken,
+ SourceLocation &LAngleLoc,
+ TemplateArgList &TemplateArgs,
+ SourceLocation &RAngleLoc);
+
+ bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+ const CXXScopeSpec *SS,
+ UnqualifiedId &TemplateName,
+ SourceLocation TemplateKWLoc = SourceLocation(),
+ bool AllowTypeAnnotation = true);
+ void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
+ bool IsTemplateArgumentList(unsigned Skip = 0);
+ bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
+ ParsedTemplateArgument ParseTemplateTemplateArgument();
+ ParsedTemplateArgument ParseTemplateArgument();
+ DeclPtrTy ParseExplicitInstantiation(SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ SourceLocation &DeclEnd);
+
+ //===--------------------------------------------------------------------===//
+ // GNU G++: Type Traits [Type-Traits.html in the GCC manual]
+ OwningExprResult ParseUnaryTypeTrait();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Scope.h b/contrib/llvm/tools/clang/include/clang/Parse/Scope.h
new file mode 100644
index 0000000..023f40d
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/Scope.h
@@ -0,0 +1,329 @@
+//===--- 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_PARSE_SCOPE_H
+#define LLVM_CLANG_PARSE_SCOPE_H
+
+#include "clang/Parse/Action.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace clang {
+
+/// 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 {
+ /// FnScope - This indicates that the scope corresponds to a function, which
+ /// means that labels are set here.
+ FnScope = 0x01,
+
+ /// BreakScope - This is a while,do,switch,for, etc that can have break
+ /// stmts embedded into it.
+ BreakScope = 0x02,
+
+ /// ContinueScope - This is a while,do,for, which can have continue
+ /// stmt embedded into it.
+ ContinueScope = 0x04,
+
+ /// DeclScope - This is a scope that can contain a declaration. Some scopes
+ /// just contain loop constructs but don't contain decls.
+ DeclScope = 0x08,
+
+ /// ControlScope - The controlling scope in a if/switch/while/for statement.
+ ControlScope = 0x10,
+
+ /// ClassScope - The scope of a struct/union/class definition.
+ ClassScope = 0x20,
+
+ /// BlockScope - This is a scope that corresponds to a block 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, BreakScope, ContinueScope, and DeclScope flags set as well.
+ BlockScope = 0x40,
+
+ /// TemplateParamScope - 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,
+
+ /// FunctionPrototypeScope - This is a scope that corresponds to the
+ /// parameters within a function prototype.
+ FunctionPrototypeScope = 0x100,
+
+ /// AtCatchScope - This is a scope that corresponds to the Objective-C
+ /// @catch statement.
+ AtCatchScope = 0x200,
+
+ /// ObjCMethodScope - This scope corresponds to an Objective-C method body.
+ /// It always has FnScope and DeclScope set as well.
+ ObjCMethodScope = 0x400,
+
+ /// ElseScope - This scope corresponds to an 'else' scope of an if/then/else
+ /// statement.
+ ElseScope = 0x800
+ };
+private:
+ /// The parent scope for this scope. This is null for the translation-unit
+ /// scope.
+ Scope *AnyParent;
+
+ /// Depth - This is the depth of this scope. The translation-unit scope has
+ /// depth 0.
+ unsigned short Depth;
+
+ /// Flags - This contains a set of ScopeFlags, which indicates how the scope
+ /// interrelates with other control flow statements.
+ unsigned short Flags;
+
+ /// 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;
+
+ /// BreakParent/ContinueParent - This is a direct link to the immediately
+ /// preceeding BreakParent/ContinueParent if this scope is not one, or null if
+ /// there is no containing break/continue scope.
+ Scope *BreakParent, *ContinueParent;
+
+ /// ControlParent - This is a direct link to the immediately
+ /// preceeding ControlParent if this scope is not one, or null if
+ /// there is no containing control scope.
+ Scope *ControlParent;
+
+ /// 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<Action::DeclPtrTy, 32> DeclSetTy;
+ DeclSetTy DeclsInScope;
+
+ /// Entity - The entity 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. This field is
+ /// maintained by the Action implementation.
+ void *Entity;
+
+ typedef llvm::SmallVector<Action::DeclPtrTy, 2> UsingDirectivesTy;
+ UsingDirectivesTy UsingDirectives;
+
+ /// \brief The number of errors at the start of the given scope.
+ unsigned NumErrorsAtStart;
+
+public:
+ Scope(Scope *Parent, unsigned ScopeFlags) {
+ 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 does not 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; }
+
+ /// getContinueParent - Return the closest scope that a continue statement
+ /// would be affected by. If the closest scope is a closure scope, we know
+ /// that there is no loop *inside* the closure.
+ Scope *getContinueParent() {
+ if (ContinueParent && !ContinueParent->isBlockScope())
+ return ContinueParent;
+ return 0;
+ }
+
+ const Scope *getContinueParent() const {
+ return const_cast<Scope*>(this)->getContinueParent();
+ }
+
+ /// getBreakParent - Return the closest scope that a break statement
+ /// would be affected by. If the closest scope is a block scope, we know
+ /// that there is no loop *inside* the block.
+ Scope *getBreakParent() {
+ if (BreakParent && !BreakParent->isBlockScope())
+ return BreakParent;
+ return 0;
+ }
+ const Scope *getBreakParent() const {
+ return const_cast<Scope*>(this)->getBreakParent();
+ }
+
+ Scope *getControlParent() { return ControlParent; }
+ const Scope *getControlParent() const { return ControlParent; }
+
+ Scope *getBlockParent() { return BlockParent; }
+ const Scope *getBlockParent() const { return BlockParent; }
+
+ Scope *getTemplateParamParent() { return TemplateParamParent; }
+ const Scope *getTemplateParamParent() const { return TemplateParamParent; }
+
+ typedef DeclSetTy::iterator decl_iterator;
+ decl_iterator decl_begin() const { return DeclsInScope.begin(); }
+ decl_iterator decl_end() const { return DeclsInScope.end(); }
+ bool decl_empty() const { return DeclsInScope.empty(); }
+
+ void AddDecl(Action::DeclPtrTy D) {
+ DeclsInScope.insert(D);
+ }
+
+ void RemoveDecl(Action::DeclPtrTy D) {
+ DeclsInScope.erase(D);
+ }
+
+ /// isDeclScope - Return true if this is the scope that the specified decl is
+ /// declared in.
+ bool isDeclScope(Action::DeclPtrTy D) {
+ return DeclsInScope.count(D) != 0;
+ }
+
+ void* getEntity() const { return Entity; }
+ void setEntity(void *E) { Entity = E; }
+
+ /// \brief Retrieve the number of errors that had been emitted when we
+ /// entered this scope.
+ unsigned getNumErrorsAtStart() const { return NumErrorsAtStart; }
+
+ void setNumErrorsAtStart(unsigned NumErrors) {
+ NumErrorsAtStart = NumErrors;
+ }
+
+ /// 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;
+ }
+
+ /// 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;
+ }
+
+ typedef UsingDirectivesTy::iterator udir_iterator;
+ typedef UsingDirectivesTy::const_iterator const_udir_iterator;
+
+ void PushUsingDirective(Action::DeclPtrTy UDir) {
+ UsingDirectives.push_back(UDir);
+ }
+
+ udir_iterator using_directives_begin() {
+ return UsingDirectives.begin();
+ }
+
+ udir_iterator using_directives_end() {
+ return UsingDirectives.end();
+ }
+
+ const_udir_iterator using_directives_begin() const {
+ return UsingDirectives.begin();
+ }
+
+ const_udir_iterator using_directives_end() const {
+ return UsingDirectives.end();
+ }
+
+ /// Init - This is used by the parser to implement scope caching.
+ ///
+ void Init(Scope *Parent, unsigned ScopeFlags) {
+ AnyParent = Parent;
+ Depth = AnyParent ? AnyParent->Depth+1 : 0;
+ Flags = ScopeFlags;
+
+ if (AnyParent) {
+ FnParent = AnyParent->FnParent;
+ BreakParent = AnyParent->BreakParent;
+ ContinueParent = AnyParent->ContinueParent;
+ ControlParent = AnyParent->ControlParent;
+ BlockParent = AnyParent->BlockParent;
+ TemplateParamParent = AnyParent->TemplateParamParent;
+ } else {
+ FnParent = BreakParent = ContinueParent = BlockParent = 0;
+ ControlParent = 0;
+ TemplateParamParent = 0;
+ }
+
+ // If this scope is a function or contains breaks/continues, remember it.
+ if (Flags & FnScope) FnParent = this;
+ if (Flags & BreakScope) BreakParent = this;
+ if (Flags & ContinueScope) ContinueParent = this;
+ if (Flags & ControlScope) ControlParent = this;
+ if (Flags & BlockScope) BlockParent = this;
+ if (Flags & TemplateParamScope) TemplateParamParent = this;
+ DeclsInScope.clear();
+ UsingDirectives.clear();
+ Entity = 0;
+ NumErrorsAtStart = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Template.h b/contrib/llvm/tools/clang/include/clang/Parse/Template.h
new file mode 100644
index 0000000..1f8ccfb
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Parse/Template.h
@@ -0,0 +1,183 @@
+//===--- Template.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_PARSE_TEMPLATE_H
+#define LLVM_CLANG_PARSE_TEMPLATE_H
+
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/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
+ ParsedTemplateArgument() : Kind(Type), Arg(0) { }
+
+ /// \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,
+ ActionBase::TemplateTy Template,
+ SourceLocation TemplateLoc)
+ : Kind(ParsedTemplateArgument::Template), Arg(Template.get()),
+ Loc(TemplateLoc), SS(SS) { }
+
+ /// \brief Determine whether the given template argument is invalid.
+ bool isInvalid() { return Arg == 0; }
+
+ /// \brief Determine what kind of template argument we have.
+ KindType getKind() const { return Kind; }
+
+ /// \brief Retrieve the template type argument's type.
+ ActionBase::TypeTy *getAsType() const {
+ assert(Kind == Type && "Not a template type argument");
+ return Arg;
+ }
+
+ /// \brief Retrieve the non-type template argument's expression.
+ ActionBase::ExprTy *getAsExpr() const {
+ assert(Kind == NonType && "Not a non-type template argument");
+ return Arg;
+ }
+
+ /// \brief Retrieve the template template argument's template name.
+ ActionBase::TemplateTy getAsTemplate() const {
+ assert(Kind == Template && "Not a template template argument");
+ return ActionBase::TemplateTy::make(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;
+ }
+
+ private:
+ KindType Kind;
+
+ /// \brief The actual template argument representation, which may be
+ /// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an
+ /// expression), or an ActionBase::TemplateTy (for a template).
+ void *Arg;
+
+ /// \brief the location of the template argument.
+ SourceLocation Loc;
+
+ /// \brief The nested-name-specifier that can accompany a template template
+ /// argument.
+ CXXScopeSpec SS;
+ };
+
+ /// \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 {
+ /// 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. This is an Action::TemplateTy.
+ void *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);
+ }
+
+ static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
+ TemplateIdAnnotation *TemplateId
+ = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
+ sizeof(ParsedTemplateArgument) * NumArgs);
+ TemplateId->NumArgs = NumArgs;
+ return TemplateId;
+ }
+
+ void Destroy() { free(this); }
+ };
+
+#if !defined(DISABLE_SMART_POINTERS)
+ inline void ASTTemplateArgsPtr::destroy() {
+ if (!Count)
+ return;
+
+ for (unsigned I = 0; I != Count; ++I)
+ if (Args[I].getKind() == ParsedTemplateArgument::NonType)
+ Actions.DeleteExpr(Args[I].getAsExpr());
+
+ Count = 0;
+ }
+#endif
+
+ inline const ParsedTemplateArgument &
+ ASTTemplateArgsPtr::operator[](unsigned Arg) const {
+ return Args[Arg];
+ }
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/DeltaTree.h b/contrib/llvm/tools/clang/include/clang/Rewrite/DeltaTree.h
new file mode 100644
index 0000000..f32906a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Rewrite/DeltaTree.h
@@ -0,0 +1,48 @@
+//===--- 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 CLANG_REWRITE_DELTATREE_H
+#define CLANG_REWRITE_DELTATREE_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&); // DO NOT IMPLEMENT
+ 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/contrib/llvm/tools/clang/include/clang/Rewrite/HTMLRewrite.h b/contrib/llvm/tools/clang/include/clang/Rewrite/HTMLRewrite.h
new file mode 100644
index 0000000..88caf85
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Rewrite/HTMLRewrite.h
@@ -0,0 +1,81 @@
+//==- 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_HTMLREWRITER_H
+#define LLVM_CLANG_HTMLREWRITER_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(const std::string& s,
+ bool EscapeSpaces = false, bool ReplaceTabs = false);
+
+ void AddLineNumbers(Rewriter& R, FileID FID);
+
+ void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
+ const char *title = NULL);
+
+ /// 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/contrib/llvm/tools/clang/include/clang/Rewrite/RewriteRope.h b/contrib/llvm/tools/clang/include/clang/Rewrite/RewriteRope.h
new file mode 100644
index 0000000..c0bd741
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Rewrite/RewriteRope.h
@@ -0,0 +1,230 @@
+//===--- 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_REWRITEROPE_H
+#define LLVM_CLANG_REWRITEROPE_H
+
+#include <cstring>
+#include <cassert>
+#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 addRef() {
+ if (this) ++RefCount;
+ }
+
+ void dropRef() {
+ if (this && --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 {
+ RopeRefCountString *StrData;
+ unsigned StartOffs;
+ unsigned EndOffs;
+
+ RopePiece() : StrData(0), StartOffs(0), EndOffs(0) {}
+
+ RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
+ : StrData(Str), StartOffs(Start), EndOffs(End) {
+ StrData->addRef();
+ }
+ RopePiece(const RopePiece &RP)
+ : StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) {
+ StrData->addRef();
+ }
+
+ ~RopePiece() {
+ StrData->dropRef();
+ }
+
+ void operator=(const RopePiece &RHS) {
+ if (StrData != RHS.StrData) {
+ StrData->dropRef();
+ StrData = RHS.StrData;
+ StrData->addRef();
+ }
+ StartOffs = RHS.StartOffs;
+ EndOffs = RHS.EndOffs;
+ }
+
+ 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(0), CurPiece(0), 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;
+ }
+ private:
+ void MoveToNextPiece();
+ };
+
+ //===--------------------------------------------------------------------===//
+ // RopePieceBTree Class
+ //===--------------------------------------------------------------------===//
+
+ class RopePieceBTree {
+ void /*RopePieceBTreeNode*/ *Root;
+ void operator=(const RopePieceBTree &); // DO NOT IMPLEMENT
+ 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.
+ RopeRefCountString *AllocBuffer;
+ unsigned AllocOffs;
+ enum { AllocChunkSize = 4080 };
+
+public:
+ RewriteRope() : AllocBuffer(0), AllocOffs(AllocChunkSize) {}
+ RewriteRope(const RewriteRope &RHS)
+ : Chunks(RHS.Chunks), AllocBuffer(0), AllocOffs(AllocChunkSize) {
+ }
+
+ ~RewriteRope() {
+ // If we had an allocation buffer, drop our reference to it.
+ AllocBuffer->dropRef();
+ }
+
+ 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/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h
new file mode 100644
index 0000000..adda866
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h
@@ -0,0 +1,225 @@
+//===--- 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_REWRITER_H
+#define LLVM_CLANG_REWRITER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Rewrite/DeltaTree.h"
+#include "clang/Rewrite/RewriteRope.h"
+#include "llvm/ADT/StringRef.h"
+#include <cstring>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace llvm { class raw_ostream; }
+
+namespace clang {
+ class LangOptions;
+ class Rewriter;
+ class SourceManager;
+ class Stmt;
+
+/// 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;
+
+ /// Buffer - This is the actual buffer itself. Note that using a vector or
+ /// string is a horribly inefficient way to do this, we should use a rope
+ /// instead.
+ typedef RewriteRope BufferTy;
+ BufferTy Buffer;
+public:
+ typedef BufferTy::const_iterator iterator;
+ iterator begin() const { return Buffer.begin(); }
+ iterator end() const { return Buffer.end(); }
+ unsigned size() const { return Buffer.size(); }
+
+ llvm::raw_ostream &write(llvm::raw_ostream &) const;
+
+ /// RemoveText - Remove the specified text.
+ void RemoveText(unsigned OrigOffset, unsigned Size);
+
+ /// 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, const llvm::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, const llvm::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, const llvm::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,
+ const llvm::StringRef &NewStr);
+
+private: // Methods only usable by Rewriter.
+
+ /// 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);
+ }
+
+ /// 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);
+ }
+};
+
+
+/// 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:
+ typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator;
+
+ explicit Rewriter(SourceManager &SM, const LangOptions &LO)
+ : SourceMgr(&SM), LangOpts(&LO) {}
+ explicit Rewriter() : SourceMgr(0), LangOpts(0) {}
+
+ void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
+ SourceMgr = &SM;
+ LangOpts = &LO;
+ }
+ SourceManager &getSourceMgr() { return *SourceMgr; }
+ const LangOptions &getLangOpts() { 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) 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.
+ bool InsertText(SourceLocation Loc, const llvm::StringRef &Str,
+ bool InsertAfter = true);
+
+ /// 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, const llvm::StringRef &Str) {
+ return InsertText(Loc, 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, const llvm::StringRef &Str) {
+ return InsertText(Loc, Str, false);
+ }
+
+ /// RemoveText - Remove the specified text region.
+ bool RemoveText(SourceLocation Start, unsigned Length);
+
+ /// 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,
+ const llvm::StringRef &NewStr);
+
+ /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
+ /// printer to generate the replacement code. This returns true if the input
+ /// could not be rewritten, or false if successful.
+ bool ReplaceStmt(Stmt *From, Stmt *To);
+
+ /// 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() ? 0 : &I->second;
+ }
+
+ // Iterators over rewrite buffers.
+ buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
+ buffer_iterator buffer_end() { return RewriteBuffers.end(); }
+
+private:
+ unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/TokenRewriter.h b/contrib/llvm/tools/clang/include/clang/Rewrite/TokenRewriter.h
new file mode 100644
index 0000000..62ea12a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Rewrite/TokenRewriter.h
@@ -0,0 +1,79 @@
+//===--- 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_TOKENREWRITER_H
+#define LLVM_CLANG_TOKENREWRITER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <list>
+#include <map>
+
+namespace clang {
+ class Token;
+ 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.
+ ///
+ llvm::OwningPtr<ScratchBuffer> ScratchBuf;
+
+ TokenRewriter(const TokenRewriter&); // DO NOT IMPLEMENT
+ void operator=(const TokenRewriter&); // DO NOT IMPLEMENT.
+ 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/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h
new file mode 100644
index 0000000..1f1c0cc
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -0,0 +1,555 @@
+//===---- 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 "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+class raw_ostream;
+}
+
+namespace clang {
+
+/// \brief Default priority values for code-completion results based
+/// on their kind.
+enum {
+ /// \brief Priority for a declaration that is in the local scope.
+ CCP_LocalDeclaration = 8,
+ /// \brief Priority for a member declaration found from the current
+ /// method or member function.
+ CCP_MemberDeclaration = 20,
+ /// \brief Priority for a language keyword (that isn't any of the other
+ /// categories).
+ CCP_Keyword = 30,
+ /// \brief Priority for a code pattern.
+ CCP_CodePattern = 30,
+ /// \brief Priority for a type.
+ CCP_Type = 40,
+ /// \brief Priority for a non-type declaration.
+ CCP_Declaration = 50,
+ /// \brief Priority for a constant value (e.g., enumerator).
+ CCP_Constant = 60,
+ /// \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 value deltas that are applied to code-completion results
+/// based on the context of the result.
+enum {
+ /// \brief The result is in a base class.
+ CCD_InBaseClass = 2
+};
+
+class FunctionDecl;
+class FunctionType;
+class FunctionTemplateDecl;
+class IdentifierInfo;
+class NamedDecl;
+class NestedNameSpecifier;
+class Sema;
+
+/// \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 Verticle 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(0) { }
+
+ Chunk(ChunkKind Kind, llvm::StringRef Text = "");
+
+ /// \brief Create a new text chunk.
+ static Chunk CreateText(llvm::StringRef Text);
+
+ /// \brief Create a new optional chunk.
+ static Chunk CreateOptional(std::auto_ptr<CodeCompletionString> Optional);
+
+ /// \brief Create a new placeholder chunk.
+ static Chunk CreatePlaceholder(llvm::StringRef Placeholder);
+
+ /// \brief Create a new informative chunk.
+ static Chunk CreateInformative(llvm::StringRef Informative);
+
+ /// \brief Create a new result type chunk.
+ static Chunk CreateResultType(llvm::StringRef ResultType);
+
+ /// \brief Create a new current-parameter chunk.
+ static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter);
+
+ /// \brief Clone the given chunk.
+ Chunk Clone() const;
+
+ /// \brief Destroy this chunk, deallocating any memory it owns.
+ void Destroy();
+ };
+
+private:
+ /// \brief The chunks stored in this string.
+ llvm::SmallVector<Chunk, 4> Chunks;
+
+ CodeCompletionString(const CodeCompletionString &); // DO NOT IMPLEMENT
+ CodeCompletionString &operator=(const CodeCompletionString &); // DITTO
+
+public:
+ CodeCompletionString() { }
+ ~CodeCompletionString() { clear(); }
+
+ typedef llvm::SmallVector<Chunk, 4>::const_iterator iterator;
+ iterator begin() const { return Chunks.begin(); }
+ iterator end() const { return Chunks.end(); }
+ bool empty() const { return Chunks.empty(); }
+ unsigned size() const { return Chunks.size(); }
+ void clear();
+
+ Chunk &operator[](unsigned I) {
+ assert(I < size() && "Chunk index out-of-range");
+ return Chunks[I];
+ }
+
+ const Chunk &operator[](unsigned I) const {
+ assert(I < size() && "Chunk index out-of-range");
+ return Chunks[I];
+ }
+
+ /// \brief Add a new typed-text chunk.
+ /// The text string will be copied.
+ void AddTypedTextChunk(llvm::StringRef Text) {
+ Chunks.push_back(Chunk(CK_TypedText, Text));
+ }
+
+ /// \brief Add a new text chunk.
+ /// The text string will be copied.
+ void AddTextChunk(llvm::StringRef Text) {
+ Chunks.push_back(Chunk::CreateText(Text));
+ }
+
+ /// \brief Add a new optional chunk.
+ void AddOptionalChunk(std::auto_ptr<CodeCompletionString> Optional) {
+ Chunks.push_back(Chunk::CreateOptional(Optional));
+ }
+
+ /// \brief Add a new placeholder chunk.
+ /// The placeholder text will be copied.
+ void AddPlaceholderChunk(llvm::StringRef Placeholder) {
+ Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
+ }
+
+ /// \brief Add a new informative chunk.
+ /// The text will be copied.
+ void AddInformativeChunk(llvm::StringRef Text) {
+ Chunks.push_back(Chunk::CreateInformative(Text));
+ }
+
+ /// \brief Add a new result-type chunk.
+ /// The text will be copied.
+ void AddResultTypeChunk(llvm::StringRef ResultType) {
+ Chunks.push_back(Chunk::CreateResultType(ResultType));
+ }
+
+ /// \brief Add a new current-parameter chunk.
+ /// The text will be copied.
+ void AddCurrentParameterChunk(llvm::StringRef CurrentParameter) {
+ Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
+ }
+
+ /// \brief Add a new chunk.
+ void AddChunk(Chunk C) { Chunks.push_back(C); }
+
+ /// \brief Returns the text in the TypedText chunk.
+ const char *getTypedText() const;
+
+ /// \brief Retrieve a string representation of the code completion string,
+ /// which is mainly useful for debugging.
+ std::string getAsString() const;
+
+ /// \brief Clone this code-completion string.
+ CodeCompletionString *Clone() const;
+
+ /// \brief Serialize this code-completion string to the given stream.
+ void Serialize(llvm::raw_ostream &OS) const;
+
+ /// \brief Deserialize a code-completion string from the given string.
+ ///
+ /// \returns true if successful, false otherwise.
+ bool Deserialize(const char *&Str, const char *StrEnd);
+};
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const CodeCompletionString &CCS);
+
+/// \brief Abstract interface for a consumer of code-completion
+/// information.
+class CodeCompleteConsumer {
+protected:
+ /// \brief Whether to include macros in the code-completion results.
+ bool IncludeMacros;
+
+ /// \brief Whether to include code patterns (such as for loops) within
+ /// the completion results.
+ bool IncludeCodePatterns;
+
+ /// \brief Whether the output format for the code-completion consumer is
+ /// binary.
+ bool OutputIsBinary;
+
+public:
+ /// \brief Captures a result of code completion.
+ struct Result {
+ /// \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 The kind of result stored here.
+ ResultKind Kind;
+
+ union {
+ /// \brief When Kind == RK_Declaration, the declaration we are referring
+ /// to.
+ NamedDecl *Declaration;
+
+ /// \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.
+ 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 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 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.
+ Result(NamedDecl *Declaration,
+ NestedNameSpecifier *Qualifier = 0,
+ bool QualifierIsInformative = false)
+ : Kind(RK_Declaration), Declaration(Declaration),
+ Priority(getPriorityFromDecl(Declaration)), StartParameter(0),
+ Hidden(false), QualifierIsInformative(QualifierIsInformative),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ Qualifier(Qualifier) {
+ }
+
+ /// \brief Build a result that refers to a keyword or symbol.
+ Result(const char *Keyword, unsigned Priority = CCP_Keyword)
+ : Kind(RK_Keyword), Keyword(Keyword), Priority(Priority),
+ StartParameter(0), Hidden(false), QualifierIsInformative(0),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ Qualifier(0) { }
+
+ /// \brief Build a result that refers to a macro.
+ Result(IdentifierInfo *Macro, unsigned Priority = CCP_Macro)
+ : Kind(RK_Macro), Macro(Macro), Priority(Priority), StartParameter(0),
+ Hidden(false), QualifierIsInformative(0),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ Qualifier(0) { }
+
+ /// \brief Build a result that refers to a pattern.
+ Result(CodeCompletionString *Pattern, unsigned Priority = CCP_CodePattern)
+ : Kind(RK_Pattern), Pattern(Pattern), Priority(Priority),
+ StartParameter(0), Hidden(false), QualifierIsInformative(0),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ Qualifier(0) { }
+
+ /// \brief Retrieve the declaration stored in this result.
+ 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.
+ CodeCompletionString *CreateCodeCompletionString(Sema &S);
+
+ void Destroy();
+
+ /// brief Determine a base priority for the given declaration.
+ static unsigned getPriorityFromDecl(NamedDecl *ND);
+ };
+
+ 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(FunctionTemplate) { }
+
+ 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) const;
+ };
+
+ CodeCompleteConsumer() : IncludeMacros(false), OutputIsBinary(false) { }
+
+ CodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
+ bool OutputIsBinary)
+ : IncludeMacros(IncludeMacros), IncludeCodePatterns(IncludeCodePatterns),
+ OutputIsBinary(OutputIsBinary) { }
+
+ /// \brief Whether the code-completion consumer wants to see macros.
+ bool includeMacros() const { return IncludeMacros; }
+
+ /// \brief Whether the code-completion consumer wants to see code patterns.
+ bool includeCodePatterns() const { return IncludeCodePatterns; }
+
+ /// \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, Result *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 A simple code-completion consumer that prints the results it
+/// receives in a simple format.
+class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
+ /// \brief The raw output stream.
+ llvm::raw_ostream &OS;
+
+public:
+ /// \brief Create a new printing code-completion consumer that prints its
+ /// results to the given raw output stream.
+ PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
+ llvm::raw_ostream &OS)
+ : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, false), OS(OS) {}
+
+ /// \brief Prints the finalized code-completion results.
+ virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
+ unsigned NumResults);
+
+ virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+ OverloadCandidate *Candidates,
+ unsigned NumCandidates);
+};
+
+/// \brief A code-completion consumer that prints the results it receives
+/// in a format that is parsable by the CIndex library.
+class CIndexCodeCompleteConsumer : public CodeCompleteConsumer {
+ /// \brief The raw output stream.
+ llvm::raw_ostream &OS;
+
+public:
+ /// \brief Create a new CIndex code-completion consumer that prints its
+ /// results to the given raw output stream in a format readable to the CIndex
+ /// library.
+ CIndexCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
+ llvm::raw_ostream &OS)
+ : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, true), OS(OS) {}
+
+ /// \brief Prints the finalized code-completion results.
+ virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
+ unsigned NumResults);
+
+ virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+ OverloadCandidate *Candidates,
+ unsigned NumCandidates);
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h
new file mode 100644
index 0000000..d27e292
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h
@@ -0,0 +1,59 @@
+//===--- 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_EXTERNAL_SEMA_SOURCE_H
+#define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
+
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExternalASTSource.h"
+
+namespace clang {
+
+class Sema;
+
+/// \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;
+ }
+
+ /// \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.
+ ///
+ /// \returns a pair of Objective-C methods lists containing the
+ /// instance and factory methods, respectively, with this selector.
+ virtual std::pair<ObjCMethodList, ObjCMethodList>
+ ReadMethodPool(Selector Sel) {
+ return std::pair<ObjCMethodList, ObjCMethodList>();
+ }
+
+ // isa/cast/dyn_cast support
+ static bool classof(const ExternalASTSource *Source) {
+ return Source->SemaSource;
+ }
+ static bool classof(const ExternalSemaSource *) { return true; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ParseAST.h b/contrib/llvm/tools/clang/include/clang/Sema/ParseAST.h
new file mode 100644
index 0000000..f6cff2a
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Sema/ParseAST.h
@@ -0,0 +1,43 @@
+//===--- 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_SEMA_PARSEAST_H
+#define LLVM_CLANG_SEMA_PARSEAST_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 CompleteTranslationUnit When true, the parsed file is
+ /// considered to be a complete translation unit, and any
+ /// end-of-translation-unit wrapup will be performed.
+ ///
+ /// \param CompletionConsumer If given, an object to consume code completion
+ /// results.
+ void ParseAST(Preprocessor &pp, ASTConsumer *C,
+ ASTContext &Ctx, bool PrintStats = false,
+ bool CompleteTranslationUnit = true,
+ CodeCompleteConsumer *CompletionConsumer = 0);
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Sema/SemaConsumer.h b/contrib/llvm/tools/clang/include/clang/Sema/SemaConsumer.h
new file mode 100644
index 0000000..3689a6e
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Sema/SemaConsumer.h
@@ -0,0 +1,48 @@
+//===--- 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 {
+ 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;
+ }
+ static bool classof(const SemaConsumer *) { return true; }
+ };
+}
+
+#endif
diff --git a/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h
new file mode 100644
index 0000000..a5a1364
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h
@@ -0,0 +1,27 @@
+//===--- 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_DIAGNOSTICSEMA_H
+#define LLVM_CLANG_DIAGNOSTICSEMA_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+ namespace diag {
+ enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
+#define SEMASTART
+#include "clang/Basic/DiagnosticSemaKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_SEMA_DIAGNOSTICS
+ };
+ } // end namespace diag
+} // end namespace clang
+
+#endif
OpenPOWER on IntegriCloud