From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/include/CMakeLists.txt | 1 + clang/include/Makefile | 4 + clang/include/clang-c/Index.h | 4748 ++++++++++++++ clang/include/clang-c/Makefile | 38 + clang/include/clang/ARCMigrate/ARCMT.h | 122 + clang/include/clang/ARCMigrate/ARCMTActions.h | 77 + clang/include/clang/ARCMigrate/FileRemapper.h | 80 + clang/include/clang/AST/.#Expr_flymake.h | 1 + clang/include/clang/AST/APValue.h | 446 ++ clang/include/clang/AST/AST.h | 28 + clang/include/clang/AST/ASTConsumer.h | 128 + clang/include/clang/AST/ASTContext.h | 1998 ++++++ clang/include/clang/AST/ASTDiagnostic.h | 50 + clang/include/clang/AST/ASTImporter.h | 278 + clang/include/clang/AST/ASTMutationListener.h | 84 + clang/include/clang/AST/ASTVector.h | 397 ++ clang/include/clang/AST/Attr.h | 254 + clang/include/clang/AST/BaseSubobject.h | 87 + clang/include/clang/AST/BuiltinTypes.def | 224 + clang/include/clang/AST/CMakeLists.txt | 17 + clang/include/clang/AST/CXXInheritance.h | 370 ++ clang/include/clang/AST/CanonicalType.h | 778 +++ clang/include/clang/AST/CharUnits.h | 217 + clang/include/clang/AST/Decl.h | 3339 ++++++++++ clang/include/clang/AST/DeclAccessPair.h | 72 + clang/include/clang/AST/DeclBase.h | 1636 +++++ clang/include/clang/AST/DeclCXX.h | 2938 +++++++++ clang/include/clang/AST/DeclContextInternals.h | 223 + clang/include/clang/AST/DeclFriend.h | 198 + clang/include/clang/AST/DeclGroup.h | 151 + clang/include/clang/AST/DeclLookups.h | 88 + clang/include/clang/AST/DeclObjC.h | 1988 ++++++ clang/include/clang/AST/DeclTemplate.h | 2106 ++++++ clang/include/clang/AST/DeclVisitor.h | 54 + clang/include/clang/AST/DeclarationName.h | 580 ++ clang/include/clang/AST/DependentDiagnostic.h | 192 + clang/include/clang/AST/EvaluatedExprVisitor.h | 83 + clang/include/clang/AST/Expr.h | 4561 +++++++++++++ clang/include/clang/AST/ExprCXX.h | 3638 +++++++++++ clang/include/clang/AST/ExprObjC.h | 1541 +++++ clang/include/clang/AST/ExternalASTSource.h | 528 ++ clang/include/clang/AST/GlobalDecl.h | 124 + clang/include/clang/AST/LambdaMangleContext.h | 36 + clang/include/clang/AST/Makefile | 29 + clang/include/clang/AST/Mangle.h | 152 + clang/include/clang/AST/NSAPI.h | 152 + clang/include/clang/AST/NestedNameSpecifier.h | 481 ++ clang/include/clang/AST/OperationKinds.h | 345 + clang/include/clang/AST/ParentMap.h | 62 + clang/include/clang/AST/PrettyPrinter.h | 146 + clang/include/clang/AST/RecordLayout.h | 228 + clang/include/clang/AST/RecursiveASTVisitor.h | 2242 +++++++ clang/include/clang/AST/Redeclarable.h | 181 + clang/include/clang/AST/SelectorLocationsKind.h | 83 + clang/include/clang/AST/Stmt.h | 1747 +++++ clang/include/clang/AST/StmtCXX.h | 295 + clang/include/clang/AST/StmtGraphTraits.h | 83 + clang/include/clang/AST/StmtIterator.h | 230 + clang/include/clang/AST/StmtObjC.h | 381 ++ clang/include/clang/AST/StmtVisitor.h | 189 + clang/include/clang/AST/TemplateBase.h | 657 ++ clang/include/clang/AST/TemplateName.h | 558 ++ clang/include/clang/AST/Type.h | 5022 ++++++++++++++ clang/include/clang/AST/TypeLoc.h | 1817 ++++++ clang/include/clang/AST/TypeLocNodes.def | 41 + clang/include/clang/AST/TypeLocVisitor.h | 62 + clang/include/clang/AST/TypeNodes.def | 127 + clang/include/clang/AST/TypeOrdering.h | 77 + clang/include/clang/AST/TypeVisitor.h | 53 + clang/include/clang/AST/UnresolvedSet.h | 186 + clang/include/clang/AST/VTTBuilder.h | 176 + clang/include/clang/AST/VTableBuilder.h | 357 + clang/include/clang/Analysis/Analyses/.#Interval.h | 1 + .../clang/Analysis/Analyses/.#Interval_flymake.h | 1 + .../clang/Analysis/Analyses/.#LiveVariables.h | 1 + .../Analysis/Analyses/.#LiveVariables_flymake.h | 1 + .../Analysis/Analyses/CFGReachabilityAnalysis.h | 49 + clang/include/clang/Analysis/Analyses/Dominators.h | 212 + .../include/clang/Analysis/Analyses/FormatString.h | 652 ++ clang/include/clang/Analysis/Analyses/Interval.h | 50 + .../Analyses/IntervalSolver/.#EquationSystem.hpp | 1 + .../IntervalSolver/.#EquationSystem_flymake.hpp | 1 + .../Analyses/IntervalSolver/.#Expression.hpp | 1 + .../IntervalSolver/.#Expression_flymake.hpp | 1 + .../Analyses/IntervalSolver/.#Operator_flymake.hpp | 1 + .../Analysis/Analyses/IntervalSolver/Complete.hpp | 128 + .../Analyses/IntervalSolver/EquationSystem.hpp | 150 + .../Analyses/IntervalSolver/Expression.hpp | 198 + .../Analysis/Analyses/IntervalSolver/IdMap.hpp | 82 + .../Analysis/Analyses/IntervalSolver/IdSet.hpp | 116 + .../clang/Analysis/Analyses/IntervalSolver/Log.hpp | 32 + .../Analyses/IntervalSolver/MaxStrategy.hpp | 153 + .../Analysis/Analyses/IntervalSolver/Operator.hpp | 168 + .../Analyses/IntervalSolver/VariableAssignment.hpp | 98 + .../clang/Analysis/Analyses/LiveVariables.h | 120 + .../clang/Analysis/Analyses/PostOrderCFGView.h | 111 + .../Analysis/Analyses/PseudoConstantAnalysis.h | 45 + .../clang/Analysis/Analyses/ReachableCode.h | 56 + .../include/clang/Analysis/Analyses/ThreadSafety.h | 159 + .../clang/Analysis/Analyses/UninitializedValues.h | 53 + clang/include/clang/Analysis/AnalysisContext.h | 432 ++ clang/include/clang/Analysis/AnalysisDiagnostic.h | 28 + clang/include/clang/Analysis/CFG.h | 938 +++ clang/include/clang/Analysis/CFGStmtMap.h | 52 + clang/include/clang/Analysis/CallGraph.h | 257 + .../Analysis/DomainSpecific/CocoaConventions.h | 42 + .../clang/Analysis/FlowSensitive/DataflowSolver.h | 343 + .../clang/Analysis/FlowSensitive/DataflowValues.h | 172 + clang/include/clang/Analysis/ProgramPoint.h | 490 ++ .../clang/Analysis/Support/BlkExprDeclBitVector.h | 307 + clang/include/clang/Analysis/Support/BumpVector.h | 244 + .../Analysis/Visitors/CFGRecStmtDeclVisitor.h | 103 + .../clang/Analysis/Visitors/CFGRecStmtVisitor.h | 59 + .../clang/Analysis/Visitors/CFGStmtVisitor.h | 175 + clang/include/clang/Basic/ABI.h | 126 + clang/include/clang/Basic/AddressSpaces.h | 44 + clang/include/clang/Basic/AllDiagnostics.h | 39 + clang/include/clang/Basic/Attr.td | 716 ++ clang/include/clang/Basic/AttrKinds.h | 33 + clang/include/clang/Basic/Builtins.def | 836 +++ clang/include/clang/Basic/Builtins.h | 163 + clang/include/clang/Basic/BuiltinsARM.def | 52 + clang/include/clang/Basic/BuiltinsHexagon.def | 689 ++ clang/include/clang/Basic/BuiltinsPPC.def | 209 + clang/include/clang/Basic/BuiltinsPTX.def | 62 + clang/include/clang/Basic/BuiltinsX86.def | 635 ++ clang/include/clang/Basic/CMakeLists.txt | 33 + clang/include/clang/Basic/ConvertUTF.h | 166 + clang/include/clang/Basic/DeclNodes.td | 77 + clang/include/clang/Basic/Diagnostic.h | 1207 ++++ clang/include/clang/Basic/Diagnostic.td | 98 + clang/include/clang/Basic/DiagnosticASTKinds.td | 211 + .../include/clang/Basic/DiagnosticAnalysisKinds.td | 12 + clang/include/clang/Basic/DiagnosticCategories.h | 26 + clang/include/clang/Basic/DiagnosticCategories.td | 10 + clang/include/clang/Basic/DiagnosticCommonKinds.td | 109 + clang/include/clang/Basic/DiagnosticDriverKinds.td | 138 + .../include/clang/Basic/DiagnosticFrontendKinds.td | 134 + clang/include/clang/Basic/DiagnosticGroups.td | 415 ++ clang/include/clang/Basic/DiagnosticIDs.h | 279 + clang/include/clang/Basic/DiagnosticLexKinds.td | 503 ++ clang/include/clang/Basic/DiagnosticParseKinds.td | 718 ++ clang/include/clang/Basic/DiagnosticSemaKinds.td | 5498 ++++++++++++++++ .../clang/Basic/DiagnosticSerializationKinds.td | 60 + .../clang/Basic/ExceptionSpecificationType.h | 54 + clang/include/clang/Basic/ExpressionTraits.h | 25 + clang/include/clang/Basic/FileManager.h | 234 + clang/include/clang/Basic/FileSystemOptions.h | 31 + clang/include/clang/Basic/FileSystemStatCache.h | 103 + clang/include/clang/Basic/IdentifierTable.h | 809 +++ clang/include/clang/Basic/LLVM.h | 73 + clang/include/clang/Basic/Lambda.h | 38 + clang/include/clang/Basic/LangOptions.def | 170 + clang/include/clang/Basic/LangOptions.h | 122 + clang/include/clang/Basic/Linkage.h | 68 + clang/include/clang/Basic/MacroBuilder.h | 46 + clang/include/clang/Basic/Makefile | 61 + clang/include/clang/Basic/Module.h | 284 + clang/include/clang/Basic/OnDiskHashTable.h | 485 ++ clang/include/clang/Basic/OpenCL.h | 28 + clang/include/clang/Basic/OpenCLExtensions.def | 32 + clang/include/clang/Basic/OperatorKinds.def | 106 + clang/include/clang/Basic/OperatorKinds.h | 35 + clang/include/clang/Basic/PartialDiagnostic.h | 352 + clang/include/clang/Basic/PrettyStackTrace.h | 37 + clang/include/clang/Basic/SourceLocation.h | 426 ++ clang/include/clang/Basic/SourceManager.h | 1402 ++++ clang/include/clang/Basic/SourceManagerInternals.h | 130 + clang/include/clang/Basic/Specifiers.h | 173 + clang/include/clang/Basic/StmtNodes.td | 170 + clang/include/clang/Basic/TargetBuiltins.h | 110 + clang/include/clang/Basic/TargetInfo.h | 695 ++ clang/include/clang/Basic/TargetOptions.h | 45 + clang/include/clang/Basic/TemplateKinds.h | 39 + clang/include/clang/Basic/TokenKinds.def | 596 ++ clang/include/clang/Basic/TokenKinds.h | 70 + clang/include/clang/Basic/TypeTraits.h | 95 + clang/include/clang/Basic/Version.h | 78 + clang/include/clang/Basic/Version.inc.in | 6 + clang/include/clang/Basic/VersionTuple.h | 123 + clang/include/clang/Basic/Visibility.h | 48 + clang/include/clang/Basic/arm_neon.td | 395 ++ clang/include/clang/CMakeLists.txt | 7 + clang/include/clang/CodeGen/BackendUtil.h | 40 + clang/include/clang/CodeGen/CodeGenAction.h | 103 + clang/include/clang/CodeGen/ModuleBuilder.h | 46 + clang/include/clang/Config/config.h.cmake | 14 + clang/include/clang/Config/config.h.in | 24 + clang/include/clang/Driver/Action.h | 254 + clang/include/clang/Driver/Arg.h | 122 + clang/include/clang/Driver/ArgList.h | 426 ++ clang/include/clang/Driver/CC1AsOptions.h | 32 + clang/include/clang/Driver/CC1AsOptions.td | 91 + clang/include/clang/Driver/CC1Options.h | 32 + clang/include/clang/Driver/CC1Options.td | 842 +++ clang/include/clang/Driver/CMakeLists.txt | 11 + clang/include/clang/Driver/Compilation.h | 166 + clang/include/clang/Driver/Driver.h | 418 ++ clang/include/clang/Driver/DriverDiagnostic.h | 28 + clang/include/clang/Driver/Job.h | 122 + clang/include/clang/Driver/Makefile | 18 + clang/include/clang/Driver/ObjCRuntime.h | 49 + clang/include/clang/Driver/OptParser.td | 138 + clang/include/clang/Driver/OptSpecifier.h | 39 + clang/include/clang/Driver/OptTable.h | 186 + clang/include/clang/Driver/Option.h | 318 + clang/include/clang/Driver/Options.h | 32 + clang/include/clang/Driver/Options.td | 967 +++ clang/include/clang/Driver/Phases.h | 32 + clang/include/clang/Driver/Tool.h | 75 + clang/include/clang/Driver/ToolChain.h | 257 + clang/include/clang/Driver/Types.def | 93 + clang/include/clang/Driver/Types.h | 96 + clang/include/clang/Driver/Util.h | 28 + clang/include/clang/Edit/Commit.h | 140 + clang/include/clang/Edit/EditedSource.h | 87 + clang/include/clang/Edit/EditsReceiver.h | 35 + clang/include/clang/Edit/FileOffset.h | 65 + clang/include/clang/Edit/Rewriters.h | 33 + clang/include/clang/Frontend/ASTConsumers.h | 57 + clang/include/clang/Frontend/ASTUnit.h | 791 +++ clang/include/clang/Frontend/Analyses.def | 65 + clang/include/clang/Frontend/AnalyzerOptions.h | 137 + .../clang/Frontend/ChainedDiagnosticConsumer.h | 73 + .../include/clang/Frontend/ChainedIncludesSource.h | 75 + clang/include/clang/Frontend/CodeGenOptions.h | 231 + .../include/clang/Frontend/CommandLineSourceLoc.h | 87 + clang/include/clang/Frontend/CompilerInstance.h | 664 ++ clang/include/clang/Frontend/CompilerInvocation.h | 221 + .../clang/Frontend/DependencyOutputOptions.h | 56 + clang/include/clang/Frontend/DiagnosticOptions.h | 108 + clang/include/clang/Frontend/DiagnosticRenderer.h | 149 + clang/include/clang/Frontend/FrontendAction.h | 277 + clang/include/clang/Frontend/FrontendActions.h | 209 + clang/include/clang/Frontend/FrontendDiagnostic.h | 28 + clang/include/clang/Frontend/FrontendOptions.h | 208 + .../clang/Frontend/FrontendPluginRegistry.h | 23 + clang/include/clang/Frontend/HeaderSearchOptions.h | 124 + clang/include/clang/Frontend/LangStandard.h | 92 + clang/include/clang/Frontend/LangStandards.def | 120 + .../include/clang/Frontend/LayoutOverrideSource.h | 61 + .../include/clang/Frontend/LogDiagnosticPrinter.h | 79 + clang/include/clang/Frontend/MigratorOptions.h | 31 + clang/include/clang/Frontend/MultiplexConsumer.h | 64 + clang/include/clang/Frontend/PreprocessorOptions.h | 224 + .../clang/Frontend/PreprocessorOutputOptions.h | 37 + .../clang/Frontend/SerializedDiagnosticPrinter.h | 62 + clang/include/clang/Frontend/TextDiagnostic.h | 123 + .../include/clang/Frontend/TextDiagnosticBuffer.h | 54 + .../include/clang/Frontend/TextDiagnosticPrinter.h | 59 + clang/include/clang/Frontend/Utils.h | 108 + .../clang/Frontend/VerifyDiagnosticConsumer.h | 97 + clang/include/clang/FrontendTool/Utils.h | 30 + clang/include/clang/Lex/CMakeLists.txt | 5 + clang/include/clang/Lex/CodeCompletionHandler.h | 71 + clang/include/clang/Lex/DirectoryLookup.h | 170 + .../include/clang/Lex/ExternalPreprocessorSource.h | 40 + clang/include/clang/Lex/HeaderMap.h | 72 + clang/include/clang/Lex/HeaderSearch.h | 562 ++ clang/include/clang/Lex/LexDiagnostic.h | 28 + clang/include/clang/Lex/Lexer.h | 563 ++ clang/include/clang/Lex/LiteralSupport.h | 239 + clang/include/clang/Lex/MacroInfo.h | 305 + clang/include/clang/Lex/Makefile | 13 + clang/include/clang/Lex/ModuleLoader.h | 65 + clang/include/clang/Lex/ModuleMap.h | 237 + clang/include/clang/Lex/MultipleIncludeOpt.h | 130 + clang/include/clang/Lex/PPCallbacks.h | 385 ++ clang/include/clang/Lex/PTHLexer.h | 105 + clang/include/clang/Lex/PTHManager.h | 140 + clang/include/clang/Lex/Pragma.h | 126 + clang/include/clang/Lex/PreprocessingRecord.h | 637 ++ clang/include/clang/Lex/Preprocessor.h | 1308 ++++ clang/include/clang/Lex/PreprocessorLexer.h | 180 + clang/include/clang/Lex/ScratchBuffer.h | 45 + clang/include/clang/Lex/Token.h | 299 + clang/include/clang/Lex/TokenConcatenation.h | 72 + clang/include/clang/Lex/TokenLexer.h | 187 + clang/include/clang/Makefile | 44 + clang/include/clang/Parse/CMakeLists.txt | 4 + clang/include/clang/Parse/Makefile | 13 + clang/include/clang/Parse/ParseAST.h | 49 + clang/include/clang/Parse/ParseDiagnostic.h | 28 + clang/include/clang/Parse/Parser.h | 2231 +++++++ clang/include/clang/Rewrite/ASTConsumers.h | 48 + clang/include/clang/Rewrite/DeltaTree.h | 48 + clang/include/clang/Rewrite/FixItRewriter.h | 130 + clang/include/clang/Rewrite/FrontendActions.h | 78 + clang/include/clang/Rewrite/HTMLRewrite.h | 81 + clang/include/clang/Rewrite/RewriteRope.h | 231 + clang/include/clang/Rewrite/Rewriter.h | 288 + clang/include/clang/Rewrite/Rewriters.h | 30 + clang/include/clang/Rewrite/TokenRewriter.h | 79 + clang/include/clang/Sema/AnalysisBasedWarnings.h | 102 + clang/include/clang/Sema/AttributeList.h | 555 ++ clang/include/clang/Sema/CMakeLists.txt | 14 + clang/include/clang/Sema/CXXFieldCollector.h | 79 + clang/include/clang/Sema/CodeCompleteConsumer.h | 992 +++ clang/include/clang/Sema/DeclSpec.h | 1984 ++++++ clang/include/clang/Sema/DelayedDiagnostic.h | 220 + clang/include/clang/Sema/Designator.h | 218 + clang/include/clang/Sema/ExternalSemaSource.h | 183 + clang/include/clang/Sema/IdentifierResolver.h | 221 + clang/include/clang/Sema/Initialization.h | 1001 +++ clang/include/clang/Sema/LocInfoType.h | 63 + clang/include/clang/Sema/Lookup.h | 715 ++ clang/include/clang/Sema/Makefile | 27 + clang/include/clang/Sema/ObjCMethodList.h | 38 + clang/include/clang/Sema/Overload.h | 813 +++ clang/include/clang/Sema/Ownership.h | 469 ++ clang/include/clang/Sema/ParsedTemplate.h | 219 + clang/include/clang/Sema/PrettyDeclStackTrace.h | 47 + clang/include/clang/Sema/Scope.h | 329 + clang/include/clang/Sema/ScopeInfo.h | 380 ++ clang/include/clang/Sema/Sema.h | 6879 ++++++++++++++++++++ clang/include/clang/Sema/SemaConsumer.h | 49 + clang/include/clang/Sema/SemaDiagnostic.h | 28 + clang/include/clang/Sema/SemaFixItUtils.h | 91 + clang/include/clang/Sema/SemaInternal.h | 30 + clang/include/clang/Sema/Template.h | 491 ++ clang/include/clang/Sema/TemplateDeduction.h | 135 + clang/include/clang/Sema/TypoCorrection.h | 256 + clang/include/clang/Sema/Weak.h | 46 + clang/include/clang/Serialization/ASTBitCodes.h | 1279 ++++ .../Serialization/ASTDeserializationListener.h | 60 + clang/include/clang/Serialization/ASTReader.h | 1524 +++++ clang/include/clang/Serialization/ASTWriter.h | 738 +++ clang/include/clang/Serialization/CMakeLists.txt | 9 + .../clang/Serialization/ContinuousRangeMap.h | 130 + clang/include/clang/Serialization/Makefile | 19 + clang/include/clang/Serialization/Module.h | 364 ++ clang/include/clang/Serialization/ModuleManager.h | 158 + .../clang/Serialization/SerializationDiagnostic.h | 28 + .../clang/StaticAnalyzer/Checkers/CheckerBase.td | 39 + .../clang/StaticAnalyzer/Checkers/ClangCheckers.h | 22 + .../StaticAnalyzer/Checkers/CommonBugCategories.h | 24 + .../StaticAnalyzer/Checkers/DereferenceChecker.h | 35 + .../clang/StaticAnalyzer/Checkers/LocalCheckers.h | 28 + .../StaticAnalyzer/Core/BugReporter/BugReporter.h | 453 ++ .../Core/BugReporter/BugReporterVisitor.h | 243 + .../StaticAnalyzer/Core/BugReporter/BugType.h | 67 + .../Core/BugReporter/PathDiagnostic.h | 679 ++ clang/include/clang/StaticAnalyzer/Core/Checker.h | 441 ++ .../clang/StaticAnalyzer/Core/CheckerManager.h | 594 ++ .../clang/StaticAnalyzer/Core/CheckerOptInfo.h | 43 + .../clang/StaticAnalyzer/Core/CheckerRegistry.h | 134 + .../StaticAnalyzer/Core/PathDiagnosticConsumers.h | 46 + .../Core/PathSensitive/.#CheckerContext_flymake.h | 1 + .../Core/PathSensitive/AnalysisManager.h | 203 + .../Core/PathSensitive/BasicValueFactory.h | 199 + .../Core/PathSensitive/BlockCounter.h | 62 + .../Core/PathSensitive/CheckerContext.h | 239 + .../Core/PathSensitive/CheckerHelpers.h | 43 + .../Core/PathSensitive/ConstraintManager.h | 81 + .../StaticAnalyzer/Core/PathSensitive/CoreEngine.h | 541 ++ .../Core/PathSensitive/Environment.h | 139 + .../Core/PathSensitive/ExplodedGraph.h | 480 ++ .../StaticAnalyzer/Core/PathSensitive/ExprEngine.h | 496 ++ .../Core/PathSensitive/FunctionSummary.h | 107 + .../StaticAnalyzer/Core/PathSensitive/MemRegion.h | 1230 ++++ .../Core/PathSensitive/ObjCMessage.h | 293 + .../Core/PathSensitive/ProgramState.h | 796 +++ .../Core/PathSensitive/ProgramStateTrait.h | 197 + .../Core/PathSensitive/ProgramState_Fwd.h | 43 + .../Core/PathSensitive/SValBuilder.h | 320 + .../StaticAnalyzer/Core/PathSensitive/SVals.h | 519 ++ .../StaticAnalyzer/Core/PathSensitive/Store.h | 304 + .../StaticAnalyzer/Core/PathSensitive/StoreRef.h | 51 + .../StaticAnalyzer/Core/PathSensitive/SubEngine.h | 130 + .../Core/PathSensitive/SummaryManager.h | 61 + .../Core/PathSensitive/SymbolManager.h | 668 ++ .../Core/PathSensitive/TaintManager.h | 40 + .../StaticAnalyzer/Core/PathSensitive/TaintTag.h | 27 + .../StaticAnalyzer/Core/PathSensitive/WorkList.h | 102 + .../StaticAnalyzer/Frontend/CheckerRegistration.h | 33 + .../StaticAnalyzer/Frontend/FrontendActions.h | 35 + clang/include/clang/Tooling/CompilationDatabase.h | 218 + clang/include/clang/Tooling/Tooling.h | 213 + 378 files changed, 129395 insertions(+) create mode 100644 clang/include/CMakeLists.txt create mode 100644 clang/include/Makefile create mode 100644 clang/include/clang-c/Index.h create mode 100644 clang/include/clang-c/Makefile create mode 100644 clang/include/clang/ARCMigrate/ARCMT.h create mode 100644 clang/include/clang/ARCMigrate/ARCMTActions.h create mode 100644 clang/include/clang/ARCMigrate/FileRemapper.h create mode 120000 clang/include/clang/AST/.#Expr_flymake.h create mode 100644 clang/include/clang/AST/APValue.h create mode 100644 clang/include/clang/AST/AST.h create mode 100644 clang/include/clang/AST/ASTConsumer.h create mode 100644 clang/include/clang/AST/ASTContext.h create mode 100644 clang/include/clang/AST/ASTDiagnostic.h create mode 100644 clang/include/clang/AST/ASTImporter.h create mode 100644 clang/include/clang/AST/ASTMutationListener.h create mode 100644 clang/include/clang/AST/ASTVector.h create mode 100644 clang/include/clang/AST/Attr.h create mode 100644 clang/include/clang/AST/BaseSubobject.h create mode 100644 clang/include/clang/AST/BuiltinTypes.def create mode 100644 clang/include/clang/AST/CMakeLists.txt create mode 100644 clang/include/clang/AST/CXXInheritance.h create mode 100644 clang/include/clang/AST/CanonicalType.h create mode 100644 clang/include/clang/AST/CharUnits.h create mode 100644 clang/include/clang/AST/Decl.h create mode 100644 clang/include/clang/AST/DeclAccessPair.h create mode 100644 clang/include/clang/AST/DeclBase.h create mode 100644 clang/include/clang/AST/DeclCXX.h create mode 100644 clang/include/clang/AST/DeclContextInternals.h create mode 100644 clang/include/clang/AST/DeclFriend.h create mode 100644 clang/include/clang/AST/DeclGroup.h create mode 100644 clang/include/clang/AST/DeclLookups.h create mode 100644 clang/include/clang/AST/DeclObjC.h create mode 100644 clang/include/clang/AST/DeclTemplate.h create mode 100644 clang/include/clang/AST/DeclVisitor.h create mode 100644 clang/include/clang/AST/DeclarationName.h create mode 100644 clang/include/clang/AST/DependentDiagnostic.h create mode 100644 clang/include/clang/AST/EvaluatedExprVisitor.h create mode 100644 clang/include/clang/AST/Expr.h create mode 100644 clang/include/clang/AST/ExprCXX.h create mode 100644 clang/include/clang/AST/ExprObjC.h create mode 100644 clang/include/clang/AST/ExternalASTSource.h create mode 100644 clang/include/clang/AST/GlobalDecl.h create mode 100644 clang/include/clang/AST/LambdaMangleContext.h create mode 100644 clang/include/clang/AST/Makefile create mode 100644 clang/include/clang/AST/Mangle.h create mode 100644 clang/include/clang/AST/NSAPI.h create mode 100644 clang/include/clang/AST/NestedNameSpecifier.h create mode 100644 clang/include/clang/AST/OperationKinds.h create mode 100644 clang/include/clang/AST/ParentMap.h create mode 100644 clang/include/clang/AST/PrettyPrinter.h create mode 100644 clang/include/clang/AST/RecordLayout.h create mode 100644 clang/include/clang/AST/RecursiveASTVisitor.h create mode 100644 clang/include/clang/AST/Redeclarable.h create mode 100644 clang/include/clang/AST/SelectorLocationsKind.h create mode 100644 clang/include/clang/AST/Stmt.h create mode 100644 clang/include/clang/AST/StmtCXX.h create mode 100644 clang/include/clang/AST/StmtGraphTraits.h create mode 100644 clang/include/clang/AST/StmtIterator.h create mode 100644 clang/include/clang/AST/StmtObjC.h create mode 100644 clang/include/clang/AST/StmtVisitor.h create mode 100644 clang/include/clang/AST/TemplateBase.h create mode 100644 clang/include/clang/AST/TemplateName.h create mode 100644 clang/include/clang/AST/Type.h create mode 100644 clang/include/clang/AST/TypeLoc.h create mode 100644 clang/include/clang/AST/TypeLocNodes.def create mode 100644 clang/include/clang/AST/TypeLocVisitor.h create mode 100644 clang/include/clang/AST/TypeNodes.def create mode 100644 clang/include/clang/AST/TypeOrdering.h create mode 100644 clang/include/clang/AST/TypeVisitor.h create mode 100644 clang/include/clang/AST/UnresolvedSet.h create mode 100644 clang/include/clang/AST/VTTBuilder.h create mode 100644 clang/include/clang/AST/VTableBuilder.h create mode 120000 clang/include/clang/Analysis/Analyses/.#Interval.h create mode 120000 clang/include/clang/Analysis/Analyses/.#Interval_flymake.h create mode 120000 clang/include/clang/Analysis/Analyses/.#LiveVariables.h create mode 120000 clang/include/clang/Analysis/Analyses/.#LiveVariables_flymake.h create mode 100644 clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h create mode 100644 clang/include/clang/Analysis/Analyses/Dominators.h create mode 100644 clang/include/clang/Analysis/Analyses/FormatString.h create mode 100644 clang/include/clang/Analysis/Analyses/Interval.h create mode 120000 clang/include/clang/Analysis/Analyses/IntervalSolver/.#EquationSystem.hpp create mode 120000 clang/include/clang/Analysis/Analyses/IntervalSolver/.#EquationSystem_flymake.hpp create mode 120000 clang/include/clang/Analysis/Analyses/IntervalSolver/.#Expression.hpp create mode 120000 clang/include/clang/Analysis/Analyses/IntervalSolver/.#Expression_flymake.hpp create mode 120000 clang/include/clang/Analysis/Analyses/IntervalSolver/.#Operator_flymake.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/Complete.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/EquationSystem.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/Expression.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/IdMap.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/IdSet.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/Log.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/MaxStrategy.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/Operator.hpp create mode 100644 clang/include/clang/Analysis/Analyses/IntervalSolver/VariableAssignment.hpp create mode 100644 clang/include/clang/Analysis/Analyses/LiveVariables.h create mode 100644 clang/include/clang/Analysis/Analyses/PostOrderCFGView.h create mode 100644 clang/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h create mode 100644 clang/include/clang/Analysis/Analyses/ReachableCode.h create mode 100644 clang/include/clang/Analysis/Analyses/ThreadSafety.h create mode 100644 clang/include/clang/Analysis/Analyses/UninitializedValues.h create mode 100644 clang/include/clang/Analysis/AnalysisContext.h create mode 100644 clang/include/clang/Analysis/AnalysisDiagnostic.h create mode 100644 clang/include/clang/Analysis/CFG.h create mode 100644 clang/include/clang/Analysis/CFGStmtMap.h create mode 100644 clang/include/clang/Analysis/CallGraph.h create mode 100644 clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h create mode 100644 clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h create mode 100644 clang/include/clang/Analysis/FlowSensitive/DataflowValues.h create mode 100644 clang/include/clang/Analysis/ProgramPoint.h create mode 100644 clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h create mode 100644 clang/include/clang/Analysis/Support/BumpVector.h create mode 100644 clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h create mode 100644 clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h create mode 100644 clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h create mode 100644 clang/include/clang/Basic/ABI.h create mode 100644 clang/include/clang/Basic/AddressSpaces.h create mode 100644 clang/include/clang/Basic/AllDiagnostics.h create mode 100644 clang/include/clang/Basic/Attr.td create mode 100644 clang/include/clang/Basic/AttrKinds.h create mode 100644 clang/include/clang/Basic/Builtins.def create mode 100644 clang/include/clang/Basic/Builtins.h create mode 100644 clang/include/clang/Basic/BuiltinsARM.def create mode 100644 clang/include/clang/Basic/BuiltinsHexagon.def create mode 100644 clang/include/clang/Basic/BuiltinsPPC.def create mode 100644 clang/include/clang/Basic/BuiltinsPTX.def create mode 100644 clang/include/clang/Basic/BuiltinsX86.def create mode 100644 clang/include/clang/Basic/CMakeLists.txt create mode 100644 clang/include/clang/Basic/ConvertUTF.h create mode 100644 clang/include/clang/Basic/DeclNodes.td create mode 100644 clang/include/clang/Basic/Diagnostic.h create mode 100644 clang/include/clang/Basic/Diagnostic.td create mode 100644 clang/include/clang/Basic/DiagnosticASTKinds.td create mode 100644 clang/include/clang/Basic/DiagnosticAnalysisKinds.td create mode 100644 clang/include/clang/Basic/DiagnosticCategories.h create mode 100644 clang/include/clang/Basic/DiagnosticCategories.td create mode 100644 clang/include/clang/Basic/DiagnosticCommonKinds.td create mode 100644 clang/include/clang/Basic/DiagnosticDriverKinds.td create mode 100644 clang/include/clang/Basic/DiagnosticFrontendKinds.td create mode 100644 clang/include/clang/Basic/DiagnosticGroups.td create mode 100644 clang/include/clang/Basic/DiagnosticIDs.h create mode 100644 clang/include/clang/Basic/DiagnosticLexKinds.td create mode 100644 clang/include/clang/Basic/DiagnosticParseKinds.td create mode 100644 clang/include/clang/Basic/DiagnosticSemaKinds.td create mode 100644 clang/include/clang/Basic/DiagnosticSerializationKinds.td create mode 100644 clang/include/clang/Basic/ExceptionSpecificationType.h create mode 100644 clang/include/clang/Basic/ExpressionTraits.h create mode 100644 clang/include/clang/Basic/FileManager.h create mode 100644 clang/include/clang/Basic/FileSystemOptions.h create mode 100644 clang/include/clang/Basic/FileSystemStatCache.h create mode 100644 clang/include/clang/Basic/IdentifierTable.h create mode 100644 clang/include/clang/Basic/LLVM.h create mode 100644 clang/include/clang/Basic/Lambda.h create mode 100644 clang/include/clang/Basic/LangOptions.def create mode 100644 clang/include/clang/Basic/LangOptions.h create mode 100644 clang/include/clang/Basic/Linkage.h create mode 100644 clang/include/clang/Basic/MacroBuilder.h create mode 100644 clang/include/clang/Basic/Makefile create mode 100644 clang/include/clang/Basic/Module.h create mode 100644 clang/include/clang/Basic/OnDiskHashTable.h create mode 100644 clang/include/clang/Basic/OpenCL.h create mode 100644 clang/include/clang/Basic/OpenCLExtensions.def create mode 100644 clang/include/clang/Basic/OperatorKinds.def create mode 100644 clang/include/clang/Basic/OperatorKinds.h create mode 100644 clang/include/clang/Basic/PartialDiagnostic.h create mode 100644 clang/include/clang/Basic/PrettyStackTrace.h create mode 100644 clang/include/clang/Basic/SourceLocation.h create mode 100644 clang/include/clang/Basic/SourceManager.h create mode 100644 clang/include/clang/Basic/SourceManagerInternals.h create mode 100644 clang/include/clang/Basic/Specifiers.h create mode 100644 clang/include/clang/Basic/StmtNodes.td create mode 100644 clang/include/clang/Basic/TargetBuiltins.h create mode 100644 clang/include/clang/Basic/TargetInfo.h create mode 100644 clang/include/clang/Basic/TargetOptions.h create mode 100644 clang/include/clang/Basic/TemplateKinds.h create mode 100644 clang/include/clang/Basic/TokenKinds.def create mode 100644 clang/include/clang/Basic/TokenKinds.h create mode 100644 clang/include/clang/Basic/TypeTraits.h create mode 100644 clang/include/clang/Basic/Version.h create mode 100644 clang/include/clang/Basic/Version.inc.in create mode 100644 clang/include/clang/Basic/VersionTuple.h create mode 100644 clang/include/clang/Basic/Visibility.h create mode 100644 clang/include/clang/Basic/arm_neon.td create mode 100644 clang/include/clang/CMakeLists.txt create mode 100644 clang/include/clang/CodeGen/BackendUtil.h create mode 100644 clang/include/clang/CodeGen/CodeGenAction.h create mode 100644 clang/include/clang/CodeGen/ModuleBuilder.h create mode 100644 clang/include/clang/Config/config.h.cmake create mode 100644 clang/include/clang/Config/config.h.in create mode 100644 clang/include/clang/Driver/Action.h create mode 100644 clang/include/clang/Driver/Arg.h create mode 100644 clang/include/clang/Driver/ArgList.h create mode 100644 clang/include/clang/Driver/CC1AsOptions.h create mode 100644 clang/include/clang/Driver/CC1AsOptions.td create mode 100644 clang/include/clang/Driver/CC1Options.h create mode 100644 clang/include/clang/Driver/CC1Options.td create mode 100644 clang/include/clang/Driver/CMakeLists.txt create mode 100644 clang/include/clang/Driver/Compilation.h create mode 100644 clang/include/clang/Driver/Driver.h create mode 100644 clang/include/clang/Driver/DriverDiagnostic.h create mode 100644 clang/include/clang/Driver/Job.h create mode 100644 clang/include/clang/Driver/Makefile create mode 100644 clang/include/clang/Driver/ObjCRuntime.h create mode 100644 clang/include/clang/Driver/OptParser.td create mode 100644 clang/include/clang/Driver/OptSpecifier.h create mode 100644 clang/include/clang/Driver/OptTable.h create mode 100644 clang/include/clang/Driver/Option.h create mode 100644 clang/include/clang/Driver/Options.h create mode 100644 clang/include/clang/Driver/Options.td create mode 100644 clang/include/clang/Driver/Phases.h create mode 100644 clang/include/clang/Driver/Tool.h create mode 100644 clang/include/clang/Driver/ToolChain.h create mode 100644 clang/include/clang/Driver/Types.def create mode 100644 clang/include/clang/Driver/Types.h create mode 100644 clang/include/clang/Driver/Util.h create mode 100644 clang/include/clang/Edit/Commit.h create mode 100644 clang/include/clang/Edit/EditedSource.h create mode 100644 clang/include/clang/Edit/EditsReceiver.h create mode 100644 clang/include/clang/Edit/FileOffset.h create mode 100644 clang/include/clang/Edit/Rewriters.h create mode 100644 clang/include/clang/Frontend/ASTConsumers.h create mode 100644 clang/include/clang/Frontend/ASTUnit.h create mode 100644 clang/include/clang/Frontend/Analyses.def create mode 100644 clang/include/clang/Frontend/AnalyzerOptions.h create mode 100644 clang/include/clang/Frontend/ChainedDiagnosticConsumer.h create mode 100644 clang/include/clang/Frontend/ChainedIncludesSource.h create mode 100644 clang/include/clang/Frontend/CodeGenOptions.h create mode 100644 clang/include/clang/Frontend/CommandLineSourceLoc.h create mode 100644 clang/include/clang/Frontend/CompilerInstance.h create mode 100644 clang/include/clang/Frontend/CompilerInvocation.h create mode 100644 clang/include/clang/Frontend/DependencyOutputOptions.h create mode 100644 clang/include/clang/Frontend/DiagnosticOptions.h create mode 100644 clang/include/clang/Frontend/DiagnosticRenderer.h create mode 100644 clang/include/clang/Frontend/FrontendAction.h create mode 100644 clang/include/clang/Frontend/FrontendActions.h create mode 100644 clang/include/clang/Frontend/FrontendDiagnostic.h create mode 100644 clang/include/clang/Frontend/FrontendOptions.h create mode 100644 clang/include/clang/Frontend/FrontendPluginRegistry.h create mode 100644 clang/include/clang/Frontend/HeaderSearchOptions.h create mode 100644 clang/include/clang/Frontend/LangStandard.h create mode 100644 clang/include/clang/Frontend/LangStandards.def create mode 100644 clang/include/clang/Frontend/LayoutOverrideSource.h create mode 100644 clang/include/clang/Frontend/LogDiagnosticPrinter.h create mode 100644 clang/include/clang/Frontend/MigratorOptions.h create mode 100644 clang/include/clang/Frontend/MultiplexConsumer.h create mode 100644 clang/include/clang/Frontend/PreprocessorOptions.h create mode 100644 clang/include/clang/Frontend/PreprocessorOutputOptions.h create mode 100644 clang/include/clang/Frontend/SerializedDiagnosticPrinter.h create mode 100644 clang/include/clang/Frontend/TextDiagnostic.h create mode 100644 clang/include/clang/Frontend/TextDiagnosticBuffer.h create mode 100644 clang/include/clang/Frontend/TextDiagnosticPrinter.h create mode 100644 clang/include/clang/Frontend/Utils.h create mode 100644 clang/include/clang/Frontend/VerifyDiagnosticConsumer.h create mode 100644 clang/include/clang/FrontendTool/Utils.h create mode 100644 clang/include/clang/Lex/CMakeLists.txt create mode 100644 clang/include/clang/Lex/CodeCompletionHandler.h create mode 100644 clang/include/clang/Lex/DirectoryLookup.h create mode 100644 clang/include/clang/Lex/ExternalPreprocessorSource.h create mode 100644 clang/include/clang/Lex/HeaderMap.h create mode 100644 clang/include/clang/Lex/HeaderSearch.h create mode 100644 clang/include/clang/Lex/LexDiagnostic.h create mode 100644 clang/include/clang/Lex/Lexer.h create mode 100644 clang/include/clang/Lex/LiteralSupport.h create mode 100644 clang/include/clang/Lex/MacroInfo.h create mode 100644 clang/include/clang/Lex/Makefile create mode 100644 clang/include/clang/Lex/ModuleLoader.h create mode 100644 clang/include/clang/Lex/ModuleMap.h create mode 100644 clang/include/clang/Lex/MultipleIncludeOpt.h create mode 100644 clang/include/clang/Lex/PPCallbacks.h create mode 100644 clang/include/clang/Lex/PTHLexer.h create mode 100644 clang/include/clang/Lex/PTHManager.h create mode 100644 clang/include/clang/Lex/Pragma.h create mode 100644 clang/include/clang/Lex/PreprocessingRecord.h create mode 100644 clang/include/clang/Lex/Preprocessor.h create mode 100644 clang/include/clang/Lex/PreprocessorLexer.h create mode 100644 clang/include/clang/Lex/ScratchBuffer.h create mode 100644 clang/include/clang/Lex/Token.h create mode 100644 clang/include/clang/Lex/TokenConcatenation.h create mode 100644 clang/include/clang/Lex/TokenLexer.h create mode 100644 clang/include/clang/Makefile create mode 100644 clang/include/clang/Parse/CMakeLists.txt create mode 100644 clang/include/clang/Parse/Makefile create mode 100644 clang/include/clang/Parse/ParseAST.h create mode 100644 clang/include/clang/Parse/ParseDiagnostic.h create mode 100644 clang/include/clang/Parse/Parser.h create mode 100644 clang/include/clang/Rewrite/ASTConsumers.h create mode 100644 clang/include/clang/Rewrite/DeltaTree.h create mode 100644 clang/include/clang/Rewrite/FixItRewriter.h create mode 100644 clang/include/clang/Rewrite/FrontendActions.h create mode 100644 clang/include/clang/Rewrite/HTMLRewrite.h create mode 100644 clang/include/clang/Rewrite/RewriteRope.h create mode 100644 clang/include/clang/Rewrite/Rewriter.h create mode 100644 clang/include/clang/Rewrite/Rewriters.h create mode 100644 clang/include/clang/Rewrite/TokenRewriter.h create mode 100644 clang/include/clang/Sema/AnalysisBasedWarnings.h create mode 100644 clang/include/clang/Sema/AttributeList.h create mode 100644 clang/include/clang/Sema/CMakeLists.txt create mode 100644 clang/include/clang/Sema/CXXFieldCollector.h create mode 100644 clang/include/clang/Sema/CodeCompleteConsumer.h create mode 100644 clang/include/clang/Sema/DeclSpec.h create mode 100644 clang/include/clang/Sema/DelayedDiagnostic.h create mode 100644 clang/include/clang/Sema/Designator.h create mode 100644 clang/include/clang/Sema/ExternalSemaSource.h create mode 100644 clang/include/clang/Sema/IdentifierResolver.h create mode 100644 clang/include/clang/Sema/Initialization.h create mode 100644 clang/include/clang/Sema/LocInfoType.h create mode 100644 clang/include/clang/Sema/Lookup.h create mode 100644 clang/include/clang/Sema/Makefile create mode 100644 clang/include/clang/Sema/ObjCMethodList.h create mode 100644 clang/include/clang/Sema/Overload.h create mode 100644 clang/include/clang/Sema/Ownership.h create mode 100644 clang/include/clang/Sema/ParsedTemplate.h create mode 100644 clang/include/clang/Sema/PrettyDeclStackTrace.h create mode 100644 clang/include/clang/Sema/Scope.h create mode 100644 clang/include/clang/Sema/ScopeInfo.h create mode 100644 clang/include/clang/Sema/Sema.h create mode 100644 clang/include/clang/Sema/SemaConsumer.h create mode 100644 clang/include/clang/Sema/SemaDiagnostic.h create mode 100644 clang/include/clang/Sema/SemaFixItUtils.h create mode 100644 clang/include/clang/Sema/SemaInternal.h create mode 100644 clang/include/clang/Sema/Template.h create mode 100644 clang/include/clang/Sema/TemplateDeduction.h create mode 100644 clang/include/clang/Sema/TypoCorrection.h create mode 100644 clang/include/clang/Sema/Weak.h create mode 100644 clang/include/clang/Serialization/ASTBitCodes.h create mode 100644 clang/include/clang/Serialization/ASTDeserializationListener.h create mode 100644 clang/include/clang/Serialization/ASTReader.h create mode 100644 clang/include/clang/Serialization/ASTWriter.h create mode 100644 clang/include/clang/Serialization/CMakeLists.txt create mode 100644 clang/include/clang/Serialization/ContinuousRangeMap.h create mode 100644 clang/include/clang/Serialization/Makefile create mode 100644 clang/include/clang/Serialization/Module.h create mode 100644 clang/include/clang/Serialization/ModuleManager.h create mode 100644 clang/include/clang/Serialization/SerializationDiagnostic.h create mode 100644 clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td create mode 100644 clang/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h create mode 100644 clang/include/clang/StaticAnalyzer/Checkers/CommonBugCategories.h create mode 100644 clang/include/clang/StaticAnalyzer/Checkers/DereferenceChecker.h create mode 100644 clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/Checker.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/CheckerManager.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h create mode 120000 clang/include/clang/StaticAnalyzer/Core/PathSensitive/.#CheckerContext_flymake.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h create mode 100644 clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h create mode 100644 clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h create mode 100644 clang/include/clang/Tooling/CompilationDatabase.h create mode 100644 clang/include/clang/Tooling/Tooling.h (limited to 'clang/include') diff --git a/clang/include/CMakeLists.txt b/clang/include/CMakeLists.txt new file mode 100644 index 0000000..253a09b --- /dev/null +++ b/clang/include/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(clang) diff --git a/clang/include/Makefile b/clang/include/Makefile new file mode 100644 index 0000000..79b9adf --- /dev/null +++ b/clang/include/Makefile @@ -0,0 +1,4 @@ +CLANG_LEVEL := .. +DIRS := clang clang-c + +include $(CLANG_LEVEL)/Makefile diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h new file mode 100644 index 0000000..13ba6ba --- /dev/null +++ b/clang/include/clang-c/Index.h @@ -0,0 +1,4748 @@ +/*===-- 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 +#include +#include + +#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 + +#ifdef __GNUC__ + #define CINDEX_DEPRECATED __attribute__((deprecated)) +#else + #ifdef _MSC_VER + #define CINDEX_DEPRECATED __declspec(deprecated) + #else + #define CINDEX_DEPRECATED + #endif +#endif + +/** \defgroup CINDEX libclang: 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 struct CXTranslationUnitImpl *CXTranslationUnit; + +/** + * \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; +}; + +/** + * \brief Describes the availability of a particular entity, which indicates + * whether the use of this entity will result in a warning or error due to + * it being deprecated or unavailable. + */ +enum CXAvailabilityKind { + /** + * \brief The entity is available. + */ + CXAvailability_Available, + /** + * \brief The entity is available, but has been deprecated (and its use is + * not recommended). + */ + CXAvailability_Deprecated, + /** + * \brief The entity is not available; any use of it will be an error. + */ + CXAvailability_NotAvailable, + /** + * \brief The entity is available, but not accessible; any use of it will be + * an error. + */ + CXAvailability_NotAccessible +}; + +/** + * \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 { + void *data; + unsigned private_flags; +} 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); + +typedef enum { + /** + * \brief Used to indicate that no special CXIndex options are needed. + */ + CXGlobalOpt_None = 0x0, + + /** + * \brief Used to indicate that threads that libclang creates for indexing + * purposes should use background priority. + * Affects \see clang_indexSourceFile, \see clang_indexTranslationUnit, + * \see clang_parseTranslationUnit, \see clang_saveTranslationUnit. + */ + CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 0x1, + + /** + * \brief Used to indicate that threads that libclang creates for editing + * purposes should use background priority. + * Affects \see clang_reparseTranslationUnit, \see clang_codeCompleteAt, + * \see clang_annotateTokens + */ + CXGlobalOpt_ThreadBackgroundPriorityForEditing = 0x2, + + /** + * \brief Used to indicate that all threads that libclang creates should use + * background priority. + */ + CXGlobalOpt_ThreadBackgroundPriorityForAll = + CXGlobalOpt_ThreadBackgroundPriorityForIndexing | + CXGlobalOpt_ThreadBackgroundPriorityForEditing + +} CXGlobalOptFlags; + +/** + * \brief Sets general options associated with a CXIndex. + * + * For example: + * \code + * CXIndex idx = ...; + * clang_CXIndex_setGlobalOptions(idx, + * clang_CXIndex_getGlobalOptions(idx) | + * CXGlobalOpt_ThreadBackgroundPriorityForIndexing); + * \endcode + * + * \param options A bitmask of options, a bitwise OR of CXGlobalOpt_XXX flags. + */ +CINDEX_LINKAGE void clang_CXIndex_setGlobalOptions(CXIndex, unsigned options); + +/** + * \brief Gets the general options associated with a CXIndex. + * + * \returns A bitmask of options, a bitwise OR of CXGlobalOpt_XXX flags that + * are associated with the given CXIndex object. + */ +CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex); + +/** + * \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 Determine whether the given header is guarded against + * multiple inclusions, either with the conventional + * #ifndef/#define/#endif macro guards or with #pragma once. + */ +CINDEX_LINKAGE unsigned +clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file); + +/** + * \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_getExpansionLocation() or clang_getSpellingLocation() + * 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 Retrieves the source location associated with a given character offset + * in a particular translation unit. + */ +CINDEX_LINKAGE CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, + CXFile file, + unsigned offset); + +/** + * \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 Determine whether two ranges are equivalent. + * + * \returns non-zero if the ranges are the same, zero if they differ. + */ +CINDEX_LINKAGE unsigned clang_equalRanges(CXSourceRange range1, + CXSourceRange range2); + +/** + * \brief Returns non-zero if \arg range is null. + */ +CINDEX_LINKAGE int clang_Range_isNull(CXSourceRange range); + +/** + * \brief Retrieve the file, line, column, and offset represented by + * the given source location. + * + * If the location refers into a macro expansion, retrieves the + * location of the macro expansion. + * + * \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_getExpansionLocation(CXSourceLocation location, + CXFile *file, + unsigned *line, + unsigned *column, + unsigned *offset); + +/** + * \brief Retrieve the file, line, column, and offset represented by + * the given source location, as specified in a # line directive. + * + * Example: given the following source code in a file somefile.c + * + * #123 "dummy.c" 1 + * + * static int func(void) + * { + * return 0; + * } + * + * the location information returned by this function would be + * + * File: dummy.c Line: 124 Column: 12 + * + * whereas clang_getExpansionLocation would have returned + * + * File: somefile.c Line: 3 Column: 12 + * + * \param location the location within a source file that will be decomposed + * into its parts. + * + * \param filename [out] if non-NULL, will be set to the filename of the + * source location. Note that filenames returned will be for "virtual" files, + * which don't necessarily exist on the machine running clang - e.g. when + * parsing preprocessed output obtained from a different environment. If + * a non-NULL value is passed in, remember to dispose of the returned value + * using \c clang_disposeString() once you've finished with it. For an invalid + * source location, an empty string is returned. + * + * \param line [out] if non-NULL, will be set to the line number of the + * source location. For an invalid source location, zero is returned. + * + * \param column [out] if non-NULL, will be set to the column number of the + * source location. For an invalid source location, zero is returned. + */ +CINDEX_LINKAGE void clang_getPresumedLocation(CXSourceLocation location, + CXString *filename, + unsigned *line, + unsigned *column); + +/** + * \brief Legacy API to retrieve the file, line, column, and offset represented + * by the given source location. + * + * This interface has been replaced by the newer interface + * \see clang_getExpansionLocation(). See that interface's documentation for + * details. + */ +CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location, + CXFile *file, + unsigned *line, + unsigned *column, + unsigned *offset); + +/** + * \brief Retrieve the file, line, column, and offset represented by + * the given source location. + * + * If the location refers into a macro instantiation, return where the + * location was originally spelled in the source file. + * + * \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_getSpellingLocation(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); + +/** + * @} + */ + +/** + * \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 A group of CXDiagnostics. + */ +typedef void *CXDiagnosticSet; + +/** + * \brief Determine the number of diagnostics in a CXDiagnosticSet. + */ +CINDEX_LINKAGE unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags); + +/** + * \brief Retrieve a diagnostic associated with the given CXDiagnosticSet. + * + * \param Unit the CXDiagnosticSet 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_getDiagnosticInSet(CXDiagnosticSet Diags, + unsigned Index); + + +/** + * \brief Describes the kind of error that occurred (if any) in a call to + * \c clang_loadDiagnostics. + */ +enum CXLoadDiag_Error { + /** + * \brief Indicates that no error occurred. + */ + CXLoadDiag_None = 0, + + /** + * \brief Indicates that an unknown error occurred while attempting to + * deserialize diagnostics. + */ + CXLoadDiag_Unknown = 1, + + /** + * \brief Indicates that the file containing the serialized diagnostics + * could not be opened. + */ + CXLoadDiag_CannotLoad = 2, + + /** + * \brief Indicates that the serialized diagnostics file is invalid or + * corrupt. + */ + CXLoadDiag_InvalidFile = 3 +}; + +/** + * \brief Deserialize a set of diagnostics from a Clang diagnostics bitcode + * file. + * + * \param The name of the file to deserialize. + * \param A pointer to a enum value recording if there was a problem + * deserializing the diagnostics. + * \param A pointer to a CXString for recording the error string + * if the file was not successfully loaded. + * + * \returns A loaded CXDiagnosticSet if successful, and NULL otherwise. These + * diagnostics should be released using clang_disposeDiagnosticSet(). + */ +CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics(const char *file, + enum CXLoadDiag_Error *error, + CXString *errorString); + +/** + * \brief Release a CXDiagnosticSet and all of its contained diagnostics. + */ +CINDEX_LINKAGE void clang_disposeDiagnosticSet(CXDiagnosticSet Diags); + +/** + * \brief Retrieve the child diagnostics of a CXDiagnostic. This + * CXDiagnosticSet does not need to be released by clang_diposeDiagnosticSet. + */ +CINDEX_LINKAGE CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D); + +/** + * \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 Retrieve the complete set of diagnostics associated with a + * translation unit. + * + * \param Unit the translation unit to query. + */ +CINDEX_LINKAGE CXDiagnosticSet + clang_getDiagnosticSetFromTU(CXTranslationUnit Unit); + +/** + * \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 Display the option name associated with this diagnostic, if any. + * + * The option name displayed (e.g., -Wconversion) will be placed in brackets + * after the diagnostic text. This option corresponds to the clang flag + * \c -fdiagnostics-show-option. + */ + CXDiagnostic_DisplayOption = 0x08, + + /** + * \brief Display the category number associated with this diagnostic, if any. + * + * The category number is displayed within brackets after the diagnostic text. + * This option corresponds to the clang flag + * \c -fdiagnostics-show-category=id. + */ + CXDiagnostic_DisplayCategoryId = 0x10, + + /** + * \brief Display the category name associated with this diagnostic, if any. + * + * The category name is displayed within brackets after the diagnostic text. + * This option corresponds to the clang flag + * \c -fdiagnostics-show-category=name. + */ + CXDiagnostic_DisplayCategoryName = 0x20 +}; + +/** + * \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 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 Retrieve the name of the command-line option that enabled this + * diagnostic. + * + * \param Diag The diagnostic to be queried. + * + * \param Disable If non-NULL, will be set to the option that disables this + * diagnostic (if any). + * + * \returns A string that contains the command-line option used to enable this + * warning, such as "-Wconversion" or "-pedantic". + */ +CINDEX_LINKAGE CXString clang_getDiagnosticOption(CXDiagnostic Diag, + CXString *Disable); + +/** + * \brief Retrieve the category number for this diagnostic. + * + * Diagnostics can be categorized into groups along with other, related + * diagnostics (e.g., diagnostics under the same warning flag). This routine + * retrieves the category number for the given diagnostic. + * + * \returns The number of the category that contains this diagnostic, or zero + * if this diagnostic is uncategorized. + */ +CINDEX_LINKAGE unsigned clang_getDiagnosticCategory(CXDiagnostic); + +/** + * \brief Retrieve the name of a particular diagnostic category. This + * is now deprecated. Use clang_getDiagnosticCategoryText() + * instead. + * + * \param Category A diagnostic category number, as returned by + * \c clang_getDiagnosticCategory(). + * + * \returns The name of the given diagnostic category. + */ +CINDEX_DEPRECATED CINDEX_LINKAGE +CXString clang_getDiagnosticCategoryName(unsigned Category); + +/** + * \brief Retrieve the diagnostic category text for a given diagnostic. + * + * + * \returns The text of the given diagnostic category. + */ +CINDEX_LINKAGE CXString clang_getDiagnosticCategoryText(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 ' (both '-o' and '' are ignored) + * + * \param CIdx The index object with which the translation unit will be + * associated. + * + * \param source_filename - The name of the source file to load, or NULL if the + * source file is included in \p clang_command_line_args. + * + * \param num_clang_command_line_args The number of command-line arguments in + * \p clang_command_line_args. + * + * \param clang_command_line_args The command-line arguments that would be + * passed to the \c clang executable if it were being invoked out-of-process. + * These command-line options will be parsed and will affect how the translation + * unit is parsed. Note that the following options are ignored: '-c', + * '-emit-ast', '-fsyntex-only' (which is the default), and '-o '. + * + * \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. + */ +CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile( + CXIndex CIdx, + const char *source_filename, + int num_clang_command_line_args, + const char * const *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 Flags that control the creation of translation units. + * + * The enumerators in this enumeration type are meant to be bitwise + * ORed together to specify which options should be used when + * constructing the translation unit. + */ +enum CXTranslationUnit_Flags { + /** + * \brief Used to indicate that no special translation-unit options are + * needed. + */ + CXTranslationUnit_None = 0x0, + + /** + * \brief Used to indicate that the parser should construct a "detailed" + * preprocessing record, including all macro definitions and instantiations. + * + * Constructing a detailed preprocessing record requires more memory + * and time to parse, since the information contained in the record + * is usually not retained. However, it can be useful for + * applications that require more detailed information about the + * behavior of the preprocessor. + */ + CXTranslationUnit_DetailedPreprocessingRecord = 0x01, + + /** + * \brief Used to indicate that the translation unit is incomplete. + * + * When a translation unit is considered "incomplete", semantic + * analysis that is typically performed at the end of the + * translation unit will be suppressed. For example, this suppresses + * the completion of tentative declarations in C and of + * instantiation of implicitly-instantiation function templates in + * C++. This option is typically used when parsing a header with the + * intent of producing a precompiled header. + */ + CXTranslationUnit_Incomplete = 0x02, + + /** + * \brief Used to indicate that the translation unit should be built with an + * implicit precompiled header for the preamble. + * + * An implicit precompiled header is used as an optimization when a + * particular translation unit is likely to be reparsed many times + * when the sources aren't changing that often. In this case, an + * implicit precompiled header will be built containing all of the + * initial includes at the top of the main file (what we refer to as + * the "preamble" of the file). In subsequent parses, if the + * preamble or the files in it have not changed, \c + * clang_reparseTranslationUnit() will re-use the implicit + * precompiled header to improve parsing performance. + */ + CXTranslationUnit_PrecompiledPreamble = 0x04, + + /** + * \brief Used to indicate that the translation unit should cache some + * code-completion results with each reparse of the source file. + * + * Caching of code-completion results is a performance optimization that + * introduces some overhead to reparsing but improves the performance of + * code-completion operations. + */ + CXTranslationUnit_CacheCompletionResults = 0x08, + /** + * \brief DEPRECATED: Enable precompiled preambles in C++. + * + * Note: this is a *temporary* option that is available only while + * we are testing C++ precompiled preamble support. It is deprecated. + */ + CXTranslationUnit_CXXPrecompiledPreamble = 0x10, + + /** + * \brief DEPRECATED: Enabled chained precompiled preambles in C++. + * + * Note: this is a *temporary* option that is available only while + * we are testing C++ precompiled preamble support. It is deprecated. + */ + CXTranslationUnit_CXXChainedPCH = 0x20, + + /** + * \brief Used to indicate that function/method bodies should be skipped while + * parsing. + * + * This option can be used to search for declarations/definitions while + * ignoring the usages. + */ + CXTranslationUnit_SkipFunctionBodies = 0x40 +}; + +/** + * \brief Returns the set of flags that is suitable for parsing a translation + * unit that is being edited. + * + * The set of flags returned provide options for \c clang_parseTranslationUnit() + * to indicate that the translation unit is likely to be reparsed many times, + * either explicitly (via \c clang_reparseTranslationUnit()) or implicitly + * (e.g., by code completion (\c clang_codeCompletionAt())). The returned flag + * set contains an unspecified set of optimizations (e.g., the precompiled + * preamble) geared toward improving the performance of these routines. The + * set of optimizations enabled may change from one version to the next. + */ +CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void); + +/** + * \brief Parse the given source file and the translation unit corresponding + * to that file. + * + * This routine is the main entry point for the Clang C API, providing the + * ability to parse a source file into a translation unit that can then be + * queried by other functions in the API. This routine accepts a set of + * command-line arguments so that the compilation can be configured in the same + * way that the compiler is configured on the command line. + * + * \param CIdx The index object with which the translation unit will be + * associated. + * + * \param source_filename The name of the source file to load, or NULL if the + * source file is included in \p command_line_args. + * + * \param command_line_args The command-line arguments that would be + * passed to the \c clang executable if it were being invoked out-of-process. + * These command-line options will be parsed and will affect how the translation + * unit is parsed. Note that the following options are ignored: '-c', + * '-emit-ast', '-fsyntex-only' (which is the default), and '-o '. + * + * \param num_command_line_args The number of command-line arguments in + * \p command_line_args. + * + * \param unsaved_files the files that have not yet been saved to disk + * but may be required for parsing, 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 num_unsaved_files the number of unsaved file entries in \p + * unsaved_files. + * + * \param options A bitmask of options that affects how the translation unit + * is managed but not its compilation. This should be a bitwise OR of the + * CXTranslationUnit_XXX flags. + * + * \returns A new translation unit describing the parsed code and containing + * any diagnostics produced by the compiler. If there is a failure from which + * the compiler cannot recover, returns NULL. + */ +CINDEX_LINKAGE CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, + const char *source_filename, + const char * const *command_line_args, + int num_command_line_args, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, + unsigned options); + +/** + * \brief Flags that control how translation units are saved. + * + * The enumerators in this enumeration type are meant to be bitwise + * ORed together to specify which options should be used when + * saving the translation unit. + */ +enum CXSaveTranslationUnit_Flags { + /** + * \brief Used to indicate that no special saving options are needed. + */ + CXSaveTranslationUnit_None = 0x0 +}; + +/** + * \brief Returns the set of flags that is suitable for saving a translation + * unit. + * + * The set of flags returned provide options for + * \c clang_saveTranslationUnit() by default. The returned flag + * set contains an unspecified set of options that save translation units with + * the most commonly-requested data. + */ +CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU); + +/** + * \brief Describes the kind of error that occurred (if any) in a call to + * \c clang_saveTranslationUnit(). + */ +enum CXSaveError { + /** + * \brief Indicates that no error occurred while saving a translation unit. + */ + CXSaveError_None = 0, + + /** + * \brief Indicates that an unknown error occurred while attempting to save + * the file. + * + * This error typically indicates that file I/O failed when attempting to + * write the file. + */ + CXSaveError_Unknown = 1, + + /** + * \brief Indicates that errors during translation prevented this attempt + * to save the translation unit. + * + * Errors that prevent the translation unit from being saved can be + * extracted using \c clang_getNumDiagnostics() and \c clang_getDiagnostic(). + */ + CXSaveError_TranslationErrors = 2, + + /** + * \brief Indicates that the translation unit to be saved was somehow + * invalid (e.g., NULL). + */ + CXSaveError_InvalidTU = 3 +}; + +/** + * \brief Saves a translation unit into a serialized representation of + * that translation unit on disk. + * + * Any translation unit that was parsed without error can be saved + * into a file. The translation unit can then be deserialized into a + * new \c CXTranslationUnit with \c clang_createTranslationUnit() or, + * if it is an incomplete translation unit that corresponds to a + * header, used as a precompiled header when parsing other translation + * units. + * + * \param TU The translation unit to save. + * + * \param FileName The file to which the translation unit will be saved. + * + * \param options A bitmask of options that affects how the translation unit + * is saved. This should be a bitwise OR of the + * CXSaveTranslationUnit_XXX flags. + * + * \returns A value that will match one of the enumerators of the CXSaveError + * enumeration. Zero (CXSaveError_None) indicates that the translation unit was + * saved successfully, while a non-zero value indicates that a problem occurred. + */ +CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU, + const char *FileName, + unsigned options); + +/** + * \brief Destroy the specified CXTranslationUnit object. + */ +CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit); + +/** + * \brief Flags that control the reparsing of translation units. + * + * The enumerators in this enumeration type are meant to be bitwise + * ORed together to specify which options should be used when + * reparsing the translation unit. + */ +enum CXReparse_Flags { + /** + * \brief Used to indicate that no special reparsing options are needed. + */ + CXReparse_None = 0x0 +}; + +/** + * \brief Returns the set of flags that is suitable for reparsing a translation + * unit. + * + * The set of flags returned provide options for + * \c clang_reparseTranslationUnit() by default. The returned flag + * set contains an unspecified set of optimizations geared toward common uses + * of reparsing. The set of optimizations enabled may change from one version + * to the next. + */ +CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU); + +/** + * \brief Reparse the source files that produced this translation unit. + * + * This routine can be used to re-parse the source files that originally + * created the given translation unit, for example because those source files + * have changed (either on disk or as passed via \p unsaved_files). The + * source code will be reparsed with the same command-line options as it + * was originally parsed. + * + * Reparsing a translation unit invalidates all cursors and source locations + * that refer into that translation unit. This makes reparsing a translation + * unit semantically equivalent to destroying the translation unit and then + * creating a new translation unit with the same command-line arguments. + * However, it may be more efficient to reparse a translation + * unit using this routine. + * + * \param TU The translation unit whose contents will be re-parsed. The + * translation unit must originally have been built with + * \c clang_createTranslationUnitFromSourceFile(). + * + * \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 parsing, 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 options A bitset of options composed of the flags in CXReparse_Flags. + * The function \c clang_defaultReparseOptions() produces a default set of + * options recommended for most uses, based on the translation unit. + * + * \returns 0 if the sources could be reparsed. A non-zero value will be + * returned if reparsing was impossible, such that the translation unit is + * invalid. In such cases, the only valid call for \p TU is + * \c clang_disposeTranslationUnit(TU). + */ +CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU, + unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files, + unsigned options); + +/** + * \brief Categorizes how memory is being used by a translation unit. + */ +enum CXTUResourceUsageKind { + CXTUResourceUsage_AST = 1, + CXTUResourceUsage_Identifiers = 2, + CXTUResourceUsage_Selectors = 3, + CXTUResourceUsage_GlobalCompletionResults = 4, + CXTUResourceUsage_SourceManagerContentCache = 5, + CXTUResourceUsage_AST_SideTables = 6, + CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7, + CXTUResourceUsage_SourceManager_Membuffer_MMap = 8, + CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9, + CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10, + CXTUResourceUsage_Preprocessor = 11, + CXTUResourceUsage_PreprocessingRecord = 12, + CXTUResourceUsage_SourceManager_DataStructures = 13, + CXTUResourceUsage_Preprocessor_HeaderSearch = 14, + CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST, + CXTUResourceUsage_MEMORY_IN_BYTES_END = + CXTUResourceUsage_Preprocessor_HeaderSearch, + + CXTUResourceUsage_First = CXTUResourceUsage_AST, + CXTUResourceUsage_Last = CXTUResourceUsage_Preprocessor_HeaderSearch +}; + +/** + * \brief Returns the human-readable null-terminated C string that represents + * the name of the memory category. This string should never be freed. + */ +CINDEX_LINKAGE +const char *clang_getTUResourceUsageName(enum CXTUResourceUsageKind kind); + +typedef struct CXTUResourceUsageEntry { + /* \brief The memory usage category. */ + enum CXTUResourceUsageKind kind; + /* \brief Amount of resources used. + The units will depend on the resource kind. */ + unsigned long amount; +} CXTUResourceUsageEntry; + +/** + * \brief The memory usage of a CXTranslationUnit, broken into categories. + */ +typedef struct CXTUResourceUsage { + /* \brief Private data member, used for queries. */ + void *data; + + /* \brief The number of entries in the 'entries' array. */ + unsigned numEntries; + + /* \brief An array of key-value pairs, representing the breakdown of memory + usage. */ + CXTUResourceUsageEntry *entries; + +} CXTUResourceUsage; + +/** + * \brief Return the memory usage of a translation unit. This object + * should be released with clang_disposeCXTUResourceUsage(). + */ +CINDEX_LINKAGE CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU); + +CINDEX_LINKAGE void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage); + +/** + * @} + */ + +/** + * \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, + /** \brief A C++ constructor. */ + CXCursor_Constructor = 24, + /** \brief A C++ destructor. */ + CXCursor_Destructor = 25, + /** \brief A C++ conversion function. */ + CXCursor_ConversionFunction = 26, + /** \brief A C++ template type parameter. */ + CXCursor_TemplateTypeParameter = 27, + /** \brief A C++ non-type template parameter. */ + CXCursor_NonTypeTemplateParameter = 28, + /** \brief A C++ template template parameter. */ + CXCursor_TemplateTemplateParameter = 29, + /** \brief A C++ function template. */ + CXCursor_FunctionTemplate = 30, + /** \brief A C++ class template. */ + CXCursor_ClassTemplate = 31, + /** \brief A C++ class template partial specialization. */ + CXCursor_ClassTemplatePartialSpecialization = 32, + /** \brief A C++ namespace alias declaration. */ + CXCursor_NamespaceAlias = 33, + /** \brief A C++ using directive. */ + CXCursor_UsingDirective = 34, + /** \brief A C++ using declaration. */ + CXCursor_UsingDeclaration = 35, + /** \brief A C++ alias declaration */ + CXCursor_TypeAliasDecl = 36, + /** \brief An Objective-C @synthesize definition. */ + CXCursor_ObjCSynthesizeDecl = 37, + /** \brief An Objective-C @dynamic definition. */ + CXCursor_ObjCDynamicDecl = 38, + /** \brief An access specifier. */ + CXCursor_CXXAccessSpecifier = 39, + + CXCursor_FirstDecl = CXCursor_UnexposedDecl, + CXCursor_LastDecl = CXCursor_CXXAccessSpecifier, + + /* 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_CXXBaseSpecifier = 44, + /** + * \brief A reference to a class template, function template, template + * template parameter, or class template partial specialization. + */ + CXCursor_TemplateRef = 45, + /** + * \brief A reference to a namespace or namespace alias. + */ + CXCursor_NamespaceRef = 46, + /** + * \brief A reference to a member of a struct, union, or class that occurs in + * some non-expression context, e.g., a designated initializer. + */ + CXCursor_MemberRef = 47, + /** + * \brief A reference to a labeled statement. + * + * This cursor kind is used to describe the jump to "start_over" in the + * goto statement in the following example: + * + * \code + * start_over: + * ++counter; + * + * goto start_over; + * \endcode + * + * A label reference cursor refers to a label statement. + */ + CXCursor_LabelRef = 48, + + /** + * \brief A reference to a set of overloaded functions or function templates + * that has not yet been resolved to a specific function or function template. + * + * An overloaded declaration reference cursor occurs in C++ templates where + * a dependent name refers to a function. For example: + * + * \code + * template void swap(T&, T&); + * + * struct X { ... }; + * void swap(X&, X&); + * + * template + * void reverse(T* first, T* last) { + * while (first < last - 1) { + * swap(*first, *--last); + * ++first; + * } + * } + * + * struct Y { }; + * void swap(Y&, Y&); + * \endcode + * + * Here, the identifier "swap" is associated with an overloaded declaration + * reference. In the template definition, "swap" refers to either of the two + * "swap" functions declared above, so both results will be available. At + * instantiation time, "swap" may also refer to other functions found via + * argument-dependent lookup (e.g., the "swap" function at the end of the + * example). + * + * The functions \c clang_getNumOverloadedDecls() and + * \c clang_getOverloadedDecl() can be used to retrieve the definitions + * referenced by this cursor. + */ + CXCursor_OverloadedDeclRef = 49, + + /** + * \brief A reference to a variable that occurs in some non-expression + * context, e.g., a C++ lambda capture list. + */ + CXCursor_VariableRef = 50, + + CXCursor_LastRef = CXCursor_VariableRef, + + /* 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, + + /** \brief An integer literal. + */ + CXCursor_IntegerLiteral = 106, + + /** \brief A floating point number literal. + */ + CXCursor_FloatingLiteral = 107, + + /** \brief An imaginary number literal. + */ + CXCursor_ImaginaryLiteral = 108, + + /** \brief A string literal. + */ + CXCursor_StringLiteral = 109, + + /** \brief A character literal. + */ + CXCursor_CharacterLiteral = 110, + + /** \brief A parenthesized expression, e.g. "(1)". + * + * This AST node is only formed if full location information is requested. + */ + CXCursor_ParenExpr = 111, + + /** \brief This represents the unary-expression's (except sizeof and + * alignof). + */ + CXCursor_UnaryOperator = 112, + + /** \brief [C99 6.5.2.1] Array Subscripting. + */ + CXCursor_ArraySubscriptExpr = 113, + + /** \brief A builtin binary operation expression such as "x + y" or + * "x <= y". + */ + CXCursor_BinaryOperator = 114, + + /** \brief Compound assignment such as "+=". + */ + CXCursor_CompoundAssignOperator = 115, + + /** \brief The ?: ternary operator. + */ + CXCursor_ConditionalOperator = 116, + + /** \brief 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: (int)f. + */ + CXCursor_CStyleCastExpr = 117, + + /** \brief [C99 6.5.2.5] + */ + CXCursor_CompoundLiteralExpr = 118, + + /** \brief Describes an C or C++ initializer list. + */ + CXCursor_InitListExpr = 119, + + /** \brief The GNU address of label extension, representing &&label. + */ + CXCursor_AddrLabelExpr = 120, + + /** \brief This is the GNU Statement Expression extension: ({int X=4; X;}) + */ + CXCursor_StmtExpr = 121, + + /** \brief Represents a C11 generic selection. + */ + CXCursor_GenericSelectionExpr = 122, + + /** \brief 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). + */ + CXCursor_GNUNullExpr = 123, + + /** \brief C++'s static_cast<> expression. + */ + CXCursor_CXXStaticCastExpr = 124, + + /** \brief C++'s dynamic_cast<> expression. + */ + CXCursor_CXXDynamicCastExpr = 125, + + /** \brief C++'s reinterpret_cast<> expression. + */ + CXCursor_CXXReinterpretCastExpr = 126, + + /** \brief C++'s const_cast<> expression. + */ + CXCursor_CXXConstCastExpr = 127, + + /** \brief Represents an explicit C++ type conversion that uses "functional" + * notion (C++ [expr.type.conv]). + * + * Example: + * \code + * x = int(0.5); + * \endcode + */ + CXCursor_CXXFunctionalCastExpr = 128, + + /** \brief A C++ typeid expression (C++ [expr.typeid]). + */ + CXCursor_CXXTypeidExpr = 129, + + /** \brief [C++ 2.13.5] C++ Boolean Literal. + */ + CXCursor_CXXBoolLiteralExpr = 130, + + /** \brief [C++0x 2.14.7] C++ Pointer Literal. + */ + CXCursor_CXXNullPtrLiteralExpr = 131, + + /** \brief Represents the "this" expression in C++ + */ + CXCursor_CXXThisExpr = 132, + + /** \brief [C++ 15] C++ Throw Expression. + * + * This handles 'throw' and 'throw' assignment-expression. When + * assignment-expression isn't present, Op will be null. + */ + CXCursor_CXXThrowExpr = 133, + + /** \brief A new expression for memory allocation and constructor calls, e.g: + * "new CXXNewExpr(foo)". + */ + CXCursor_CXXNewExpr = 134, + + /** \brief A delete expression for memory deallocation and destructor calls, + * e.g. "delete[] pArray". + */ + CXCursor_CXXDeleteExpr = 135, + + /** \brief A unary expression. + */ + CXCursor_UnaryExpr = 136, + + /** \brief An Objective-C string literal i.e. @"foo". + */ + CXCursor_ObjCStringLiteral = 137, + + /** \brief An Objective-C @encode expression. + */ + CXCursor_ObjCEncodeExpr = 138, + + /** \brief An Objective-C @selector expression. + */ + CXCursor_ObjCSelectorExpr = 139, + + /** \brief An Objective-C @protocol expression. + */ + CXCursor_ObjCProtocolExpr = 140, + + /** \brief An Objective-C "bridged" cast expression, which casts between + * Objective-C pointers and C pointers, transferring ownership in the process. + * + * \code + * NSString *str = (__bridge_transfer NSString *)CFCreateString(); + * \endcode + */ + CXCursor_ObjCBridgedCastExpr = 141, + + /** \brief Represents a C++0x pack expansion that produces a sequence of + * expressions. + * + * A pack expansion expression contains a pattern (which itself is an + * expression) followed by an ellipsis. For example: + * + * \code + * template + * void forward(F f, Types &&...args) { + * f(static_cast(args)...); + * } + * \endcode + */ + CXCursor_PackExpansionExpr = 142, + + /** \brief Represents an expression that computes the length of a parameter + * pack. + * + * \code + * template + * struct count { + * static const unsigned value = sizeof...(Types); + * }; + * \endcode + */ + CXCursor_SizeOfPackExpr = 143, + + /* \brief Represents a C++ lambda expression that produces a local function + * object. + * + * \code + * void abssort(float *x, unsigned N) { + * std::sort(x, x + N, + * [](float a, float b) { + * return std::abs(a) < std::abs(b); + * }); + * } + * \endcode + */ + CXCursor_LambdaExpr = 144, + + /** \brief Objective-c Boolean Literal. + */ + CXCursor_ObjCBoolLiteralExpr = 145, + + CXCursor_LastExpr = CXCursor_ObjCBoolLiteralExpr, + + /* 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, + + /** \brief A labelled statement in a function. + * + * This cursor kind is used to describe the "start_over:" label statement in + * the following example: + * + * \code + * start_over: + * ++counter; + * \endcode + * + */ + CXCursor_LabelStmt = 201, + + /** \brief A group of statements like { stmt stmt }. + * + * This cursor kind is used to describe compound statements, e.g. function + * bodies. + */ + CXCursor_CompoundStmt = 202, + + /** \brief A case statment. + */ + CXCursor_CaseStmt = 203, + + /** \brief A default statement. + */ + CXCursor_DefaultStmt = 204, + + /** \brief An if statement + */ + CXCursor_IfStmt = 205, + + /** \brief A switch statement. + */ + CXCursor_SwitchStmt = 206, + + /** \brief A while statement. + */ + CXCursor_WhileStmt = 207, + + /** \brief A do statement. + */ + CXCursor_DoStmt = 208, + + /** \brief A for statement. + */ + CXCursor_ForStmt = 209, + + /** \brief A goto statement. + */ + CXCursor_GotoStmt = 210, + + /** \brief An indirect goto statement. + */ + CXCursor_IndirectGotoStmt = 211, + + /** \brief A continue statement. + */ + CXCursor_ContinueStmt = 212, + + /** \brief A break statement. + */ + CXCursor_BreakStmt = 213, + + /** \brief A return statement. + */ + CXCursor_ReturnStmt = 214, + + /** \brief A GNU inline assembly statement extension. + */ + CXCursor_AsmStmt = 215, + + /** \brief Objective-C's overall @try-@catch-@finally statement. + */ + CXCursor_ObjCAtTryStmt = 216, + + /** \brief Objective-C's @catch statement. + */ + CXCursor_ObjCAtCatchStmt = 217, + + /** \brief Objective-C's @finally statement. + */ + CXCursor_ObjCAtFinallyStmt = 218, + + /** \brief Objective-C's @throw statement. + */ + CXCursor_ObjCAtThrowStmt = 219, + + /** \brief Objective-C's @synchronized statement. + */ + CXCursor_ObjCAtSynchronizedStmt = 220, + + /** \brief Objective-C's autorelease pool statement. + */ + CXCursor_ObjCAutoreleasePoolStmt = 221, + + /** \brief Objective-C's collection statement. + */ + CXCursor_ObjCForCollectionStmt = 222, + + /** \brief C++'s catch statement. + */ + CXCursor_CXXCatchStmt = 223, + + /** \brief C++'s try statement. + */ + CXCursor_CXXTryStmt = 224, + + /** \brief C++'s for (* : *) statement. + */ + CXCursor_CXXForRangeStmt = 225, + + /** \brief Windows Structured Exception Handling's try statement. + */ + CXCursor_SEHTryStmt = 226, + + /** \brief Windows Structured Exception Handling's except statement. + */ + CXCursor_SEHExceptStmt = 227, + + /** \brief Windows Structured Exception Handling's finally statement. + */ + CXCursor_SEHFinallyStmt = 228, + + /** \brief The null satement ";": C99 6.8.3p3. + * + * This cursor kind is used to describe the null statement. + */ + CXCursor_NullStmt = 230, + + /** \brief Adaptor class for mixing declarations with statements and + * expressions. + */ + CXCursor_DeclStmt = 231, + + CXCursor_LastStmt = CXCursor_DeclStmt, + + /** + * \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_CXXFinalAttr = 404, + CXCursor_CXXOverrideAttr = 405, + CXCursor_AnnotateAttr = 406, + CXCursor_AsmLabelAttr = 407, + CXCursor_LastAttr = CXCursor_AsmLabelAttr, + + /* Preprocessing */ + CXCursor_PreprocessingDirective = 500, + CXCursor_MacroDefinition = 501, + CXCursor_MacroExpansion = 502, + CXCursor_MacroInstantiation = CXCursor_MacroExpansion, + CXCursor_InclusionDirective = 503, + CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective, + CXCursor_LastPreprocessing = CXCursor_InclusionDirective +}; + +/** + * \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; + int xdata; + 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 Returns non-zero if \arg cursor is null. + */ +CINDEX_LINKAGE int clang_Cursor_isNull(CXCursor); + +/** + * \brief Compute a hash value for the given cursor. + */ +CINDEX_LINKAGE unsigned clang_hashCursor(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 attribute. + */ +CINDEX_LINKAGE unsigned clang_isAttribute(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 Determine the availability of the entity that this cursor refers to. + * + * \param cursor The cursor to query. + * + * \returns The availability of the cursor. + */ +CINDEX_LINKAGE enum CXAvailabilityKind +clang_getCursorAvailability(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); + +/** + * \brief Returns the translation unit that a cursor originated from. + */ +CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor); + + +/** + * \brief A fast container representing a set of CXCursors. + */ +typedef struct CXCursorSetImpl *CXCursorSet; + +/** + * \brief Creates an empty CXCursorSet. + */ +CINDEX_LINKAGE CXCursorSet clang_createCXCursorSet(); + +/** + * \brief Disposes a CXCursorSet and releases its associated memory. + */ +CINDEX_LINKAGE void clang_disposeCXCursorSet(CXCursorSet cset); + +/** + * \brief Queries a CXCursorSet to see if it contains a specific CXCursor. + * + * \returns non-zero if the set contains the specified cursor. +*/ +CINDEX_LINKAGE unsigned clang_CXCursorSet_contains(CXCursorSet cset, + CXCursor cursor); + +/** + * \brief Inserts a CXCursor into a CXCursorSet. + * + * \returns zero if the CXCursor was already in the set, and non-zero otherwise. +*/ +CINDEX_LINKAGE unsigned clang_CXCursorSet_insert(CXCursorSet cset, + CXCursor cursor); + +/** + * \brief Determine the semantic parent of the given cursor. + * + * The semantic parent of a cursor is the cursor that semantically contains + * the given \p cursor. For many declarations, the lexical and semantic parents + * are equivalent (the lexical parent is returned by + * \c clang_getCursorLexicalParent()). They diverge when declarations or + * definitions are provided out-of-line. For example: + * + * \code + * class C { + * void f(); + * }; + * + * void C::f() { } + * \endcode + * + * In the out-of-line definition of \c C::f, the semantic parent is the + * the class \c C, of which this function is a member. The lexical parent is + * the place where the declaration actually occurs in the source code; in this + * case, the definition occurs in the translation unit. In general, the + * lexical parent for a given entity can change without affecting the semantics + * of the program, and the lexical parent of different declarations of the + * same entity may be different. Changing the semantic parent of a declaration, + * on the other hand, can have a major impact on semantics, and redeclarations + * of a particular entity should all have the same semantic context. + * + * In the example above, both declarations of \c C::f have \c C as their + * semantic context, while the lexical context of the first \c C::f is \c C + * and the lexical context of the second \c C::f is the translation unit. + * + * For global declarations, the semantic parent is the translation unit. + */ +CINDEX_LINKAGE CXCursor clang_getCursorSemanticParent(CXCursor cursor); + +/** + * \brief Determine the lexical parent of the given cursor. + * + * The lexical parent of a cursor is the cursor in which the given \p cursor + * was actually written. For many declarations, the lexical and semantic parents + * are equivalent (the semantic parent is returned by + * \c clang_getCursorSemanticParent()). They diverge when declarations or + * definitions are provided out-of-line. For example: + * + * \code + * class C { + * void f(); + * }; + * + * void C::f() { } + * \endcode + * + * In the out-of-line definition of \c C::f, the semantic parent is the + * the class \c C, of which this function is a member. The lexical parent is + * the place where the declaration actually occurs in the source code; in this + * case, the definition occurs in the translation unit. In general, the + * lexical parent for a given entity can change without affecting the semantics + * of the program, and the lexical parent of different declarations of the + * same entity may be different. Changing the semantic parent of a declaration, + * on the other hand, can have a major impact on semantics, and redeclarations + * of a particular entity should all have the same semantic context. + * + * In the example above, both declarations of \c C::f have \c C as their + * semantic context, while the lexical context of the first \c C::f is \c C + * and the lexical context of the second \c C::f is the translation unit. + * + * For declarations written in the global scope, the lexical parent is + * the translation unit. + */ +CINDEX_LINKAGE CXCursor clang_getCursorLexicalParent(CXCursor cursor); + +/** + * \brief Determine the set of methods that are overridden by the given + * method. + * + * In both Objective-C and C++, a method (aka virtual member function, + * in C++) can override a virtual method in a base class. For + * Objective-C, a method is said to override any method in the class's + * base class, its protocols, or its categories' protocols, that has the same + * selector and is of the same kind (class or instance). + * If no such method exists, the search continues to the class's superclass, + * its protocols, and its categories, and so on. A method from an Objective-C + * implementation is considered to override the same methods as its + * corresponding method in the interface. + * + * For C++, a virtual member function overrides any virtual member + * function with the same signature that occurs in its base + * classes. With multiple inheritance, a virtual member function can + * override several virtual member functions coming from different + * base classes. + * + * In all cases, this function determines the immediate overridden + * method, rather than all of the overridden methods. For example, if + * a method is originally declared in a class A, then overridden in B + * (which in inherits from A) and also in C (which inherited from B), + * then the only overridden method returned from this function when + * invoked on C's method will be B's method. The client may then + * invoke this function again, given the previously-found overridden + * methods, to map out the complete method-override set. + * + * \param cursor A cursor representing an Objective-C or C++ + * method. This routine will compute the set of methods that this + * method overrides. + * + * \param overridden A pointer whose pointee will be replaced with a + * pointer to an array of cursors, representing the set of overridden + * methods. If there are no overridden methods, the pointee will be + * set to NULL. The pointee must be freed via a call to + * \c clang_disposeOverriddenCursors(). + * + * \param num_overridden A pointer to the number of overridden + * functions, will be set to the number of overridden functions in the + * array pointed to by \p overridden. + */ +CINDEX_LINKAGE void clang_getOverriddenCursors(CXCursor cursor, + CXCursor **overridden, + unsigned *num_overridden); + +/** + * \brief Free the set of overridden cursors returned by \c + * clang_getOverriddenCursors(). + */ +CINDEX_LINKAGE void clang_disposeOverriddenCursors(CXCursor *overridden); + +/** + * \brief Retrieve the file that is included by the given inclusion directive + * cursor. + */ +CINDEX_LINKAGE CXFile clang_getIncludedFile(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, + CXType_FunctionNoProto = 110, + CXType_FunctionProto = 111, + CXType_ConstantArray = 112, + CXType_Vector = 113 +}; + +/** + * \brief Describes the calling convention of a function type + */ +enum CXCallingConv { + CXCallingConv_Default = 0, + CXCallingConv_C = 1, + CXCallingConv_X86StdCall = 2, + CXCallingConv_X86FastCall = 3, + CXCallingConv_X86ThisCall = 4, + CXCallingConv_X86Pascal = 5, + CXCallingConv_AAPCS = 6, + CXCallingConv_AAPCS_VFP = 7, + + CXCallingConv_Invalid = 100, + CXCallingConv_Unexposed = 200 +}; + + +/** + * \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); + +/** + * \brief Retrieve the underlying type of a typedef declaration. + * + * If the cursor does not reference a typedef declaration, an invalid type is + * returned. + */ +CINDEX_LINKAGE CXType clang_getTypedefDeclUnderlyingType(CXCursor C); + +/** + * \brief Retrieve the integer type of an enum declaration. + * + * If the cursor does not reference an enum declaration, an invalid type is + * returned. + */ +CINDEX_LINKAGE CXType clang_getEnumDeclIntegerType(CXCursor C); + +/** + * \brief Retrieve the integer value of an enum constant declaration as a signed + * long long. + * + * If the cursor does not reference an enum constant declaration, LLONG_MIN is returned. + * Since this is also potentially a valid constant value, the kind of the cursor + * must be verified before calling this function. + */ +CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C); + +/** + * \brief Retrieve the integer value of an enum constant declaration as an unsigned + * long long. + * + * If the cursor does not reference an enum constant declaration, ULLONG_MAX is returned. + * Since this is also potentially a valid constant value, the kind of the cursor + * must be verified before calling this function. + */ +CINDEX_LINKAGE unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C); + +/** + * \brief Retrieve the number of non-variadic arguments associated with a given + * cursor. + * + * If a cursor that is not a function or method is passed in, -1 is returned. + */ +CINDEX_LINKAGE int clang_Cursor_getNumArguments(CXCursor C); + +/** + * \brief Retrieve the argument cursor of a function or method. + * + * If a cursor that is not a function or method is passed in or the index + * exceeds the number of arguments, an invalid cursor is returned. + */ +CINDEX_LINKAGE CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i); + +/** + * \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); + +/** + * \determine Determine whether a CXType has the "const" qualifier set, + * without looking through typedefs that may have added "const" at a different level. + */ +CINDEX_LINKAGE unsigned clang_isConstQualifiedType(CXType T); + +/** + * \determine Determine whether a CXType has the "volatile" qualifier set, + * without looking through typedefs that may have added "volatile" at a different level. + */ +CINDEX_LINKAGE unsigned clang_isVolatileQualifiedType(CXType T); + +/** + * \determine Determine whether a CXType has the "restrict" qualifier set, + * without looking through typedefs that may have added "restrict" at a different level. + */ +CINDEX_LINKAGE unsigned clang_isRestrictQualifiedType(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); + +/** + * Returns the Objective-C type encoding for the specified declaration. + */ +CINDEX_LINKAGE CXString clang_getDeclObjCTypeEncoding(CXCursor C); + +/** + * \brief Retrieve the spelling of a given CXTypeKind. + */ +CINDEX_LINKAGE CXString clang_getTypeKindSpelling(enum CXTypeKind K); + +/** + * \brief Retrieve the calling convention associated with a function type. + * + * If a non-function type is passed in, CXCallingConv_Invalid is returned. + */ +CINDEX_LINKAGE enum CXCallingConv clang_getFunctionTypeCallingConv(CXType T); + +/** + * \brief Retrieve the result type associated with a function type. + * + * If a non-function type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_getResultType(CXType T); + +/** + * \brief Retrieve the number of non-variadic arguments associated with a function type. + * + * If a non-function type is passed in, -1 is returned. + */ +CINDEX_LINKAGE int clang_getNumArgTypes(CXType T); + +/** + * \brief Retrieve the type of an argument of a function type. + * + * If a non-function type is passed in or the function does not have enough parameters, + * an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_getArgType(CXType T, unsigned i); + +/** + * \brief Return 1 if the CXType is a variadic function type, and 0 otherwise. + * + */ +CINDEX_LINKAGE unsigned clang_isFunctionTypeVariadic(CXType T); + +/** + * \brief Retrieve the result type associated with a given cursor. + * + * This only returns a valid type if the cursor refers to a function or method. + */ +CINDEX_LINKAGE CXType clang_getCursorResultType(CXCursor C); + +/** + * \brief Return 1 if the CXType is a POD (plain old data) type, and 0 + * otherwise. + */ +CINDEX_LINKAGE unsigned clang_isPODType(CXType T); + +/** + * \brief Return the element type of an array, complex, or vector type. + * + * If a type is passed in that is not an array, complex, or vector type, + * an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_getElementType(CXType T); + +/** + * \brief Return the number of elements of an array or vector type. + * + * If a type is passed in that is not an array or vector type, + * -1 is returned. + */ +CINDEX_LINKAGE long long clang_getNumElements(CXType T); + +/** + * \brief Return the element type of an array type. + * + * If a non-array type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_getArrayElementType(CXType T); + +/** + * \brief Return the the array size of a constant array. + * + * If a non-array type is passed in, -1 is returned. + */ +CINDEX_LINKAGE long long clang_getArraySize(CXType T); + +/** + * \brief Returns 1 if the base class specified by the cursor with kind + * CX_CXXBaseSpecifier is virtual. + */ +CINDEX_LINKAGE unsigned clang_isVirtualBase(CXCursor); + +/** + * \brief Represents the C++ access control level to a base class for a + * cursor with kind CX_CXXBaseSpecifier. + */ +enum CX_CXXAccessSpecifier { + CX_CXXInvalidAccessSpecifier, + CX_CXXPublic, + CX_CXXProtected, + CX_CXXPrivate +}; + +/** + * \brief Returns the access control level for the C++ base specifier + * represented by a cursor with kind CXCursor_CXXBaseSpecifier or + * CXCursor_AccessSpecifier. + */ +CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor); + +/** + * \brief Determine the number of overloaded declarations referenced by a + * \c CXCursor_OverloadedDeclRef cursor. + * + * \param cursor The cursor whose overloaded declarations are being queried. + * + * \returns The number of overloaded declarations referenced by \c cursor. If it + * is not a \c CXCursor_OverloadedDeclRef cursor, returns 0. + */ +CINDEX_LINKAGE unsigned clang_getNumOverloadedDecls(CXCursor cursor); + +/** + * \brief Retrieve a cursor for one of the overloaded declarations referenced + * by a \c CXCursor_OverloadedDeclRef cursor. + * + * \param cursor The cursor whose overloaded declarations are being queried. + * + * \param index The zero-based index into the set of overloaded declarations in + * the cursor. + * + * \returns A cursor representing the declaration referenced by the given + * \c cursor at the specified \c index. If the cursor does not have an + * associated set of overloaded declarations, or if the index is out of bounds, + * returns \c clang_getNullCursor(); + */ +CINDEX_LINKAGE CXCursor clang_getOverloadedDecl(CXCursor cursor, + unsigned index); + +/** + * @} + */ + +/** + * \defgroup CINDEX_ATTRIBUTES Information for attributes + * + * @{ + */ + + +/** + * \brief For cursors representing an iboutletcollection attribute, + * this function returns the collection element type. + * + */ +CINDEX_LINKAGE CXType clang_getIBOutletCollectionType(CXCursor); + +/** + * @} + */ + +/** + * \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); +#ifdef __has_feature +# if __has_feature(blocks) +/** + * \brief Visitor invoked for each cursor found by a traversal. + * + * This visitor block will be invoked for each cursor found by + * clang_visitChildrenWithBlock(). Its first argument is the cursor being + * visited, its second argument is the parent visitor for that cursor. + * + * The visitor should return one of the \c CXChildVisitResult values + * to direct clang_visitChildrenWithBlock(). + */ +typedef enum CXChildVisitResult + (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); + +/** + * Visits the children of a cursor using the specified block. Behaves + * identically to clang_visitChildren() in all other respects. + */ +unsigned clang_visitChildrenWithBlock(CXCursor parent, + CXCursorVisitorBlock block); +# endif +#endif + +/** + * @} + */ + +/** + * \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 Retrieve a range for a piece that forms the cursors spelling name. + * Most of the times there is only one range for the complete spelling but for + * objc methods and objc message expressions, there are multiple pieces for each + * selector identifier. + * + * \param pieceIndex the index of the spelling name piece. If this is greater + * than the actual number of pieces, it will return a NULL (invalid) range. + * + * \param options Reserved. + */ +CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor, + unsigned pieceIndex, + unsigned options); + +/** + * \brief Retrieve the display name for the entity referenced by this cursor. + * + * The display name contains extra information that helps identify the cursor, + * such as the parameters of a function or template or the arguments of a + * class template specialization. + */ +CINDEX_LINKAGE CXString clang_getCursorDisplayName(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); + +/** + * \brief Retrieve the canonical cursor corresponding to the given cursor. + * + * In the C family of languages, many kinds of entities can be declared several + * times within a single translation unit. For example, a structure type can + * be forward-declared (possibly multiple times) and later defined: + * + * \code + * struct X; + * struct X; + * struct X { + * int member; + * }; + * \endcode + * + * The declarations and the definition of \c X are represented by three + * different cursors, all of which are declarations of the same underlying + * entity. One of these cursor is considered the "canonical" cursor, which + * is effectively the representative for the underlying entity. One can + * determine if two cursors are declarations of the same underlying entity by + * comparing their canonical cursors. + * + * \returns The canonical cursor for the entity referred to by the given cursor. + */ +CINDEX_LINKAGE CXCursor clang_getCanonicalCursor(CXCursor); + + +/** + * \brief If the cursor points to a selector identifier in a objc method or + * message expression, this returns the selector index. + * + * After getting a cursor with \see clang_getCursor, this can be called to + * determine if the location points to a selector identifier. + * + * \returns The selector index if the cursor is an objc method or message + * expression and the cursor is pointing to a selector identifier, or -1 + * otherwise. + */ +CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(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 or member function template is + * declared 'static'. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C); + +/** + * \brief Determine if a C++ member function or member function template is + * explicitly declared 'virtual' or if it overrides a virtual method from + * one of the base classes. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C); + +/** + * \brief Given a cursor that represents a template, determine + * the cursor kind of the specializations would be generated by instantiating + * the template. + * + * This routine can be used to determine what flavor of function template, + * class template, or class template partial specialization is stored in the + * cursor. For example, it can describe whether a class template cursor is + * declared with "struct", "class" or "union". + * + * \param C The cursor to query. This cursor should represent a template + * declaration. + * + * \returns The cursor kind of the specializations that would be generated + * by instantiating the template \p C. If \p C is not a template, returns + * \c CXCursor_NoDeclFound. + */ +CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C); + +/** + * \brief Given a cursor that may represent a specialization or instantiation + * of a template, retrieve the cursor that represents the template that it + * specializes or from which it was instantiated. + * + * This routine determines the template involved both for explicit + * specializations of templates and for implicit instantiations of the template, + * both of which are referred to as "specializations". For a class template + * specialization (e.g., \c std::vector), this routine will return + * either the primary template (\c std::vector) or, if the specialization was + * instantiated from a class template partial specialization, the class template + * partial specialization. For a class template partial specialization and a + * function template specialization (including instantiations), this + * this routine will return the specialized template. + * + * For members of a class template (e.g., member functions, member classes, or + * static data members), returns the specialized or instantiated member. + * Although not strictly "templates" in the C++ language, members of class + * templates have the same notions of specializations and instantiations that + * templates do, so this routine treats them similarly. + * + * \param C A cursor that may be a specialization of a template or a member + * of a template. + * + * \returns If the given cursor is a specialization or instantiation of a + * template or a member thereof, the template or member that it specializes or + * from which it was instantiated. Otherwise, returns a NULL cursor. + */ +CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C); + +/** + * \brief Given a cursor that references something else, return the source range + * covering that reference. + * + * \param C A cursor pointing to a member reference, a declaration reference, or + * an operator call. + * \param NameFlags A bitset with three independent flags: + * CXNameRange_WantQualifier, CXNameRange_WantTemplateArgs, and + * CXNameRange_WantSinglePiece. + * \param PieceIndex For contiguous names or when passing the flag + * CXNameRange_WantSinglePiece, only one piece with index 0 is + * available. When the CXNameRange_WantSinglePiece flag is not passed for a + * non-contiguous names, this index can be used to retreive the individual + * pieces of the name. See also CXNameRange_WantSinglePiece. + * + * \returns The piece of the name pointed to by the given cursor. If there is no + * name, or if the PieceIndex is out-of-range, a null-cursor will be returned. + */ +CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, + unsigned NameFlags, + unsigned PieceIndex); + +enum CXNameRefFlags { + /** + * \brief Include the nested-name-specifier, e.g. Foo:: in x.Foo::y, in the + * range. + */ + CXNameRange_WantQualifier = 0x1, + + /** + * \brief Include the explicit template arguments, e.g. in x.f, in + * the range. + */ + CXNameRange_WantTemplateArgs = 0x2, + + /** + * \brief If the name is non-contiguous, return the full spanning range. + * + * Non-contiguous names occur in Objective-C when a selector with two or more + * parameters is used, or in C++ when using an operator: + * \code + * [object doSomething:here withValue:there]; // ObjC + * return some_vector[1]; // C++ + * \endcode + */ + CXNameRange_WantSinglePiece = 0x4 +}; + +/** + * @} + */ + +/** + * \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); +CINDEX_LINKAGE void clang_executeOnThread(void (*fn)(void*), void *user_data, + unsigned stack_size); + +/** + * @} + */ + +/** + * \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. + */ +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 Determine the availability of the entity that this code-completion + * string refers to. + * + * \param completion_string The completion string to query. + * + * \returns The availability of the completion string. + */ +CINDEX_LINKAGE enum CXAvailabilityKind +clang_getCompletionAvailability(CXCompletionString completion_string); + +/** + * \brief Retrieve the number of annotations associated with the given + * completion string. + * + * \param completion_string the completion string to query. + * + * \returns the number of annotations associated with the given completion + * string. + */ +CINDEX_LINKAGE unsigned +clang_getCompletionNumAnnotations(CXCompletionString completion_string); + +/** + * \brief Retrieve the annotation associated with the given completion string. + * + * \param completion_string the completion string to query. + * + * \param annotation_number the 0-based index of the annotation of the + * completion string. + * + * \returns annotation string associated with the completion at index + * \c annotation_number, or a NULL string if that annotation is not available. + */ +CINDEX_LINKAGE CXString +clang_getCompletionAnnotation(CXCompletionString completion_string, + unsigned annotation_number); + +/** + * \brief Retrieve the parent context of the given completion string. + * + * The parent context of a completion string is the semantic parent of + * the declaration (if any) that the code completion represents. For example, + * a code completion for an Objective-C method would have the method's class + * or protocol as its context. + * + * \param completion_string The code completion string whose parent is + * being queried. + * + * \param kind If non-NULL, will be set to the kind of the parent context, + * or CXCursor_NotImplemented if there is no context. + * + * \param Returns the name of the completion parent, e.g., "NSObject" if + * the completion string represents a method in the NSObject class. + */ +CINDEX_LINKAGE CXString +clang_getCompletionParent(CXCompletionString completion_string, + enum CXCursorKind *kind); +/** + * \brief Retrieve a completion string for an arbitrary declaration or macro + * definition cursor. + * + * \param cursor The cursor to query. + * + * \returns A non-context-sensitive completion string for declaration and macro + * definition cursors, or NULL for other kinds of cursors. + */ +CINDEX_LINKAGE CXCompletionString +clang_getCursorCompletionString(CXCursor cursor); + +/** + * \brief Contains the results of code-completion. + * + * This data structure contains the results of code completion, as + * produced by \c clang_codeCompleteAt(). 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 Flags that can be passed to \c clang_codeCompleteAt() to + * modify its behavior. + * + * The enumerators in this enumeration can be bitwise-OR'd together to + * provide multiple options to \c clang_codeCompleteAt(). + */ +enum CXCodeComplete_Flags { + /** + * \brief Whether to include macros within the set of code + * completions returned. + */ + CXCodeComplete_IncludeMacros = 0x01, + + /** + * \brief Whether to include code patterns for language constructs + * within the set of code completions, e.g., for loops. + */ + CXCodeComplete_IncludeCodePatterns = 0x02 +}; + +/** + * \brief Bits that represent the context under which completion is occurring. + * + * The enumerators in this enumeration may be bitwise-OR'd together if multiple + * contexts are occurring simultaneously. + */ +enum CXCompletionContext { + /** + * \brief The context for completions is unexposed, as only Clang results + * should be included. (This is equivalent to having no context bits set.) + */ + CXCompletionContext_Unexposed = 0, + + /** + * \brief Completions for any possible type should be included in the results. + */ + CXCompletionContext_AnyType = 1 << 0, + + /** + * \brief Completions for any possible value (variables, function calls, etc.) + * should be included in the results. + */ + CXCompletionContext_AnyValue = 1 << 1, + /** + * \brief Completions for values that resolve to an Objective-C object should + * be included in the results. + */ + CXCompletionContext_ObjCObjectValue = 1 << 2, + /** + * \brief Completions for values that resolve to an Objective-C selector + * should be included in the results. + */ + CXCompletionContext_ObjCSelectorValue = 1 << 3, + /** + * \brief Completions for values that resolve to a C++ class type should be + * included in the results. + */ + CXCompletionContext_CXXClassTypeValue = 1 << 4, + + /** + * \brief Completions for fields of the member being accessed using the dot + * operator should be included in the results. + */ + CXCompletionContext_DotMemberAccess = 1 << 5, + /** + * \brief Completions for fields of the member being accessed using the arrow + * operator should be included in the results. + */ + CXCompletionContext_ArrowMemberAccess = 1 << 6, + /** + * \brief Completions for properties of the Objective-C object being accessed + * using the dot operator should be included in the results. + */ + CXCompletionContext_ObjCPropertyAccess = 1 << 7, + + /** + * \brief Completions for enum tags should be included in the results. + */ + CXCompletionContext_EnumTag = 1 << 8, + /** + * \brief Completions for union tags should be included in the results. + */ + CXCompletionContext_UnionTag = 1 << 9, + /** + * \brief Completions for struct tags should be included in the results. + */ + CXCompletionContext_StructTag = 1 << 10, + + /** + * \brief Completions for C++ class names should be included in the results. + */ + CXCompletionContext_ClassTag = 1 << 11, + /** + * \brief Completions for C++ namespaces and namespace aliases should be + * included in the results. + */ + CXCompletionContext_Namespace = 1 << 12, + /** + * \brief Completions for C++ nested name specifiers should be included in + * the results. + */ + CXCompletionContext_NestedNameSpecifier = 1 << 13, + + /** + * \brief Completions for Objective-C interfaces (classes) should be included + * in the results. + */ + CXCompletionContext_ObjCInterface = 1 << 14, + /** + * \brief Completions for Objective-C protocols should be included in + * the results. + */ + CXCompletionContext_ObjCProtocol = 1 << 15, + /** + * \brief Completions for Objective-C categories should be included in + * the results. + */ + CXCompletionContext_ObjCCategory = 1 << 16, + /** + * \brief Completions for Objective-C instance messages should be included + * in the results. + */ + CXCompletionContext_ObjCInstanceMessage = 1 << 17, + /** + * \brief Completions for Objective-C class messages should be included in + * the results. + */ + CXCompletionContext_ObjCClassMessage = 1 << 18, + /** + * \brief Completions for Objective-C selector names should be included in + * the results. + */ + CXCompletionContext_ObjCSelectorName = 1 << 19, + + /** + * \brief Completions for preprocessor macro names should be included in + * the results. + */ + CXCompletionContext_MacroName = 1 << 20, + + /** + * \brief Natural language completions should be included in the results. + */ + CXCompletionContext_NaturalLanguage = 1 << 21, + + /** + * \brief The current context is unknown, so set all contexts. + */ + CXCompletionContext_Unknown = ((1 << 22) - 1) +}; + +/** + * \brief Returns a default set of code-completion options that can be + * passed to\c clang_codeCompleteAt(). + */ +CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void); + +/** + * \brief Perform code completion at a given location in a translation unit. + * + * 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 TU The translation unit in which code-completion should + * occur. The source files for this translation unit need not be + * completely up-to-date (and the contents of those source files may + * be overridden via \p unsaved_files). Cursors referring into the + * translation unit may be invalidated by this invocation. + * + * \param complete_filename The name of the source file where code + * completion should be performed. This filename may be any file + * included in the translation unit. + * + * \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 unsaved_files the Tiles that have not yet been saved to disk + * but may be required for parsing or 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 num_unsaved_files The number of unsaved file entries in \p + * unsaved_files. + * + * \param options Extra options that control the behavior of code + * completion, expressed as a bitwise OR of the enumerators of the + * CXCodeComplete_Flags enumeration. The + * \c clang_defaultCodeCompleteOptions() function returns a default set + * of code-completion options. + * + * \returns If successful, a new \c 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_codeCompleteAt(CXTranslationUnit TU, + const char *complete_filename, + unsigned complete_line, + unsigned complete_column, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, + unsigned options); + +/** + * \brief Sort the code-completion results in case-insensitive alphabetical + * order. + * + * \param Results The set of results to sort. + * \param NumResults The number of results in \p Results. + */ +CINDEX_LINKAGE +void clang_sortCodeCompletionResults(CXCompletionResult *Results, + unsigned NumResults); + +/** + * \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); + +/** + * \brief Determines what compeltions are appropriate for the context + * the given code completion. + * + * \param Results the code completion results to query + * + * \returns the kinds of completions that are appropriate for use + * along with the given code completion results. + */ +CINDEX_LINKAGE +unsigned long long clang_codeCompleteGetContexts( + CXCodeCompleteResults *Results); + +/** + * \brief Returns the cursor kind for the container for the current code + * completion context. The container is only guaranteed to be set for + * contexts where a container exists (i.e. member accesses or Objective-C + * message sends); if there is not a container, this function will return + * CXCursor_InvalidCode. + * + * \param Results the code completion results to query + * + * \param IsIncomplete on return, this value will be false if Clang has complete + * information about the container. If Clang does not have complete + * information, this value will be true. + * + * \returns the container kind, or CXCursor_InvalidCode if there is not a + * container + */ +CINDEX_LINKAGE +enum CXCursorKind clang_codeCompleteGetContainerKind( + CXCodeCompleteResults *Results, + unsigned *IsIncomplete); + +/** + * \brief Returns the USR for the container for the current code completion + * context. If there is not a container for the current context, this + * function will return the empty string. + * + * \param Results the code completion results to query + * + * \returns the USR for the container + */ +CINDEX_LINKAGE +CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results); + + +/** + * \brief Returns the currently-entered selector for an Objective-C message + * send, formatted like "initWithFoo:bar:". Only guaranteed to return a + * non-empty string for CXCompletionContext_ObjCInstanceMessage and + * CXCompletionContext_ObjCClassMessage. + * + * \param Results the code completion results to query + * + * \returns the selector (or partial selector) that has been entered thus far + * for an Objective-C message send. + */ +CINDEX_LINKAGE +CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results); + +/** + * @} + */ + + +/** + * \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 Enable/disable crash recovery. + * + * \param Flag to indicate if crash recovery is enabled. A non-zero value + * enables crash recovery, while 0 disables it. + */ +CINDEX_LINKAGE void clang_toggleCrashRecovery(unsigned isEnabled); + + /** + * \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); + +/** + * @} + */ + +/** \defgroup CINDEX_REMAPPING Remapping functions + * + * @{ + */ + +/** + * \brief A remapping of original source files and their translated files. + */ +typedef void *CXRemapping; + +/** + * \brief Retrieve a remapping. + * + * \param path the path that contains metadata about remappings. + * + * \returns the requested remapping. This remapping must be freed + * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred. + */ +CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path); + +/** + * \brief Retrieve a remapping. + * + * \param filePaths pointer to an array of file paths containing remapping info. + * + * \param numFiles number of file paths. + * + * \returns the requested remapping. This remapping must be freed + * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred. + */ +CINDEX_LINKAGE +CXRemapping clang_getRemappingsFromFileList(const char **filePaths, + unsigned numFiles); + +/** + * \brief Determine the number of remappings. + */ +CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping); + +/** + * \brief Get the original and the associated filename from the remapping. + * + * \param original If non-NULL, will be set to the original filename. + * + * \param transformed If non-NULL, will be set to the filename that the original + * is associated with. + */ +CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index, + CXString *original, CXString *transformed); + +/** + * \brief Dispose the remapping. + */ +CINDEX_LINKAGE void clang_remap_dispose(CXRemapping); + +/** + * @} + */ + +/** \defgroup CINDEX_HIGH Higher level API functions + * + * @{ + */ + +enum CXVisitorResult { + CXVisit_Break, + CXVisit_Continue +}; + +typedef struct { + void *context; + enum CXVisitorResult (*visit)(void *context, CXCursor, CXSourceRange); +} CXCursorAndRangeVisitor; + +/** + * \brief Find references of a declaration in a specific file. + * + * \param cursor pointing to a declaration or a reference of one. + * + * \param file to search for references. + * + * \param visitor callback that will receive pairs of CXCursor/CXSourceRange for + * each reference found. + * The CXSourceRange will point inside the file; if the reference is inside + * a macro (and not a macro argument) the CXSourceRange will be invalid. + */ +CINDEX_LINKAGE void clang_findReferencesInFile(CXCursor cursor, CXFile file, + CXCursorAndRangeVisitor visitor); + +#ifdef __has_feature +# if __has_feature(blocks) + +typedef enum CXVisitorResult + (^CXCursorAndRangeVisitorBlock)(CXCursor, CXSourceRange); + +CINDEX_LINKAGE +void clang_findReferencesInFileWithBlock(CXCursor, CXFile, + CXCursorAndRangeVisitorBlock); + +# endif +#endif + +/** + * \brief The client's data object that is associated with a CXFile. + */ +typedef void *CXIdxClientFile; + +/** + * \brief The client's data object that is associated with a semantic entity. + */ +typedef void *CXIdxClientEntity; + +/** + * \brief The client's data object that is associated with a semantic container + * of entities. + */ +typedef void *CXIdxClientContainer; + +/** + * \brief The client's data object that is associated with an AST file (PCH + * or module). + */ +typedef void *CXIdxClientASTFile; + +/** + * \brief Source location passed to index callbacks. + */ +typedef struct { + void *ptr_data[2]; + unsigned int_data; +} CXIdxLoc; + +/** + * \brief Data for \see ppIncludedFile callback. + */ +typedef struct { + /** + * \brief Location of '#' in the #include/#import directive. + */ + CXIdxLoc hashLoc; + /** + * \brief Filename as written in the #include/#import directive. + */ + const char *filename; + /** + * \brief The actual file that the #include/#import directive resolved to. + */ + CXFile file; + int isImport; + int isAngled; +} CXIdxIncludedFileInfo; + +/** + * \brief Data for \see importedASTFile callback. + */ +typedef struct { + CXFile file; + /** + * \brief Location where the file is imported. It is useful mostly for + * modules. + */ + CXIdxLoc loc; + /** + * \brief Non-zero if the AST file is a module otherwise it's a PCH. + */ + int isModule; +} CXIdxImportedASTFileInfo; + +typedef enum { + CXIdxEntity_Unexposed = 0, + CXIdxEntity_Typedef = 1, + CXIdxEntity_Function = 2, + CXIdxEntity_Variable = 3, + CXIdxEntity_Field = 4, + CXIdxEntity_EnumConstant = 5, + + CXIdxEntity_ObjCClass = 6, + CXIdxEntity_ObjCProtocol = 7, + CXIdxEntity_ObjCCategory = 8, + + CXIdxEntity_ObjCInstanceMethod = 9, + CXIdxEntity_ObjCClassMethod = 10, + CXIdxEntity_ObjCProperty = 11, + CXIdxEntity_ObjCIvar = 12, + + CXIdxEntity_Enum = 13, + CXIdxEntity_Struct = 14, + CXIdxEntity_Union = 15, + + CXIdxEntity_CXXClass = 16, + CXIdxEntity_CXXNamespace = 17, + CXIdxEntity_CXXNamespaceAlias = 18, + CXIdxEntity_CXXStaticVariable = 19, + CXIdxEntity_CXXStaticMethod = 20, + CXIdxEntity_CXXInstanceMethod = 21, + CXIdxEntity_CXXConstructor = 22, + CXIdxEntity_CXXDestructor = 23, + CXIdxEntity_CXXConversionFunction = 24, + CXIdxEntity_CXXTypeAlias = 25 + +} CXIdxEntityKind; + +typedef enum { + CXIdxEntityLang_None = 0, + CXIdxEntityLang_C = 1, + CXIdxEntityLang_ObjC = 2, + CXIdxEntityLang_CXX = 3 +} CXIdxEntityLanguage; + +/** + * \brief Extra C++ template information for an entity. This can apply to: + * CXIdxEntity_Function + * CXIdxEntity_CXXClass + * CXIdxEntity_CXXStaticMethod + * CXIdxEntity_CXXInstanceMethod + * CXIdxEntity_CXXConstructor + * CXIdxEntity_CXXConversionFunction + * CXIdxEntity_CXXTypeAlias + */ +typedef enum { + CXIdxEntity_NonTemplate = 0, + CXIdxEntity_Template = 1, + CXIdxEntity_TemplatePartialSpecialization = 2, + CXIdxEntity_TemplateSpecialization = 3 +} CXIdxEntityCXXTemplateKind; + +typedef enum { + CXIdxAttr_Unexposed = 0, + CXIdxAttr_IBAction = 1, + CXIdxAttr_IBOutlet = 2, + CXIdxAttr_IBOutletCollection = 3 +} CXIdxAttrKind; + +typedef struct { + CXIdxAttrKind kind; + CXCursor cursor; + CXIdxLoc loc; +} CXIdxAttrInfo; + +typedef struct { + CXIdxEntityKind kind; + CXIdxEntityCXXTemplateKind templateKind; + CXIdxEntityLanguage lang; + const char *name; + const char *USR; + CXCursor cursor; + const CXIdxAttrInfo *const *attributes; + unsigned numAttributes; +} CXIdxEntityInfo; + +typedef struct { + CXCursor cursor; +} CXIdxContainerInfo; + +typedef struct { + const CXIdxAttrInfo *attrInfo; + const CXIdxEntityInfo *objcClass; + CXCursor classCursor; + CXIdxLoc classLoc; +} CXIdxIBOutletCollectionAttrInfo; + +typedef struct { + const CXIdxEntityInfo *entityInfo; + CXCursor cursor; + CXIdxLoc loc; + const CXIdxContainerInfo *semanticContainer; + /** + * \brief Generally same as \see semanticContainer but can be different in + * cases like out-of-line C++ member functions. + */ + const CXIdxContainerInfo *lexicalContainer; + int isRedeclaration; + int isDefinition; + int isContainer; + const CXIdxContainerInfo *declAsContainer; + /** + * \brief Whether the declaration exists in code or was created implicitly + * by the compiler, e.g. implicit objc methods for properties. + */ + int isImplicit; + const CXIdxAttrInfo *const *attributes; + unsigned numAttributes; +} CXIdxDeclInfo; + +typedef enum { + CXIdxObjCContainer_ForwardRef = 0, + CXIdxObjCContainer_Interface = 1, + CXIdxObjCContainer_Implementation = 2 +} CXIdxObjCContainerKind; + +typedef struct { + const CXIdxDeclInfo *declInfo; + CXIdxObjCContainerKind kind; +} CXIdxObjCContainerDeclInfo; + +typedef struct { + const CXIdxEntityInfo *base; + CXCursor cursor; + CXIdxLoc loc; +} CXIdxBaseClassInfo; + +typedef struct { + const CXIdxEntityInfo *protocol; + CXCursor cursor; + CXIdxLoc loc; +} CXIdxObjCProtocolRefInfo; + +typedef struct { + const CXIdxObjCProtocolRefInfo *const *protocols; + unsigned numProtocols; +} CXIdxObjCProtocolRefListInfo; + +typedef struct { + const CXIdxObjCContainerDeclInfo *containerInfo; + const CXIdxBaseClassInfo *superInfo; + const CXIdxObjCProtocolRefListInfo *protocols; +} CXIdxObjCInterfaceDeclInfo; + +typedef struct { + const CXIdxObjCContainerDeclInfo *containerInfo; + const CXIdxEntityInfo *objcClass; + CXCursor classCursor; + CXIdxLoc classLoc; + const CXIdxObjCProtocolRefListInfo *protocols; +} CXIdxObjCCategoryDeclInfo; + +typedef struct { + const CXIdxDeclInfo *declInfo; + const CXIdxEntityInfo *getter; + const CXIdxEntityInfo *setter; +} CXIdxObjCPropertyDeclInfo; + +typedef struct { + const CXIdxDeclInfo *declInfo; + const CXIdxBaseClassInfo *const *bases; + unsigned numBases; +} CXIdxCXXClassDeclInfo; + +/** + * \brief Data for \see indexEntityReference callback. + */ +typedef enum { + /** + * \brief The entity is referenced directly in user's code. + */ + CXIdxEntityRef_Direct = 1, + /** + * \brief An implicit reference, e.g. a reference of an ObjC method via the + * dot syntax. + */ + CXIdxEntityRef_Implicit = 2 +} CXIdxEntityRefKind; + +/** + * \brief Data for \see indexEntityReference callback. + */ +typedef struct { + CXIdxEntityRefKind kind; + /** + * \brief Reference cursor. + */ + CXCursor cursor; + CXIdxLoc loc; + /** + * \brief The entity that gets referenced. + */ + const CXIdxEntityInfo *referencedEntity; + /** + * \brief Immediate "parent" of the reference. For example: + * + * \code + * Foo *var; + * \endcode + * + * The parent of reference of type 'Foo' is the variable 'var'. + * For references inside statement bodies of functions/methods, + * the parentEntity will be the function/method. + */ + const CXIdxEntityInfo *parentEntity; + /** + * \brief Lexical container context of the reference. + */ + const CXIdxContainerInfo *container; +} CXIdxEntityRefInfo; + +typedef struct { + /** + * \brief Called periodically to check whether indexing should be aborted. + * Should return 0 to continue, and non-zero to abort. + */ + int (*abortQuery)(CXClientData client_data, void *reserved); + + /** + * \brief Called at the end of indexing; passes the complete diagnostic set. + */ + void (*diagnostic)(CXClientData client_data, + CXDiagnosticSet, void *reserved); + + CXIdxClientFile (*enteredMainFile)(CXClientData client_data, + CXFile mainFile, void *reserved); + + /** + * \brief Called when a file gets #included/#imported. + */ + CXIdxClientFile (*ppIncludedFile)(CXClientData client_data, + const CXIdxIncludedFileInfo *); + + /** + * \brief Called when a AST file (PCH or module) gets imported. + * + * AST files will not get indexed (there will not be callbacks to index all + * the entities in an AST file). The recommended action is that, if the AST + * file is not already indexed, to block further indexing and initiate a new + * indexing job specific to the AST file. + */ + CXIdxClientASTFile (*importedASTFile)(CXClientData client_data, + const CXIdxImportedASTFileInfo *); + + /** + * \brief Called at the beginning of indexing a translation unit. + */ + CXIdxClientContainer (*startedTranslationUnit)(CXClientData client_data, + void *reserved); + + void (*indexDeclaration)(CXClientData client_data, + const CXIdxDeclInfo *); + + /** + * \brief Called to index a reference of an entity. + */ + void (*indexEntityReference)(CXClientData client_data, + const CXIdxEntityRefInfo *); + +} IndexerCallbacks; + +CINDEX_LINKAGE int clang_index_isEntityObjCContainerKind(CXIdxEntityKind); +CINDEX_LINKAGE const CXIdxObjCContainerDeclInfo * +clang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *); + +CINDEX_LINKAGE const CXIdxObjCInterfaceDeclInfo * +clang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *); + +CINDEX_LINKAGE +const CXIdxObjCCategoryDeclInfo * +clang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *); + +CINDEX_LINKAGE const CXIdxObjCProtocolRefListInfo * +clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *); + +CINDEX_LINKAGE const CXIdxObjCPropertyDeclInfo * +clang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *); + +CINDEX_LINKAGE const CXIdxIBOutletCollectionAttrInfo * +clang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *); + +CINDEX_LINKAGE const CXIdxCXXClassDeclInfo * +clang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *); + +/** + * \brief For retrieving a custom CXIdxClientContainer attached to a + * container. + */ +CINDEX_LINKAGE CXIdxClientContainer +clang_index_getClientContainer(const CXIdxContainerInfo *); + +/** + * \brief For setting a custom CXIdxClientContainer attached to a + * container. + */ +CINDEX_LINKAGE void +clang_index_setClientContainer(const CXIdxContainerInfo *,CXIdxClientContainer); + +/** + * \brief For retrieving a custom CXIdxClientEntity attached to an entity. + */ +CINDEX_LINKAGE CXIdxClientEntity +clang_index_getClientEntity(const CXIdxEntityInfo *); + +/** + * \brief For setting a custom CXIdxClientEntity attached to an entity. + */ +CINDEX_LINKAGE void +clang_index_setClientEntity(const CXIdxEntityInfo *, CXIdxClientEntity); + +/** + * \brief An indexing action, to be applied to one or multiple translation units + * but not on concurrent threads. If there are threads doing indexing + * concurrently, they should use different CXIndexAction objects. + */ +typedef void *CXIndexAction; + +/** + * \brief An indexing action, to be applied to one or multiple translation units + * but not on concurrent threads. If there are threads doing indexing + * concurrently, they should use different CXIndexAction objects. + * + * \param CIdx The index object with which the index action will be associated. + */ +CINDEX_LINKAGE CXIndexAction clang_IndexAction_create(CXIndex CIdx); + +/** + * \brief Destroy the given index action. + * + * The index action must not be destroyed until all of the translation units + * created within that index action have been destroyed. + */ +CINDEX_LINKAGE void clang_IndexAction_dispose(CXIndexAction); + +typedef enum { + /** + * \brief Used to indicate that no special indexing options are needed. + */ + CXIndexOpt_None = 0x0, + + /** + * \brief Used to indicate that \see indexEntityReference should be invoked + * for only one reference of an entity per source file that does not also + * include a declaration/definition of the entity. + */ + CXIndexOpt_SuppressRedundantRefs = 0x1, + + /** + * \brief Function-local symbols should be indexed. If this is not set + * function-local symbols will be ignored. + */ + CXIndexOpt_IndexFunctionLocalSymbols = 0x2, + + /** + * \brief Implicit function/class template instantiations should be indexed. + * If this is not set, implicit instantiations will be ignored. + */ + CXIndexOpt_IndexImplicitTemplateInstantiations = 0x4, + + /** + * \brief Suppress all compiler warnings when parsing for indexing. + */ + CXIndexOpt_SuppressWarnings = 0x8 +} CXIndexOptFlags; + +/** + * \brief Index the given source file and the translation unit corresponding + * to that file via callbacks implemented through \see IndexerCallbacks. + * + * \param client_data pointer data supplied by the client, which will + * be passed to the invoked callbacks. + * + * \param index_callbacks Pointer to indexing callbacks that the client + * implements. + * + * \param index_callbacks_size Size of \see IndexerCallbacks structure that gets + * passed in index_callbacks. + * + * \param index_options A bitmask of options that affects how indexing is + * performed. This should be a bitwise OR of the CXIndexOpt_XXX flags. + * + * \param out_TU [out] pointer to store a CXTranslationUnit that can be reused + * after indexing is finished. Set to NULL if you do not require it. + * + * \returns If there is a failure from which the there is no recovery, returns + * non-zero, otherwise returns 0. + * + * The rest of the parameters are the same as \see clang_parseTranslationUnit. + */ +CINDEX_LINKAGE int clang_indexSourceFile(CXIndexAction, + CXClientData client_data, + IndexerCallbacks *index_callbacks, + unsigned index_callbacks_size, + unsigned index_options, + const char *source_filename, + const char * const *command_line_args, + int num_command_line_args, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, + CXTranslationUnit *out_TU, + unsigned TU_options); + +/** + * \brief Index the given translation unit via callbacks implemented through + * \see IndexerCallbacks. + * + * The order of callback invocations is not guaranteed to be the same as + * when indexing a source file. The high level order will be: + * + * -Preprocessor callbacks invocations + * -Declaration/reference callbacks invocations + * -Diagnostic callback invocations + * + * The parameters are the same as \see clang_indexSourceFile. + * + * \returns If there is a failure from which the there is no recovery, returns + * non-zero, otherwise returns 0. + */ +CINDEX_LINKAGE int clang_indexTranslationUnit(CXIndexAction, + CXClientData client_data, + IndexerCallbacks *index_callbacks, + unsigned index_callbacks_size, + unsigned index_options, + CXTranslationUnit); + +/** + * \brief Retrieve the CXIdxFile, file, line, column, and offset represented by + * the given CXIdxLoc. + * + * If the location refers into a macro expansion, retrieves the + * location of the macro expansion and if it refers into a macro argument + * retrieves the location of the argument. + */ +CINDEX_LINKAGE void clang_indexLoc_getFileLocation(CXIdxLoc loc, + CXIdxClientFile *indexFile, + CXFile *file, + unsigned *line, + unsigned *column, + unsigned *offset); + +/** + * \brief Retrieve the CXSourceLocation represented by the given CXIdxLoc. + */ +CINDEX_LINKAGE +CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc loc); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/clang/include/clang-c/Makefile b/clang/include/clang-c/Makefile new file mode 100644 index 0000000..b29e29e --- /dev/null +++ b/clang/include/clang-c/Makefile @@ -0,0 +1,38 @@ +CLANG_LEVEL := ../.. +DIRS := + +include $(CLANG_LEVEL)/Makefile + +IntIncludeDir = $(DESTDIR)$(PROJ_internal_prefix)/include + +install-local:: + $(Echo) Installing Clang C API include files + $(Verb) $(MKDIR) $(IntIncludeDir) + $(Verb) if test -d "$(PROJ_SRC_DIR)" ; then \ + cd $(PROJ_SRC_DIR)/.. && \ + 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=`dirname "$(IntIncludeDir)/$$hdr"` ; \ + if test \! -d "$$instdir" ; then \ + $(EchoCmd) Making install directory $$instdir ; \ + $(MKDIR) $$instdir ;\ + fi ; \ + $(DataInstall) $$hdr $(IntIncludeDir)/$$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 \ + instdir=`dirname "$(IntIncludeDir)/$$hdr"` ; \ + if test \! -d "$$instdir" ; then \ + $(EchoCmd) Making install directory $$instdir ; \ + $(MKDIR) $$instdir ;\ + fi ; \ + $(DataInstall) $$hdr $(IntIncludeDir)/$$hdr ; \ + done ; \ + fi +endif diff --git a/clang/include/clang/ARCMigrate/ARCMT.h b/clang/include/clang/ARCMigrate/ARCMT.h new file mode 100644 index 0000000..86a6cbb --- /dev/null +++ b/clang/include/clang/ARCMigrate/ARCMT.h @@ -0,0 +1,122 @@ +//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_H +#define LLVM_CLANG_ARCMIGRATE_ARCMT_H + +#include "clang/ARCMigrate/FileRemapper.h" +#include "clang/Frontend/CompilerInvocation.h" + +namespace clang { + class ASTContext; + class DiagnosticConsumer; + +namespace arcmt { + class MigrationPass; + +/// \brief Creates an AST with the provided CompilerInvocation but with these +/// changes: +/// -if a PCH/PTH is set, the original header is used instead +/// -Automatic Reference Counting mode is enabled +/// +/// It then checks the AST and produces errors/warning for ARC migration issues +/// that the user needs to handle manually. +/// +/// \param emitPremigrationARCErrors if true all ARC errors will get emitted +/// even if the migrator can fix them, but the function will still return false +/// if all ARC errors can be fixed. +/// +/// \param plistOut if non-empty, it is the file path to store the plist with +/// the pre-migration ARC diagnostics. +/// +/// \returns false if no error is produced, true otherwise. +bool checkForManualIssues(CompilerInvocation &CI, + const FrontendInputFile &Input, + DiagnosticConsumer *DiagClient, + bool emitPremigrationARCErrors = false, + StringRef plistOut = StringRef()); + +/// \brief Works similar to checkForManualIssues but instead of checking, it +/// applies automatic modifications to source files to conform to ARC. +/// +/// \returns false if no error is produced, true otherwise. +bool applyTransformations(CompilerInvocation &origCI, + const FrontendInputFile &Input, + DiagnosticConsumer *DiagClient); + +/// \brief Applies automatic modifications and produces temporary files +/// and metadata into the \arg outputDir path. +/// +/// \param emitPremigrationARCErrors if true all ARC errors will get emitted +/// even if the migrator can fix them, but the function will still return false +/// if all ARC errors can be fixed. +/// +/// \param plistOut if non-empty, it is the file path to store the plist with +/// the pre-migration ARC diagnostics. +/// +/// \returns false if no error is produced, true otherwise. +bool migrateWithTemporaryFiles(CompilerInvocation &origCI, + const FrontendInputFile &Input, + DiagnosticConsumer *DiagClient, + StringRef outputDir, + bool emitPremigrationARCErrors, + StringRef plistOut); + +/// \brief Get the set of file remappings from the \arg outputDir path that +/// migrateWithTemporaryFiles produced. +/// +/// \returns false if no error is produced, true otherwise. +bool getFileRemappings(std::vector > &remap, + StringRef outputDir, + DiagnosticConsumer *DiagClient); + +/// \brief Get the set of file remappings from a list of files with remapping +/// info. +/// +/// \returns false if no error is produced, true otherwise. +bool getFileRemappingsFromFileList( + std::vector > &remap, + ArrayRef remapFiles, + DiagnosticConsumer *DiagClient); + +typedef void (*TransformFn)(MigrationPass &pass); + +std::vector getAllTransformations(LangOptions::GCMode OrigGCMode, + bool NoFinalizeRemoval); + +class MigrationProcess { + CompilerInvocation OrigCI; + DiagnosticConsumer *DiagClient; + FileRemapper Remapper; + +public: + MigrationProcess(const CompilerInvocation &CI, DiagnosticConsumer *diagClient, + StringRef outputDir = StringRef()); + + class RewriteListener { + public: + virtual ~RewriteListener(); + + virtual void start(ASTContext &Ctx) { } + virtual void finish() { } + + virtual void insert(SourceLocation loc, StringRef text) { } + virtual void remove(CharSourceRange range) { } + }; + + bool applyTransform(TransformFn trans, RewriteListener *listener = 0); + + FileRemapper &getRemapper() { return Remapper; } +}; + +} // end namespace arcmt + +} // end namespace clang + +#endif diff --git a/clang/include/clang/ARCMigrate/ARCMTActions.h b/clang/include/clang/ARCMigrate/ARCMTActions.h new file mode 100644 index 0000000..e075252 --- /dev/null +++ b/clang/include/clang/ARCMigrate/ARCMTActions.h @@ -0,0 +1,77 @@ +//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H +#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H + +#include "clang/Frontend/FrontendAction.h" +#include "clang/ARCMigrate/FileRemapper.h" +#include "llvm/ADT/OwningPtr.h" + +namespace clang { +namespace arcmt { + +class CheckAction : public WrapperFrontendAction { +protected: + virtual bool BeginInvocation(CompilerInstance &CI); + +public: + CheckAction(FrontendAction *WrappedAction); +}; + +class ModifyAction : public WrapperFrontendAction { +protected: + virtual bool BeginInvocation(CompilerInstance &CI); + +public: + ModifyAction(FrontendAction *WrappedAction); +}; + +class MigrateSourceAction : public ASTFrontendAction { + FileRemapper Remapper; +protected: + virtual bool BeginInvocation(CompilerInstance &CI); + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + StringRef InFile); +}; + +class MigrateAction : public WrapperFrontendAction { + std::string MigrateDir; + std::string PlistOut; + bool EmitPremigrationARCErros; +protected: + virtual bool BeginInvocation(CompilerInstance &CI); + +public: + MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, + StringRef plistOut, + bool emitPremigrationARCErrors); +}; + +/// \brief Migrates to modern ObjC syntax. +class ObjCMigrateAction : public WrapperFrontendAction { + std::string MigrateDir; + bool MigrateLiterals; + bool MigrateSubscripting; + FileRemapper Remapper; + CompilerInstance *CompInst; +public: + ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, + bool migrateLiterals, + bool migrateSubscripting); + +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile); + virtual bool BeginInvocation(CompilerInstance &CI); +}; + +} +} + +#endif diff --git a/clang/include/clang/ARCMigrate/FileRemapper.h b/clang/include/clang/ARCMigrate/FileRemapper.h new file mode 100644 index 0000000..fe7cfad --- /dev/null +++ b/clang/include/clang/ARCMigrate/FileRemapper.h @@ -0,0 +1,80 @@ +//===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H +#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" + +namespace llvm { + class MemoryBuffer; +} + +namespace clang { + class FileManager; + class FileEntry; + class DiagnosticsEngine; + class PreprocessorOptions; + +namespace arcmt { + +class FileRemapper { + // FIXME: Reuse the same FileManager for multiple ASTContexts. + OwningPtr FileMgr; + + typedef llvm::PointerUnion Target; + typedef llvm::DenseMap MappingsTy; + MappingsTy FromToMappings; + + llvm::DenseMap ToFromMappings; + +public: + FileRemapper(); + ~FileRemapper(); + + bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag, + bool ignoreIfFilesChanged); + bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag, + bool ignoreIfFilesChanged); + bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag); + bool flushToFile(StringRef outputPath, DiagnosticsEngine &Diag); + + bool overwriteOriginal(DiagnosticsEngine &Diag, + StringRef outputDir = StringRef()); + + void remap(StringRef filePath, llvm::MemoryBuffer *memBuf); + void remap(StringRef filePath, StringRef newPath); + + void applyMappings(PreprocessorOptions &PPOpts) const; + + void transferMappingsAndClear(PreprocessorOptions &PPOpts); + + void clear(StringRef outputDir = StringRef()); + +private: + void remap(const FileEntry *file, llvm::MemoryBuffer *memBuf); + void remap(const FileEntry *file, const FileEntry *newfile); + + const FileEntry *getOriginalFile(StringRef filePath); + void resetTarget(Target &targ); + + bool report(const Twine &err, DiagnosticsEngine &Diag); + + std::string getRemapInfoFile(StringRef outputDir); +}; + +} // end namespace arcmt + +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/.#Expr_flymake.h b/clang/include/clang/AST/.#Expr_flymake.h new file mode 120000 index 0000000..235903b --- /dev/null +++ b/clang/include/clang/AST/.#Expr_flymake.h @@ -0,0 +1 @@ +carlo@pc-4w14-0.cs.usyd.edu.au.1585:1347012043 \ No newline at end of file diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h new file mode 100644 index 0000000..1b6e90c --- /dev/null +++ b/clang/include/clang/AST/APValue.h @@ -0,0 +1,446 @@ +//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the APValue class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_APVALUE_H +#define LLVM_CLANG_AST_APVALUE_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" + +namespace clang { + class AddrLabelExpr; + class ASTContext; + class CharUnits; + class DiagnosticBuilder; + class Expr; + class FieldDecl; + class Decl; + class ValueDecl; + class CXXRecordDecl; + class QualType; + +/// APValue - This class implements a discriminated union of [uninitialized] +/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], +/// [Vector: N * APValue], [Array: N * APValue] +class APValue { + typedef llvm::APSInt APSInt; + typedef llvm::APFloat APFloat; +public: + enum ValueKind { + Uninitialized, + Int, + Float, + ComplexInt, + ComplexFloat, + LValue, + Vector, + Array, + Struct, + Union, + MemberPointer, + AddrLabelDiff + }; + typedef llvm::PointerUnion LValueBase; + typedef llvm::PointerIntPair BaseOrMemberType; + union LValuePathEntry { + /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item + /// in the path. An opaque value of type BaseOrMemberType. + void *BaseOrMember; + /// ArrayIndex - The array index of the next item in the path. + uint64_t ArrayIndex; + }; + struct NoLValuePath {}; + struct UninitArray {}; + struct UninitStruct {}; +private: + ValueKind Kind; + + struct ComplexAPSInt { + APSInt Real, Imag; + ComplexAPSInt() : Real(1), Imag(1) {} + }; + struct ComplexAPFloat { + APFloat Real, Imag; + ComplexAPFloat() : Real(0.0), Imag(0.0) {} + }; + struct LV; + struct Vec { + APValue *Elts; + unsigned NumElts; + Vec() : Elts(0), NumElts(0) {} + ~Vec() { delete[] Elts; } + }; + struct Arr { + APValue *Elts; + unsigned NumElts, ArrSize; + Arr(unsigned NumElts, unsigned ArrSize); + ~Arr(); + }; + struct StructData { + APValue *Elts; + unsigned NumBases; + unsigned NumFields; + StructData(unsigned NumBases, unsigned NumFields); + ~StructData(); + }; + struct UnionData { + const FieldDecl *Field; + APValue *Value; + UnionData(); + ~UnionData(); + }; + struct AddrLabelDiffData { + const AddrLabelExpr* LHSExpr; + const AddrLabelExpr* RHSExpr; + }; + struct MemberPointerData; + + 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); + APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex) + : Kind(Uninitialized) { + MakeLValue(); setLValue(B, O, N, CallIndex); + } + APValue(LValueBase B, const CharUnits &O, ArrayRef Path, + bool OnePastTheEnd, unsigned CallIndex) + : Kind(Uninitialized) { + MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex); + } + APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { + MakeArray(InitElts, Size); + } + APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) { + MakeStruct(B, M); + } + explicit APValue(const FieldDecl *D, const APValue &V = APValue()) + : Kind(Uninitialized) { + MakeUnion(); setUnion(D, V); + } + APValue(const ValueDecl *Member, bool IsDerivedMember, + ArrayRef Path) : Kind(Uninitialized) { + MakeMemberPointer(Member, IsDerivedMember, Path); + } + APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) + : Kind(Uninitialized) { + MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); + } + + ~APValue() { + MakeUninit(); + } + + /// \brief Swaps the contents of this and the given APValue. + void swap(APValue &RHS); + + ValueKind getKind() const { return Kind; } + bool isUninit() const { return Kind == Uninitialized; } + bool isInt() const { return Kind == Int; } + bool isFloat() const { return Kind == Float; } + bool isComplexInt() const { return Kind == ComplexInt; } + bool isComplexFloat() const { return Kind == ComplexFloat; } + bool isLValue() const { return Kind == LValue; } + bool isVector() const { return Kind == Vector; } + bool isArray() const { return Kind == Array; } + bool isStruct() const { return Kind == Struct; } + bool isUnion() const { return Kind == Union; } + bool isMemberPointer() const { return Kind == MemberPointer; } + bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } + + void dump() const; + void dump(raw_ostream &OS) const; + + void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const; + std::string getAsString(ASTContext &Ctx, QualType Ty) const; + + APSInt &getInt() { + assert(isInt() && "Invalid accessor"); + return *(APSInt*)(char*)Data; + } + const APSInt &getInt() const { + return const_cast(this)->getInt(); + } + + APFloat &getFloat() { + assert(isFloat() && "Invalid accessor"); + return *(APFloat*)(char*)Data; + } + const APFloat &getFloat() const { + return const_cast(this)->getFloat(); + } + + APSInt &getComplexIntReal() { + assert(isComplexInt() && "Invalid accessor"); + return ((ComplexAPSInt*)(char*)Data)->Real; + } + const APSInt &getComplexIntReal() const { + return const_cast(this)->getComplexIntReal(); + } + + APSInt &getComplexIntImag() { + assert(isComplexInt() && "Invalid accessor"); + return ((ComplexAPSInt*)(char*)Data)->Imag; + } + const APSInt &getComplexIntImag() const { + return const_cast(this)->getComplexIntImag(); + } + + APFloat &getComplexFloatReal() { + assert(isComplexFloat() && "Invalid accessor"); + return ((ComplexAPFloat*)(char*)Data)->Real; + } + const APFloat &getComplexFloatReal() const { + return const_cast(this)->getComplexFloatReal(); + } + + APFloat &getComplexFloatImag() { + assert(isComplexFloat() && "Invalid accessor"); + return ((ComplexAPFloat*)(char*)Data)->Imag; + } + const APFloat &getComplexFloatImag() const { + return const_cast(this)->getComplexFloatImag(); + } + + const LValueBase getLValueBase() const; + CharUnits &getLValueOffset(); + const CharUnits &getLValueOffset() const { + return const_cast(this)->getLValueOffset(); + } + bool isLValueOnePastTheEnd() const; + bool hasLValuePath() const; + ArrayRef getLValuePath() const; + unsigned getLValueCallIndex() const; + + APValue &getVectorElt(unsigned I) { + assert(isVector() && "Invalid accessor"); + assert(I < getVectorLength() && "Index out of range"); + return ((Vec*)(char*)Data)->Elts[I]; + } + const APValue &getVectorElt(unsigned I) const { + return const_cast(this)->getVectorElt(I); + } + unsigned getVectorLength() const { + assert(isVector() && "Invalid accessor"); + return ((const Vec*)(const void *)Data)->NumElts; + } + + APValue &getArrayInitializedElt(unsigned I) { + assert(isArray() && "Invalid accessor"); + assert(I < getArrayInitializedElts() && "Index out of range"); + return ((Arr*)(char*)Data)->Elts[I]; + } + const APValue &getArrayInitializedElt(unsigned I) const { + return const_cast(this)->getArrayInitializedElt(I); + } + bool hasArrayFiller() const { + return getArrayInitializedElts() != getArraySize(); + } + APValue &getArrayFiller() { + assert(isArray() && "Invalid accessor"); + assert(hasArrayFiller() && "No array filler"); + return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()]; + } + const APValue &getArrayFiller() const { + return const_cast(this)->getArrayFiller(); + } + unsigned getArrayInitializedElts() const { + assert(isArray() && "Invalid accessor"); + return ((const Arr*)(const void *)Data)->NumElts; + } + unsigned getArraySize() const { + assert(isArray() && "Invalid accessor"); + return ((const Arr*)(const void *)Data)->ArrSize; + } + + unsigned getStructNumBases() const { + assert(isStruct() && "Invalid accessor"); + return ((const StructData*)(const char*)Data)->NumBases; + } + unsigned getStructNumFields() const { + assert(isStruct() && "Invalid accessor"); + return ((const StructData*)(const char*)Data)->NumFields; + } + APValue &getStructBase(unsigned i) { + assert(isStruct() && "Invalid accessor"); + return ((StructData*)(char*)Data)->Elts[i]; + } + APValue &getStructField(unsigned i) { + assert(isStruct() && "Invalid accessor"); + return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i]; + } + const APValue &getStructBase(unsigned i) const { + return const_cast(this)->getStructBase(i); + } + const APValue &getStructField(unsigned i) const { + return const_cast(this)->getStructField(i); + } + + const FieldDecl *getUnionField() const { + assert(isUnion() && "Invalid accessor"); + return ((const UnionData*)(const char*)Data)->Field; + } + APValue &getUnionValue() { + assert(isUnion() && "Invalid accessor"); + return *((UnionData*)(char*)Data)->Value; + } + const APValue &getUnionValue() const { + return const_cast(this)->getUnionValue(); + } + + const ValueDecl *getMemberPointerDecl() const; + bool isMemberPointerToDerivedMember() const; + ArrayRef getMemberPointerPath() const; + + const AddrLabelExpr* getAddrLabelDiffLHS() const { + assert(isAddrLabelDiff() && "Invalid accessor"); + return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr; + } + const AddrLabelExpr* getAddrLabelDiffRHS() const { + assert(isAddrLabelDiff() && "Invalid accessor"); + return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr; + } + + 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(LValueBase B, const CharUnits &O, NoLValuePath, + unsigned CallIndex); + void setLValue(LValueBase B, const CharUnits &O, + ArrayRef Path, bool OnePastTheEnd, + unsigned CallIndex); + void setUnion(const FieldDecl *Field, const APValue &Value) { + assert(isUnion() && "Invalid accessor"); + ((UnionData*)(char*)Data)->Field = Field; + *((UnionData*)(char*)Data)->Value = Value; + } + void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, + const AddrLabelExpr* RHSExpr) { + ((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr; + ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr; + } + + /// Assign by swapping from a copy of the RHS. + APValue &operator=(APValue RHS) { + swap(RHS); + return *this; + } + +private: + void DestroyDataAndMakeUninit(); + void MakeUninit() { + if (Kind != Uninitialized) + DestroyDataAndMakeUninit(); + } + void MakeInt() { + assert(isUninit() && "Bad state change"); + new ((void*)Data) 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(); + void MakeArray(unsigned InitElts, unsigned Size); + void MakeStruct(unsigned B, unsigned M) { + assert(isUninit() && "Bad state change"); + new ((void*)(char*)Data) StructData(B, M); + Kind = Struct; + } + void MakeUnion() { + assert(isUninit() && "Bad state change"); + new ((void*)(char*)Data) UnionData(); + Kind = Union; + } + void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, + ArrayRef Path); + void MakeAddrLabelDiff() { + assert(isUninit() && "Bad state change"); + new ((void*)(char*)Data) AddrLabelDiffData(); + Kind = AddrLabelDiff; + } +}; + +} // end namespace clang. + +#endif diff --git a/clang/include/clang/AST/AST.h b/clang/include/clang/AST/AST.h new file mode 100644 index 0000000..164c5fb --- /dev/null +++ b/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/clang/include/clang/AST/ASTConsumer.h b/clang/include/clang/AST/ASTConsumer.h new file mode 100644 index 0000000..69a3866 --- /dev/null +++ b/clang/include/clang/AST/ASTConsumer.h @@ -0,0 +1,128 @@ +//===--- 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 HandleTagDeclDefinition; + class ASTMutationListener; + class ASTDeserializationListener; // layering violation because void* is ugly + class SemaConsumer; // layering violation required for safe SemaConsumer + class TagDecl; + class VarDecl; + class FunctionDecl; + +/// 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. + /// + /// \returns true to continue parsing, or false to abort parsing. + virtual bool HandleTopLevelDecl(DeclGroupRef D); + + /// HandleInterestingDecl - Handle the specified interesting declaration. This + /// is called by the AST reader when deserializing things that might interest + /// the consumer. The default implementation forwards to HandleTopLevelDecl. + virtual void HandleInterestingDecl(DeclGroupRef D); + + /// HandleTranslationUnit - This method is called when the ASTs for entire + /// translation unit have been parsed. + virtual void HandleTranslationUnit(ASTContext &Ctx) {} + + /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl + /// (e.g. struct, union, enum, class) is completed. This allows the client to + /// hack on the type, which can occur at any point in the file (because these + /// can be defined in declspecs). + virtual void HandleTagDeclDefinition(TagDecl *D) {} + + /// \brief Invoked when a function is implicitly instantiated. + /// Note that at this point point it does not have a body, its body is + /// instantiated at the end of the translation unit and passed to + /// HandleTopLevelDecl. + virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {} + + /// \brief Handle the specified top-level declaration that occurred inside + /// and ObjC container. + /// The default implementation ignored them. + virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D); + + /// CompleteTentativeDefinition - Callback invoked at the end of a translation + /// unit to notify the consumer that the given tentative definition should be + /// completed. + /// + /// The variable declaration itself will be a tentative + /// definition. If it had an incomplete array type, its type will + /// have already been changed to an array of size 1. However, the + /// declaration remains a tentative definition and has not been + /// modified by the introduction of an implicit zero initializer. + virtual void CompleteTentativeDefinition(VarDecl *D) {} + + /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this + // variable has been instantiated. + virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {} + + /// \brief Callback involved at the end of a translation unit to + /// notify the consumer that a vtable for the given C++ class is + /// required. + /// + /// \param RD The class whose vtable was used. + /// + /// \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) {} + + /// \brief If the consumer is interested in entities getting modified after + /// their initial creation, it should return a pointer to + /// an ASTMutationListener here. + virtual ASTMutationListener *GetASTMutationListener() { return 0; } + + /// \brief If the consumer is interested in entities being deserialized from + /// AST files, it should return a pointer to a ASTDeserializationListener here + virtual ASTDeserializationListener *GetASTDeserializationListener() { + return 0; + } + + /// 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/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h new file mode 100644 index 0000000..96e41c5 --- /dev/null +++ b/clang/include/clang/AST/ASTContext.h @@ -0,0 +1,1998 @@ +//===--- 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/AddressSpaces.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/VersionTuple.h" +#include "clang/AST/Decl.h" +#include "clang/AST/LambdaMangleContext.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 "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/TinyPtrVector.h" +#include "llvm/Support/Allocator.h" +#include + +namespace llvm { + struct fltSemantics; +} + +namespace clang { + class FileManager; + class ASTRecordLayout; + class BlockExpr; + class CharUnits; + class DiagnosticsEngine; + class Expr; + class ExternalASTSource; + class ASTMutationListener; + class IdentifierTable; + class SelectorTable; + class SourceManager; + class TargetInfo; + class CXXABI; + // Decls + class DeclContext; + class CXXConversionDecl; + class CXXMethodDecl; + class CXXRecordDecl; + class Decl; + class FieldDecl; + class MangleContext; + class ObjCIvarDecl; + class ObjCIvarRefExpr; + class ObjCPropertyDecl; + class ParmVarDecl; + class RecordDecl; + class StoredDeclsMap; + class TagDecl; + class TemplateTemplateParmDecl; + class TemplateTypeParmDecl; + class TranslationUnitDecl; + class TypeDecl; + class TypedefNameDecl; + 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 : public RefCountedBase { + ASTContext &this_() { return *this; } + + mutable std::vector Types; + mutable llvm::FoldingSet ExtQualNodes; + mutable llvm::FoldingSet ComplexTypes; + mutable llvm::FoldingSet PointerTypes; + mutable llvm::FoldingSet BlockPointerTypes; + mutable llvm::FoldingSet LValueReferenceTypes; + mutable llvm::FoldingSet RValueReferenceTypes; + mutable llvm::FoldingSet MemberPointerTypes; + mutable llvm::FoldingSet ConstantArrayTypes; + mutable llvm::FoldingSet IncompleteArrayTypes; + mutable std::vector VariableArrayTypes; + mutable llvm::FoldingSet DependentSizedArrayTypes; + mutable llvm::FoldingSet + DependentSizedExtVectorTypes; + mutable llvm::FoldingSet VectorTypes; + mutable llvm::FoldingSet FunctionNoProtoTypes; + mutable llvm::ContextualFoldingSet + FunctionProtoTypes; + mutable llvm::FoldingSet DependentTypeOfExprTypes; + mutable llvm::FoldingSet DependentDecltypeTypes; + mutable llvm::FoldingSet TemplateTypeParmTypes; + mutable llvm::FoldingSet + SubstTemplateTypeParmTypes; + mutable llvm::FoldingSet + SubstTemplateTypeParmPackTypes; + mutable llvm::ContextualFoldingSet + TemplateSpecializationTypes; + mutable llvm::FoldingSet ParenTypes; + mutable llvm::FoldingSet ElaboratedTypes; + mutable llvm::FoldingSet DependentNameTypes; + mutable llvm::ContextualFoldingSet + DependentTemplateSpecializationTypes; + llvm::FoldingSet PackExpansionTypes; + mutable llvm::FoldingSet ObjCObjectTypes; + mutable llvm::FoldingSet ObjCObjectPointerTypes; + mutable llvm::FoldingSet AutoTypes; + mutable llvm::FoldingSet AtomicTypes; + llvm::FoldingSet AttributedTypes; + + mutable llvm::FoldingSet QualifiedTemplateNames; + mutable llvm::FoldingSet DependentTemplateNames; + mutable llvm::FoldingSet + SubstTemplateTemplateParms; + mutable llvm::ContextualFoldingSet + SubstTemplateTemplateParmPacks; + + /// \brief The set of nested name specifiers. + /// + /// This set is managed by the NestedNameSpecifier class. + mutable llvm::FoldingSet NestedNameSpecifiers; + mutable NestedNameSpecifier *GlobalNestedNameSpecifier; + friend class NestedNameSpecifier; + + /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts. + /// This is lazily created. This is intentionally not serialized. + mutable llvm::DenseMap + ASTRecordLayouts; + mutable llvm::DenseMap + ObjCLayouts; + + /// TypeInfoMap - A cache from types to size and alignment information. + typedef llvm::DenseMap > TypeInfoMap; + mutable TypeInfoMap MemoizedTypeInfo; + + /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions. + llvm::DenseMap KeyFunctions; + + /// \brief Mapping from ObjCContainers to their ObjCImplementations. + llvm::DenseMap ObjCImpls; + + /// \brief Mapping from ObjCMethod to its duplicate declaration in the same + /// interface. + llvm::DenseMap ObjCMethodRedecls; + + /// \brief Mapping from __block VarDecls to their copy initialization expr. + llvm::DenseMap BlockVarCopyInits; + + /// \brief Mapping from class scope functions specialization to their + /// template patterns. + llvm::DenseMap + ClassScopeSpecializationPattern; + + /// \brief Representation of a "canonical" template template parameter that + /// is used in canonical template names. + class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode { + TemplateTemplateParmDecl *Parm; + + public: + CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm) + : Parm(Parm) { } + + TemplateTemplateParmDecl *getParam() const { return Parm; } + + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); } + + static void Profile(llvm::FoldingSetNodeID &ID, + TemplateTemplateParmDecl *Parm); + }; + mutable llvm::FoldingSet + CanonTemplateTemplateParms; + + TemplateTemplateParmDecl * + getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; + + /// \brief The typedef for the __int128_t type. + mutable TypedefDecl *Int128Decl; + + /// \brief The typedef for the __uint128_t type. + mutable TypedefDecl *UInt128Decl; + + /// 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; + + /// \brief The typedef for the predefined 'id' type. + mutable TypedefDecl *ObjCIdDecl; + + /// \brief The typedef for the predefined 'SEL' type. + mutable TypedefDecl *ObjCSelDecl; + + /// \brief The typedef for the predefined 'Class' type. + mutable TypedefDecl *ObjCClassDecl; + + /// \brief The typedef for the predefined 'Protocol' class in Objective-C. + mutable ObjCInterfaceDecl *ObjCProtocolClassDecl; + + // Typedefs which may be provided defining the structure of Objective-C + // pseudo-builtins + QualType ObjCIdRedefinitionType; + QualType ObjCClassRedefinitionType; + QualType ObjCSelRedefinitionType; + + QualType ObjCConstantStringType; + mutable RecordDecl *CFConstantStringTypeDecl; + + QualType ObjCNSStringType; + + /// \brief The typedef declaration for the Objective-C "instancetype" type. + TypedefDecl *ObjCInstanceTypeDecl; + + /// \brief The type for the C FILE type. + TypeDecl *FILEDecl; + + /// \brief The type for the C jmp_buf type. + TypeDecl *jmp_bufDecl; + + /// \brief The type for the C sigjmp_buf type. + TypeDecl *sigjmp_bufDecl; + + /// \brief The type for the C ucontext_t type. + TypeDecl *ucontext_tDecl; + + /// \brief Type for the Block descriptor for Blocks CodeGen. + /// + /// Since this is only used for generation of debug info, it is not + /// serialized. + mutable RecordDecl *BlockDescriptorType; + + /// \brief Type for the Block descriptor for Blocks CodeGen. + /// + /// Since this is only used for generation of debug info, it is not + /// serialized. + mutable RecordDecl *BlockDescriptorExtendedType; + + /// \brief Declaration for the CUDA cudaConfigureCall function. + FunctionDecl *cudaConfigureCallDecl; + + TypeSourceInfo NullTypeSourceInfo; + + /// \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 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 + /// struct X { + /// static T value; + /// }; + /// + /// template + /// T X::value = T(17); + /// + /// int *x = &X::value; + /// \endcode + /// + /// This mapping will contain an entry that maps from the VarDecl for + /// X::value to the corresponding VarDecl for X::value (within the + /// class template X) and will be marked TSK_ImplicitInstantiation. + llvm::DenseMap + 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 + /// struct A { + /// void f(); + /// }; + /// + /// template + /// struct B : A { + /// using A::f; + /// }; + /// + /// template struct B; + /// \endcode + /// + /// This mapping will contain an entry that maps from the UsingDecl in + /// B to the UnresolvedUsingDecl in B. + llvm::DenseMap InstantiatedFromUsingDecl; + + llvm::DenseMap + InstantiatedFromUsingShadowDecl; + + llvm::DenseMap InstantiatedFromUnnamedFieldDecl; + + /// \brief Mapping that stores the methods overridden by a given C++ + /// member function. + /// + /// Since most C++ member functions aren't virtual and therefore + /// don't override anything, we store the overridden functions in + /// this map on the side rather than within the CXXMethodDecl structure. + typedef llvm::TinyPtrVector CXXMethodVector; + llvm::DenseMap OverriddenMethods; + + /// \brief Mapping from each declaration context to its corresponding lambda + /// mangling context. + llvm::DenseMap LambdaMangleContexts; + + /// \brief Mapping that stores parameterIndex values for ParmVarDecls + /// when that value exceeds the bitfield size of + /// ParmVarDeclBits.ParameterIndex. + typedef llvm::DenseMap ParameterIndexTable; + ParameterIndexTable ParamIndices; + + ImportDecl *FirstLocalImport; + ImportDecl *LastLocalImport; + + 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; + + /// \brief The allocator used to create AST objects. + /// + /// AST objects are never destructed; rather, all memory associated with the + /// AST objects will be released when the ASTContext itself is destroyed. + mutable llvm::BumpPtrAllocator BumpAlloc; + + /// \brief Allocator for partial diagnostics. + PartialDiagnostic::StorageAllocator DiagAllocator; + + /// \brief The current C++ ABI. + OwningPtr ABI; + CXXABI *createCXXABI(const TargetInfo &T); + + /// \brief The logical -> physical address space map. + const LangAS::Map *AddrSpaceMap; + + friend class ASTDeclReader; + friend class ASTReader; + friend class ASTWriter; + friend class CXXRecordDecl; + + const TargetInfo *Target; + clang::PrintingPolicy PrintingPolicy; + +public: + IdentifierTable &Idents; + SelectorTable &Selectors; + Builtin::Context &BuiltinInfo; + mutable DeclarationNameTable DeclarationNames; + OwningPtr ExternalSource; + ASTMutationListener *Listener; + + clang::PrintingPolicy getPrintingPolicy() const { return PrintingPolicy; } + + void setPrintingPolicy(clang::PrintingPolicy Policy) { + PrintingPolicy = Policy; + } + + SourceManager& getSourceManager() { return SourceMgr; } + const SourceManager& getSourceManager() const { return SourceMgr; } + void *Allocate(unsigned Size, unsigned Align = 8) const { + return BumpAlloc.Allocate(Size, Align); + } + void Deallocate(void *Ptr) const { } + + /// Return the total amount of physical memory allocated for representing + /// AST nodes and type information. + size_t getASTAllocatedMemory() const { + return BumpAlloc.getTotalMemory(); + } + /// Return the total memory used for various side tables. + size_t getSideTableAllocatedMemory() const; + + PartialDiagnostic::StorageAllocator &getDiagAllocator() { + return DiagAllocator; + } + + const TargetInfo &getTargetInfo() const { return *Target; } + + const LangOptions& getLangOpts() const { return LangOpts; } + + DiagnosticsEngine &getDiagnostics() const; + + FullSourceLoc getFullLoc(SourceLocation Loc) const { + return FullSourceLoc(Loc,SourceMgr); + } + + /// \brief Retrieve the attributes for the given declaration. + AttrVec& getDeclAttrs(const Decl *D); + + /// \brief Erase the attributes corresponding to the given declaration. + void eraseDeclAttrs(const Decl *D); + + /// \brief If this variable is an instantiated static data member of a + /// class template specialization, returns the templated static data member + /// from which it was instantiated. + MemberSpecializationInfo *getInstantiatedFromStaticDataMember( + const VarDecl *Var); + + FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD); + + void setClassScopeSpecializationPattern(FunctionDecl *FD, + FunctionDecl *Pattern); + + /// \brief Note that the static data member \p Inst is an instantiation of + /// the static data member template \p Tmpl of a class template. + void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, + TemplateSpecializationKind TSK, + SourceLocation PointOfInstantiation = SourceLocation()); + + /// \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); + + /// ZeroBitfieldFollowsNonBitfield - return 'true" if 'FD' is a zero-length + /// bitfield which follows the non-bitfield 'LastFD'. + bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; + + /// ZeroBitfieldFollowsBitfield - return 'true" if 'FD' is a zero-length + /// bitfield which follows the bitfield 'LastFD'. + bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; + + /// BitfieldFollowsBitfield - return 'true" if 'FD' is a + /// bitfield which follows the bitfield 'LastFD'. + bool BitfieldFollowsBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; + + /// NonBitfieldFollowsBitfield - return 'true" if 'FD' is not a + /// bitfield which follows the bitfield 'LastFD'. + bool NonBitfieldFollowsBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; + + /// BitfieldFollowsNonBitfield - return 'true" if 'FD' is a + /// bitfield which follows the none bitfield 'LastFD'. + bool BitfieldFollowsNonBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; + + // Access to the set of methods overridden by the given C++ method. + typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator; + overridden_cxx_method_iterator + overridden_methods_begin(const CXXMethodDecl *Method) const; + + overridden_cxx_method_iterator + overridden_methods_end(const CXXMethodDecl *Method) const; + + unsigned overridden_methods_size(const CXXMethodDecl *Method) const; + + /// \brief Note that the given C++ \p Method overrides the given \p + /// Overridden method. + void addOverriddenMethod(const CXXMethodDecl *Method, + const CXXMethodDecl *Overridden); + + /// \brief Notify the AST context that a new import declaration has been + /// parsed or implicitly created within this translation unit. + void addedLocalImportDecl(ImportDecl *Import); + + static ImportDecl *getNextLocalImport(ImportDecl *Import) { + return Import->NextLocalImport; + } + + /// \brief Iterator that visits import declarations. + class import_iterator { + ImportDecl *Import; + + public: + typedef ImportDecl *value_type; + typedef ImportDecl *reference; + typedef ImportDecl *pointer; + typedef int difference_type; + typedef std::forward_iterator_tag iterator_category; + + import_iterator() : Import() { } + explicit import_iterator(ImportDecl *Import) : Import(Import) { } + + reference operator*() const { return Import; } + pointer operator->() const { return Import; } + + import_iterator &operator++() { + Import = ASTContext::getNextLocalImport(Import); + return *this; + } + + import_iterator operator++(int) { + import_iterator Other(*this); + ++(*this); + return Other; + } + + friend bool operator==(import_iterator X, import_iterator Y) { + return X.Import == Y.Import; + } + + friend bool operator!=(import_iterator X, import_iterator Y) { + return X.Import != Y.Import; + } + }; + + import_iterator local_import_begin() const { + return import_iterator(FirstLocalImport); + } + import_iterator local_import_end() const { return import_iterator(); } + + 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 HalfTy; // [OpenCL 6.1.1.1], ARM NEON + CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; + CanQualType VoidPtrTy, NullPtrTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType PseudoObjectTy, ARCUnbridgedCastTy; + CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; + CanQualType ObjCBuiltinBoolTy; + + // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. + mutable QualType AutoDeductTy; // Deduction against 'auto'. + mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'. + + ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t, + IdentifierTable &idents, SelectorTable &sels, + Builtin::Context &builtins, + unsigned size_reserve, + bool DelayInitialization = false); + + ~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(OwningPtr &Source); + + /// \brief Retrieve a pointer to the external AST source associated + /// with this AST context, if any. + ExternalASTSource *getExternalSource() const { return ExternalSource.get(); } + + /// \brief Attach an AST mutation listener to the AST context. + /// + /// The AST mutation listener provides the ability to track modifications to + /// the abstract syntax tree entities committed after they were initially + /// created. + void setASTMutationListener(ASTMutationListener *Listener) { + this->Listener = Listener; + } + + /// \brief Retrieve a pointer to the AST mutation listener associated + /// with this AST context, if any. + ASTMutationListener *getASTMutationListener() const { return Listener; } + + void PrintStats() const; + const std::vector& getTypes() const { return Types; } + + /// \brief Retrieve the declaration for the 128-bit signed integer type. + TypedefDecl *getInt128Decl() const; + + /// \brief Retrieve the declaration for the 128-bit unsigned integer type. + TypedefDecl *getUInt128Decl() const; + + //===--------------------------------------------------------------------===// + // Type Constructors + //===--------------------------------------------------------------------===// + +private: + /// getExtQualType - Return a type with extended qualifiers. + QualType getExtQualType(const Type *Base, Qualifiers Quals) const; + + QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const; + +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) const; + + /// 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) const; + + /// 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) const { + 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) const { + return T.withFastQualifiers(Qualifiers::Volatile); + } + + /// 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) const { return T.withConst(); } + + /// adjustFunctionType - Change the ExtInfo on a function type. + const FunctionType *adjustFunctionType(const FunctionType *Fn, + FunctionType::ExtInfo EInfo); + + /// getComplexType - Return the uniqued reference to the type for a complex + /// number with the specified element type. + QualType getComplexType(QualType T) const; + CanQualType getComplexType(CanQualType T) const { + return CanQualType::CreateUnsafe(getComplexType((QualType) T)); + } + + /// getPointerType - Return the uniqued reference to the type for a pointer to + /// the specified type. + QualType getPointerType(QualType T) const; + CanQualType getPointerType(CanQualType T) const { + return CanQualType::CreateUnsafe(getPointerType((QualType) T)); + } + + /// getAtomicType - Return the uniqued reference to the atomic type for + /// the specified type. + QualType getAtomicType(QualType T) const; + + /// getBlockPointerType - Return the uniqued reference to the type for a block + /// of the specified type. + QualType getBlockPointerType(QualType T) const; + + /// This gets the struct used to keep track of the descriptor for pointer to + /// blocks. + QualType getBlockDescriptorType() const; + + /// This gets the struct used to keep track of the extended descriptor for + /// pointer to blocks. + QualType getBlockDescriptorExtendedType() const; + + void setcudaConfigureCallDecl(FunctionDecl *FD) { + cudaConfigureCallDecl = FD; + } + FunctionDecl *getcudaConfigureCallDecl() { + return cudaConfigureCallDecl; + } + + /// This builds the struct used for __block variables. + QualType BuildByRefType(StringRef DeclName, QualType Ty) const; + + /// Returns true iff we need copy/dispose helpers for the given type. + bool BlockRequiresCopying(QualType Ty) const; + + /// getLValueReferenceType - Return the uniqued reference to the type for an + /// lvalue reference to the specified type. + QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true) + const; + + /// getRValueReferenceType - Return the uniqued reference to the type for an + /// rvalue reference to the specified type. + QualType getRValueReferenceType(QualType T) const; + + /// 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) const; + + /// 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 IndexTypeQuals, + SourceRange Brackets) const; + + /// 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 IndexTypeQuals, + SourceRange Brackets) const; + + /// 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 IndexTypeQuals) const; + + /// 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 IndexTypeQuals) const; + + /// getVariableArrayDecayedType - Returns a vla type where known sizes + /// are replaced with [*]. + QualType getVariableArrayDecayedType(QualType Ty) const; + + /// 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, + VectorType::VectorKind VecKind) const; + + /// 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) const; + + /// 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) const; + + /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. + /// + QualType getFunctionNoProtoType(QualType ResultTy, + const FunctionType::ExtInfo &Info) const; + + QualType getFunctionNoProtoType(QualType ResultTy) const { + return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo()); + } + + /// getFunctionType - Return a normal function type with a typed + /// argument list. + QualType getFunctionType(QualType ResultTy, + const QualType *Args, unsigned NumArgs, + const FunctionProtoType::ExtProtoInfo &EPI) const; + + /// getTypeDeclType - Return the unique reference to the type for + /// the specified type declaration. + QualType getTypeDeclType(const TypeDecl *Decl, + const TypeDecl *PrevDecl = 0) const { + assert(Decl && "Passed null for Decl param"); + if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); + + if (PrevDecl) { + assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl"); + Decl->TypeForDecl = PrevDecl->TypeForDecl; + return QualType(PrevDecl->TypeForDecl, 0); + } + + return getTypeDeclTypeSlow(Decl); + } + + /// getTypedefType - Return the unique reference to the type for the + /// specified typedef-name decl. + QualType getTypedefType(const TypedefNameDecl *Decl, + QualType Canon = QualType()) const; + + QualType getRecordType(const RecordDecl *Decl) const; + + QualType getEnumType(const EnumDecl *Decl) const; + + QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const; + + QualType getAttributedType(AttributedType::Kind attrKind, + QualType modifiedType, + QualType equivalentType); + + QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced, + QualType Replacement) const; + QualType getSubstTemplateTypeParmPackType( + const TemplateTypeParmType *Replaced, + const TemplateArgument &ArgPack); + + QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, + bool ParameterPack, + TemplateTypeParmDecl *ParmDecl = 0) const; + + QualType getTemplateSpecializationType(TemplateName T, + const TemplateArgument *Args, + unsigned NumArgs, + QualType Canon = QualType()) const; + + QualType getCanonicalTemplateSpecializationType(TemplateName T, + const TemplateArgument *Args, + unsigned NumArgs) const; + + QualType getTemplateSpecializationType(TemplateName T, + const TemplateArgumentListInfo &Args, + QualType Canon = QualType()) const; + + TypeSourceInfo * + getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc, + const TemplateArgumentListInfo &Args, + QualType Canon = QualType()) const; + + QualType getParenType(QualType NamedType) const; + + QualType getElaboratedType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, + QualType NamedType) const; + QualType getDependentNameType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, + const IdentifierInfo *Name, + QualType Canon = QualType()) const; + + QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, + const IdentifierInfo *Name, + const TemplateArgumentListInfo &Args) const; + QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, + const IdentifierInfo *Name, + unsigned NumArgs, + const TemplateArgument *Args) const; + + QualType getPackExpansionType(QualType Pattern, + llvm::Optional NumExpansions); + + QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, + ObjCInterfaceDecl *PrevDecl = 0) const; + + QualType getObjCObjectType(QualType Base, + ObjCProtocolDecl * const *Protocols, + unsigned NumProtocols) const; + + /// getObjCObjectPointerType - Return a ObjCObjectPointerType type + /// for the given ObjCObjectType. + QualType getObjCObjectPointerType(QualType OIT) const; + + /// getTypeOfType - GCC extension. + QualType getTypeOfExprType(Expr *e) const; + QualType getTypeOfType(QualType t) const; + + /// getDecltypeType - C++0x decltype. + QualType getDecltypeType(Expr *e, QualType UnderlyingType) const; + + /// getUnaryTransformType - unary type transforms + QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType, + UnaryTransformType::UTTKind UKind) const; + + /// getAutoType - C++0x deduced auto type. + QualType getAutoType(QualType DeducedType) const; + + /// getAutoDeductType - C++0x deduction pattern for 'auto' type. + QualType getAutoDeductType() const; + + /// getAutoRRefDeductType - C++0x deduction pattern for 'auto &&' type. + QualType getAutoRRefDeductType() const; + + /// getTagDeclType - Return the unique reference to the type for the + /// specified TagDecl (struct/union/class/enum) decl. + QualType getTagDeclType(const TagDecl *Decl) const; + + /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined + /// in . The sizeof operator requires this (C99 6.5.3.4p4). + CanQualType getSizeType() const; + + /// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5), + /// defined in . + CanQualType getIntMaxType() const; + + /// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5), + /// defined in . + CanQualType getUIntMaxType() const; + + /// getWCharType - In C++, this returns the unique wchar_t type. In C99, this + /// returns a type compatible with the type defined in 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" (C99 7.17) + /// defined in . Pointer - pointer requires this (C99 6.5.6p9). + QualType getPointerDiffType() const; + + // getCFConstantStringType - Return the C structure type used to represent + // constant CFStrings. + QualType getCFConstantStringType() const; + + /// Get the structure type used to representation CFStrings, or NULL + /// if it hasn't yet been built. + QualType getRawCFConstantStringType() const { + if (CFConstantStringTypeDecl) + return getTagDeclType(CFConstantStringTypeDecl); + return QualType(); + } + void setCFConstantStringType(QualType T); + + // This setter/getter represents the ObjC type for an NSConstantString. + void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl); + QualType getObjCConstantStringInterface() const { + return ObjCConstantStringType; + } + + QualType getObjCNSStringType() const { + return ObjCNSStringType; + } + + void setObjCNSStringType(QualType T) { + ObjCNSStringType = T; + } + + /// \brief Retrieve the type that 'id' has been defined to, which may be + /// different from the built-in 'id' if 'id' has been typedef'd. + QualType getObjCIdRedefinitionType() const { + if (ObjCIdRedefinitionType.isNull()) + return getObjCIdType(); + return ObjCIdRedefinitionType; + } + + /// \brief Set the user-written type that redefines 'id'. + void setObjCIdRedefinitionType(QualType RedefType) { + ObjCIdRedefinitionType = RedefType; + } + + /// \brief Retrieve the type that 'Class' has been defined to, which may be + /// different from the built-in 'Class' if 'Class' has been typedef'd. + QualType getObjCClassRedefinitionType() const { + if (ObjCClassRedefinitionType.isNull()) + return getObjCClassType(); + return ObjCClassRedefinitionType; + } + + /// \brief Set the user-written type that redefines 'SEL'. + void setObjCClassRedefinitionType(QualType RedefType) { + ObjCClassRedefinitionType = RedefType; + } + + /// \brief Retrieve the type that 'SEL' has been defined to, which may be + /// different from the built-in 'SEL' if 'SEL' has been typedef'd. + QualType getObjCSelRedefinitionType() const { + if (ObjCSelRedefinitionType.isNull()) + return getObjCSelType(); + return ObjCSelRedefinitionType; + } + + + /// \brief Set the user-written type that redefines 'SEL'. + void setObjCSelRedefinitionType(QualType RedefType) { + ObjCSelRedefinitionType = RedefType; + } + + /// \brief Retrieve the Objective-C "instancetype" type, if already known; + /// otherwise, returns a NULL type; + QualType getObjCInstanceType() { + return getTypeDeclType(getObjCInstanceTypeDecl()); + } + + /// \brief Retrieve the typedef declaration corresponding to the Objective-C + /// "instancetype" type. + TypedefDecl *getObjCInstanceTypeDecl(); + + /// \brief Set the type for the C FILE type. + void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; } + + /// \brief Retrieve the C FILE type. + QualType getFILEType() const { + if (FILEDecl) + return getTypeDeclType(FILEDecl); + return QualType(); + } + + /// \brief Set the type for the C jmp_buf type. + void setjmp_bufDecl(TypeDecl *jmp_bufDecl) { + this->jmp_bufDecl = jmp_bufDecl; + } + + /// \brief Retrieve the C jmp_buf type. + QualType getjmp_bufType() const { + if (jmp_bufDecl) + return getTypeDeclType(jmp_bufDecl); + return QualType(); + } + + /// \brief Set the type for the C sigjmp_buf type. + void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl) { + this->sigjmp_bufDecl = sigjmp_bufDecl; + } + + /// \brief Retrieve the C sigjmp_buf type. + QualType getsigjmp_bufType() const { + if (sigjmp_bufDecl) + return getTypeDeclType(sigjmp_bufDecl); + return QualType(); + } + + /// \brief Set the type for the C ucontext_t type. + void setucontext_tDecl(TypeDecl *ucontext_tDecl) { + this->ucontext_tDecl = ucontext_tDecl; + } + + /// \brief Retrieve the C ucontext_t type. + QualType getucontext_tType() const { + if (ucontext_tDecl) + return getTypeDeclType(ucontext_tDecl); + return QualType(); + } + + /// \brief The result type of logical operations, '<', '>', '!=', etc. + QualType getLogicalOperationType() const { + return getLangOpts().CPlusPlus ? BoolTy : IntTy; + } + + /// 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) const; + + void getLegacyIntegralTypeEncoding(QualType &t) const; + + // Put the string version of type qualifiers into S. + void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, + std::string &S) const; + + /// getObjCEncodingForFunctionDecl - Returns the encoded type for this + /// function. This is in the same format as Objective-C method encodings. + /// + /// \returns true if an error occurred (e.g., because one of the parameter + /// types is incomplete), false otherwise. + bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S); + + /// getObjCEncodingForMethodDecl - Return the encoded type for this method + /// declaration. + /// + /// \returns true if an error occurred (e.g., because one of the parameter + /// types is incomplete), false otherwise. + bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S, + bool Extended = false) + const; + + /// getObjCEncodingForBlock - Return the encoded type for this block + /// declaration. + std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const; + + /// getObjCEncodingForPropertyDecl - Return the encoded type for + /// this method declaration. If non-NULL, Container must be either + /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should + /// only be NULL when getting encodings for protocol properties. + void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, + const Decl *Container, + std::string &S) const; + + bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, + ObjCProtocolDecl *rProto) const; + + /// getObjCEncodingTypeSize returns size of type for objective-c encoding + /// purpose in characters. + CharUnits getObjCEncodingTypeSize(QualType t) const; + + /// \brief Retrieve the typedef corresponding to the predefined 'id' type + /// in Objective-C. + TypedefDecl *getObjCIdDecl() const; + + /// 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 getTypeDeclType(getObjCIdDecl()); + } + + /// \brief Retrieve the typedef corresponding to the predefined 'SEL' type + /// in Objective-C. + TypedefDecl *getObjCSelDecl() const; + + /// \brief Retrieve the type that corresponds to the predefined Objective-C + /// 'SEL' type. + QualType getObjCSelType() const { + return getTypeDeclType(getObjCSelDecl()); + } + + /// \brief Retrieve the typedef declaration corresponding to the predefined + /// Objective-C 'Class' type. + TypedefDecl *getObjCClassDecl() const; + + /// 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 getTypeDeclType(getObjCClassDecl()); + } + + /// \brief Retrieve the Objective-C class declaration corresponding to + /// the predefined 'Protocol' class. + ObjCInterfaceDecl *getObjCProtocolDecl() const; + + /// \brief Retrieve the type of the Objective-C "Protocol" class. + QualType getObjCProtoType() const { + return getObjCInterfaceType(getObjCProtocolDecl()); + } + + 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) const { + return getQualifiedType(T, Qualifiers::fromCVRMask(CVR)); + } + + /// getQualifiedType - Un-split a SplitQualType. + QualType getQualifiedType(SplitQualType split) const { + return getQualifiedType(split.Ty, split.Quals); + } + + /// getQualifiedType - Returns a type with additional qualifiers. + QualType getQualifiedType(QualType T, Qualifiers Qs) const { + if (!Qs.hasNonFastQualifiers()) + return T.withFastQualifiers(Qs.getFastQualifiers()); + QualifierCollector Qc(Qs); + const Type *Ptr = Qc.strip(T); + return getExtQualType(Ptr, Qc); + } + + /// getQualifiedType - Returns a type with additional qualifiers. + QualType getQualifiedType(const Type *T, Qualifiers Qs) const { + if (!Qs.hasNonFastQualifiers()) + return QualType(T, Qs.getFastQualifiers()); + return getExtQualType(T, Qs); + } + + /// getLifetimeQualifiedType - Returns a type with the given + /// lifetime qualifier. + QualType getLifetimeQualifiedType(QualType type, + Qualifiers::ObjCLifetime lifetime) { + assert(type.getObjCLifetime() == Qualifiers::OCL_None); + assert(lifetime != Qualifiers::OCL_None); + + Qualifiers qs; + qs.addObjCLifetime(lifetime); + return getQualifiedType(type, qs); + } + + DeclarationNameInfo getNameForTemplate(TemplateName Name, + SourceLocation NameLoc) const; + + TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin, + UnresolvedSetIterator End) const; + + TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, + bool TemplateKeyword, + TemplateDecl *Template) const; + + TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, + const IdentifierInfo *Name) const; + TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, + OverloadedOperatorKind Operator) const; + TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param, + TemplateName replacement) const; + TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, + const TemplateArgument &ArgPack) const; + + enum GetBuiltinTypeError { + GE_None, //< No error + GE_Missing_stdio, //< Missing a type from + GE_Missing_setjmp, //< Missing a type from + GE_Missing_ucontext //< Missing a type from + }; + + /// GetBuiltinType - Return the type for the specified builtin. If + /// IntegerConstantArgs is non-null, it is filled in with a bitmask of + /// arguments to the builtin that are required to be integer constant + /// expressions. + QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, + unsigned *IntegerConstantArgs = 0) const; + +private: + CanQualType getFromTargetType(unsigned Type) const; + std::pair getTypeInfoImpl(const Type *T) const; + + //===--------------------------------------------------------------------===// + // Type Predicates. + //===--------------------------------------------------------------------===// + +public: + /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's + /// garbage collection attribute. + /// + Qualifiers::GC getObjCGCAttrKind(QualType Ty) const; + + /// areCompatibleVectorTypes - Return true if the given vector types + /// are of the same unqualified type or if they are equivalent to the same + /// GCC vector type, ignoring whether they are target-specific (AltiVec or + /// Neon) types. + bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec); + + /// isObjCNSObjectType - Return true if this is an NSObject object with + /// its NSObject attribute set. + static bool isObjCNSObjectType(QualType Ty) { + return Ty->isObjCNSObjectType(); + } + + //===--------------------------------------------------------------------===// + // 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 getTypeInfo(const Type *T) const; + std::pair getTypeInfo(QualType T) const { + 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) const { + return getTypeInfo(T).first; + } + uint64_t getTypeSize(const Type *T) const { + return getTypeInfo(T).first; + } + + /// getCharWidth - Return the size of the character type, in bits + uint64_t getCharWidth() const { + return getTypeSize(CharTy); + } + + /// toCharUnitsFromBits - Convert a size in bits to a size in characters. + CharUnits toCharUnitsFromBits(int64_t BitSize) const; + + /// toBits - Convert a size in characters to a size in bits. + int64_t toBits(CharUnits CharSize) const; + + /// getTypeSizeInChars - Return the size of the specified type, in characters. + /// This method does not work on incomplete types. + CharUnits getTypeSizeInChars(QualType T) const; + CharUnits getTypeSizeInChars(const Type *T) const; + + /// getTypeAlign - Return the ABI-specified alignment of a type, in bits. + /// This method does not work on incomplete types. + unsigned getTypeAlign(QualType T) const { + return getTypeInfo(T).second; + } + unsigned getTypeAlign(const Type *T) const { + 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) const; + CharUnits getTypeAlignInChars(const Type *T) const; + + std::pair getTypeInfoInChars(const Type *T) const; + std::pair getTypeInfoInChars(QualType T) const; + + /// 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) const; + + /// 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) const; + + /// 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) const; + + /// getASTObjCInterfaceLayout - Get or compute information about the + /// layout of the specified Objective-C interface. + const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) + const; + + void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS, + bool Simple = false) const; + + /// 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) const; + + /// getKeyFunction - Get the key function for the given record decl, or NULL + /// if there isn't one. The key function is, according to the Itanium C++ ABI + /// section 5.2.3: + /// + /// ...the first non-pure virtual function that is not inline at the point + /// of class definition. + const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD); + + /// Get the offset of a FieldDecl or IndirectFieldDecl, in bits. + uint64_t getFieldOffset(const ValueDecl *FD) const; + + bool isNearlyEmpty(const CXXRecordDecl *RD) const; + + MangleContext *createMangleContext(); + + void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, + SmallVectorImpl &Ivars) const; + + unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const; + void CollectInheritedProtocols(const Decl *CDecl, + llvm::SmallPtrSet &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 { + return CanQualType::CreateUnsafe(T.getCanonicalType()); + } + + const Type *getCanonicalType(const Type *T) const { + 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) const; + + /// \brief Determine whether the given types are equivalent. + bool hasSameType(QualType T1, QualType T2) const { + 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) const { + return getCanonicalType(T1).getTypePtr() == + getCanonicalType(T2).getTypePtr(); + } + + bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2); + + /// \brief Retrieves the "canonical" nested name specifier for a + /// given nested name specifier. + /// + /// The canonical nested name specifier is a nested name specifier + /// that uniquely identifies a type or namespace within the type + /// system. For example, given: + /// + /// \code + /// namespace N { + /// struct S { + /// template struct X { typename T* type; }; + /// }; + /// } + /// + /// template struct Y { + /// typename N::S::X::type member; + /// }; + /// \endcode + /// + /// Here, the nested-name-specifier for N::S::X:: will be + /// S::X, since 'S' and 'X' are uniquely defined + /// by declarations in the type system and the canonical type for + /// the template type parameter 'T' is template-param-0-0. + NestedNameSpecifier * + getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const; + + /// \brief Retrieves the default calling convention to use for + /// C++ instance methods. + CallingConv getDefaultMethodCallConv(); + + /// \brief Retrieves the canonical representation of the given + /// calling convention. + CallingConv getCanonicalCallConv(CallingConv CC) const { + if (!LangOpts.MRTD && 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::template rebind, where the nested name + /// specifier itself is dependent. In this case, the canonical + /// template name uses the shortest form of the dependent + /// nested-name-specifier, which itself contains all canonical + /// types, values, and templates. + TemplateName getCanonicalTemplateName(TemplateName Name) const; + + /// \brief Determine whether the given template names refer to the same + /// template. + bool hasSameTemplateName(TemplateName X, TemplateName Y); + + /// \brief Retrieve the "canonical" template argument. + /// + /// The canonical template argument is the simplest template argument + /// (which may be a type, value, expression, or declaration) that + /// expresses the value of the argument. + TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) + const; + + /// Type Query functions. If the type is an instance of the specified class, + /// return the Type pointer for the underlying maximally pretty type. This + /// is a member of ASTContext because this may need to do some amount of + /// canonicalization, e.g. to move type qualifiers into the element type. + const ArrayType *getAsArrayType(QualType T) const; + const ConstantArrayType *getAsConstantArrayType(QualType T) const { + return dyn_cast_or_null(getAsArrayType(T)); + } + const VariableArrayType *getAsVariableArrayType(QualType T) const { + return dyn_cast_or_null(getAsArrayType(T)); + } + const IncompleteArrayType *getAsIncompleteArrayType(QualType T) const { + return dyn_cast_or_null(getAsArrayType(T)); + } + const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T) + const { + return dyn_cast_or_null(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) const; + + /// getBaseElementType - Returns the innermost element type of a type + /// (which needn't actually be an array type). + QualType getBaseElementType(QualType QT) const; + + /// getConstantArrayElementCount - Returns number of constant array elements. + uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const; + + /// \brief Perform adjustment on the parameter type of a function. + /// + /// This routine adjusts the given parameter type @p T to the actual + /// parameter type used by semantic analysis (C99 6.7.5.3p[7,8], + /// C++ [dcl.fct]p3). The adjusted parameter type is returned. + QualType getAdjustedParameterType(QualType T); + + /// \brief Retrieve the parameter type as adjusted for use in the signature + /// of a function, decaying array and function types and removing top-level + /// cv-qualifiers. + QualType getSignatureParameterType(QualType T); + + /// 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) const; + + /// 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) const; + + /// \brief Recurses in pointer/array types until it finds an objc retainable + /// type and returns its ownership. + Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const; + + /// \brief Whether this is a promotable bitfield reference according + /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions). + /// + /// \returns the type this bit-field will promote to, or NULL if no + /// promotion occurs. + QualType isPromotableBitField(Expr *E) const; + + /// 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) const; + + /// 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) const; + + /// 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; + + unsigned getTargetAddressSpace(QualType T) const { + return getTargetAddressSpace(T.getQualifiers()); + } + + unsigned getTargetAddressSpace(Qualifiers Q) const { + return getTargetAddressSpace(Q.getAddressSpace()); + } + + unsigned getTargetAddressSpace(unsigned AS) const { + if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count) + return AS; + else + return (*AddrSpaceMap)[AS - LangAS::Offset]; + } + +private: + // Helper for integer ordering + unsigned getIntegerRank(const Type *T) const; + +public: + + //===--------------------------------------------------------------------===// + // Type Compatibility Predicates + //===--------------------------------------------------------------------===// + + /// Compatibility predicates used to check assignment expressions. + bool typesAreCompatible(QualType T1, QualType T2, + bool CompareUnqualified = false); // C99 6.2.7p1 + + bool propertyTypesAreCompatible(QualType, QualType); + bool typesAreBlockPointerCompatible(QualType, QualType); + + bool isObjCIdType(QualType T) const { + return T == getObjCIdType(); + } + bool isObjCClassType(QualType T) const { + return T == getObjCClassType(); + } + bool isObjCSelType(QualType T) const { + return T == getObjCSelType(); + } + bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS); + bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, + bool ForCompare); + + bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS); + + // Check the safety of assignment from LHS to RHS + bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, + const ObjCObjectPointerType *RHSOPT); + bool canAssignObjCInterfaces(const ObjCObjectType *LHS, + const ObjCObjectType *RHS); + bool canAssignObjCInterfacesInBlockPointer( + const ObjCObjectPointerType *LHSOPT, + const ObjCObjectPointerType *RHSOPT, + bool BlockReturnType); + bool areComparableObjCPointerTypes(QualType LHS, QualType RHS); + QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT, + const ObjCObjectPointerType *RHSOPT); + bool canBindObjCObjectType(QualType To, QualType From); + + // Functions for calculating composite types + QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false, + bool Unqualified = false, bool BlockReturnType = false); + QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, + bool Unqualified = false); + QualType mergeFunctionArgumentTypes(QualType, QualType, + bool OfBlockPointer=false, + bool Unqualified = false); + QualType mergeTransparentUnionType(QualType, QualType, + bool OfBlockPointer=false, + bool Unqualified = false); + + QualType mergeObjCGCQualifiers(QualType, QualType); + + bool FunctionTypesMatchOnNSConsumedAttrs( + const FunctionProtoType *FromFunctionType, + const FunctionProtoType *ToFunctionType); + + void ResetObjCLayout(const ObjCContainerDecl *CD) { + ObjCLayouts[CD] = 0; + } + + //===--------------------------------------------------------------------===// + // Integer Predicates + //===--------------------------------------------------------------------===// + + // The width of an integer, as defined in C99 6.2.6.2. This is the number + // of bits in an integer type excluding any padding bits. + unsigned getIntWidth(QualType T) const; + + // Per C99 6.2.5p6, for every signed integer type, there is a corresponding + // unsigned integer type. This method takes a signed type, and returns the + // corresponding unsigned integer type. + QualType getCorrespondingUnsignedType(QualType T); + + //===--------------------------------------------------------------------===// + // Type Iterators. + //===--------------------------------------------------------------------===// + + typedef std::vector::iterator type_iterator; + typedef std::vector::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) const { + llvm::APSInt Res(getIntWidth(Type), + !Type->isSignedIntegerOrEnumerationType()); + Res = Value; + return Res; + } + + bool isSentinelNullExpr(const Expr *E); + + /// \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 returns true if there is at lease one @implementation in TU. + bool AnyObjCImplementation() { + return !ObjCImpls.empty(); + } + + /// \brief Set the implementation of ObjCInterfaceDecl. + void setObjCImplementation(ObjCInterfaceDecl *IFaceD, + ObjCImplementationDecl *ImplD); + /// \brief Set the implementation of ObjCCategoryDecl. + void setObjCImplementation(ObjCCategoryDecl *CatD, + ObjCCategoryImplDecl *ImplD); + + /// \brief Get the duplicate declaration of a ObjCMethod in the same + /// interface, or null if non exists. + const ObjCMethodDecl *getObjCMethodRedeclaration( + const ObjCMethodDecl *MD) const { + llvm::DenseMap::const_iterator + I = ObjCMethodRedecls.find(MD); + if (I == ObjCMethodRedecls.end()) + return 0; + return I->second; + } + + void setObjCMethodRedeclaration(const ObjCMethodDecl *MD, + const ObjCMethodDecl *Redecl) { + ObjCMethodRedecls[MD] = Redecl; + } + + /// \brief Returns the objc interface that \arg ND belongs to if it is a + /// objc method/property/ivar etc. that is part of an interface, + /// otherwise returns null. + ObjCInterfaceDecl *getObjContainingInterface(NamedDecl *ND) const; + + /// \brief Set the copy inialization expression of a block var decl. + void setBlockVarCopyInits(VarDecl*VD, Expr* Init); + /// \brief Get the copy initialization expression of VarDecl,or NULL if + /// none exists. + Expr *getBlockVarCopyInits(const VarDecl*VD); + + /// \brief Allocate an uninitialized TypeSourceInfo. + /// + /// The caller should initialize the memory held by TypeSourceInfo using + /// the TypeLoc wrappers. + /// + /// \param T the type that will be the basis for type source info. This type + /// should refer to how the declarator was written in source code, not to + /// what type semantic analysis resolved the declarator to. + /// + /// \param Size the size of the type info to create, or 0 if the size + /// should be calculated based on the type. + TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0) const; + + /// \brief Allocate a TypeSourceInfo where all locations have been + /// initialized to a given location, which defaults to the empty + /// location. + TypeSourceInfo * + getTrivialTypeSourceInfo(QualType T, + SourceLocation Loc = SourceLocation()) const; + + TypeSourceInfo *getNullTypeSourceInfo() { return &NullTypeSourceInfo; } + + /// \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); + + GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD); + GVALinkage GetGVALinkageForVariable(const VarDecl *VD); + + /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH + /// lazily, only when used; this is only relevant for function or file scoped + /// var definitions. + /// + /// \returns true if the function/var must be CodeGen'ed/deserialized even if + /// it is not used. + bool DeclMustBeEmitted(const Decl *D); + + /// \brief Retrieve the lambda mangling number for a lambda expression. + unsigned getLambdaManglingNumber(CXXMethodDecl *CallOperator); + + /// \brief Used by ParmVarDecl to store on the side the + /// index of the parameter when it exceeds the size of the normal bitfield. + void setParameterIndex(const ParmVarDecl *D, unsigned index); + + /// \brief Used by ParmVarDecl to retrieve on the side the + /// index of the parameter when it exceeds the size of the normal bitfield. + unsigned getParameterIndex(const ParmVarDecl *D) const; + + //===--------------------------------------------------------------------===// + // Statistics + //===--------------------------------------------------------------------===// + + /// \brief The number of implicitly-declared default constructors. + static unsigned NumImplicitDefaultConstructors; + + /// \brief The number of implicitly-declared default constructors for + /// which declarations were built. + static unsigned NumImplicitDefaultConstructorsDeclared; + + /// \brief The number of implicitly-declared copy constructors. + static unsigned NumImplicitCopyConstructors; + + /// \brief The number of implicitly-declared copy constructors for + /// which declarations were built. + static unsigned NumImplicitCopyConstructorsDeclared; + + /// \brief The number of implicitly-declared move constructors. + static unsigned NumImplicitMoveConstructors; + + /// \brief The number of implicitly-declared move constructors for + /// which declarations were built. + static unsigned NumImplicitMoveConstructorsDeclared; + + /// \brief The number of implicitly-declared copy assignment operators. + static unsigned NumImplicitCopyAssignmentOperators; + + /// \brief The number of implicitly-declared copy assignment operators for + /// which declarations were built. + static unsigned NumImplicitCopyAssignmentOperatorsDeclared; + + /// \brief The number of implicitly-declared move assignment operators. + static unsigned NumImplicitMoveAssignmentOperators; + + /// \brief The number of implicitly-declared move assignment operators for + /// which declarations were built. + static unsigned NumImplicitMoveAssignmentOperatorsDeclared; + + /// \brief The number of implicitly-declared destructors. + static unsigned NumImplicitDestructors; + + /// \brief The number of implicitly-declared destructors for which + /// declarations were built. + static unsigned NumImplicitDestructorsDeclared; + +private: + ASTContext(const ASTContext&); // DO NOT IMPLEMENT + void operator=(const ASTContext&); // DO NOT IMPLEMENT + +public: + /// \brief Initialize built-in types. + /// + /// This routine may only be invoked once for a given ASTContext object. + /// It is normally invoked by the ASTContext constructor. However, the + /// constructor can be asked to delay initialization, which places the burden + /// of calling this function on the user of that object. + /// + /// \param Target The target + void InitBuiltinTypes(const TargetInfo &Target); + +private: + 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, + bool StructField = false, + bool EncodeBlockParameters = false, + bool EncodeClassNames = false) const; + + // Adds the encoding of the structure's members. + void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S, + const FieldDecl *Field, + bool includeVBases = true) const; + + // Adds the encoding of a method parameter or return type. + void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, + QualType T, std::string& S, + bool Extended) const; + + const ASTRecordLayout & + getObjCLayout(const ObjCInterfaceDecl *D, + const ObjCImplementationDecl *Impl) const; + +private: + /// \brief A set of deallocations that should be performed when the + /// ASTContext is destroyed. + SmallVector, 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 LastSDM; + + /// \brief A counter used to uniquely identify "blocks". + mutable unsigned int UniqueBlockByRefTypeID; + + friend class DeclContext; + friend class DeclarationNameTable; + void ReleaseDeclContextMaps(); +}; + +/// @brief Utility function for constructing a nullary selector. +static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) { + IdentifierInfo* II = &Ctx.Idents.get(name); + return Ctx.Selectors.getSelector(0, &II); +} + +/// @brief Utility function for constructing an unary selector. +static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) { + IdentifierInfo* II = &Ctx.Idents.get(name); + return Ctx.Selectors.getSelector(1, &II); +} + +} // end namespace clang + +// operator new and delete aren't allowed inside namespaces. + +/// @brief Placement new for using the ASTContext's allocator. +/// +/// This placement form of operator new uses the ASTContext's allocator for +/// obtaining memory. +/// +/// IMPORTANT: These are also declared in clang/AST/Attr.h! Any changes here +/// need to also be made there. +/// +/// We intentionally avoid using a nothrow specification here so that the calls +/// to this operator will not perform a null check on the result -- the +/// underlying allocator never returns null pointers. +/// +/// Usage looks like this (assuming there's an ASTContext 'Context' in scope): +/// @code +/// // Default alignment (8) +/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments); +/// // Specific alignment +/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments); +/// @endcode +/// 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, const clang::ASTContext &C, + size_t Alignment) { + return C.Allocate(Bytes, Alignment); +} +/// @brief Placement delete companion to the new above. +/// +/// This operator is just a companion to the new above. There is no way of +/// invoking it directly; see the new operator for more details. This operator +/// is called implicitly by the compiler if a placement new expression using +/// the ASTContext throws in the object constructor. +inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) { + C.Deallocate(Ptr); +} + +/// This placement form of operator new[] uses the ASTContext's allocator for +/// obtaining memory. +/// +/// We intentionally avoid using a nothrow specification here so that the calls +/// to this operator will not perform a null check on the result -- the +/// underlying allocator never returns null pointers. +/// +/// Usage looks like this (assuming there's an ASTContext 'Context' in scope): +/// @code +/// // Default alignment (8) +/// char *data = new (Context) char[10]; +/// // Specific alignment +/// char *data = new (Context, 4) char[10]; +/// @endcode +/// 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, const clang::ASTContext& C, + size_t Alignment = 8) { + return C.Allocate(Bytes, Alignment); +} + +/// @brief Placement delete[] companion to the new[] above. +/// +/// This operator is just a companion to the new[] above. There is no way of +/// invoking it directly; see the new[] operator for more details. This operator +/// is called implicitly by the compiler if a placement new[] expression using +/// the ASTContext throws in the object constructor. +inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) { + C.Deallocate(Ptr); +} + +#endif diff --git a/clang/include/clang/AST/ASTDiagnostic.h b/clang/include/clang/AST/ASTDiagnostic.h new file mode 100644 index 0000000..64e955e --- /dev/null +++ b/clang/include/clang/AST/ASTDiagnostic.h @@ -0,0 +1,50 @@ +//===--- 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,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, +#define ASTSTART +#include "clang/Basic/DiagnosticASTKinds.inc" +#undef DIAG + NUM_BUILTIN_AST_DIAGNOSTICS + }; + } // end namespace diag + + /// \brief DiagnosticsEngine argument formatting function for diagnostics that + /// involve AST nodes. + /// + /// This function formats diagnostic arguments for various AST nodes, + /// including types, declaration names, nested name specifiers, and + /// declaration contexts, into strings that can be printed as part of + /// diagnostics. It is meant to be used as the argument to + /// \c DiagnosticsEngine::SetArgToStringFn(), where the cookie is an \c + /// ASTContext pointer. + void FormatASTNodeDiagnosticArgument( + DiagnosticsEngine::ArgumentKind Kind, + intptr_t Val, + const char *Modifier, + unsigned ModLen, + const char *Argument, + unsigned ArgLen, + const DiagnosticsEngine::ArgumentValue *PrevArgs, + unsigned NumPrevArgs, + SmallVectorImpl &Output, + void *Cookie, + ArrayRef QualTypeVals); +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h new file mode 100644 index 0000000..7157efe --- /dev/null +++ b/clang/include/clang/AST/ASTImporter.h @@ -0,0 +1,278 @@ +//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTImporter class which imports AST nodes from one +// context into another context. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_ASTIMPORTER_H +#define LLVM_CLANG_AST_ASTIMPORTER_H + +#include "clang/AST/DeclarationName.h" +#include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallVector.h" + +namespace clang { + class ASTContext; + class Decl; + class DeclContext; + class DiagnosticsEngine; + class Expr; + class FileManager; + class IdentifierInfo; + class NestedNameSpecifier; + class Stmt; + class TypeSourceInfo; + + /// \brief Imports selected nodes from one AST context into another context, + /// merging AST nodes where appropriate. + class ASTImporter { + public: + typedef llvm::DenseSet > NonEquivalentDeclSet; + + private: + /// \brief The contexts we're importing to and from. + ASTContext &ToContext, &FromContext; + + /// \brief The file managers we're importing to and from. + FileManager &ToFileManager, &FromFileManager; + + /// \brief Whether to perform a minimal import. + bool Minimal; + + /// \brief Mapping from the already-imported types in the "from" context + /// to the corresponding types in the "to" context. + llvm::DenseMap ImportedTypes; + + /// \brief Mapping from the already-imported declarations in the "from" + /// context to the corresponding declarations in the "to" context. + llvm::DenseMap ImportedDecls; + + /// \brief Mapping from the already-imported statements in the "from" + /// context to the corresponding statements in the "to" context. + llvm::DenseMap ImportedStmts; + + /// \brief Mapping from the already-imported FileIDs in the "from" source + /// manager to the corresponding FileIDs in the "to" source manager. + llvm::DenseMap ImportedFileIDs; + + /// \brief Imported, anonymous tag declarations that are missing their + /// corresponding typedefs. + SmallVector AnonTagsWithPendingTypedefs; + + /// \brief Declaration (from, to) pairs that are known not to be equivalent + /// (which we have already complained about). + NonEquivalentDeclSet NonEquivalentDecls; + + public: + /// \brief Create a new AST importer. + /// + /// \param ToContext The context we'll be importing into. + /// + /// \param ToFileManager The file manager we'll be importing into. + /// + /// \param FromContext The context we'll be importing from. + /// + /// \param FromFileManager The file manager we'll be importing into. + /// + /// \param MinimalImport If true, the importer will attempt to import + /// as little as it can, e.g., by importing declarations as forward + /// declarations that can be completed at a later point. + ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, + ASTContext &FromContext, FileManager &FromFileManager, + bool MinimalImport); + + virtual ~ASTImporter(); + + /// \brief Whether the importer will perform a minimal import, creating + /// to-be-completed forward declarations when possible. + bool isMinimalImport() const { return Minimal; } + + /// \brief Import the given type from the "from" context into the "to" + /// context. + /// + /// \returns the equivalent type in the "to" context, or a NULL type if + /// an error occurred. + QualType Import(QualType FromT); + + /// \brief Import the given type source information from the + /// "from" context into the "to" context. + /// + /// \returns the equivalent type source information in the "to" + /// context, or NULL if an error occurred. + TypeSourceInfo *Import(TypeSourceInfo *FromTSI); + + /// \brief Import the given declaration from the "from" context into the + /// "to" context. + /// + /// \returns the equivalent declaration in the "to" context, or a NULL type + /// if an error occurred. + Decl *Import(Decl *FromD); + + /// \brief Import the given declaration context from the "from" + /// AST context into the "to" AST context. + /// + /// \returns the equivalent declaration context in the "to" + /// context, or a NULL type if an error occurred. + DeclContext *ImportContext(DeclContext *FromDC); + + /// \brief Import the given expression from the "from" context into the + /// "to" context. + /// + /// \returns the equivalent expression in the "to" context, or NULL if + /// an error occurred. + Expr *Import(Expr *FromE); + + /// \brief Import the given statement from the "from" context into the + /// "to" context. + /// + /// \returns the equivalent statement in the "to" context, or NULL if + /// an error occurred. + Stmt *Import(Stmt *FromS); + + /// \brief Import the given nested-name-specifier from the "from" + /// context into the "to" context. + /// + /// \returns the equivalent nested-name-specifier in the "to" + /// context, or NULL if an error occurred. + NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS); + + /// \brief Import the given nested-name-specifier from the "from" + /// context into the "to" context. + /// + /// \returns the equivalent nested-name-specifier in the "to" + /// context. + NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS); + + /// \brief Import the goven template name from the "from" context into the + /// "to" context. + TemplateName Import(TemplateName From); + + /// \brief Import the given source location from the "from" context into + /// the "to" context. + /// + /// \returns the equivalent source location in the "to" context, or an + /// invalid source location if an error occurred. + SourceLocation Import(SourceLocation FromLoc); + + /// \brief Import the given source range from the "from" context into + /// the "to" context. + /// + /// \returns the equivalent source range in the "to" context, or an + /// invalid source location if an error occurred. + SourceRange Import(SourceRange FromRange); + + /// \brief Import the given declaration name from the "from" + /// context into the "to" context. + /// + /// \returns the equivalent declaration name in the "to" context, + /// or an empty declaration name if an error occurred. + DeclarationName Import(DeclarationName FromName); + + /// \brief Import the given identifier from the "from" context + /// into the "to" context. + /// + /// \returns the equivalent identifier in the "to" context. + IdentifierInfo *Import(const IdentifierInfo *FromId); + + /// \brief Import the given Objective-C selector from the "from" + /// context into the "to" context. + /// + /// \returns the equivalent selector in the "to" context. + Selector Import(Selector FromSel); + + /// \brief Import the given file ID from the "from" context into the + /// "to" context. + /// + /// \returns the equivalent file ID in the source manager of the "to" + /// context. + FileID Import(FileID); + + /// \brief Import the definition of the given declaration, including all of + /// the declarations it contains. + /// + /// This routine is intended to be used + void ImportDefinition(Decl *From); + + /// \brief Cope with a name conflict when importing a declaration into the + /// given context. + /// + /// This routine is invoked whenever there is a name conflict while + /// importing a declaration. The returned name will become the name of the + /// imported declaration. By default, the returned name is the same as the + /// original name, leaving the conflict unresolve such that name lookup + /// for this name is likely to find an ambiguity later. + /// + /// Subclasses may override this routine to resolve the conflict, e.g., by + /// renaming the declaration being imported. + /// + /// \param Name the name of the declaration being imported, which conflicts + /// with other declarations. + /// + /// \param DC the declaration context (in the "to" AST context) in which + /// the name is being imported. + /// + /// \param IDNS the identifier namespace in which the name will be found. + /// + /// \param Decls the set of declarations with the same name as the + /// declaration being imported. + /// + /// \param NumDecls the number of conflicting declarations in \p Decls. + /// + /// \returns the name that the newly-imported declaration should have. + virtual DeclarationName HandleNameConflict(DeclarationName Name, + DeclContext *DC, + unsigned IDNS, + NamedDecl **Decls, + unsigned NumDecls); + + /// \brief Retrieve the context that AST nodes are being imported into. + ASTContext &getToContext() const { return ToContext; } + + /// \brief Retrieve the context that AST nodes are being imported from. + ASTContext &getFromContext() const { return FromContext; } + + /// \brief Retrieve the file manager that AST nodes are being imported into. + FileManager &getToFileManager() const { return ToFileManager; } + + /// \brief Retrieve the file manager that AST nodes are being imported from. + FileManager &getFromFileManager() const { return FromFileManager; } + + /// \brief Report a diagnostic in the "to" context. + DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID); + + /// \brief Report a diagnostic in the "from" context. + DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID); + + /// \brief Return the set of declarations that we know are not equivalent. + NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; } + + /// \brief Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl. + /// Mark the Decl as complete, filling it in as much as possible. + /// + /// \param D A declaration in the "to" context. + virtual void CompleteDecl(Decl* D); + + /// \brief Note that we have imported the "from" declaration by mapping it + /// to the (potentially-newly-created) "to" declaration. + /// + /// Subclasses can override this function to observe all of the \c From -> + /// \c To declaration mappings as they are imported. + virtual Decl *Imported(Decl *From, Decl *To); + + /// \brief Determine whether the given types are structurally + /// equivalent. + bool IsStructurallyEquivalent(QualType From, QualType To); + }; +} + +#endif // LLVM_CLANG_AST_ASTIMPORTER_H diff --git a/clang/include/clang/AST/ASTMutationListener.h b/clang/include/clang/AST/ASTMutationListener.h new file mode 100644 index 0000000..cb038a0 --- /dev/null +++ b/clang/include/clang/AST/ASTMutationListener.h @@ -0,0 +1,84 @@ +//===--- ASTMutationListener.h - AST Mutation Interface --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTMutationListener interface. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H +#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H + +namespace clang { + class Decl; + class DeclContext; + class TagDecl; + class CXXRecordDecl; + class ClassTemplateDecl; + class ClassTemplateSpecializationDecl; + class FunctionDecl; + class FunctionTemplateDecl; + class ObjCCategoryDecl; + class ObjCInterfaceDecl; + class ObjCContainerDecl; + class ObjCPropertyDecl; + +/// \brief An abstract interface that should be implemented by listeners +/// that want to be notified when an AST entity gets modified after its +/// initial creation. +class ASTMutationListener { +public: + virtual ~ASTMutationListener(); + + /// \brief A new TagDecl definition was completed. + virtual void CompletedTagDefinition(const TagDecl *D) { } + + /// \brief A new declaration with name has been added to a DeclContext. + virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D) {} + + /// \brief An implicit member was added after the definition was completed. + virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {} + + /// \brief A template specialization (or partial one) was added to the + /// template declaration. + virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, + const ClassTemplateSpecializationDecl *D) {} + + /// \brief A template specialization (or partial one) was added to the + /// template declaration. + virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, + const FunctionDecl *D) {} + + /// \brief An implicit member got a definition. + virtual void CompletedImplicitDefinition(const FunctionDecl *D) {} + + /// \brief A static data member was implicitly instantiated. + virtual void StaticDataMemberInstantiated(const VarDecl *D) {} + + /// \brief A new objc category class was added for an interface. + virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, + const ObjCInterfaceDecl *IFD) {} + + /// \brief A objc class extension redeclared or introduced a property. + /// + /// \param Prop the property in the class extension + /// + /// \param OrigProp the property from the original interface that was declared + /// or null if the property was introduced. + /// + /// \param ClassExt the class extension. + virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, + const ObjCPropertyDecl *OrigProp, + const ObjCCategoryDecl *ClassExt) {} + + // NOTE: If new methods are added they should also be added to + // MultiplexASTMutationListener. +}; + +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/ASTVector.h b/clang/include/clang/AST/ASTVector.h new file mode 100644 index 0000000..217dfad --- /dev/null +++ b/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 +#include +#include + +#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 + inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) { + _Scalar_ptr_iterator_tag _Cat; + return _Cat; + } + + template + 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 +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::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_reverse_iterator; + typedef std::reverse_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::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 + 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 + 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(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 + 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(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 +void ASTVector::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::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/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h new file mode 100644 index 0000000..ef1aa25 --- /dev/null +++ b/clang/include/clang/AST/Attr.h @@ -0,0 +1,254 @@ +//===--- 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 "clang/Basic/LLVM.h" +#include "clang/Basic/AttrKinds.h" +#include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include + +namespace clang { + class ASTContext; + class IdentifierInfo; + class ObjCInterfaceDecl; + class Expr; + class QualType; + class FunctionDecl; + class TypeSourceInfo; +} + +// Defined in ASTContext.h +void *operator new(size_t Bytes, const clang::ASTContext &C, + size_t Alignment = 16); +// FIXME: Being forced to not have a default argument here due to redeclaration +// rules on default arguments sucks +void *operator new[](size_t Bytes, const clang::ASTContext &C, + size_t Alignment); + +// It is good practice to pair new/delete operators. Also, MSVC gives many +// warnings if a matching delete overload is not declared, even though the +// throw() spec guarantees it will not be implicitly called. +void operator delete(void *Ptr, const clang::ASTContext &C, size_t); +void operator delete[](void *Ptr, const clang::ASTContext &C, size_t); + +namespace clang { + +/// Attr - This represents one attribute. +class Attr { +private: + SourceRange Range; + unsigned AttrKind : 16; + +protected: + bool Inherited : 1; + + virtual ~Attr(); + + void* operator new(size_t bytes) throw() { + llvm_unreachable("Attrs cannot be allocated with regular 'new'."); + } + void operator delete(void* data) throw() { + llvm_unreachable("Attrs cannot be released with regular 'delete'."); + } + +public: + // Forward so that the regular new and delete do not hide global ones. + void* operator new(size_t Bytes, ASTContext &C, + size_t Alignment = 16) throw() { + return ::operator new(Bytes, C, Alignment); + } + void operator delete(void *Ptr, ASTContext &C, + size_t Alignment) throw() { + return ::operator delete(Ptr, C, Alignment); + } + +protected: + Attr(attr::Kind AK, SourceRange R) + : Range(R), AttrKind(AK), Inherited(false) {} + +public: + + attr::Kind getKind() const { + return static_cast(AttrKind); + } + + SourceLocation getLocation() const { return Range.getBegin(); } + SourceRange getRange() const { return Range; } + void setRange(SourceRange R) { Range = R; } + + bool isInherited() const { return Inherited; } + + // Clone this attribute. + virtual Attr* clone(ASTContext &C) const = 0; + + virtual bool isLateParsed() const { return false; } + + // Pretty print this attribute. + virtual void printPretty(llvm::raw_ostream &OS, ASTContext &C) const = 0; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *) { return true; } +}; + +class InheritableAttr : public Attr { + virtual void anchor(); +protected: + InheritableAttr(attr::Kind AK, SourceRange R) + : Attr(AK, R) {} + +public: + void setInherited(bool I) { Inherited = I; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + return A->getKind() <= attr::LAST_INHERITABLE; + } + static bool classof(const InheritableAttr *) { return true; } +}; + +class InheritableParamAttr : public InheritableAttr { + virtual void anchor(); +protected: + InheritableParamAttr(attr::Kind AK, SourceRange R) + : InheritableAttr(AK, R) {} + +public: + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + return A->getKind() <= attr::LAST_INHERITABLE_PARAM; + } + static bool classof(const InheritableParamAttr *) { return true; } +}; + +#include "clang/AST/Attrs.inc" + +/// AttrVec - A vector of Attr, which is how they are stored on the AST. +typedef SmallVector AttrVec; +typedef SmallVector ConstAttrVec; + +/// DestroyAttrs - Destroy the contents of an AttrVec. +inline void DestroyAttrs (AttrVec& V, ASTContext &C) { +} + +/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only +/// providing attributes that are of a specifc type. +template +class specific_attr_iterator { + /// Current - The current, underlying iterator. + /// In order to ensure we don't dereference an invalid iterator unless + /// specifically requested, we don't necessarily advance this all the + /// way. Instead, we advance it when an operation is requested; if the + /// operation is acting on what should be a past-the-end iterator, + /// then we offer no guarantees, but this way we do not dererence a + /// past-the-end iterator when we move to a past-the-end position. + mutable AttrVec::const_iterator Current; + + void AdvanceToNext() const { + while (!isa(*Current)) + ++Current; + } + + void AdvanceToNext(AttrVec::const_iterator I) const { + while (Current != I && !isa(*Current)) + ++Current; + } + +public: + typedef SpecificAttr* value_type; + typedef SpecificAttr* reference; + typedef SpecificAttr* pointer; + typedef std::forward_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + specific_attr_iterator() : Current() { } + explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { } + + reference operator*() const { + AdvanceToNext(); + return cast(*Current); + } + pointer operator->() const { + AdvanceToNext(); + return cast(*Current); + } + + specific_attr_iterator& operator++() { + ++Current; + return *this; + } + specific_attr_iterator operator++(int) { + specific_attr_iterator Tmp(*this); + ++(*this); + return Tmp; + } + + friend bool operator==(specific_attr_iterator Left, + specific_attr_iterator Right) { + if (Left.Current < Right.Current) + Left.AdvanceToNext(Right.Current); + else + Right.AdvanceToNext(Left.Current); + return Left.Current == Right.Current; + } + friend bool operator!=(specific_attr_iterator Left, + specific_attr_iterator Right) { + return !(Left == Right); + } +}; + +template +inline specific_attr_iterator specific_attr_begin(const AttrVec& vec) { + return specific_attr_iterator(vec.begin()); +} +template +inline specific_attr_iterator specific_attr_end(const AttrVec& vec) { + return specific_attr_iterator(vec.end()); +} + +template +inline bool hasSpecificAttr(const AttrVec& vec) { + return specific_attr_begin(vec) != specific_attr_end(vec); +} +template +inline T *getSpecificAttr(const AttrVec& vec) { + specific_attr_iterator i = specific_attr_begin(vec); + if (i != specific_attr_end(vec)) + return *i; + else + return 0; +} + +/// getMaxAlignment - Returns the highest alignment value found among +/// AlignedAttrs in an AttrVec, or 0 if there are none. +inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) { + unsigned Align = 0; + specific_attr_iterator i(V.begin()), e(V.end()); + for(; i != e; ++i) + Align = std::max(Align, i->getAlignment(Ctx)); + return Align; +} + +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/BaseSubobject.h b/clang/include/clang/AST/BaseSubobject.h new file mode 100644 index 0000000..6a036bb --- /dev/null +++ b/clang/include/clang/AST/BaseSubobject.h @@ -0,0 +1,87 @@ +//===--- BaseSubobject.h - BaseSubobject class ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides a definition of the BaseSubobject class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_BASESUBOBJECT_H +#define LLVM_CLANG_AST_BASESUBOBJECT_H + +#include "clang/AST/CharUnits.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/type_traits.h" + +namespace clang { + class CXXRecordDecl; + +// BaseSubobject - Uniquely identifies a direct or indirect base class. +// Stores both the base class decl and the offset from the most derived class to +// the base class. Used for vtable and VTT generation. +class BaseSubobject { + /// Base - The base class declaration. + const CXXRecordDecl *Base; + + /// BaseOffset - The offset from the most derived class to the base class. + CharUnits BaseOffset; + +public: + BaseSubobject() { } + BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset) + : Base(Base), BaseOffset(BaseOffset) { } + + /// getBase - Returns the base class declaration. + const CXXRecordDecl *getBase() const { return Base; } + + /// getBaseOffset - Returns the base class offset. + CharUnits getBaseOffset() const { return BaseOffset; } + + friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) { + return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset; + } +}; + +} // end namespace clang + +namespace llvm { + +template<> struct DenseMapInfo { + static clang::BaseSubobject getEmptyKey() { + return clang::BaseSubobject( + DenseMapInfo::getEmptyKey(), + clang::CharUnits::fromQuantity(DenseMapInfo::getEmptyKey())); + } + + static clang::BaseSubobject getTombstoneKey() { + return clang::BaseSubobject( + DenseMapInfo::getTombstoneKey(), + clang::CharUnits::fromQuantity(DenseMapInfo::getTombstoneKey())); + } + + static unsigned getHashValue(const clang::BaseSubobject &Base) { + return + DenseMapInfo::getHashValue(Base.getBase()) ^ + DenseMapInfo::getHashValue(Base.getBaseOffset().getQuantity()); + } + + static bool isEqual(const clang::BaseSubobject &LHS, + const clang::BaseSubobject &RHS) { + return LHS == RHS; + } +}; + +// It's OK to treat BaseSubobject as a POD type. +template <> struct isPodLike { + static const bool value = true; +}; + +} + +#endif diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def new file mode 100644 index 0000000..34e6fc5 --- /dev/null +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -0,0 +1,224 @@ +//===-- BuiltinTypeNodes.def - Metadata about BuiltinTypes ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the database about various builtin singleton types. +// +// BuiltinType::Id is the enumerator defining the type. +// +// Context.SingletonId is the global singleton of this type. Some global +// singletons are shared by multiple types. +// +// BUILTIN_TYPE(Id, SingletonId) - A builtin type that has not been +// covered by any other #define. Defining this macro covers all +// the builtins. +// +// SIGNED_TYPE(Id, SingletonId) - A signed integral type. +// +// UNSIGNED_TYPE(Id, SingletonId) - An unsigned integral type. +// +// FLOATING_TYPE(Id, SingletonId) - A floating-point type. +// +// PLACEHOLDER_TYPE(Id, SingletonId) - A placeholder type. Placeholder +// types are used to perform context-sensitive checking of specific +// forms of expression. +// +// SHARED_SINGLETON_TYPE(Expansion) - The given expansion corresponds +// to a builtin which uses a shared singleton type. +// +//===----------------------------------------------------------------------===// + +#ifndef SIGNED_TYPE +#define SIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId) +#endif + +#ifndef UNSIGNED_TYPE +#define UNSIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId) +#endif + +#ifndef FLOATING_TYPE +#define FLOATING_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId) +#endif + +#ifndef PLACEHOLDER_TYPE +#define PLACEHOLDER_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId) +#endif + +#ifndef SHARED_SINGLETON_TYPE +#define SHARED_SINGLETON_TYPE(Expansion) Expansion +#endif + +//===- Builtin Types ------------------------------------------------------===// + +// void +BUILTIN_TYPE(Void, VoidTy) + +//===- Unsigned Types -----------------------------------------------------===// + +// 'bool' in C++, '_Bool' in C99 +UNSIGNED_TYPE(Bool, BoolTy) + +// 'char' for targets where it's unsigned +SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(Char_U, CharTy)) + +// 'unsigned char', explicitly qualified +UNSIGNED_TYPE(UChar, UnsignedCharTy) + +// 'wchar_t' for targets where it's unsigned +SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy)) + +// 'char16_t' in C++ +UNSIGNED_TYPE(Char16, Char16Ty) + +// 'char32_t' in C++ +UNSIGNED_TYPE(Char32, Char32Ty) + +// 'unsigned short' +UNSIGNED_TYPE(UShort, UnsignedShortTy) + +// 'unsigned int' +UNSIGNED_TYPE(UInt, UnsignedIntTy) + +// 'unsigned long' +UNSIGNED_TYPE(ULong, UnsignedLongTy) + +// 'unsigned long long' +UNSIGNED_TYPE(ULongLong, UnsignedLongLongTy) + +// '__uint128_t' +UNSIGNED_TYPE(UInt128, UnsignedInt128Ty) + +//===- Signed Types -------------------------------------------------------===// + +// 'char' for targets where it's signed +SHARED_SINGLETON_TYPE(SIGNED_TYPE(Char_S, CharTy)) + +// 'signed char', explicitly qualified +SIGNED_TYPE(SChar, SignedCharTy) + +// 'wchar_t' for targets where it's signed +SHARED_SINGLETON_TYPE(SIGNED_TYPE(WChar_S, WCharTy)) + +// 'short' or 'signed short' +SIGNED_TYPE(Short, ShortTy) + +// 'int' or 'signed int' +SIGNED_TYPE(Int, IntTy) + +// 'long' or 'signed long' +SIGNED_TYPE(Long, LongTy) + +// 'long long' or 'signed long long' +SIGNED_TYPE(LongLong, LongLongTy) + +// '__int128_t' +SIGNED_TYPE(Int128, Int128Ty) + +//===- Floating point types -----------------------------------------------===// + +// 'half' in OpenCL, '__fp16' in ARM NEON. +FLOATING_TYPE(Half, HalfTy) + +// 'float' +FLOATING_TYPE(Float, FloatTy) + +// 'double' +FLOATING_TYPE(Double, DoubleTy) + +// 'long double' +FLOATING_TYPE(LongDouble, LongDoubleTy) + +//===- Language-specific types --------------------------------------------===// + +// This is the type of C++0x 'nullptr'. +BUILTIN_TYPE(NullPtr, NullPtrTy) + +// The primitive Objective C 'id' type. The user-visible 'id' +// type is a typedef of an ObjCObjectPointerType to an +// ObjCObjectType with this as its base. In fact, this only ever +// shows up in an AST as the base type of an ObjCObjectType. +BUILTIN_TYPE(ObjCId, ObjCBuiltinIdTy) + +// The primitive Objective C 'Class' type. The user-visible +// 'Class' type is a typedef of an ObjCObjectPointerType to an +// ObjCObjectType with this as its base. In fact, this only ever +// shows up in an AST as the base type of an ObjCObjectType. +BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy) + +// The primitive Objective C 'SEL' type. The user-visible 'SEL' +// type is a typedef of a PointerType to this. +BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy) + +// This represents the type of an expression whose type is +// totally unknown, e.g. 'T::foo'. It is permitted for this to +// appear in situations where the structure of the type is +// theoretically deducible. +BUILTIN_TYPE(Dependent, DependentTy) + +// The type of an unresolved overload set. A placeholder type. +// Expressions with this type have one of the following basic +// forms, with parentheses generally permitted: +// foo # possibly qualified, not if an implicit access +// foo # possibly qualified, not if an implicit access +// &foo # possibly qualified, not if an implicit access +// x->foo # only if might be a static member function +// &x->foo # only if might be a static member function +// &Class::foo # when a pointer-to-member; sub-expr also has this type +// OverloadExpr::find can be used to analyze the expression. +// +// Overload should be the first placeholder type, or else change +// BuiltinType::isNonOverloadPlaceholderType() +PLACEHOLDER_TYPE(Overload, OverloadTy) + +// The type of a bound C++ non-static member function. +// A placeholder type. Expressions with this type have one of the +// following basic forms: +// foo # if an implicit access +// x->foo # if only contains non-static members +PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) + +// The type of an expression which refers to a pseudo-object, +// such as those introduced by Objective C's @property or +// VS.NET's __property declarations. A placeholder type. The +// pseudo-object is actually accessed by emitting a call to +// some sort of function or method; typically there is a pair +// of a setter and a getter, with the setter used if the +// pseudo-object reference is used syntactically as the +// left-hand-side of an assignment operator. +// +// A pseudo-object reference naming an Objective-C @property is +// always a dot access with a base of object-pointer type, +// e.g. 'x.foo'. +// +// In VS.NET, a __property declaration creates an implicit +// member with an associated name, which can then be named +// in any of the normal ways an ordinary member could be. +PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy) + +// __builtin_any_type. A placeholder type. Useful for clients +// like debuggers that don't know what type to give something. +// Only a small number of operations are valid on expressions of +// unknown type, most notably explicit casts. +PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy) + +// The type of a cast which, in ARC, would normally require a +// __bridge, but which might be okay depending on the immediate +// context. +PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy) + +#ifdef LAST_BUILTIN_TYPE +LAST_BUILTIN_TYPE(ARCUnbridgedCast) +#undef LAST_BUILTIN_TYPE +#endif + +#undef SHARED_SINGLETON_TYPE +#undef PLACEHOLDER_TYPE +#undef FLOATING_TYPE +#undef SIGNED_TYPE +#undef UNSIGNED_TYPE +#undef BUILTIN_TYPE diff --git a/clang/include/clang/AST/CMakeLists.txt b/clang/include/clang/AST/CMakeLists.txt new file mode 100644 index 0000000..c10cda8 --- /dev/null +++ b/clang/include/clang/AST/CMakeLists.txt @@ -0,0 +1,17 @@ +clang_tablegen(Attrs.inc -gen-clang-attr-classes + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + SOURCE ../Basic/Attr.td + TARGET ClangAttrClasses) + +clang_tablegen(AttrImpl.inc -gen-clang-attr-impl + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + SOURCE ../Basic/Attr.td + TARGET ClangAttrImpl) + +clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes + SOURCE ../Basic/StmtNodes.td + TARGET ClangStmtNodes) + +clang_tablegen(DeclNodes.inc -gen-clang-decl-nodes + SOURCE ../Basic/DeclNodes.td + TARGET ClangDeclNodes) diff --git a/clang/include/clang/AST/CXXInheritance.h b/clang/include/clang/AST/CXXInheritance.h new file mode 100644 index 0000000..44c554b --- /dev/null +++ b/clang/include/clang/AST/CXXInheritance.h @@ -0,0 +1,370 @@ +//===------ 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/SmallSet.h" +#include "llvm/ADT/SmallVector.h" +#include +#include +#include + +namespace clang { + +class CXXBaseSpecifier; +class CXXMethodDecl; +class CXXRecordDecl; +class NamedDecl; + +/// \brief Represents an element in a path from a derived class to a +/// base class. +/// +/// Each step in the path references the link from a +/// derived class to one of its direct base classes, along with a +/// base "number" that identifies which base subobject of the +/// original derived class we are referencing. +struct CXXBasePathElement { + /// \brief The base specifier that states the link from a derived + /// class to a base class, which will be followed by this base + /// path element. + const CXXBaseSpecifier *Base; + + /// \brief The record decl of the class that the base is a base of. + const CXXRecordDecl *Class; + + /// \brief Identifies which base class subobject (of type + /// \c Base->getType()) this base path element refers to. + /// + /// This value is only valid if \c !Base->isVirtual(), because there + /// is no base numbering for the zero or one virtual bases of a + /// given type. + int SubobjectNumber; +}; + +/// \brief Represents a path from a specific derived class +/// (which is not represented as part of the path) to a particular +/// (direct or indirect) base class subobject. +/// +/// Individual elements in the path are described by the \c CXXBasePathElement +/// structure, which captures both the link from a derived class to one of its +/// direct bases and identification describing which base class +/// subobject is being used. +class CXXBasePath : public SmallVector { +public: + CXXBasePath() : Access(AS_public) {} + + /// \brief The access along this inheritance path. This is only + /// calculated when recording paths. AS_none is a special value + /// used to indicate a path which permits no legal access. + AccessSpecifier Access; + + /// \brief The set of declarations found inside this base class + /// subobject. + DeclContext::lookup_result Decls; + + void clear() { + SmallVectorImpl::clear(); + Access = AS_public; + } +}; + +/// BasePaths - Represents the set of paths from a derived class to +/// one of its (direct or indirect) bases. For example, given the +/// following class hierarchy: +/// +/// @code +/// class A { }; +/// class B : public A { }; +/// class C : public A { }; +/// class D : public B, public C{ }; +/// @endcode +/// +/// There are two potential BasePaths to represent paths from D to a +/// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0) +/// and another is (D,0)->(C,0)->(A,1). These two paths actually +/// refer to two different base class subobjects of the same type, +/// so the BasePaths object refers to an ambiguous path. On the +/// other hand, consider the following class hierarchy: +/// +/// @code +/// class A { }; +/// class B : public virtual A { }; +/// class C : public virtual A { }; +/// class D : public B, public C{ }; +/// @endcode +/// +/// Here, there are two potential BasePaths again, (D, 0) -> (B, 0) +/// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them +/// refer to the same base class subobject of type A (the virtual +/// one), there is no ambiguity. +class CXXBasePaths { + /// \brief The type from which this search originated. + CXXRecordDecl *Origin; + + /// Paths - The actual set of paths that can be taken from the + /// derived class to the same base class. + std::list 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, 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::iterator paths_iterator; + typedef std::list::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 > + Overrides; + +public: + // Iterate over the set of subobjects that have overriding methods. + typedef llvm::DenseMap > + ::iterator iterator; + typedef llvm::DenseMap > + ::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 SmallVector::iterator + overriding_iterator; + typedef SmallVector::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 { }; + +/// \brief A set of all the primary bases for a class. +class CXXIndirectPrimaryBaseSet + : public llvm::SmallSet { }; + +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h new file mode 100644 index 0000000..6cce888 --- /dev/null +++ b/clang/include/clang/AST/CanonicalType.h @@ -0,0 +1,778 @@ +//===-- 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 + +namespace clang { + +template class CanProxy; +template 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 will be of that +/// type (or some subclass of that type). The typedef @c CanQualType is just +/// a shorthand for @c CanQual. +/// +/// An instance of @c CanQual can be implicitly converted to a +/// @c CanQual when T is derived from U, which essentially provides an +/// implicit upcast. For example, @c CanQual can be +/// converted to @c CanQual. Note that any @c CanQual type can +/// be implicitly converted to a QualType, but the reverse operation requires +/// a call to ASTContext::getCanonicalType(). +/// +/// +template +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 + CanQual(const CanQual& Other, + typename llvm::enable_if, int>::type = 0); + + /// \brief Retrieve the underlying type pointer, which refers to a + /// canonical type. + /// + /// The underlying pointer must not be NULL. + const T *getTypePtr() const { return cast(Stored.getTypePtr()); } + + /// \brief Retrieve the underlying type pointer, which refers to a + /// canonical type, or NULL. + /// + const T *getTypePtrOrNull() const { + return cast_or_null(Stored.getTypePtrOrNull()); + } + + /// \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(); + } + + SplitQualType split() const { return Stored.split(); } + + /// \brief Retrieve a canonical type pointer with a different static type, + /// upcasting or downcasting as needed. + /// + /// The getAs() function is typically used to try to downcast to a + /// more specific (canonical) type in the type system. For example: + /// + /// @code + /// void f(CanQual T) { + /// if (CanQual Ptr = T->getAs()) { + /// // 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 CanProxy getAs() const; + + template CanProxy castAs() const; + + /// \brief Overloaded arrow operator that produces a canonical type + /// proxy. + CanProxy 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 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 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 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 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 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 CreateUnsafe(QualType Other); + + void dump() const { Stored.dump(); } + + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.AddPointer(getAsOpaquePtr()); + } +}; + +template +inline bool operator==(CanQual x, CanQual y) { + return x.getAsOpaquePtr() == y.getAsOpaquePtr(); +} + +template +inline bool operator!=(CanQual x, CanQual y) { + return x.getAsOpaquePtr() != y.getAsOpaquePtr(); +} + +/// \brief Represents a canonical, potentially-qualified type. +typedef CanQual CanQualType; + +inline CanQualType Type::getCanonicalTypeUnqualified() const { + return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); +} + +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + CanQualType T) { + DB << static_cast(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 +class CanProxyBase { +protected: + CanQual Stored; + +public: + /// \brief Retrieve the pointer to the underlying Type + const T *getTypePtr() const { return Stored.getTypePtr(); } + + /// \brief Implicit conversion to the underlying pointer. + /// + /// Also provides the ability to use canonical type proxies in a Boolean + // context,e.g., + /// @code + /// if (CanQual Ptr = T->getAs()) { ... } + /// @endcode + operator const T*() const { return this->Stored.getTypePtrOrNull(); } + + /// \brief Try to convert the given canonical type to a specific structural + /// type. + template CanProxy getAs() const { + return this->Stored.template getAs(); + } + + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass) + + // Type predicates + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl) + + /// \brief Retrieve the proxy-adaptor type. + /// + /// This arrow operator is used when CanProxyAdaptor has been specialized + /// for the given type T. In that case, we reference members of the + /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden + /// by the arrow operator in the primary CanProxyAdaptor template. + const CanProxyAdaptor *operator->() const { + return static_cast *>(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 +struct CanProxyAdaptor : CanProxyBase { }; + +/// \brief Canonical proxy type returned when retrieving the members of a +/// canonical type or as the result of the @c CanQual::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 +class CanProxy : public CanProxyAdaptor { +public: + /// \brief Build a NULL proxy. + CanProxy() { } + + /// \brief Build a proxy to the given canonical type. + CanProxy(CanQual Stored) { this->Stored = Stored; } + + /// \brief Implicit conversion to the stored canonical type. + operator CanQual() const { return this->Stored; } +}; + +} // end namespace clang + +namespace llvm { + +/// Implement simplify_type for CanQual, so that we can dyn_cast from +/// CanQual to a specific Type class. We're prefer isa/dyn_cast/cast/etc. +/// to return smart pointer (proxies?). +template +struct simplify_type > { + typedef const T *SimpleType; + static SimpleType getSimplifiedValue(const ::clang::CanQual &Val) { + return Val.getTypePtr(); + } +}; +template +struct simplify_type< ::clang::CanQual > +: public simplify_type > {}; + +// Teach SmallPtrSet that CanQual is "basically a pointer". +template +class PointerLikeTypeTraits > { +public: + static inline void *getAsVoidPointer(clang::CanQual P) { + return P.getAsOpaquePtr(); + } + static inline clang::CanQual getFromVoidPointer(void *P) { + return clang::CanQual::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 +class CanTypeIterator { + InputIterator Iter; + +public: + typedef CanQualType value_type; + typedef value_type reference; + typedef CanProxy pointer; + typedef typename std::iterator_traits::difference_type + difference_type; + typedef typename std::iterator_traits::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 : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, + getSizeModifier) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + 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 + : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, + getSizeModifier) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + 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 + : public CanProxyBase { + 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 + : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + 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 + 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 : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr) + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) +}; + +template <> +struct CanProxyAdaptor + : public CanProxyBase { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType) + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields) +}; + +template<> +struct CanProxyAdaptor : public CanProxyBase { + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier) +}; + +template<> +struct CanProxyAdaptor + : public CanProxyBase { + 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 + : public CanProxyBase { + 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 +inline CanQual CanQual::getUnqualifiedType() const { + return CanQual::CreateUnsafe(Stored.getLocalUnqualifiedType()); +} + +template +inline CanQual CanQual::getNonReferenceType() const { + if (CanQual RefType = getAs()) + return RefType->getPointeeType(); + else + return *this; +} + +template +CanQual CanQual::getFromOpaquePtr(void *Ptr) { + CanQual Result; + Result.Stored = QualType::getFromOpaquePtr(Ptr); + assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 || + Result.Stored.isCanonical()) && "Type is not canonical!"); + return Result; +} + +template +CanQual CanQual::CreateUnsafe(QualType Other) { + assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!"); + assert((Other.isNull() || isa(Other.getTypePtr())) && + "Dynamic type does not meet the static type's requires"); + CanQual Result; + Result.Stored = Other; + return Result; +} + +template +template +CanProxy CanQual::getAs() const { + if (Stored.isNull()) + return CanProxy(); + + if (isa(Stored.getTypePtr())) + return CanQual::CreateUnsafe(Stored); + + return CanProxy(); +} + +template +template +CanProxy CanQual::castAs() const { + assert(!Stored.isNull() && isa(Stored.getTypePtr())); + return CanQual::CreateUnsafe(Stored); +} + +template +CanProxy CanQual::operator->() const { + return CanProxy(*this); +} + +template +typename CanTypeIterator::pointer +CanTypeIterator::operator->() const { + return CanProxy(*this); +} + +} + + +#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H diff --git a/clang/include/clang/AST/CharUnits.h b/clang/include/clang/AST/CharUnits.h new file mode 100644 index 0000000..5be3582 --- /dev/null +++ b/clang/include/clang/AST/CharUnits.h @@ -0,0 +1,217 @@ +//===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the CharUnits class +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_CHARUNITS_H +#define LLVM_CLANG_AST_CHARUNITS_H + +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/MathExtras.h" + +namespace clang { + + /// CharUnits - This is an opaque type for sizes expressed in character units. + /// Instances of this type represent a quantity as a multiple of the size + /// of the standard C type, char, on the target architecture. As an opaque + /// type, CharUnits protects you from accidentally combining operations on + /// quantities in bit units and character units. + /// + /// 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 wherever you calculate sizes, offsets, or alignments + /// in character units. + class CharUnits { + public: + typedef int64_t QuantityType; + + private: + QuantityType Quantity; + + explicit CharUnits(QuantityType C) : Quantity(C) {} + + public: + + /// CharUnits - A default constructor. + CharUnits() : Quantity(0) {} + + /// Zero - Construct a CharUnits quantity of zero. + static CharUnits Zero() { + return CharUnits(0); + } + + /// One - Construct a CharUnits quantity of one. + static CharUnits One() { + return CharUnits(1); + } + + /// fromQuantity - Construct a CharUnits quantity from a raw integer type. + static CharUnits fromQuantity(QuantityType Quantity) { + return CharUnits(Quantity); + } + + // Compound assignment. + CharUnits& operator+= (const CharUnits &Other) { + Quantity += Other.Quantity; + return *this; + } + CharUnits& operator++ () { + ++Quantity; + return *this; + } + CharUnits operator++ (int) { + return CharUnits(Quantity++); + } + CharUnits& operator-= (const CharUnits &Other) { + Quantity -= Other.Quantity; + return *this; + } + CharUnits& operator-- () { + --Quantity; + return *this; + } + CharUnits operator-- (int) { + return CharUnits(Quantity--); + } + + // Comparison operators. + bool operator== (const CharUnits &Other) const { + return Quantity == Other.Quantity; + } + bool operator!= (const CharUnits &Other) const { + return Quantity != Other.Quantity; + } + + // Relational operators. + bool operator< (const CharUnits &Other) const { + return Quantity < Other.Quantity; + } + bool operator<= (const CharUnits &Other) const { + return Quantity <= Other.Quantity; + } + bool operator> (const CharUnits &Other) const { + return Quantity > Other.Quantity; + } + bool operator>= (const CharUnits &Other) const { + return Quantity >= Other.Quantity; + } + + // Other predicates. + + /// isZero - Test whether the quantity equals zero. + bool isZero() const { return Quantity == 0; } + + /// isOne - Test whether the quantity equals one. + bool isOne() const { return Quantity == 1; } + + /// isPositive - Test whether the quantity is greater than zero. + bool isPositive() const { return Quantity > 0; } + + /// isNegative - Test whether the quantity is less than zero. + bool isNegative() const { return Quantity < 0; } + + /// isPowerOfTwo - Test whether the quantity is a power of two. + /// Zero is not a power of two. + bool isPowerOfTwo() const { + return (Quantity & -Quantity) == Quantity; + } + + // Arithmetic operators. + CharUnits operator* (QuantityType N) const { + return CharUnits(Quantity * N); + } + CharUnits operator/ (QuantityType N) const { + return CharUnits(Quantity / N); + } + QuantityType operator/ (const CharUnits &Other) const { + return Quantity / Other.Quantity; + } + CharUnits operator% (QuantityType N) const { + return CharUnits(Quantity % N); + } + QuantityType operator% (const CharUnits &Other) const { + return Quantity % Other.Quantity; + } + CharUnits operator+ (const CharUnits &Other) const { + return CharUnits(Quantity + Other.Quantity); + } + CharUnits operator- (const CharUnits &Other) const { + return CharUnits(Quantity - Other.Quantity); + } + CharUnits operator- () const { + return CharUnits(-Quantity); + } + + + // Conversions. + + /// getQuantity - Get the raw integer representation of this quantity. + QuantityType getQuantity() const { return Quantity; } + + /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is + /// greater than or equal to this quantity and is a multiple of \arg + /// Align. Align must be non-zero. + CharUnits RoundUpToAlignment(const CharUnits &Align) { + return CharUnits(llvm::RoundUpToAlignment(Quantity, + Align.Quantity)); + } + + + }; // class CharUnit +} // namespace clang + +inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, + const clang::CharUnits &CU) { + return CU * Scale; +} + +namespace llvm { + +template<> struct DenseMapInfo { + static clang::CharUnits getEmptyKey() { + clang::CharUnits::QuantityType Quantity = + DenseMapInfo::getEmptyKey(); + + return clang::CharUnits::fromQuantity(Quantity); + } + + static clang::CharUnits getTombstoneKey() { + clang::CharUnits::QuantityType Quantity = + DenseMapInfo::getTombstoneKey(); + + return clang::CharUnits::fromQuantity(Quantity); + } + + static unsigned getHashValue(const clang::CharUnits &CU) { + clang::CharUnits::QuantityType Quantity = CU.getQuantity(); + return DenseMapInfo::getHashValue(Quantity); + } + + static bool isEqual(const clang::CharUnits &LHS, + const clang::CharUnits &RHS) { + return LHS == RHS; + } +}; + +template <> struct isPodLike { + static const bool value = true; +}; + +} // end namespace llvm + +#endif // LLVM_CLANG_AST_CHARUNITS_H diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h new file mode 100644 index 0000000..0c47f2e --- /dev/null +++ b/clang/include/clang/AST/Decl.h @@ -0,0 +1,3339 @@ +//===--- 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" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Compiler.h" + +namespace clang { +class CXXTemporary; +class Expr; +class FunctionTemplateDecl; +class Stmt; +class CompoundStmt; +class StringLiteral; +class NestedNameSpecifier; +class TemplateParameterList; +class TemplateArgumentList; +struct ASTTemplateArgumentListInfo; +class MemberSpecializationInfo; +class FunctionTemplateSpecializationInfo; +class DependentFunctionTemplateSpecializationInfo; +class TypeLoc; +class UnresolvedSetImpl; +class LabelStmt; +class Module; + +/// \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(&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 { + virtual void anchor(); + ASTContext &Ctx; + + /// The (most recently entered) anonymous namespace for this + /// translation unit, if one has been created. + NamespaceDecl *AnonymousNamespace; + + explicit TranslationUnitDecl(ASTContext &ctx) + : 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(const_cast(D)); + } + static TranslationUnitDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } +}; + +/// NamedDecl - This represents a decl with a name. Many decls have names such +/// as ObjCMethodDecl, but not @class, etc. +class NamedDecl : public Decl { + virtual void anchor(); + /// Name - The name of this declaration, which is typically a normal + /// identifier but may also be a special kind of name (C++ + /// constructor, Objective-C selector, etc.) + DeclarationName Name; + +private: + NamedDecl *getUnderlyingDeclImpl(); + +protected: + NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) + : Decl(DK, DC, L), Name(N) { } + +public: + /// getIdentifier - Get the identifier that names this declaration, + /// if there is one. This will return NULL if this declaration has + /// no name (e.g., for an unnamed class) or if the name is a special + /// name (C++ constructor, Objective-C selector, etc.). + IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); } + + /// getName - Get the name of identifier for this declaration as a StringRef. + /// This requires that the declaration have a name and that it be a simple + /// identifier. + StringRef getName() const { + assert(Name.isIdentifier() && "Name is not a simple identifier"); + return getIdentifier() ? getIdentifier()->getName() : ""; + } + + /// getNameAsString - Get a human-readable name for the declaration, even if + /// it is one of the special kinds of names (C++ constructor, Objective-C + /// selector, etc). Creating this name requires expensive string + /// manipulation, so it should be called only when performance doesn't matter. + /// For simple declarations, getNameAsCString() should suffice. + // + // FIXME: This function should be renamed to indicate that it is not just an + // alternate form of getName(), and clients should move as appropriate. + // + // FIXME: Deprecated, move clients to getName(). + std::string getNameAsString() const { return Name.getAsString(); } + + void printName(raw_ostream &os) const { 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; + + using Decl::isModulePrivate; + using Decl::setModulePrivate; + + /// \brief Determine whether this declaration is hidden from name lookup. + bool isHidden() const { return Hidden; } + + /// \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(DC)) + DC = DC->getParent(); + + return DC->isRecord(); + } + + /// \brief Determine whether the given declaration is an instance member of + /// a C++ class. + bool isCXXInstanceMember() const; + + class LinkageInfo { + Linkage linkage_; + Visibility visibility_; + bool explicit_; + + public: + LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), + explicit_(false) {} + LinkageInfo(Linkage L, Visibility V, bool E) + : linkage_(L), visibility_(V), explicit_(E) {} + + static LinkageInfo external() { + return LinkageInfo(); + } + static LinkageInfo internal() { + return LinkageInfo(InternalLinkage, DefaultVisibility, false); + } + static LinkageInfo uniqueExternal() { + return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); + } + static LinkageInfo none() { + return LinkageInfo(NoLinkage, DefaultVisibility, false); + } + + Linkage linkage() const { return linkage_; } + Visibility visibility() const { return visibility_; } + bool visibilityExplicit() const { return explicit_; } + + void setLinkage(Linkage L) { linkage_ = L; } + void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } + + void mergeLinkage(Linkage L) { + setLinkage(minLinkage(linkage(), L)); + } + void mergeLinkage(LinkageInfo Other) { + mergeLinkage(Other.linkage()); + } + + // Merge the visibility V giving preference to explicit ones. + // This is used, for example, when merging the visibility of a class + // down to one of its members. If the member has no explicit visibility, + // the class visibility wins. + void mergeVisibility(Visibility V, bool E = false) { + // If one has explicit visibility and the other doesn't, keep the + // explicit one. + if (visibilityExplicit() && !E) + return; + if (!visibilityExplicit() && E) + setVisibility(V, E); + + // If both are explicit or both are implicit, keep the minimum. + setVisibility(minVisibility(visibility(), V), visibilityExplicit() || E); + } + // Merge the visibility V, keeping the most restrictive one. + // This is used for cases like merging the visibility of a template + // argument to an instantiation. If we already have a hidden class, + // no argument should give it default visibility. + void mergeVisibilityWithMin(Visibility V, bool E = false) { + // Never increase the visibility + if (visibility() < V) + return; + + // If this visibility is explicit, keep it. + if (visibilityExplicit() && !E) + return; + setVisibility(V, E); + } + void mergeVisibility(LinkageInfo Other) { + mergeVisibility(Other.visibility(), Other.visibilityExplicit()); + } + void mergeVisibilityWithMin(LinkageInfo Other) { + mergeVisibilityWithMin(Other.visibility(), Other.visibilityExplicit()); + } + + void merge(LinkageInfo Other) { + mergeLinkage(Other); + mergeVisibility(Other); + } + void mergeWithMin(LinkageInfo Other) { + mergeLinkage(Other); + mergeVisibilityWithMin(Other); + } + + friend LinkageInfo merge(LinkageInfo L, LinkageInfo R) { + L.merge(R); + return L; + } + }; + + /// \brief Determine what kind of linkage this entity has. + Linkage getLinkage() const; + + /// \brief Determines the visibility of this entity. + Visibility getVisibility() const { + return getLinkageAndVisibility().visibility(); + } + + /// \brief Determines the linkage and visibility of this entity. + LinkageInfo getLinkageAndVisibility() const; + + /// \brief If visibility was explicitly specified for this + /// declaration, return that visibility. + llvm::Optional getExplicitVisibility() const; + + /// \brief Clear the linkage cache in response to a change + /// to the declaration. + void ClearLinkageCache(); + + /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for + /// the underlying named decl. + NamedDecl *getUnderlyingDecl() { + // Fast-path the common case. + if (this->getKind() != UsingShadow && + this->getKind() != ObjCCompatibleAlias) + return this; + + return getUnderlyingDeclImpl(); + } + const NamedDecl *getUnderlyingDecl() const { + return const_cast(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 >= firstNamed && K <= lastNamed; } +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) { + ND.printName(OS); + return OS; +} + +/// LabelDecl - Represents the declaration of a label. Labels also have a +/// corresponding LabelStmt, which indicates the position that the label was +/// defined at. For normal labels, the location of the decl is the same as the +/// location of the statement. For GNU local labels (__label__), the decl +/// location is where the __label__ is. +class LabelDecl : public NamedDecl { + virtual void anchor(); + LabelStmt *TheStmt; + /// LocStart - For normal labels, this is the same as the main declaration + /// label, i.e., the location of the identifier; for GNU local labels, + /// this is the location of the __label__ keyword. + SourceLocation LocStart; + + LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, + LabelStmt *S, SourceLocation StartL) + : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {} + +public: + static LabelDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation IdentL, IdentifierInfo *II); + static LabelDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation IdentL, IdentifierInfo *II, + SourceLocation GnuLabelL); + static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + LabelStmt *getStmt() const { return TheStmt; } + void setStmt(LabelStmt *T) { TheStmt = T; } + + bool isGnuLocal() const { return LocStart != getLocation(); } + void setLocStart(SourceLocation L) { LocStart = L; } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(LocStart, getLocation()); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const LabelDecl *D) { return true; } + static bool classofKind(Kind K) { return K == Label; } +}; + +/// NamespaceDecl - Represent a C++ namespace. +class NamespaceDecl : public NamedDecl, public DeclContext, + public Redeclarable +{ + virtual void anchor(); + + /// LocStart - The starting location of the source range, pointing + /// to either the namespace or the inline keyword. + SourceLocation LocStart; + /// RBraceLoc - The ending location of the source range. + SourceLocation RBraceLoc; + + /// \brief A pointer to either the anonymous namespace that lives just inside + /// this namespace or to the first namespace in the chain (the latter case + /// only when this is not the first in the chain), along with a + /// boolean value indicating whether this is an inline namespace. + llvm::PointerIntPair AnonOrFirstNamespaceAndInline; + + NamespaceDecl(DeclContext *DC, bool Inline, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + NamespaceDecl *PrevDecl); + + typedef Redeclarable redeclarable_base; + virtual NamespaceDecl *getNextRedeclaration() { + return RedeclLink.getNext(); + } + virtual NamespaceDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual NamespaceDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + +public: + static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, + bool Inline, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + NamespaceDecl *PrevDecl); + + static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + /// \brief Returns true if this is an anonymous namespace declaration. + /// + /// For example: + /// \code + /// namespace { + /// ... + /// }; + /// \endcode + /// q.v. C++ [namespace.unnamed] + bool isAnonymousNamespace() const { + return !getIdentifier(); + } + + /// \brief Returns true if this is an inline namespace declaration. + bool isInline() const { + return AnonOrFirstNamespaceAndInline.getInt(); + } + + /// \brief Set whether this is an inline namespace declaration. + void setInline(bool Inline) { + AnonOrFirstNamespaceAndInline.setInt(Inline); + } + + /// \brief Get the original (first) namespace declaration. + NamespaceDecl *getOriginalNamespace() { + if (isFirstDeclaration()) + return this; + + return AnonOrFirstNamespaceAndInline.getPointer(); + } + + /// \brief Get the original (first) namespace declaration. + const NamespaceDecl *getOriginalNamespace() const { + if (isFirstDeclaration()) + return this; + + return AnonOrFirstNamespaceAndInline.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 isFirstDeclaration(); + } + + /// \brief Retrieve the anonymous namespace nested inside this namespace, + /// if any. + NamespaceDecl *getAnonymousNamespace() const { + return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer(); + } + + void setAnonymousNamespace(NamespaceDecl *D) { + getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D); + } + + /// Retrieves the canonical declaration of this namespace. + NamespaceDecl *getCanonicalDecl() { + return getOriginalNamespace(); + } + const NamespaceDecl *getCanonicalDecl() const { + return getOriginalNamespace(); + } + + virtual SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(LocStart, RBraceLoc); + } + + SourceLocation getLocStart() const LLVM_READONLY { return LocStart; } + SourceLocation getRBraceLoc() const { return RBraceLoc; } + void setLocStart(SourceLocation L) { LocStart = L; } + void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const NamespaceDecl *D) { return true; } + static bool classofKind(Kind K) { return K == Namespace; } + static DeclContext *castToDeclContext(const NamespaceDecl *D) { + return static_cast(const_cast(D)); + } + static NamespaceDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// ValueDecl - Represent the declaration of a variable (in which case it is +/// an lvalue) a function (in which case it is a function designator) or +/// an enum constant. +class ValueDecl : public NamedDecl { + virtual void anchor(); + QualType DeclType; + +protected: + ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName N, QualType T) + : NamedDecl(DK, DC, L, N), DeclType(T) {} +public: + QualType getType() const { return DeclType; } + void setType(QualType newType) { DeclType = newType; } + + /// \brief Determine whether this symbol is weakly-imported, + /// or declared with the weak or weak-ref attr. + bool isWeak() const { + return hasAttr() || hasAttr() || isWeakImported(); + } + + // 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 >= firstValue && K <= lastValue; } +}; + +/// QualifierInfo - A struct with extended info about a syntactic +/// name qualifier, to be used for the case of out-of-line declarations. +struct QualifierInfo { + NestedNameSpecifierLoc QualifierLoc; + + /// NumTemplParamLists - The number of "outer" template parameter lists. + /// The count includes all of the template parameter lists that were matched + /// against the template-ids occurring into the NNS and possibly (in the + /// case of an explicit specialization) a final "template <>". + unsigned NumTemplParamLists; + + /// TemplParamLists - A new-allocated array of size NumTemplParamLists, + /// containing pointers to the "outer" template parameter lists. + /// It includes all of the template parameter lists that were matched + /// against the template-ids occurring into the NNS and possibly (in the + /// case of an explicit specialization) a final "template <>". + TemplateParameterList** TemplParamLists; + + /// Default constructor. + QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {} + + /// setTemplateParameterListsInfo - Sets info about "outer" template + /// parameter lists. + void setTemplateParameterListsInfo(ASTContext &Context, + unsigned NumTPLists, + TemplateParameterList **TPLists); + +private: + // Copy constructor and copy assignment are disabled. + QualifierInfo(const QualifierInfo&); + QualifierInfo& operator=(const QualifierInfo&); +}; + +/// \brief Represents a ValueDecl that came out of a declarator. +/// Contains type source information through TypeSourceInfo. +class DeclaratorDecl : public ValueDecl { + // A struct representing both a TInfo and a syntactic qualifier, + // to be used for the (uncommon) case of out-of-line declarations. + struct ExtInfo : public QualifierInfo { + TypeSourceInfo *TInfo; + }; + + llvm::PointerUnion DeclInfo; + + /// InnerLocStart - The start of the source range for this declaration, + /// ignoring outer template declarations. + SourceLocation InnerLocStart; + + bool hasExtInfo() const { return DeclInfo.is(); } + ExtInfo *getExtInfo() { return DeclInfo.get(); } + const ExtInfo *getExtInfo() const { return DeclInfo.get(); } + +protected: + DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName N, QualType T, TypeSourceInfo *TInfo, + SourceLocation StartL) + : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) { + } + +public: + TypeSourceInfo *getTypeSourceInfo() const { + return hasExtInfo() + ? getExtInfo()->TInfo + : DeclInfo.get(); + } + void setTypeSourceInfo(TypeSourceInfo *TI) { + if (hasExtInfo()) + getExtInfo()->TInfo = TI; + else + DeclInfo = TI; + } + + /// getInnerLocStart - Return SourceLocation representing start of source + /// range ignoring outer template declarations. + SourceLocation getInnerLocStart() const { return InnerLocStart; } + void setInnerLocStart(SourceLocation L) { InnerLocStart = L; } + + /// getOuterLocStart - Return SourceLocation representing start of source + /// range taking into account any outer template declarations. + SourceLocation getOuterLocStart() const; + + virtual SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY { + return getOuterLocStart(); + } + + /// \brief Retrieve the nested-name-specifier that qualifies the name of this + /// declaration, if it was present in the source. + NestedNameSpecifier *getQualifier() const { + return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier() + : 0; + } + + /// \brief Retrieve the nested-name-specifier (with source-location + /// information) that qualifies the name of this declaration, if it was + /// present in the source. + NestedNameSpecifierLoc getQualifierLoc() const { + return hasExtInfo() ? getExtInfo()->QualifierLoc + : NestedNameSpecifierLoc(); + } + + void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc); + + unsigned getNumTemplateParameterLists() const { + return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0; + } + TemplateParameterList *getTemplateParameterList(unsigned index) const { + assert(index < getNumTemplateParameterLists()); + return getExtInfo()->TemplParamLists[index]; + } + void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists, + TemplateParameterList **TPLists); + + 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 >= firstDeclarator && K <= lastDeclarator; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// \brief Structure used to store a statement, the constant value to +/// which it was evaluated (if any), and whether or not the statement +/// is an integral constant expression (if known). +struct EvaluatedStmt { + EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false), + CheckingICE(false), IsICE(false) { } + + /// \brief Whether this statement was already evaluated. + bool WasEvaluated : 1; + + /// \brief Whether this statement is being evaluated. + bool IsEvaluating : 1; + + /// \brief Whether we already checked whether this statement was an + /// integral constant expression. + bool CheckedICE : 1; + + /// \brief Whether we are checking whether this statement is an + /// integral constant expression. + bool CheckingICE : 1; + + /// \brief Whether this statement is an integral constant expression, + /// or in C++11, whether the statement is a constant expression. Only + /// valid if CheckedICE is true. + bool IsICE : 1; + + Stmt *Value; + APValue Evaluated; +}; + +/// VarDecl - An instance of this class is created to represent a variable +/// declaration or definition. +class VarDecl : public DeclaratorDecl, public Redeclarable { +public: + typedef clang::StorageClass StorageClass; + + /// 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); + + /// \brief Initialization styles. + enum InitializationStyle { + CInit, ///< C-style initialization with assignment + CallInit, ///< Call-style initialization (C++98) + ListInit ///< Direct list-initialization (C++11) + }; + +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 InitType; + + /// \brief The initializer for this variable or, for a ParmVarDecl, the + /// C++ default argument. + mutable InitType Init; + +private: + class VarDeclBitfields { + friend class VarDecl; + friend class ASTDeclReader; + + unsigned SClass : 3; + unsigned SClassAsWritten : 3; + unsigned ThreadSpecified : 1; + unsigned InitStyle : 2; + + /// \brief Whether this variable is the exception variable in a C++ catch + /// or an Objective-C @catch statement. + unsigned ExceptionVar : 1; + + /// \brief Whether this local variable could be allocated in the return + /// slot of its function, enabling the named return value optimization + /// (NRVO). + unsigned NRVOVariable : 1; + + /// \brief Whether this variable is the for-range-declaration in a C++0x + /// for-range statement. + unsigned CXXForRangeDecl : 1; + + /// \brief Whether this variable is an ARC pseudo-__strong + /// variable; see isARCPseudoStrong() for details. + unsigned ARCPseudoStrong : 1; + + /// \brief Whether this variable is (C++0x) constexpr. + unsigned IsConstexpr : 1; + }; + enum { NumVarDeclBits = 14 }; + + friend class ASTDeclReader; + friend class StmtIteratorBase; + +protected: + enum { NumParameterIndexBits = 8 }; + + class ParmVarDeclBitfields { + friend class ParmVarDecl; + friend class ASTDeclReader; + + unsigned : NumVarDeclBits; + + /// Whether this parameter inherits a default argument from a + /// prior declaration. + unsigned HasInheritedDefaultArg : 1; + + /// Whether this parameter undergoes K&R argument promotion. + unsigned IsKNRPromoted : 1; + + /// Whether this parameter is an ObjC method parameter or not. + unsigned IsObjCMethodParam : 1; + + /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier. + /// Otherwise, the number of function parameter scopes enclosing + /// the function parameter scope in which this parameter was + /// declared. + unsigned ScopeDepthOrObjCQuals : 7; + + /// The number of parameters preceding this parameter in the + /// function parameter scope in which it was declared. + unsigned ParameterIndex : NumParameterIndexBits; + }; + + union { + unsigned AllBits; + VarDeclBitfields VarDeclBits; + ParmVarDeclBitfields ParmVarDeclBits; + }; + + VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T, TypeSourceInfo *TInfo, StorageClass SC, + StorageClass SCAsWritten) + : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() { + assert(sizeof(VarDeclBitfields) <= sizeof(unsigned)); + assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned)); + AllBits = 0; + VarDeclBits.SClass = SC; + VarDeclBits.SClassAsWritten = SCAsWritten; + // Everything else is implicitly initialized to false. + } + + typedef Redeclarable redeclarable_base; + virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + virtual VarDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual VarDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + +public: + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + static VarDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, + StorageClass S, StorageClass SCAsWritten); + + static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + virtual SourceRange getSourceRange() const LLVM_READONLY; + + StorageClass getStorageClass() const { + return (StorageClass) VarDeclBits.SClass; + } + StorageClass getStorageClassAsWritten() const { + return (StorageClass) VarDeclBits.SClassAsWritten; + } + void setStorageClass(StorageClass SC); + void setStorageClassAsWritten(StorageClass SC) { + assert(isLegalForVariable(SC)); + VarDeclBits.SClassAsWritten = SC; + } + + void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; } + bool isThreadSpecified() const { + return VarDeclBits.ThreadSpecified; + } + + /// hasLocalStorage - Returns true if a variable with function scope + /// is a non-static local variable. + bool hasLocalStorage() const { + if (getStorageClass() == SC_None) + return !isFileVarDecl(); + + // Return true for: Auto, Register. + // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal. + + return getStorageClass() >= SC_Auto; + } + + /// isStaticLocal - Returns true if a variable with function scope is a + /// static local variable. + bool isStaticLocal() const { + return getStorageClass() == SC_Static && !isFileVarDecl(); + } + + /// hasExternStorage - Returns true if a variable has extern or + /// __private_extern__ storage. + bool hasExternalStorage() const { + return getStorageClass() == SC_Extern || + getStorageClass() == SC_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; + + /// isLocalVarDecl - Returns true for local variable declarations + /// other than parameters. Note that this includes static variables + /// inside of functions. It also includes variables inside blocks. + /// + /// void foo() { int x; static int y; extern int z; } + /// + bool isLocalVarDecl() const { + if (getKind() != Decl::Var) + return false; + if (const DeclContext *DC = getDeclContext()) + return DC->getRedeclContext()->isFunctionOrMethod(); + return false; + } + + /// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but + /// excludes variables declared in blocks. + bool isFunctionOrMethodVarDecl() const { + if (getKind() != Decl::Var) + return false; + const DeclContext *DC = getDeclContext()->getRedeclContext(); + return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block; + } + + /// \brief Determines whether this is a static data member. + /// + /// This will only be true in C++, and applies to, e.g., the + /// variable 'x' in: + /// \code + /// struct S { + /// static int x; + /// }; + /// \endcode + bool isStaticDataMember() const { + // If it wasn't static, it would be a FieldDecl. + return getKind() != Decl::ParmVar && getDeclContext()->isRecord(); + } + + virtual VarDecl *getCanonicalDecl(); + const VarDecl *getCanonicalDecl() const { + return const_cast(this)->getCanonicalDecl(); + } + + enum DefinitionKind { + DeclarationOnly, ///< This declaration is only a declaration. + TentativeDefinition, ///< This declaration is a tentative definition. + Definition ///< This declaration is definitely a definition. + }; + + /// \brief Check whether this declaration is a definition. If this could be + /// a tentative definition (in C), don't check whether there's an overriding + /// definition. + DefinitionKind isThisDeclarationADefinition(ASTContext &) const; + DefinitionKind isThisDeclarationADefinition() const { + return isThisDeclarationADefinition(getASTContext()); + } + + /// \brief Check whether this variable is defined in this + /// translation unit. + DefinitionKind hasDefinition(ASTContext &) const; + DefinitionKind hasDefinition() const { + return hasDefinition(getASTContext()); + } + + /// \brief Get the tentative definition that acts as the real definition in + /// a TU. Returns null if there is a proper definition available. + VarDecl *getActingDefinition(); + const VarDecl *getActingDefinition() const { + return const_cast(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(ASTContext &); + const VarDecl *getDefinition(ASTContext &C) const { + return const_cast(this)->getDefinition(C); + } + VarDecl *getDefinition() { + return getDefinition(getASTContext()); + } + const VarDecl *getDefinition() const { + return const_cast(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 (getDeclContext()->getRedeclContext()->isFileContext()) + return true; + + if (isStaticDataMember()) + return true; + + return false; + } + + /// getAnyInitializer - Get the initializer for this variable, no matter which + /// declaration it is attached to. + const Expr *getAnyInitializer() const { + const VarDecl *D; + return getAnyInitializer(D); + } + + /// getAnyInitializer - Get the initializer for this variable, no matter which + /// declaration it is attached to. Also get that declaration. + const Expr *getAnyInitializer(const VarDecl *&D) const; + + bool hasInit() const { + return !Init.isNull() && (Init.is() || Init.is()); + } + const Expr *getInit() const { + if (Init.isNull()) + return 0; + + const Stmt *S = Init.dyn_cast(); + if (!S) { + if (EvaluatedStmt *ES = Init.dyn_cast()) + S = ES->Value; + } + return (const Expr*) S; + } + Expr *getInit() { + if (Init.isNull()) + return 0; + + Stmt *S = Init.dyn_cast(); + if (!S) { + if (EvaluatedStmt *ES = Init.dyn_cast()) + S = ES->Value; + } + + return (Expr*) S; + } + + /// \brief Retrieve the address of the initializer expression. + Stmt **getInitAddress() { + if (EvaluatedStmt *ES = Init.dyn_cast()) + 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); + + /// \brief Determine whether this variable is a reference that + /// extends the lifetime of its temporary initializer. + /// + /// A reference extends the lifetime of its temporary initializer if + /// it's initializer is an rvalue that would normally go out of scope + /// at the end of the initializer (a full expression). In such cases, + /// the reference itself takes ownership of the temporary, which will + /// be destroyed when the reference goes out of scope. For example: + /// + /// \code + /// const int &r = 1.0; // creates a temporary of type 'int' + /// \endcode + bool extendsLifetimeOfTemporary() const; + + /// \brief Determine whether this variable's value can be used in a + /// constant expression, according to the relevant language standard. + /// This only checks properties of the declaration, and does not check + /// whether the initializer is in fact a constant expression. + bool isUsableInConstantExpressions(ASTContext &C) const; + + EvaluatedStmt *ensureEvaluatedStmt() const; + + /// \brief Attempt to evaluate the value of the initializer attached to this + /// declaration, and produce notes explaining why it cannot be evaluated or is + /// not a constant expression. Returns a pointer to the value if evaluation + /// succeeded, 0 otherwise. + APValue *evaluateValue() const; + APValue *evaluateValue( + llvm::SmallVectorImpl &Notes) const; + + /// \brief Return the already-evaluated value of this variable's + /// initializer, or NULL if the value is not yet known. Returns pointer + /// to untyped APValue if the value could not be evaluated. + APValue *getEvaluatedValue() const { + if (EvaluatedStmt *Eval = Init.dyn_cast()) + 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()) + return Eval->CheckedICE; + + return false; + } + + /// \brief Determines whether the initializer is an integral constant + /// expression, or in C++11, whether the initializer is a constant + /// expression. + /// + /// \pre isInitKnownICE() + bool isInitICE() const { + assert(isInitKnownICE() && + "Check whether we already know that the initializer is an ICE"); + return Init.get()->IsICE; + } + + /// \brief Determine whether the value of the initializer attached to this + /// declaration is an integral constant expression. + bool checkInitIsICE() const; + + void setInitStyle(InitializationStyle Style) { + VarDeclBits.InitStyle = Style; + } + + /// \brief The style of initialization for this declaration. + /// + /// C-style initialization is "int x = 1;". Call-style initialization is + /// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be + /// the expression inside the parens or a "ClassType(a,b,c)" class constructor + /// expression for class types. List-style initialization is C++11 syntax, + /// e.g. "int x{1};". Clients can distinguish between different forms of + /// initialization by checking this value. In particular, "int x = {1};" is + /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the + /// Init expression in all three cases is an InitListExpr. + InitializationStyle getInitStyle() const { + return static_cast(VarDeclBits.InitStyle); + } + + /// \brief Whether the initializer is a direct-initializer (list or call). + bool isDirectInit() const { + return getInitStyle() != CInit; + } + + /// \brief Determine whether this variable is the exception variable in a + /// C++ catch statememt or an Objective-C @catch statement. + bool isExceptionVariable() const { + return VarDeclBits.ExceptionVar; + } + void setExceptionVariable(bool EV) { VarDeclBits.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 VarDeclBits.NRVOVariable; } + void setNRVOVariable(bool NRVO) { VarDeclBits.NRVOVariable = NRVO; } + + /// \brief Determine whether this variable is the for-range-declaration in + /// a C++0x for-range statement. + bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; } + void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; } + + /// \brief Determine whether this variable is an ARC pseudo-__strong + /// variable. A pseudo-__strong variable has a __strong-qualified + /// type but does not actually retain the object written into it. + /// Generally such variables are also 'const' for safety. + bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; } + void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; } + + /// Whether this variable is (C++0x) constexpr. + bool isConstexpr() const { return VarDeclBits.IsConstexpr; } + void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; } + + /// \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 >= firstVar && K <= lastVar; } +}; + +class ImplicitParamDecl : public VarDecl { + virtual void anchor(); +public: + static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T); + + static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc, + IdentifierInfo *Id, QualType Type) + : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type, + /*tinfo*/ 0, SC_None, SC_None) { + setImplicit(); + } + + // 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 - Represents a parameter to a function. +class ParmVarDecl : public VarDecl { +public: + enum { MaxFunctionScopeDepth = 255 }; + enum { MaxFunctionScopeIndex = 255 }; + +protected: + ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T, TypeSourceInfo *TInfo, + StorageClass S, StorageClass SCAsWritten, Expr *DefArg) + : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S, SCAsWritten) { + assert(ParmVarDeclBits.HasInheritedDefaultArg == false); + assert(ParmVarDeclBits.IsKNRPromoted == false); + assert(ParmVarDeclBits.IsObjCMethodParam == false); + setDefaultArg(DefArg); + } + +public: + static ParmVarDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T, TypeSourceInfo *TInfo, + StorageClass S, StorageClass SCAsWritten, + Expr *DefArg); + + static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + virtual SourceRange getSourceRange() const LLVM_READONLY; + + void setObjCMethodScopeInfo(unsigned parameterIndex) { + ParmVarDeclBits.IsObjCMethodParam = true; + setParameterIndex(parameterIndex); + } + + void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) { + assert(!ParmVarDeclBits.IsObjCMethodParam); + + ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth; + assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth + && "truncation!"); + + setParameterIndex(parameterIndex); + } + + bool isObjCMethodParameter() const { + return ParmVarDeclBits.IsObjCMethodParam; + } + + unsigned getFunctionScopeDepth() const { + if (ParmVarDeclBits.IsObjCMethodParam) return 0; + return ParmVarDeclBits.ScopeDepthOrObjCQuals; + } + + /// Returns the index of this parameter in its prototype or method scope. + unsigned getFunctionScopeIndex() const { + return getParameterIndex(); + } + + ObjCDeclQualifier getObjCDeclQualifier() const { + if (!ParmVarDeclBits.IsObjCMethodParam) return OBJC_TQ_None; + return ObjCDeclQualifier(ParmVarDeclBits.ScopeDepthOrObjCQuals); + } + void setObjCDeclQualifier(ObjCDeclQualifier QTVal) { + assert(ParmVarDeclBits.IsObjCMethodParam); + ParmVarDeclBits.ScopeDepthOrObjCQuals = QTVal; + } + + /// True if the value passed to this parameter must undergo + /// K&R-style default argument promotion: + /// + /// C99 6.5.2.2. + /// If the expression that denotes the called function has a type + /// that does not include a prototype, the integer promotions are + /// performed on each argument, and arguments that have type float + /// are promoted to double. + bool isKNRPromoted() const { + return ParmVarDeclBits.IsKNRPromoted; + } + void setKNRPromoted(bool promoted) { + ParmVarDeclBits.IsKNRPromoted = promoted; + } + + Expr *getDefaultArg(); + const Expr *getDefaultArg() const { + return const_cast(this)->getDefaultArg(); + } + + void setDefaultArg(Expr *defarg) { + Init = reinterpret_cast(defarg); + } + + /// \brief Retrieve the source range that covers the entire default + /// argument. + SourceRange getDefaultArgRange() const; + void setUninstantiatedDefaultArg(Expr *arg) { + Init = reinterpret_cast(arg); + } + Expr *getUninstantiatedDefaultArg() { + return (Expr *)Init.get(); + } + const Expr *getUninstantiatedDefaultArg() const { + return (const Expr *)Init.get(); + } + + /// 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(); + } + + bool hasUninstantiatedDefaultArg() const { + return Init.is(); + } + + /// 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 ParmVarDeclBits.HasInheritedDefaultArg; + } + + void setHasInheritedDefaultArg(bool I = true) { + ParmVarDeclBits.HasInheritedDefaultArg = I; + } + + QualType getOriginalType() const { + if (getTypeSourceInfo()) + return getTypeSourceInfo()->getType(); + return getType(); + } + + /// \brief Determine whether this parameter is actually a function + /// parameter pack. + bool isParameterPack() const; + + /// setOwningFunction - Sets the function declaration that owns this + /// ParmVarDecl. Since ParmVarDecls are often created before the + /// FunctionDecls that own them, this routine is required to update + /// the DeclContext appropriately. + void setOwningFunction(DeclContext *FD) { setDeclContext(FD); } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const ParmVarDecl *D) { return true; } + static bool classofKind(Kind K) { return K == ParmVar; } + +private: + enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 }; + + void setParameterIndex(unsigned parameterIndex) { + if (parameterIndex >= ParameterIndexSentinel) { + setParameterIndexLarge(parameterIndex); + return; + } + + ParmVarDeclBits.ParameterIndex = parameterIndex; + assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!"); + } + unsigned getParameterIndex() const { + unsigned d = ParmVarDeclBits.ParameterIndex; + return d == ParameterIndexSentinel ? getParameterIndexLarge() : d; + } + + void setParameterIndexLarge(unsigned parameterIndex); + unsigned getParameterIndexLarge() const; +}; + +/// FunctionDecl - An instance of this class is created to represent a +/// function declaration or definition. +/// +/// Since a given function can be declared several times in a program, +/// there may be several FunctionDecls that correspond to that +/// function. Only one of those FunctionDecls will be found when +/// traversing the list of declarations in the context of the +/// FunctionDecl (e.g., the translation unit); this FunctionDecl +/// contains all of the information known about the function. Other, +/// previous declarations of the function are available via the +/// getPreviousDecl() chain. +class FunctionDecl : public DeclaratorDecl, public DeclContext, + public Redeclarable { +public: + typedef clang::StorageClass StorageClass; + + /// \brief The kind of templated function a FunctionDecl can be. + enum TemplatedKind { + TK_NonTemplate, + TK_FunctionTemplate, + TK_MemberSpecialization, + TK_FunctionTemplateSpecialization, + TK_DependentFunctionTemplateSpecialization + }; + +private: + /// ParamInfo - new[]'d array of pointers to VarDecls for the formal + /// parameters of this function. This is null if a prototype or if there are + /// no formals. + ParmVarDecl **ParamInfo; + + /// DeclsInPrototypeScope - Array of pointers to NamedDecls for + /// decls defined in the function prototype that are not parameters. E.g. + /// 'enum Y' in 'void f(enum Y {AA} x) {}'. + llvm::ArrayRef DeclsInPrototypeScope; + + 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 IsInlineSpecified : 1; + bool IsVirtualAsWritten : 1; + bool IsPure : 1; + bool HasInheritedPrototype : 1; + bool HasWrittenPrototype : 1; + bool IsDeleted : 1; + bool IsTrivial : 1; // sunk from CXXMethodDecl + bool IsDefaulted : 1; // sunk from CXXMethoDecl + bool IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl + bool HasImplicitReturnZero : 1; + bool IsLateTemplateParsed : 1; + bool IsConstexpr : 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 + TemplateOrSpecialization; + + /// DNLoc - Provides source/type location info for the + /// declaration name embedded in the DeclaratorDecl base class. + DeclarationNameLoc DNLoc; + + /// \brief Specify that this function declaration is actually a function + /// template specialization. + /// + /// \param C the ASTContext. + /// + /// \param Template the function template that this function template + /// specialization specializes. + /// + /// \param TemplateArgs the template arguments that produced this + /// function template specialization from the template. + /// + /// \param InsertPos If non-NULL, the position in the function template + /// specialization set where the function template specialization data will + /// be inserted. + /// + /// \param TSK the kind of template specialization this is. + /// + /// \param TemplateArgsAsWritten location info of template arguments. + /// + /// \param PointOfInstantiation point at which the function template + /// specialization was first instantiated. + void setFunctionTemplateSpecialization(ASTContext &C, + FunctionTemplateDecl *Template, + const TemplateArgumentList *TemplateArgs, + void *InsertPos, + TemplateSpecializationKind TSK, + const TemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation PointOfInstantiation); + + /// \brief Specify that this record is an instantiation of the + /// member function FD. + void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD, + TemplateSpecializationKind TSK); + + void setParams(ASTContext &C, llvm::ArrayRef NewParamInfo); + +protected: + FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified, + bool isConstexprSpecified) + : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, + StartLoc), + DeclContext(DK), + ParamInfo(0), Body(), + SClass(S), SClassAsWritten(SCAsWritten), + IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), + IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), + HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), + IsDefaulted(false), IsExplicitlyDefaulted(false), + HasImplicitReturnZero(false), IsLateTemplateParsed(false), + IsConstexpr(isConstexprSpecified), EndRangeLoc(NameInfo.getEndLoc()), + TemplateOrSpecialization(), + DNLoc(NameInfo.getInfo()) {} + + typedef Redeclarable redeclarable_base; + virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + virtual FunctionDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual FunctionDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + +public: + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + static FunctionDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation NLoc, + DeclarationName N, QualType T, + TypeSourceInfo *TInfo, + StorageClass SC = SC_None, + StorageClass SCAsWritten = SC_None, + bool isInlineSpecified = false, + bool hasWrittenPrototype = true, + bool isConstexprSpecified = false) { + DeclarationNameInfo NameInfo(N, NLoc); + return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, + SC, SCAsWritten, + isInlineSpecified, hasWrittenPrototype, + isConstexprSpecified); + } + + static FunctionDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + StorageClass SC = SC_None, + StorageClass SCAsWritten = SC_None, + bool isInlineSpecified = false, + bool hasWrittenPrototype = true, + bool isConstexprSpecified = false); + + static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + DeclarationNameInfo getNameInfo() const { + return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); + } + + virtual void getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const; + + void setRangeEnd(SourceLocation E) { EndRangeLoc = E; } + + virtual SourceRange getSourceRange() const LLVM_READONLY; + + /// \brief Returns true if the function has a body (definition). The + /// function body might be in any of the (re-)declarations of this + /// function. The variant that accepts a FunctionDecl pointer will + /// set that function declaration to the actual declaration + /// containing the body (if there is one). + bool hasBody(const FunctionDecl *&Definition) const; + + virtual bool hasBody() const { + const FunctionDecl* Definition; + return hasBody(Definition); + } + + /// hasTrivialBody - Returns whether the function has a trivial body that does + /// not require any specific codegen. + bool hasTrivialBody() const; + + /// isDefined - Returns true if the function is defined at all, including + /// a deleted definition. Except for the behavior when the function is + /// deleted, behaves like hasBody. + bool isDefined(const FunctionDecl *&Definition) const; + + virtual bool isDefined() const { + const FunctionDecl* Definition; + return isDefined(Definition); + } + + /// getBody - Retrieve the body (definition) of the function. The + /// function body might be in any of the (re-)declarations of this + /// function. The variant that accepts a FunctionDecl pointer will + /// set that function declaration to the actual declaration + /// containing the body (if there is one). + /// NOTE: For checking if there is a body, use hasBody() instead, to avoid + /// unnecessary AST de-serialization of the body. + Stmt *getBody(const FunctionDecl *&Definition) const; + + 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 isDefined. Note + /// that this returns false for a defaulted function unless that function + /// has been implicitly defined (possibly as deleted). + bool isThisDeclarationADefinition() const { + return IsDeleted || Body || IsLateTemplateParsed; + } + + /// doesThisDeclarationHaveABody - Returns whether this specific + /// declaration of the function has a body - that is, if it is a non- + /// deleted definition. + bool doesThisDeclarationHaveABody() const { + return Body || IsLateTemplateParsed; + } + + void setBody(Stmt *B); + void setLazyBody(uint64_t Offset) { Body = Offset; } + + /// Whether this function is variadic. + bool isVariadic() const; + + /// Whether this function is marked as virtual explicitly. + bool isVirtualAsWritten() const { return IsVirtualAsWritten; } + void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; } + + /// Whether this virtual function is pure, i.e. makes the containing class + /// abstract. + bool isPure() const { return IsPure; } + void setPure(bool P = true); + + /// Whether this templated function will be late parsed. + bool isLateTemplateParsed() const { return IsLateTemplateParsed; } + void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; } + + /// Whether this function is "trivial" in some specialized C++ senses. + /// Can only be true for default constructors, copy constructors, + /// copy assignment operators, and destructors. Not meaningful until + /// the class has been fully built by Sema. + bool isTrivial() const { return IsTrivial; } + void setTrivial(bool IT) { IsTrivial = IT; } + + /// Whether this function is defaulted per C++0x. Only valid for + /// special member functions. + bool isDefaulted() const { return IsDefaulted; } + void setDefaulted(bool D = true) { IsDefaulted = D; } + + /// Whether this function is explicitly defaulted per C++0x. Only valid + /// for special member functions. + bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; } + void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; } + + /// Whether falling off this function implicitly returns null/zero. + /// If a more specific implicit return value is required, front-ends + /// should synthesize the appropriate return statements. + bool hasImplicitReturnZero() const { return HasImplicitReturnZero; } + void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; } + + /// \brief Whether this function has a prototype, either because one + /// was explicitly written or because it was "inherited" by merging + /// a declaration without a prototype with a declaration that has a + /// prototype. + bool hasPrototype() const { + return HasWrittenPrototype || HasInheritedPrototype; + } + + bool hasWrittenPrototype() const { return HasWrittenPrototype; } + + /// \brief Whether this function inherited its prototype from a + /// previous declaration. + bool hasInheritedPrototype() const { return HasInheritedPrototype; } + void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; } + + /// Whether this is a (C++0x) constexpr function or constexpr constructor. + bool isConstexpr() const { return IsConstexpr; } + void setConstexpr(bool IC) { IsConstexpr = IC; } + + /// \brief Whether this function has been deleted. + /// + /// A function that is "deleted" (via the C++0x "= delete" syntax) + /// acts like a normal function, except that it cannot actually be + /// called or have its address taken. Deleted functions are + /// typically used in C++ overload resolution to attract arguments + /// whose type or lvalue/rvalue-ness would permit the use of a + /// different overload that would behave incorrectly. For example, + /// one might use deleted functions to ban implicit conversion from + /// a floating-point number to an Integer type: + /// + /// @code + /// struct Integer { + /// Integer(long); // construct from a long + /// Integer(double) = delete; // no construction from float or double + /// Integer(long double) = delete; // no construction from long double + /// }; + /// @endcode + // If a function is deleted, its first declaration must be. + bool isDeleted() const { return getCanonicalDecl()->IsDeleted; } + bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; } + void setDeletedAsWritten(bool D = true) { IsDeleted = D; } + + /// \brief Determines whether this function is "main", which is the + /// entry point into an executable program. + bool isMain() const; + + /// \brief Determines whether this operator new or delete is one + /// of the reserved global placement operators: + /// void *operator new(size_t, void *); + /// void *operator new[](size_t, void *); + /// void operator delete(void *, void *); + /// void operator delete[](void *, void *); + /// These functions have special behavior under [new.delete.placement]: + /// These functions are reserved, a C++ program may not define + /// functions that displace the versions in the Standard C++ library. + /// The provisions of [basic.stc.dynamic] do not apply to these + /// reserved placement forms of operator new and operator delete. + /// + /// This function must be an allocation or deallocation function. + bool isReservedGlobalPlacementOperator() const; + + /// \brief Determines whether this function is 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(llvm::ArrayRef NewParamInfo) { + setParams(getASTContext(), NewParamInfo); + } + + const llvm::ArrayRef &getDeclsInPrototypeScope() const { + return DeclsInPrototypeScope; + } + void setDeclsInPrototypeScope(llvm::ArrayRef NewDecls); + + /// getMinRequiredArguments - Returns the minimum number of arguments + /// needed to call this function. This may be fewer than the number of + /// function parameters, if some of the parameters have default + /// arguments (in C++). + unsigned getMinRequiredArguments() const; + + QualType getResultType() const { + return getType()->getAs()->getResultType(); + } + + /// \brief Determine the type of an expression that calls this function. + QualType getCallResultType() const { + return getType()->getAs()->getCallResultType(getASTContext()); + } + + StorageClass getStorageClass() const { return StorageClass(SClass); } + void setStorageClass(StorageClass SC); + + StorageClass getStorageClassAsWritten() const { + return StorageClass(SClassAsWritten); + } + + /// \brief Determine whether the "inline" keyword was specified for this + /// function. + bool isInlineSpecified() const { return IsInlineSpecified; } + + /// Set whether the "inline" keyword was specified for this function. + void setInlineSpecified(bool I) { + IsInlineSpecified = I; + IsInline = I; + } + + /// Flag that this function is implicitly inline. + void setImplicitlyInline() { + IsInline = true; + } + + /// \brief Determine whether this function should be inlined, because it is + /// either marked "inline" or "constexpr" or is a member function of a class + /// that was defined in the class body. + bool isInlined() const; + + bool isInlineDefinitionExternallyVisible() const; + + bool doesDeclarationForceExternallyVisibleDefinition() const; + + /// isOverloadedOperator - Whether this function declaration + /// represents an C++ overloaded operator, e.g., "operator+". + bool isOverloadedOperator() const { + return getOverloadedOperator() != OO_None; + } + + OverloadedOperatorKind getOverloadedOperator() const; + + const IdentifierInfo *getLiteralIdentifier() const; + + /// \brief If this function is an instantiation of a member function + /// of a class template specialization, retrieves the function from + /// which it was instantiated. + /// + /// This routine will return non-NULL for (non-templated) member + /// functions of class templates and for instantiations of function + /// templates. For example, given: + /// + /// \code + /// template + /// struct X { + /// void f(T); + /// }; + /// \endcode + /// + /// The declaration for X::f is a (non-templated) FunctionDecl + /// whose parent is the class template specialization X. For + /// this declaration, getInstantiatedFromFunction() will return + /// the FunctionDecl X::A. When a complete definition of + /// X::A is required, it will be instantiated from the + /// declaration returned by getInstantiatedFromMemberFunction(). + FunctionDecl *getInstantiatedFromMemberFunction() const; + + /// \brief What kind of templated function this is. + TemplatedKind getTemplatedKind() const; + + /// \brief If this function is an instantiation of a member function of a + /// class template specialization, retrieves the member specialization + /// information. + MemberSpecializationInfo *getMemberSpecializationInfo() const; + + /// \brief Specify that this record is an instantiation of the + /// member function FD. + void setInstantiationOfMemberFunction(FunctionDecl *FD, + TemplateSpecializationKind TSK) { + setInstantiationOfMemberFunction(getASTContext(), FD, TSK); + } + + /// \brief Retrieves the function template that is described by this + /// function declaration. + /// + /// Every function template is represented as a FunctionTemplateDecl + /// and a FunctionDecl (or something derived from FunctionDecl). The + /// former contains template properties (such as the template + /// parameter lists) while the latter contains the actual + /// description of the template's + /// contents. FunctionTemplateDecl::getTemplatedDecl() retrieves the + /// FunctionDecl that describes the function template, + /// getDescribedFunctionTemplate() retrieves the + /// FunctionTemplateDecl from a FunctionDecl. + FunctionTemplateDecl *getDescribedFunctionTemplate() const { + return TemplateOrSpecialization.dyn_cast(); + } + + void setDescribedFunctionTemplate(FunctionTemplateDecl *Template) { + TemplateOrSpecialization = Template; + } + + /// \brief Determine whether this function is a function template + /// specialization. + bool isFunctionTemplateSpecialization() const { + return getPrimaryTemplate() != 0; + } + + /// \brief Retrieve the class scope template pattern that this function + /// template specialization is instantiated from. + FunctionDecl *getClassScopeSpecializationPattern() const; + + /// \brief If this function is actually a function template specialization, + /// retrieve information about this function template specialization. + /// Otherwise, returns NULL. + FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const { + return TemplateOrSpecialization. + dyn_cast(); + } + + /// \brief Determines whether this function is a function template + /// specialization or a member of a class template specialization that can + /// be implicitly instantiated. + bool isImplicitlyInstantiable() const; + + /// \brief Determines if the given function was instantiated from a + /// function template. + bool isTemplateInstantiation() const; + + /// \brief Retrieve the function declaration from which this function could + /// be instantiated, if it is an instantiation (rather than a non-template + /// or a specialization, for example). + FunctionDecl *getTemplateInstantiationPattern() const; + + /// \brief Retrieve the primary template that this function template + /// specialization either specializes or was instantiated from. + /// + /// If this function declaration is not a function template specialization, + /// returns NULL. + FunctionTemplateDecl *getPrimaryTemplate() const; + + /// \brief Retrieve the template arguments used to produce this function + /// template specialization from the primary template. + /// + /// If this function declaration is not a function template specialization, + /// returns NULL. + const TemplateArgumentList *getTemplateSpecializationArgs() const; + + /// \brief Retrieve the template argument list as written in the sources, + /// if any. + /// + /// If this function declaration is not a function template specialization + /// or if it had no explicit template argument list, returns NULL. + /// Note that it an explicit template argument list may be written empty, + /// e.g., template<> void foo<>(char* s); + const ASTTemplateArgumentListInfo* + getTemplateSpecializationArgsAsWritten() const; + + /// \brief Specify that this function declaration is actually a function + /// template specialization. + /// + /// \param Template the function template that this function template + /// specialization specializes. + /// + /// \param TemplateArgs the template arguments that produced this + /// function template specialization from the template. + /// + /// \param InsertPos If non-NULL, the position in the function template + /// specialization set where the function template specialization data will + /// be inserted. + /// + /// \param TSK the kind of template specialization this is. + /// + /// \param TemplateArgsAsWritten location info of template arguments. + /// + /// \param PointOfInstantiation point at which the function template + /// specialization was first instantiated. + void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, + const TemplateArgumentList *TemplateArgs, + void *InsertPos, + TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, + const TemplateArgumentListInfo *TemplateArgsAsWritten = 0, + SourceLocation PointOfInstantiation = SourceLocation()) { + setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs, + InsertPos, TSK, TemplateArgsAsWritten, + PointOfInstantiation); + } + + /// \brief Specifies that this function declaration is actually a + /// dependent function template specialization. + void setDependentTemplateSpecialization(ASTContext &Context, + const UnresolvedSetImpl &Templates, + const TemplateArgumentListInfo &TemplateArgs); + + DependentFunctionTemplateSpecializationInfo * + getDependentSpecializationInfo() const { + return TemplateOrSpecialization. + dyn_cast(); + } + + /// \brief Determine what kind of template instantiation this function + /// represents. + TemplateSpecializationKind getTemplateSpecializationKind() const; + + /// \brief Determine what kind of template instantiation this function + /// represents. + void setTemplateSpecializationKind(TemplateSpecializationKind TSK, + SourceLocation PointOfInstantiation = SourceLocation()); + + /// \brief Retrieve the (first) point of instantiation of a function template + /// specialization or a member of a class template specialization. + /// + /// \returns the first point of instantiation, if this function was + /// instantiated from a template; otherwise, returns an invalid source + /// location. + SourceLocation getPointOfInstantiation() const; + + /// \brief Determine whether this is or was instantiated from an out-of-line + /// definition of a member function. + virtual bool isOutOfLine() const; + + /// \brief Identify a memory copying or setting function. + /// If the given function is a memory copy or setting function, returns + /// the corresponding Builtin ID. If the function is not a memory function, + /// returns 0. + unsigned getMemoryFunctionKind() const; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const FunctionDecl *D) { return true; } + static bool classofKind(Kind K) { + return K >= firstFunction && K <= lastFunction; + } + static DeclContext *castToDeclContext(const FunctionDecl *D) { + return static_cast(const_cast(D)); + } + static FunctionDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + + +/// FieldDecl - An instance of this class is created by Sema::ActOnField to +/// represent a member of a struct/union/class. +class FieldDecl : public DeclaratorDecl { + // FIXME: This can be packed into the bitfields in Decl. + bool Mutable : 1; + mutable unsigned CachedFieldIndex : 31; + + /// \brief A pointer to either the in-class initializer for this field (if + /// the boolean value is false), or the bit width expression for this bit + /// field (if the boolean value is true). + /// + /// We can safely combine these two because in-class initializers are not + /// permitted for bit-fields. + /// + /// If the boolean is false and the initializer is null, then this field has + /// an in-class initializer which has not yet been parsed and attached. + llvm::PointerIntPair InitializerOrBitWidth; +protected: + FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, + bool HasInit) + : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), + Mutable(Mutable), CachedFieldIndex(0), + InitializerOrBitWidth(BW, !HasInit) { + assert(!(BW && HasInit) && "got initializer for bitfield"); + } + +public: + static FieldDecl *Create(const ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, Expr *BW, bool Mutable, + bool HasInit); + + static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// getFieldIndex - Returns the index of this field within its record, + /// as appropriate for passing to ASTRecordLayout::getFieldOffset. + unsigned getFieldIndex() const; + + /// isMutable - Determines whether this field is mutable (C++ only). + bool isMutable() const { return Mutable; } + + /// \brief 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 InitializerOrBitWidth.getInt() && InitializerOrBitWidth.getPointer(); + } + + /// @brief Determines whether this is an unnamed bitfield. + bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); } + + /// isAnonymousStructOrUnion - Determines whether this field is a + /// representative for an anonymous struct or union. Such fields are + /// unnamed and are implicitly generated by the implementation to + /// store the data for the anonymous union or struct. + bool isAnonymousStructOrUnion() const; + + Expr *getBitWidth() const { + return isBitField() ? InitializerOrBitWidth.getPointer() : 0; + } + unsigned getBitWidthValue(const ASTContext &Ctx) const; + void setBitWidth(Expr *BW) { + assert(!InitializerOrBitWidth.getPointer() && + "bit width or initializer already set"); + InitializerOrBitWidth.setPointer(BW); + InitializerOrBitWidth.setInt(1); + } + /// removeBitWidth - Remove the bitfield width from this member. + void removeBitWidth() { + assert(isBitField() && "no bit width to remove"); + InitializerOrBitWidth.setPointer(0); + } + + /// hasInClassInitializer - Determine whether this member has a C++0x in-class + /// initializer. + bool hasInClassInitializer() const { + return !InitializerOrBitWidth.getInt(); + } + /// getInClassInitializer - Get the C++0x in-class initializer for this + /// member, or null if one has not been set. If a valid declaration has an + /// in-class initializer, but this returns null, then we have not parsed and + /// attached it yet. + Expr *getInClassInitializer() const { + return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0; + } + /// setInClassInitializer - Set the C++0x in-class initializer for this + /// member. + void setInClassInitializer(Expr *Init); + /// removeInClassInitializer - Remove the C++0x in-class initializer from this + /// member. + void removeInClassInitializer() { + assert(!InitializerOrBitWidth.getInt() && "no initializer to remove"); + InitializerOrBitWidth.setPointer(0); + InitializerOrBitWidth.setInt(1); + } + + /// getParent - Returns the parent of this field declaration, which + /// is the struct in which this method is defined. + const RecordDecl *getParent() const { + return cast(getDeclContext()); + } + + RecordDecl *getParent() { + return cast(getDeclContext()); + } + + SourceRange getSourceRange() const LLVM_READONLY; + + // 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 >= firstField && K <= lastField; } +}; + +/// 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) {} + +public: + + static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC, + SourceLocation L, IdentifierInfo *Id, + QualType T, Expr *E, + const llvm::APSInt &V); + static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + const Expr *getInitExpr() const { return (const Expr*) Init; } + Expr *getInitExpr() { return (Expr*) Init; } + const llvm::APSInt &getInitVal() const { return Val; } + + void setInitExpr(Expr *E) { Init = (Stmt*) E; } + void setInitVal(const llvm::APSInt &V) { Val = V; } + + SourceRange getSourceRange() const LLVM_READONLY; + + // 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; +}; + +/// IndirectFieldDecl - An instance of this class is created to represent a +/// field injected from an anonymous union/struct into the parent scope. +/// IndirectFieldDecl are always implicit. +class IndirectFieldDecl : public ValueDecl { + virtual void anchor(); + NamedDecl **Chaining; + unsigned ChainingSize; + + IndirectFieldDecl(DeclContext *DC, SourceLocation L, + DeclarationName N, QualType T, + NamedDecl **CH, unsigned CHS) + : ValueDecl(IndirectField, DC, L, N, T), Chaining(CH), ChainingSize(CHS) {} + +public: + static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, + QualType T, NamedDecl **CH, unsigned CHS); + + static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + typedef NamedDecl * const *chain_iterator; + chain_iterator chain_begin() const { return Chaining; } + chain_iterator chain_end() const { return Chaining+ChainingSize; } + + unsigned getChainingSize() const { return ChainingSize; } + + FieldDecl *getAnonField() const { + assert(ChainingSize >= 2); + return cast(Chaining[ChainingSize - 1]); + } + + VarDecl *getVarDecl() const { + assert(ChainingSize >= 2); + return dyn_cast(*chain_begin()); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const IndirectFieldDecl *D) { return true; } + static bool classofKind(Kind K) { return K == IndirectField; } + friend class ASTDeclReader; +}; + +/// TypeDecl - Represents a declaration of a type. +/// +class TypeDecl : public NamedDecl { + virtual void anchor(); + /// TypeForDecl - This indicates the Type object that represents + /// this TypeDecl. It is a cache maintained by + /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and + /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl. + mutable const Type *TypeForDecl; + /// LocStart - The start of the source range for this declaration. + SourceLocation LocStart; + friend class ASTContext; + friend class DeclContext; + friend class TagDecl; + friend class TemplateTypeParmDecl; + friend class TagType; + friend class ASTReader; + +protected: + TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, + SourceLocation StartL = SourceLocation()) + : NamedDecl(DK, DC, L, Id), TypeForDecl(0), LocStart(StartL) {} + +public: + // Low-level accessor + const Type *getTypeForDecl() const { return TypeForDecl; } + void setTypeForDecl(const Type *TD) { TypeForDecl = TD; } + + SourceLocation getLocStart() const LLVM_READONLY { return LocStart; } + void setLocStart(SourceLocation L) { LocStart = L; } + virtual SourceRange getSourceRange() const LLVM_READONLY { + if (LocStart.isValid()) + return SourceRange(LocStart, getLocation()); + else + return SourceRange(getLocation()); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const TypeDecl *D) { return true; } + static bool classofKind(Kind K) { return K >= firstType && K <= lastType; } +}; + + +/// Base class for declarations which introduce a typedef-name. +class TypedefNameDecl : public TypeDecl, public Redeclarable { + virtual void anchor(); + /// UnderlyingType - This is the type the typedef is set to. + TypeSourceInfo *TInfo; + +protected: + TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + TypeSourceInfo *TInfo) + : TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {} + + typedef Redeclarable redeclarable_base; + virtual TypedefNameDecl *getNextRedeclaration() { + return RedeclLink.getNext(); + } + virtual TypedefNameDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual TypedefNameDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + +public: + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + TypeSourceInfo *getTypeSourceInfo() const { + return TInfo; + } + + /// Retrieves the canonical declaration of this typedef-name. + TypedefNameDecl *getCanonicalDecl() { + return getFirstDeclaration(); + } + const TypedefNameDecl *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 TypedefNameDecl *D) { return true; } + static bool classofKind(Kind K) { + return K >= firstTypedefName && K <= lastTypedefName; + } +}; + +/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef' +/// type specifier. +class TypedefDecl : public TypedefNameDecl { + TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {} + +public: + static TypedefDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, TypeSourceInfo *TInfo); + static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceRange getSourceRange() const LLVM_READONLY; + + // 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; } +}; + +/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x +/// alias-declaration. +class TypeAliasDecl : public TypedefNameDecl { + TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {} + +public: + static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, TypeSourceInfo *TInfo); + static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceRange getSourceRange() const LLVM_READONLY; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const TypeAliasDecl *D) { return true; } + static bool classofKind(Kind K) { return K == TypeAlias; } +}; + +/// TagDecl - Represents the declaration of a struct/union/class/enum. +class TagDecl + : public TypeDecl, public DeclContext, public Redeclarable { +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; + + /// IsCompleteDefinition - True if this is a definition ("struct foo + /// {};"), false if it is a declaration ("struct foo;"). It is not + /// a definition until the definition has been fully processed. + bool IsCompleteDefinition : 1; + +protected: + /// IsBeingDefined - True if this is currently being defined. + bool IsBeingDefined : 1; + +private: + /// IsEmbeddedInDeclarator - True if this tag declaration is + /// "embedded" (i.e., defined or declared for the very first time) + /// in the syntax of a declarator. + bool IsEmbeddedInDeclarator : 1; + + /// \brief True if this tag is free standing, e.g. "struct foo;". + bool IsFreeStanding : 1; + +protected: + // These are used by (and only defined for) EnumDecl. + unsigned NumPositiveBits : 8; + unsigned NumNegativeBits : 8; + + /// IsScoped - True if this tag declaration is a scoped enumeration. Only + /// possible in C++11 mode. + bool IsScoped : 1; + /// IsScopedUsingClassTag - If this tag declaration is a scoped enum, + /// then this is true if the scoped enum was declared using the class + /// tag, false if it was declared with the struct tag. No meaning is + /// associated if this tag declaration is not a scoped enum. + bool IsScopedUsingClassTag : 1; + + /// IsFixed - True if this is an enumeration with fixed underlying type. Only + /// possible in C++11 or Microsoft extensions mode. + bool IsFixed : 1; + +private: + SourceLocation RBraceLoc; + + // A struct representing syntactic qualifier info, + // to be used for the (uncommon) case of out-of-line declarations. + typedef QualifierInfo ExtInfo; + + /// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name + /// is qualified, it points to the qualifier info (nns and range); + /// otherwise, if the tag declaration is anonymous and it is part of + /// a typedef or alias, it points to the TypedefNameDecl (used for mangling); + /// otherwise, it is a null (TypedefNameDecl) pointer. + llvm::PointerUnion TypedefNameDeclOrQualifier; + + bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is(); } + ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get(); } + const ExtInfo *getExtInfo() const { + return TypedefNameDeclOrQualifier.get(); + } + +protected: + TagDecl(Kind DK, TagKind TK, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, + TagDecl *PrevDecl, SourceLocation StartL) + : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), + TypedefNameDeclOrQualifier((TypedefNameDecl*) 0) { + assert((DK != Enum || TK == TTK_Enum) && + "EnumDecl not matched with TTK_Enum"); + TagDeclKind = TK; + IsCompleteDefinition = false; + IsBeingDefined = false; + IsEmbeddedInDeclarator = false; + IsFreeStanding = false; + setPreviousDeclaration(PrevDecl); + } + + typedef Redeclarable redeclarable_base; + virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + virtual TagDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual TagDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + + /// @brief Completes the definition of this tag declaration. + /// + /// This is a helper function for derived classes. + void completeDefinition(); + +public: + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + SourceLocation getRBraceLoc() const { return RBraceLoc; } + void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + + /// getInnerLocStart - Return SourceLocation representing start of source + /// range ignoring outer template declarations. + SourceLocation getInnerLocStart() const { return getLocStart(); } + + /// getOuterLocStart - Return SourceLocation representing start of source + /// range taking into account any outer template declarations. + SourceLocation getOuterLocStart() const; + virtual SourceRange getSourceRange() const LLVM_READONLY; + + virtual TagDecl* getCanonicalDecl(); + const TagDecl* getCanonicalDecl() const { + return const_cast(this)->getCanonicalDecl(); + } + + /// isThisDeclarationADefinition() - Return true if this declaration + /// is a completion definintion of the type. Provided for consistency. + bool isThisDeclarationADefinition() const { + return isCompleteDefinition(); + } + + /// isCompleteDefinition - Return true if this decl has its body + /// fully specified. + bool isCompleteDefinition() const { + return IsCompleteDefinition; + } + + /// isBeingDefined - Return true if this decl is currently being defined. + bool isBeingDefined() const { + return IsBeingDefined; + } + + bool isEmbeddedInDeclarator() const { + return IsEmbeddedInDeclarator; + } + void setEmbeddedInDeclarator(bool isInDeclarator) { + IsEmbeddedInDeclarator = isInDeclarator; + } + + bool isFreeStanding() const { return IsFreeStanding; } + void setFreeStanding(bool isFreeStanding = true) { + IsFreeStanding = isFreeStanding; + } + + /// \brief Whether this declaration declares a type that is + /// dependent, i.e., a type that somehow depends on template + /// parameters. + bool isDependentType() const { return isDependentContext(); } + + /// @brief Starts the definition of this tag declaration. + /// + /// This method should be invoked at the beginning of the definition + /// of this tag declaration. It will set the tag type into a state + /// where it is in the process of being defined. + void startDefinition(); + + /// getDefinition - Returns the TagDecl that actually defines this + /// struct/union/class/enum. When determining whether or not a + /// struct/union/class/enum has a definition, one should use this + /// method as opposed to 'isDefinition'. 'isDefinition' indicates + /// whether or not a specific TagDecl is defining declaration, not + /// whether or not the struct/union/class/enum type is defined. + /// This method returns NULL if there is no TagDecl that defines + /// the struct/union/class/enum. + TagDecl *getDefinition() const; + + void setCompleteDefinition(bool V) { IsCompleteDefinition = V; } + + 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; } + + TypedefNameDecl *getTypedefNameForAnonDecl() const { + return hasExtInfo() ? 0 : + TypedefNameDeclOrQualifier.get(); + } + + void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); + + /// \brief Retrieve the nested-name-specifier that qualifies the name of this + /// declaration, if it was present in the source. + NestedNameSpecifier *getQualifier() const { + return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier() + : 0; + } + + /// \brief Retrieve the nested-name-specifier (with source-location + /// information) that qualifies the name of this declaration, if it was + /// present in the source. + NestedNameSpecifierLoc getQualifierLoc() const { + return hasExtInfo() ? getExtInfo()->QualifierLoc + : NestedNameSpecifierLoc(); + } + + void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc); + + unsigned getNumTemplateParameterLists() const { + return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0; + } + TemplateParameterList *getTemplateParameterList(unsigned i) const { + assert(i < getNumTemplateParameterLists()); + return getExtInfo()->TemplParamLists[i]; + } + void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists, + TemplateParameterList **TPLists); + + // 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 >= firstTag && K <= lastTag; } + + static DeclContext *castToDeclContext(const TagDecl *D) { + return static_cast(const_cast(D)); + } + static TagDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// EnumDecl - Represents an enum. In C++11, enums can be forward-declared +/// with a fixed underlying type, and in C we allow them to be forward-declared +/// with no underlying type as an extension. +class EnumDecl : public TagDecl { + virtual void anchor(); + /// IntegerType - This represent the integer type that the enum corresponds + /// to for code generation purposes. Note that the enumerator constants may + /// have a different type than this does. + /// + /// If the underlying integer type was explicitly stated in the source + /// code, this is a TypeSourceInfo* for that type. Otherwise this type + /// was automatically deduced somehow, and this is a Type*. + /// + /// Normally if IsFixed(), this would contain a TypeSourceInfo*, but in + /// some cases it won't. + /// + /// The underlying type of an enumeration never has any qualifiers, so + /// we can get away with just storing a raw Type*, and thus save an + /// extra pointer when TypeSourceInfo is needed. + + llvm::PointerUnion IntegerType; + + /// PromotionType - The integer type that values of this type should + /// promote to. In C, enumerators are generally of an integer type + /// directly, but gcc-style large enumerators (and all enumerators + /// in C++) are of the enum type instead. + QualType PromotionType; + + /// \brief If this enumeration is an instantiation of a member enumeration + /// of a class template specialization, this is the member specialization + /// information. + MemberSpecializationInfo *SpecializationInfo; + + EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, EnumDecl *PrevDecl, + bool Scoped, bool ScopedUsingClassTag, bool Fixed) + : TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc), + SpecializationInfo(0) { + assert(Scoped || !ScopedUsingClassTag); + IntegerType = (const Type*)0; + NumNegativeBits = 0; + NumPositiveBits = 0; + IsScoped = Scoped; + IsScopedUsingClassTag = ScopedUsingClassTag; + IsFixed = Fixed; + } + + void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, + TemplateSpecializationKind TSK); +public: + EnumDecl *getCanonicalDecl() { + return cast(TagDecl::getCanonicalDecl()); + } + const EnumDecl *getCanonicalDecl() const { + return cast(TagDecl::getCanonicalDecl()); + } + + const EnumDecl *getPreviousDecl() const { + return cast_or_null(TagDecl::getPreviousDecl()); + } + EnumDecl *getPreviousDecl() { + return cast_or_null(TagDecl::getPreviousDecl()); + } + + const EnumDecl *getMostRecentDecl() const { + return cast(TagDecl::getMostRecentDecl()); + } + EnumDecl *getMostRecentDecl() { + return cast(TagDecl::getMostRecentDecl()); + } + + EnumDecl *getDefinition() const { + return cast_or_null(TagDecl::getDefinition()); + } + + static EnumDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, EnumDecl *PrevDecl, + bool IsScoped, bool IsScopedUsingClassTag, + bool IsFixed); + static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// completeDefinition - When created, the EnumDecl corresponds to a + /// forward-declared enum. This method is used to mark the + /// declaration as being defined; it's enumerators have already been + /// added (via DeclContext::addDecl). NewType is the new underlying + /// type of the enumeration type. + void completeDefinition(QualType NewType, + QualType PromotionType, + unsigned NumPositiveBits, + unsigned NumNegativeBits); + + // enumerator_iterator - Iterates through the enumerators of this + // enumeration. + typedef specific_decl_iterator enumerator_iterator; + + enumerator_iterator enumerator_begin() const { + const EnumDecl *E = getDefinition(); + if (!E) + E = this; + return enumerator_iterator(E->decls_begin()); + } + + enumerator_iterator enumerator_end() const { + const EnumDecl *E = getDefinition(); + if (!E) + E = this; + return enumerator_iterator(E->decls_end()); + } + + /// getPromotionType - Return the integer type that enumerators + /// should promote to. + QualType getPromotionType() const { return PromotionType; } + + /// \brief Set the promotion type. + void setPromotionType(QualType T) { PromotionType = T; } + + /// getIntegerType - Return the integer type this enum decl corresponds to. + /// This returns a null qualtype for an enum forward definition. + QualType getIntegerType() const { + if (!IntegerType) + return QualType(); + if (const Type* T = IntegerType.dyn_cast()) + return QualType(T, 0); + return IntegerType.get()->getType(); + } + + /// \brief Set the underlying integer type. + void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); } + + /// \brief Set the underlying integer type source info. + void setIntegerTypeSourceInfo(TypeSourceInfo* TInfo) { IntegerType = TInfo; } + + /// \brief Return the type source info for the underlying integer type, + /// if no type source info exists, return 0. + TypeSourceInfo* getIntegerTypeSourceInfo() const { + return IntegerType.dyn_cast(); + } + + /// \brief Returns the width in bits required to store all the + /// non-negative enumerators of this enum. + unsigned getNumPositiveBits() const { + return NumPositiveBits; + } + void setNumPositiveBits(unsigned Num) { + NumPositiveBits = Num; + assert(NumPositiveBits == Num && "can't store this bitcount"); + } + + /// \brief Returns the width in bits required to store all the + /// negative enumerators of this enum. These widths include + /// the rightmost leading 1; that is: + /// + /// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS + /// ------------------------ ------- ----------------- + /// -1 1111111 1 + /// -10 1110110 5 + /// -101 1001011 8 + unsigned getNumNegativeBits() const { + return NumNegativeBits; + } + void setNumNegativeBits(unsigned Num) { + NumNegativeBits = Num; + } + + /// \brief Returns true if this is a C++0x scoped enumeration. + bool isScoped() const { + return IsScoped; + } + + /// \brief Returns true if this is a C++0x scoped enumeration. + bool isScopedUsingClassTag() const { + return IsScopedUsingClassTag; + } + + /// \brief Returns true if this is a C++0x enumeration with fixed underlying + /// type. + bool isFixed() const { + return IsFixed; + } + + /// \brief Returns true if this can be considered a complete type. + bool isComplete() const { + return isCompleteDefinition() || isFixed(); + } + + /// \brief Returns the enumeration (declared within the template) + /// from which this enumeration type was instantiated, or NULL if + /// this enumeration was not instantiated from any template. + EnumDecl *getInstantiatedFromMemberEnum() const; + + /// \brief If this enumeration is a member of a specialization of a + /// templated class, determine what kind of template specialization + /// or instantiation this is. + TemplateSpecializationKind getTemplateSpecializationKind() const; + + /// \brief For an enumeration member that was instantiated from a member + /// enumeration of a templated class, set the template specialiation kind. + void setTemplateSpecializationKind(TemplateSpecializationKind TSK, + SourceLocation PointOfInstantiation = SourceLocation()); + + /// \brief If this enumeration is an instantiation of a member enumeration of + /// a class template specialization, retrieves the member specialization + /// information. + MemberSpecializationInfo *getMemberSpecializationInfo() const { + return SpecializationInfo; + } + + /// \brief Specify that this enumeration is an instantiation of the + /// member enumeration ED. + void setInstantiationOfMemberEnum(EnumDecl *ED, + TemplateSpecializationKind TSK) { + setInstantiationOfMemberEnum(getASTContext(), ED, TSK); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const EnumDecl *D) { return true; } + static bool classofKind(Kind K) { return K == Enum; } + + friend class ASTDeclReader; +}; + + +/// RecordDecl - Represents a struct/union/class. For example: +/// struct X; // Forward declaration, no "body". +/// union Y { int A, B; }; // Has body with members A and B (FieldDecls). +/// This decl will be marked invalid if *any* members are invalid. +/// +class RecordDecl : public TagDecl { + // FIXME: This can be packed into the bitfields in Decl. + /// HasFlexibleArrayMember - This is true if this struct ends with a flexible + /// array member (e.g. int X[]) or if this union contains a struct that does. + /// If so, this cannot be contained in arrays or other structs as a member. + bool HasFlexibleArrayMember : 1; + + /// AnonymousStructOrUnion - Whether this is the type of an anonymous struct + /// or union. + bool AnonymousStructOrUnion : 1; + + /// HasObjectMember - This is true if this struct has at least one member + /// containing an Objective-C object pointer type. + bool HasObjectMember : 1; + + /// \brief Whether the field declarations of this record have been loaded + /// from external storage. To avoid unnecessary deserialization of + /// methods/nested types we allow deserialization of just the fields + /// when needed. + mutable bool LoadedFieldsFromExternalStorage : 1; + friend class DeclContext; + +protected: + RecordDecl(Kind DK, TagKind TK, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, RecordDecl *PrevDecl); + +public: + static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, RecordDecl* PrevDecl = 0); + static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + + const RecordDecl *getPreviousDecl() const { + return cast_or_null(TagDecl::getPreviousDecl()); + } + RecordDecl *getPreviousDecl() { + return cast_or_null(TagDecl::getPreviousDecl()); + } + + const RecordDecl *getMostRecentDecl() const { + return cast(TagDecl::getMostRecentDecl()); + } + RecordDecl *getMostRecentDecl() { + return cast(TagDecl::getMostRecentDecl()); + } + + bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } + void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; } + + /// isAnonymousStructOrUnion - Whether this is an anonymous struct + /// or union. To be an anonymous struct or union, it must have been + /// declared without a name and there must be no objects of this + /// type declared, e.g., + /// @code + /// union { int i; float f; }; + /// @endcode + /// is an anonymous union but neither of the following are: + /// @code + /// union X { int i; float f; }; + /// union { int i; float f; } obj; + /// @endcode + bool isAnonymousStructOrUnion() const { return AnonymousStructOrUnion; } + void setAnonymousStructOrUnion(bool Anon) { + AnonymousStructOrUnion = Anon; + } + + bool hasObjectMember() const { return HasObjectMember; } + void setHasObjectMember (bool val) { HasObjectMember = val; } + + /// \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 'isCompleteDefinition'. + /// 'isCompleteDefinition' indicates whether or not a specific + /// RecordDecl is a completed definition, not whether or not the + /// record type is defined. This method returns NULL if there is + /// no RecordDecl that defines the struct/union/tag. + RecordDecl *getDefinition() const { + return cast_or_null(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 field_iterator; + + field_iterator field_begin() const; + + field_iterator field_end() const { + return field_iterator(decl_iterator()); + } + + // field_empty - Whether there are any fields (non-static data + // members) in this record. + bool field_empty() const { + return field_begin() == field_end(); + } + + /// completeDefinition - Notes that the definition of this type is + /// now complete. + virtual void completeDefinition(); + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const RecordDecl *D) { return true; } + static bool classofKind(Kind K) { + return K >= firstRecord && K <= lastRecord; + } + +private: + /// \brief Deserialize just the fields. + void LoadFieldsFromExternalStorage() const; +}; + +class FileScopeAsmDecl : public Decl { + virtual void anchor(); + StringLiteral *AsmString; + SourceLocation RParenLoc; + FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring, + SourceLocation StartL, SourceLocation EndL) + : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {} +public: + static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC, + StringLiteral *Str, SourceLocation AsmLoc, + SourceLocation RParenLoc); + + static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceLocation getAsmLoc() const { return getLocation(); } + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(getAsmLoc(), getRParenLoc()); + } + + const StringLiteral *getAsmString() const { return AsmString; } + StringLiteral *getAsmString() { return AsmString; } + void setAsmString(StringLiteral *Asm) { AsmString = Asm; } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool 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 { +public: + /// A class which contains all the information about a particular + /// captured value. + class Capture { + enum { + flag_isByRef = 0x1, + flag_isNested = 0x2 + }; + + /// The variable being captured. + llvm::PointerIntPair VariableAndFlags; + + /// The copy expression, expressed in terms of a DeclRef (or + /// BlockDeclRef) to the captured variable. Only required if the + /// variable has a C++ class type. + Expr *CopyExpr; + + public: + Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy) + : VariableAndFlags(variable, + (byRef ? flag_isByRef : 0) | (nested ? flag_isNested : 0)), + CopyExpr(copy) {} + + /// The variable being captured. + VarDecl *getVariable() const { return VariableAndFlags.getPointer(); } + + /// Whether this is a "by ref" capture, i.e. a capture of a __block + /// variable. + bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; } + + /// Whether this is a nested capture, i.e. the variable captured + /// is not from outside the immediately enclosing function/block. + bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; } + + bool hasCopyExpr() const { return CopyExpr != 0; } + Expr *getCopyExpr() const { return CopyExpr; } + void setCopyExpr(Expr *e) { CopyExpr = e; } + }; + +private: + // FIXME: This can be packed into the bitfields in Decl. + bool IsVariadic : 1; + bool CapturesCXXThis : 1; + bool BlockMissingReturnType : 1; + bool IsConversionFromLambda : 1; + /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal + /// parameters of this function. This is null if a prototype or if there are + /// no formals. + ParmVarDecl **ParamInfo; + unsigned NumParams; + + Stmt *Body; + TypeSourceInfo *SignatureAsWritten; + + Capture *Captures; + unsigned NumCaptures; + +protected: + BlockDecl(DeclContext *DC, SourceLocation CaretLoc) + : Decl(Block, DC, CaretLoc), DeclContext(Block), + IsVariadic(false), CapturesCXXThis(false), + BlockMissingReturnType(true), IsConversionFromLambda(false), + ParamInfo(0), NumParams(0), Body(0), + SignatureAsWritten(0), Captures(0), NumCaptures(0) {} + +public: + static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); + static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceLocation getCaretLocation() const { return getLocation(); } + + bool isVariadic() const { return IsVariadic; } + void setIsVariadic(bool value) { IsVariadic = value; } + + CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; } + Stmt *getBody() const { return (Stmt*) Body; } + void setBody(CompoundStmt *B) { Body = (Stmt*) B; } + + void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; } + TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; } + + // Iterator access to formal parameters. + unsigned param_size() const { return getNumParams(); } + typedef ParmVarDecl **param_iterator; + typedef ParmVarDecl * const *param_const_iterator; + + 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 { return NumParams; } + const ParmVarDecl *getParamDecl(unsigned i) const { + assert(i < getNumParams() && "Illegal param #"); + return ParamInfo[i]; + } + ParmVarDecl *getParamDecl(unsigned i) { + assert(i < getNumParams() && "Illegal param #"); + return ParamInfo[i]; + } + void setParams(llvm::ArrayRef NewParamInfo); + + /// hasCaptures - True if this block (or its nested blocks) captures + /// anything of local storage from its enclosing scopes. + bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; } + + /// getNumCaptures - Returns the number of captured variables. + /// Does not include an entry for 'this'. + unsigned getNumCaptures() const { return NumCaptures; } + + typedef const Capture *capture_iterator; + typedef const Capture *capture_const_iterator; + capture_iterator capture_begin() { return Captures; } + capture_iterator capture_end() { return Captures + NumCaptures; } + capture_const_iterator capture_begin() const { return Captures; } + capture_const_iterator capture_end() const { return Captures + NumCaptures; } + + bool capturesCXXThis() const { return CapturesCXXThis; } + bool blockMissingReturnType() const { return BlockMissingReturnType; } + void setBlockMissingReturnType(bool val) { BlockMissingReturnType = val; } + + bool isConversionFromLambda() const { return IsConversionFromLambda; } + void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; } + + bool capturesVariable(const VarDecl *var) const; + + void setCaptures(ASTContext &Context, + const Capture *begin, + const Capture *end, + bool capturesCXXThis); + + virtual SourceRange getSourceRange() const LLVM_READONLY; + + // 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(const_cast(D)); + } + static BlockDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } +}; + +/// \brief Describes a module import declaration, which makes the contents +/// of the named module visible in the current translation unit. +/// +/// An import declaration imports the named module (or submodule). For example: +/// \code +/// @__experimental_modules_import std.vector; +/// \endcode +/// +/// Import declarations can also be implicitly generated from #include/#import +/// directives. +class ImportDecl : public Decl { + /// \brief The imported module, along with a bit that indicates whether + /// we have source-location information for each identifier in the module + /// name. + /// + /// When the bit is false, we only have a single source location for the + /// end of the import declaration. + llvm::PointerIntPair ImportedAndComplete; + + /// \brief The next import in the list of imports local to the translation + /// unit being parsed (not loaded from an AST file). + ImportDecl *NextLocalImport; + + friend class ASTReader; + friend class ASTDeclReader; + friend class ASTContext; + + ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, + ArrayRef IdentifierLocs); + + ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, + SourceLocation EndLoc); + + ImportDecl(EmptyShell Empty) : Decl(Import, Empty), NextLocalImport() { } + +public: + /// \brief Create a new module import declaration. + static ImportDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, Module *Imported, + ArrayRef IdentifierLocs); + + /// \brief Create a new module import declaration for an implicitly-generated + /// import. + static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, Module *Imported, + SourceLocation EndLoc); + + /// \brief Create a new, deserialized module import declaration. + static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned NumLocations); + + /// \brief Retrieve the module that was imported by the import declaration. + Module *getImportedModule() const { return ImportedAndComplete.getPointer(); } + + /// \brief Retrieves the locations of each of the identifiers that make up + /// the complete module name in the import declaration. + /// + /// This will return an empty array if the locations of the individual + /// identifiers aren't available. + ArrayRef getIdentifierLocs() const; + + virtual SourceRange getSourceRange() const LLVM_READONLY; + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const ImportDecl *D) { return true; } + static bool classofKind(Kind K) { return K == Import; } +}; + + +/// Insertion operator for diagnostics. This allows sending NamedDecl's +/// into a diagnostic with <<. +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const NamedDecl* ND) { + DB.AddTaggedVal(reinterpret_cast(ND), + DiagnosticsEngine::ak_nameddecl); + return DB; +} +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const NamedDecl* ND) { + PD.AddTaggedVal(reinterpret_cast(ND), + DiagnosticsEngine::ak_nameddecl); + return PD; +} + +template +void Redeclarable::setPreviousDeclaration(decl_type *PrevDecl) { + // Note: This routine is implemented here because we need both NamedDecl + // and Redeclarable to be defined. + + 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(PrevDecl->getMostRecentDecl())); + First = PrevDecl->getFirstDeclaration(); + assert(First->RedeclLink.NextIsLatest() && "Expected first"); + } else { + // Make this first. + First = static_cast(this); + } + + // First one will point to this one as latest. + First->RedeclLink = LatestDeclLink(static_cast(this)); + if (NamedDecl *ND = dyn_cast(static_cast(this))) + ND->ClearLinkageCache(); +} + +// Inline function definitions. + +/// \brief Check if the given decl is complete. +/// +/// We use this function to break a cycle between the inline definitions in +/// Type.h and Decl.h. +inline bool IsEnumDeclComplete(EnumDecl *ED) { + return ED->isComplete(); +} + +/// \brief Check if the given decl is scoped. +/// +/// We use this function to break a cycle between the inline definitions in +/// Type.h and Decl.h. +inline bool IsEnumDeclScoped(EnumDecl *ED) { + return ED->isScoped(); +} + +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/DeclAccessPair.h b/clang/include/clang/AST/DeclAccessPair.h new file mode 100644 index 0000000..7ecd8f8 --- /dev/null +++ b/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(uintptr_t(AS) | + reinterpret_cast(D)); + } + + operator NamedDecl*() const { return getDecl(); } + NamedDecl *operator->() const { return getDecl(); } +}; +} + +// Take a moment to tell SmallVector that DeclAccessPair is POD. +namespace llvm { +template struct isPodLike; +template<> struct isPodLike { + static const bool value = true; +}; +} + +#endif diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h new file mode 100644 index 0000000..2232891 --- /dev/null +++ b/clang/include/clang/AST/DeclBase.h @@ -0,0 +1,1636 @@ +//===-- 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/ADT/PointerUnion.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/PrettyStackTrace.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; +class ASTMutationListener; +} + +namespace llvm { +// DeclContext* is only 4-byte aligned on 32-bit systems. +template<> + class PointerLikeTypeTraits { + typedef clang::DeclContext* PT; +public: + static inline void *getAsVoidPointer(PT P) { return P; } + static inline PT getFromVoidPointer(void *P) { + return static_cast(P); + } + enum { NumLowBitsAvailable = 2 }; +}; +} + +namespace clang { + + /// \brief Captures the result of checking the availability of a + /// declaration. + enum AvailabilityResult { + AR_Available = 0, + AR_NotYetIntroduced, + AR_Deprecated, + AR_Unavailable + }; + +/// Decl - This represents one declaration (or definition), e.g. a variable, +/// typedef, function, struct, etc. +/// +class Decl { +public: + /// \brief Lists the kind of concrete classes of Decl. + enum Kind { +#define DECL(DERIVED, BASE) DERIVED, +#define ABSTRACT_DECL(DECL) +#define DECL_RANGE(BASE, START, END) \ + first##BASE = START, last##BASE = END, +#define LAST_DECL_RANGE(BASE, START, END) \ + first##BASE = START, last##BASE = END +#include "clang/AST/DeclNodes.inc" + }; + + /// \brief A placeholder type used to construct an empty shell of a + /// decl-derived type that will be filled in later (e.g., by some + /// deserialization method). + struct EmptyShell { }; + + /// IdentifierNamespace - The different namespaces in which + /// declarations may appear. According to C99 6.2.3, there are + /// four namespaces, labels, tags, members and ordinary + /// identifiers. C++ describes lookup completely differently: + /// certain lookups merely "ignore" certain kinds of declarations, + /// usually based on whether the declaration is of a type, etc. + /// + /// These are meant as bitmasks, so that searches in + /// C++ can look into the "tag" namespace during ordinary lookup. + /// + /// Decl currently provides 15 bits of IDNS bits. + enum IdentifierNamespace { + /// Labels, declared with 'x:' and referenced with 'goto x'. + IDNS_Label = 0x0001, + + /// Tags, declared with 'struct foo;' and referenced with + /// 'struct foo'. All tags are also types. This is what + /// elaborated-type-specifiers look for in C. + IDNS_Tag = 0x0002, + + /// Types, declared with 'struct foo', typedefs, etc. + /// This is what elaborated-type-specifiers look for in C++, + /// but note that it's ill-formed to find a non-tag. + IDNS_Type = 0x0004, + + /// Members, declared with object declarations within tag + /// definitions. In C, these can only be found by "qualified" + /// lookup in member expressions. In C++, they're found by + /// normal lookup. + IDNS_Member = 0x0008, + + /// Namespaces, declared with 'namespace foo {}'. + /// Lookup for nested-name-specifiers find these. + IDNS_Namespace = 0x0010, + + /// Ordinary names. In C, everything that's not a label, tag, + /// or member ends up here. + IDNS_Ordinary = 0x0020, + + /// Objective C @protocol. + IDNS_ObjCProtocol = 0x0040, + + /// This declaration is a friend function. A friend function + /// declaration is always in this namespace but may also be in + /// IDNS_Ordinary if it was previously declared. + IDNS_OrdinaryFriend = 0x0080, + + /// This declaration is a friend class. A friend class + /// declaration is always in this namespace but may also be in + /// IDNS_Tag|IDNS_Type if it was previously declared. + IDNS_TagFriend = 0x0100, + + /// This declaration is a using declaration. A using declaration + /// *introduces* a number of other declarations into the current + /// scope, and those declarations use the IDNS of their targets, + /// but the actual using declarations go in this namespace. + IDNS_Using = 0x0200, + + /// This declaration is a C++ operator declared in a non-class + /// context. All such operators are also in IDNS_Ordinary. + /// C++ lexical operator lookup looks for these. + IDNS_NonMemberOperator = 0x0400 + }; + + /// ObjCDeclQualifier - 'Qualifiers' written next to the return and + /// parameter types in method declarations. Other than remembering + /// them and mangling them into the method's signature string, these + /// are ignored by the compiler; they are consumed by certain + /// remote-messaging frameworks. + /// + /// in, inout, and out are mutually exclusive and apply only to + /// method parameters. bycopy and byref are mutually exclusive and + /// apply only to method parameters (?). oneway applies only to + /// results. All of these expect their corresponding parameter to + /// have a particular type. None of this is currently enforced by + /// clang. + /// + /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier. + enum ObjCDeclQualifier { + OBJC_TQ_None = 0x0, + OBJC_TQ_In = 0x1, + OBJC_TQ_Inout = 0x2, + OBJC_TQ_Out = 0x4, + OBJC_TQ_Bycopy = 0x8, + OBJC_TQ_Byref = 0x10, + OBJC_TQ_Oneway = 0x20 + }; + +protected: + // Enumeration values used in the bits stored in NextInContextAndBits. + enum { + /// \brief Whether this declaration is a top-level declaration (function, + /// global variable, etc.) that is lexically inside an objc container + /// definition. + TopLevelDeclInObjCContainerFlag = 0x01, + + /// \brief Whether this declaration is private to the module in which it was + /// defined. + ModulePrivateFlag = 0x02 + }; + + /// \brief The next declaration within the same lexical + /// DeclContext. These pointers form the linked list that is + /// traversed via DeclContext's decls_begin()/decls_end(). + /// + /// The extra two bits are used for the TopLevelDeclInObjCContainer and + /// ModulePrivate bits. + llvm::PointerIntPair NextInContextAndBits; + +private: + friend class DeclContext; + + struct MultipleDC { + DeclContext *SemanticDC; + DeclContext *LexicalDC; + }; + + + /// DeclCtx - Holds either a DeclContext* or a MultipleDC*. + /// For declarations that don't contain C++ scope specifiers, it contains + /// the DeclContext where the Decl was declared. + /// For declarations with C++ scope specifiers, it contains a MultipleDC* + /// with the context where it semantically belongs (SemanticDC) and the + /// context where it was lexically declared (LexicalDC). + /// e.g.: + /// + /// namespace A { + /// void f(); // SemanticDC == LexicalDC == 'namespace A' + /// } + /// void A::f(); // SemanticDC == namespace 'A' + /// // LexicalDC == global namespace + llvm::PointerUnion DeclCtx; + + inline bool isInSemaDC() const { return DeclCtx.is(); } + inline bool isOutOfSemaDC() const { return DeclCtx.is(); } + inline MultipleDC *getMultipleDC() const { + return DeclCtx.get(); + } + inline DeclContext *getSemanticDC() const { + return DeclCtx.get(); + } + + /// Loc - The location of this decl. + SourceLocation Loc; + + /// DeclKind - This indicates which class this is. + unsigned DeclKind : 8; + + /// InvalidDecl - This indicates a semantic error occurred. + unsigned InvalidDecl : 1; + + /// HasAttrs - This indicates whether the decl has attributes or not. + unsigned HasAttrs : 1; + + /// Implicit - Whether this declaration was implicitly generated by + /// the implementation rather than explicitly written by the user. + unsigned Implicit : 1; + + /// \brief Whether this declaration was "used", meaning that a definition is + /// required. + unsigned Used : 1; + + /// \brief Whether this declaration was "referenced". + /// The difference with 'Used' is whether the reference appears in a + /// evaluated context or not, e.g. functions used in uninstantiated templates + /// are regarded as "referenced" but not "used". + unsigned Referenced : 1; + + /// \brief Whether statistic collection is enabled. + static bool StatisticsEnabled; + +protected: + /// Access - Used by C++ decls for the access specifier. + // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum + unsigned Access : 2; + friend class CXXClassMemberWrapper; + + /// \brief Whether this declaration was loaded from an AST file. + unsigned FromASTFile : 1; + + /// \brief Whether this declaration is hidden from normal name lookup, e.g., + /// because it is was loaded from an AST file is either module-private or + /// because its submodule has not been made visible. + unsigned Hidden : 1; + + /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. + unsigned IdentifierNamespace : 12; + + /// \brief Whether the \c CachedLinkage field is active. + /// + /// This field is only valid for NamedDecls subclasses. + mutable unsigned HasCachedLinkage : 1; + + /// \brief If \c HasCachedLinkage, the linkage of this declaration. + /// + /// This field is only valid for NamedDecls subclasses. + mutable unsigned CachedLinkage : 2; + + friend class ASTDeclWriter; + friend class ASTDeclReader; + friend class ASTReader; + +private: + void CheckAccessDeclContext() const; + +protected: + + Decl(Kind DK, DeclContext *DC, SourceLocation L) + : NextInContextAndBits(), DeclCtx(DC), + Loc(L), DeclKind(DK), InvalidDecl(0), + HasAttrs(false), Implicit(false), Used(false), Referenced(false), + Access(AS_none), FromASTFile(0), Hidden(0), + IdentifierNamespace(getIdentifierNamespaceForKind(DK)), + HasCachedLinkage(0) + { + if (StatisticsEnabled) add(DK); + } + + Decl(Kind DK, EmptyShell Empty) + : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0), + HasAttrs(false), Implicit(false), Used(false), Referenced(false), + Access(AS_none), FromASTFile(0), Hidden(0), + IdentifierNamespace(getIdentifierNamespaceForKind(DK)), + HasCachedLinkage(0) + { + if (StatisticsEnabled) add(DK); + } + + virtual ~Decl(); + + /// \brief Allocate memory for a deserialized declaration. + /// + /// This routine must be used to allocate memory for any declaration that is + /// deserialized from a module file. + /// + /// \param Context The context in which we will allocate memory. + /// \param ID The global ID of the deserialized declaration. + /// \param Size The size of the allocated object. + static void *AllocateDeserializedDecl(const ASTContext &Context, + unsigned ID, + unsigned Size); + +public: + + /// \brief Source range that this declaration covers. + virtual SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(getLocation(), getLocation()); + } + SourceLocation getLocStart() const LLVM_READONLY { + return getSourceRange().getBegin(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getSourceRange().getEnd(); + } + + SourceLocation getLocation() const { return Loc; } + void setLocation(SourceLocation L) { Loc = L; } + + Kind getKind() const { return static_cast(DeclKind); } + const char *getDeclKindName() const; + + Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); } + const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();} + + DeclContext *getDeclContext() { + if (isInSemaDC()) + return getSemanticDC(); + return getMultipleDC()->SemanticDC; + } + const DeclContext *getDeclContext() const { + return const_cast(this)->getDeclContext(); + } + + /// Finds the innermost non-closure context of this declaration. + /// That is, walk out the DeclContext chain, skipping any blocks. + DeclContext *getNonClosureContext(); + const DeclContext *getNonClosureContext() const { + return const_cast(this)->getNonClosureContext(); + } + + TranslationUnitDecl *getTranslationUnitDecl(); + const TranslationUnitDecl *getTranslationUnitDecl() const { + return const_cast(this)->getTranslationUnitDecl(); + } + + bool isInAnonymousNamespace() const; + + ASTContext &getASTContext() const LLVM_READONLY; + + void setAccess(AccessSpecifier AS) { + Access = AS; +#ifndef NDEBUG + CheckAccessDeclContext(); +#endif + } + + AccessSpecifier getAccess() const { +#ifndef NDEBUG + CheckAccessDeclContext(); +#endif + return AccessSpecifier(Access); + } + + bool hasAttrs() const { return HasAttrs; } + void setAttrs(const AttrVec& Attrs) { + return setAttrsImpl(Attrs, getASTContext()); + } + AttrVec &getAttrs() { + return const_cast(const_cast(this)->getAttrs()); + } + const AttrVec &getAttrs() const; + void swapAttrs(Decl *D); + void dropAttrs(); + + void addAttr(Attr *A) { + if (hasAttrs()) + getAttrs().push_back(A); + else + setAttrs(AttrVec(1, A)); + } + + typedef AttrVec::const_iterator attr_iterator; + + // FIXME: Do not rely on iterators having comparable singular values. + // Note that this should error out if they do not. + attr_iterator attr_begin() const { + return hasAttrs() ? getAttrs().begin() : 0; + } + attr_iterator attr_end() const { + return hasAttrs() ? getAttrs().end() : 0; + } + + template + void dropAttr() { + if (!HasAttrs) return; + + AttrVec &Attrs = getAttrs(); + for (unsigned i = 0, e = Attrs.size(); i != e; /* in loop */) { + if (isa(Attrs[i])) { + Attrs.erase(Attrs.begin() + i); + --e; + } + else + ++i; + } + if (Attrs.empty()) + HasAttrs = false; + } + + template + specific_attr_iterator specific_attr_begin() const { + return specific_attr_iterator(attr_begin()); + } + template + specific_attr_iterator specific_attr_end() const { + return specific_attr_iterator(attr_end()); + } + + template T *getAttr() const { + return hasAttrs() ? getSpecificAttr(getAttrs()) : 0; + } + template bool hasAttr() const { + return hasAttrs() && hasSpecificAttr(getAttrs()); + } + + /// getMaxAlignment - return the maximum alignment specified by attributes + /// on this decl, 0 if there are none. + unsigned getMaxAlignment() const { + return hasAttrs() ? getMaxAttrAlignment(getAttrs(), getASTContext()) : 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. + /// + /// \param CheckUsedAttr When true, also consider the "used" attribute + /// (in addition to the "used" bit set by \c setUsed()) when determining + /// whether the function is used. + bool isUsed(bool CheckUsedAttr = true) const; + + void setUsed(bool U = true) { Used = U; } + + /// \brief Whether this declaration was referenced. + bool isReferenced() const; + + void setReferenced(bool R = true) { Referenced = R; } + + /// \brief Whether this declaration is a top-level declaration (function, + /// global variable, etc.) that is lexically inside an objc container + /// definition. + bool isTopLevelDeclInObjCContainer() const { + return NextInContextAndBits.getInt() & TopLevelDeclInObjCContainerFlag; + } + + void setTopLevelDeclInObjCContainer(bool V = true) { + unsigned Bits = NextInContextAndBits.getInt(); + if (V) + Bits |= TopLevelDeclInObjCContainerFlag; + else + Bits &= ~TopLevelDeclInObjCContainerFlag; + NextInContextAndBits.setInt(Bits); + } + +protected: + /// \brief Whether this declaration was marked as being private to the + /// module in which it was defined. + bool isModulePrivate() const { + return NextInContextAndBits.getInt() & ModulePrivateFlag; + } + + /// \brief Specify whether this declaration was marked as being private + /// to the module in which it was defined. + void setModulePrivate(bool MP = true) { + unsigned Bits = NextInContextAndBits.getInt(); + if (MP) + Bits |= ModulePrivateFlag; + else + Bits &= ~ModulePrivateFlag; + NextInContextAndBits.setInt(Bits); + } + + /// \brief Set the owning module ID. + void setOwningModuleID(unsigned ID) { + assert(isFromASTFile() && "Only works on a deserialized declaration"); + *((unsigned*)this - 2) = ID; + } + +public: + + /// \brief Determine the availability of the given declaration. + /// + /// This routine will determine the most restrictive availability of + /// the given declaration (e.g., preferring 'unavailable' to + /// 'deprecated'). + /// + /// \param Message If non-NULL and the result is not \c + /// AR_Available, will be set to a (possibly empty) message + /// describing why the declaration has not been introduced, is + /// deprecated, or is unavailable. + AvailabilityResult getAvailability(std::string *Message = 0) const; + + /// \brief Determine whether this declaration is marked 'deprecated'. + /// + /// \param Message If non-NULL and the declaration is deprecated, + /// this will be set to the message describing why the declaration + /// was deprecated (which may be empty). + bool isDeprecated(std::string *Message = 0) const { + return getAvailability(Message) == AR_Deprecated; + } + + /// \brief Determine whether this declaration is marked 'unavailable'. + /// + /// \param Message If non-NULL and the declaration is unavailable, + /// this will be set to the message describing why the declaration + /// was made unavailable (which may be empty). + bool isUnavailable(std::string *Message = 0) const { + return getAvailability(Message) == AR_Unavailable; + } + + /// \brief Determine whether this is a weak-imported symbol. + /// + /// Weak-imported symbols are typically marked with the + /// 'weak_import' attribute, but may also be marked with an + /// 'availability' attribute where we're targing a platform prior to + /// the introduction of this feature. + bool isWeakImported() const; + + /// \brief Determines whether this symbol can be weak-imported, + /// e.g., whether it would be well-formed to add the weak_import + /// attribute. + /// + /// \param IsDefinition Set to \c true to indicate that this + /// declaration cannot be weak-imported because it has a definition. + bool canBeWeakImported(bool &IsDefinition) const; + + /// \brief Determine whether this declaration came from an AST file (such as + /// a precompiled header or module) rather than having been parsed. + bool isFromASTFile() const { return FromASTFile; } + + /// \brief Retrieve the global declaration ID associated with this + /// declaration, which specifies where in the + unsigned getGlobalID() const { + if (isFromASTFile()) + return *((const unsigned*)this - 1); + return 0; + } + + /// \brief Retrieve the global ID of the module that owns this particular + /// declaration. + unsigned getOwningModuleID() const { + if (isFromASTFile()) + return *((const unsigned*)this - 2); + + return 0; + } + + 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(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 { + return getParentFunctionOrMethod() == 0; + } + + /// \brief If this decl is defined inside a function/method/block it returns + /// the corresponding DeclContext, otherwise it returns null. + const DeclContext *getParentFunctionOrMethod() const; + DeclContext *getParentFunctionOrMethod() { + return const_cast( + const_cast(this)->getParentFunctionOrMethod()); + } + + /// \brief Retrieves the "canonical" declaration of the given declaration. + virtual Decl *getCanonicalDecl() { return this; } + const Decl *getCanonicalDecl() const { + return const_cast(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; } + + /// \brief Implementation of getPreviousDecl(), to be overridden by any + /// subclass that has a redeclaration chain. + virtual Decl *getPreviousDeclImpl() { return 0; } + + /// \brief Implementation of getMostRecentDecl(), to be overridden by any + /// subclass that has a redeclaration chain. + virtual Decl *getMostRecentDeclImpl() { return this; } + +public: + /// \brief Iterates through all the redeclarations of the same decl. + class redecl_iterator { + /// Current - The current declaration. + Decl *Current; + Decl *Starter; + + public: + typedef Decl* value_type; + typedef 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(this)); + } + redecl_iterator redecls_end() const { return redecl_iterator(); } + + /// \brief Retrieve the previous declaration that declares the same entity + /// as this declaration, or NULL if there is no previous declaration. + Decl *getPreviousDecl() { return getPreviousDeclImpl(); } + + /// \brief Retrieve the most recent declaration that declares the same entity + /// as this declaration, or NULL if there is no previous declaration. + const Decl *getPreviousDecl() const { + return const_cast(this)->getPreviousDeclImpl(); + } + + /// \brief Retrieve the most recent declaration that declares the same entity + /// as this declaration (which may be this declaration). + Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); } + + /// \brief Retrieve the most recent declaration that declares the same entity + /// as this declaration (which may be this declaration). + const Decl *getMostRecentDecl() const { + return const_cast(this)->getMostRecentDeclImpl(); + } + + /// getBody - If this Decl represents a declaration for a body of code, + /// such as a function or method definition, this method returns the + /// top-level Stmt* of that body. Otherwise this method returns null. + virtual Stmt* getBody() const { return 0; } + + /// \brief Returns true if this Decl represents a declaration for a body of + /// code, such as a function or method definition. + virtual bool hasBody() const { return getBody() != 0; } + + /// getBodyRBrace - Gets the right brace of the body, if a body exists. + /// This works whether the body is a CompoundStmt or a CXXTryStmt. + SourceLocation getBodyRBrace() const; + + // global temp stats (until we have a per-module visitor) + static void add(Kind k); + static void EnableStatistics(); + static void PrintStats(); + + /// isTemplateParameter - Determines whether this declaration is a + /// template parameter. + bool isTemplateParameter() const; + + /// isTemplateParameter - Determines whether this declaration is a + /// template parameter pack. + bool isTemplateParameterPack() const; + + /// \brief Whether this declaration is a parameter pack. + bool isParameterPack() const; + + /// \brief returns true if this declaration is a template + bool isTemplateDecl() const; + + /// \brief Whether this declaration is a function or function template. + bool isFunctionOrFunctionTemplate() const; + + /// \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 *); + + void print(raw_ostream &Out, unsigned Indentation = 0, + bool PrintInstantiation = false) const; + void print(raw_ostream &Out, const PrintingPolicy &Policy, + unsigned Indentation = 0, bool PrintInstantiation = false) const; + static void printGroup(Decl** Begin, unsigned NumDecls, + raw_ostream &Out, const PrintingPolicy &Policy, + unsigned Indentation = 0); + LLVM_ATTRIBUTE_USED void dump() const; + LLVM_ATTRIBUTE_USED void dumpXML() const; + void dumpXML(raw_ostream &OS) const; + +private: + void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx); + void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, + ASTContext &Ctx); + +protected: + ASTMutationListener *getASTMutationListener() const; +}; + +/// \brief Determine whether two declarations declare the same entity. +inline bool declaresSameEntity(const Decl *D1, const Decl *D2) { + if (!D1 || !D2) + return false; + + if (D1 == D2) + return true; + + return D1->getCanonicalDecl() == D2->getCanonicalDecl(); +} + +/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when +/// doing something to a specific decl. +class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { + const Decl *TheDecl; + SourceLocation Loc; + SourceManager &SM; + const char *Message; +public: + PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L, + SourceManager &sm, const char *Msg) + : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} + + virtual void print(raw_ostream &OS) const; +}; + +class DeclContextLookupResult + : public std::pair { +public: + DeclContextLookupResult(NamedDecl **I, NamedDecl **E) + : std::pair(I, E) {} + DeclContextLookupResult() + : std::pair() {} + + using std::pair::operator=; +}; + +class DeclContextLookupConstResult + : public std::pair { +public: + DeclContextLookupConstResult(std::pair R) + : std::pair(R) {} + DeclContextLookupConstResult(NamedDecl * const *I, NamedDecl * const *E) + : std::pair(I, E) {} + DeclContextLookupConstResult() + : std::pair() {} + + using std::pair::operator=; +}; + +/// DeclContext - This is used only as base class of specific decl types that +/// can act as declaration contexts. These decls are (only the top classes +/// that directly derive from DeclContext are mentioned, not their subclasses): +/// +/// TranslationUnitDecl +/// NamespaceDecl +/// FunctionDecl +/// TagDecl +/// ObjCMethodDecl +/// ObjCContainerDecl +/// LinkageSpecDecl +/// BlockDecl +/// +class DeclContext { + /// DeclKind - This indicates which class this is. + unsigned DeclKind : 8; + + /// \brief Whether this declaration context also has some external + /// storage that contains additional declarations that are lexically + /// part of this context. + mutable unsigned ExternalLexicalStorage : 1; + + /// \brief Whether this declaration context also has some external + /// storage that contains additional declarations that are visible + /// in this context. + mutable unsigned ExternalVisibleStorage : 1; + + /// \brief Pointer to the data structure used to lookup declarations + /// within this context (or a DependentStoredDeclsMap if this is a + /// dependent context), and a bool indicating whether we have lazily + /// omitted any declarations from the map. We maintain the invariant + /// that, if the map contains an entry for a DeclarationName, then it + /// contains all relevant entries for that name. + mutable llvm::PointerIntPair LookupPtr; + +protected: + /// FirstDecl - The first declaration stored within this declaration + /// context. + mutable Decl *FirstDecl; + + /// LastDecl - The last declaration stored within this declaration + /// context. FIXME: We could probably cache this value somewhere + /// outside of the DeclContext, to reduce the size of DeclContext by + /// another pointer. + mutable Decl *LastDecl; + + friend class ExternalASTSource; + friend class ASTWriter; + + /// \brief Build up a chain of declarations. + /// + /// \returns the first/last pair of declarations. + static std::pair + BuildDeclChain(ArrayRef Decls, bool FieldsAlreadyLoaded); + + DeclContext(Decl::Kind K) + : DeclKind(K), ExternalLexicalStorage(false), + ExternalVisibleStorage(false), LookupPtr(0, false), FirstDecl(0), + LastDecl(0) { } + +public: + ~DeclContext(); + + Decl::Kind getDeclKind() const { + return static_cast(DeclKind); + } + const char *getDeclKindName() const; + + /// getParent - Returns the containing DeclContext. + DeclContext *getParent() { + return cast(this)->getDeclContext(); + } + const DeclContext *getParent() const { + return const_cast(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(this)->getLexicalDeclContext(); + } + const DeclContext *getLexicalParent() const { + return const_cast(this)->getLexicalParent(); + } + + DeclContext *getLookupParent(); + + const DeclContext *getLookupParent() const { + return const_cast(this)->getLookupParent(); + } + + ASTContext &getParentASTContext() const { + return cast(this)->getASTContext(); + } + + bool isClosure() const { + return DeclKind == Decl::Block; + } + + bool isObjCContainer() const { + switch (DeclKind) { + case Decl::ObjCCategory: + case Decl::ObjCCategoryImpl: + case Decl::ObjCImplementation: + case Decl::ObjCInterface: + case Decl::ObjCProtocol: + return true; + } + return false; + } + + bool isFunctionOrMethod() const { + switch (DeclKind) { + case Decl::Block: + case Decl::ObjCMethod: + return true; + default: + return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction; + } + } + + bool isFileContext() const { + return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace; + } + + bool isTranslationUnit() const { + return DeclKind == Decl::TranslationUnit; + } + + bool isRecord() const { + return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord; + } + + bool isNamespace() const { + return DeclKind == Decl::Namespace; + } + + bool isInlineNamespace() const; + + /// \brief Determines whether this context is dependent on a + /// template parameter. + bool isDependentContext() const; + + /// isTransparentContext - Determines whether this context is a + /// "transparent" context, meaning that the members declared in this + /// context are semantically declared in the nearest enclosing + /// non-transparent (opaque) context but are lexically declared in + /// this context. For example, consider the enumerators of an + /// enumeration type: + /// @code + /// enum E { + /// Val1 + /// }; + /// @endcode + /// Here, E is a transparent context, so its enumerator (Val1) will + /// appear (semantically) that it is in the same context of E. + /// Examples of transparent contexts include: enumerations (except for + /// C++0x scoped enums), and C++ linkage specifications. + bool isTransparentContext() const; + + /// \brief Determines whether this context is, or is nested within, + /// a C++ extern "C" linkage spec. + bool isExternCContext() const; + + /// \brief Determine whether this declaration context is equivalent + /// to the declaration context DC. + bool Equals(const DeclContext *DC) const { + return DC && this->getPrimaryContext() == DC->getPrimaryContext(); + } + + /// \brief Determine whether this declaration context encloses the + /// declaration context DC. + bool Encloses(const DeclContext *DC) const; + + /// \brief Find the nearest non-closure ancestor of this context, + /// i.e. the innermost semantic parent of this context which is not + /// a closure. A context may be its own non-closure ancestor. + DeclContext *getNonClosureAncestor(); + const DeclContext *getNonClosureAncestor() const { + return const_cast(this)->getNonClosureAncestor(); + } + + /// getPrimaryContext - There may be many different + /// declarations of the same entity (including forward declarations + /// of classes, multiple definitions of namespaces, etc.), each with + /// a different set of declarations. This routine returns the + /// "primary" DeclContext structure, which will contain the + /// information needed to perform name lookup into this context. + DeclContext *getPrimaryContext(); + const DeclContext *getPrimaryContext() const { + return const_cast(this)->getPrimaryContext(); + } + + /// getRedeclContext - Retrieve the context in which an entity conflicts with + /// other entities of the same name, or where it is a redeclaration if the + /// two entities are compatible. This skips through transparent contexts. + DeclContext *getRedeclContext(); + const DeclContext *getRedeclContext() const { + return const_cast(this)->getRedeclContext(); + } + + /// \brief Retrieve the nearest enclosing namespace context. + DeclContext *getEnclosingNamespaceContext(); + const DeclContext *getEnclosingNamespaceContext() const { + return const_cast(this)->getEnclosingNamespaceContext(); + } + + /// \brief Test if this context is part of the enclosing namespace set of + /// the context NS, as defined in C++0x [namespace.def]p9. If either context + /// isn't a namespace, this is equivalent to Equals(). + /// + /// The enclosing namespace set of a namespace is the namespace and, if it is + /// inline, its enclosing namespace, recursively. + bool InEnclosingNamespaceSetOf(const DeclContext *NS) const; + + /// \\brief Collects all of the declaration contexts that are semantically + /// connected to this declaration context. + /// + /// For declaration contexts that have multiple semantically connected but + /// syntactically distinct contexts, such as C++ namespaces, this routine + /// retrieves the complete set of such declaration contexts in source order. + /// For example, given: + /// + /// \code + /// namespace N { + /// int x; + /// } + /// namespace N { + /// int y; + /// } + /// \endcode + /// + /// The \c Contexts parameter will contain both definitions of N. + /// + /// \param Contexts Will be cleared and set to the set of declaration + /// contexts that are semanticaly connected to this declaration context, + /// in source order, including this context (which may be the only result, + /// for non-namespace contexts). + void collectAllContexts(llvm::SmallVectorImpl &Contexts); + + /// decl_iterator - Iterates through the declarations stored + /// within this context. + class decl_iterator { + /// Current - The current declaration. + Decl *Current; + + public: + typedef Decl* value_type; + typedef 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; + + /// noload_decls_begin/end - Iterate over the declarations stored in this + /// context that are currently loaded; don't attempt to retrieve anything + /// from an external source. + decl_iterator noload_decls_begin() const; + decl_iterator noload_decls_end() 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 + 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(*Current)) + ++Current; + } + + public: + typedef SpecificDecl* value_type; + typedef SpecificDecl* reference; + typedef SpecificDecl* pointer; + typedef std::iterator_traits::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(*Current); } + pointer operator->() const { return cast(*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 + 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(*Current) || + (Acceptable && !(cast(*Current)->*Acceptable)()))) + ++Current; + } + + public: + typedef SpecificDecl* value_type; + typedef SpecificDecl* reference; + typedef SpecificDecl* pointer; + typedef std::iterator_traits::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(*Current); } + pointer operator->() const { return cast(*Current); } + + filtered_decl_iterator& operator++() { + ++Current; + SkipToNextDecl(); + return *this; + } + + filtered_decl_iterator operator++(int) { + filtered_decl_iterator tmp(*this); + ++(*this); + return tmp; + } + + friend bool operator==(const filtered_decl_iterator& x, + const filtered_decl_iterator& y) { + return x.Current == y.Current; + } + + friend bool operator!=(const filtered_decl_iterator& x, + const filtered_decl_iterator& y) { + return x.Current != y.Current; + } + }; + + /// @brief Add the declaration D into this context. + /// + /// This routine should be invoked when the declaration D has first + /// been declared, to place D into the context where it was + /// (lexically) defined. Every declaration must be added to one + /// (and only one!) context, where it can be visited via + /// [decls_begin(), decls_end()). Once a declaration has been added + /// to its lexical context, the corresponding DeclContext owns the + /// declaration. + /// + /// If D is also a NamedDecl, it will be made visible within its + /// semantic context via makeDeclVisibleInContext. + void addDecl(Decl *D); + + /// @brief Add the declaration D into this context, but suppress + /// searches for external declarations with the same name. + /// + /// Although analogous in function to addDecl, this removes an + /// important check. This is only useful if the Decl is being + /// added in response to an external search; in all other cases, + /// addDecl() is the right function to use. + /// See the ASTImporter for use cases. + void addDeclInternal(Decl *D); + + /// @brief Add the declaration D to this context without modifying + /// any lookup tables. + /// + /// This is useful for some operations in dependent contexts where + /// the semantic context might not be dependent; this basically + /// only happens with friends. + void addHiddenDecl(Decl *D); + + /// @brief Removes a declaration from this context. + void removeDecl(Decl *D); + + /// 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 DeclContextLookupResult lookup_result; + typedef DeclContextLookupConstResult 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 A simplistic name lookup mechanism that performs name lookup + /// into this declaration context without consulting the external source. + /// + /// This function should almost never be used, because it subverts the + /// usual relationship between a DeclContext and the external source. + /// See the ASTImporter for the (few, but important) use cases. + void localUncachedLookup(DeclarationName Name, + llvm::SmallVectorImpl &Results); + + /// @brief Makes a declaration visible within this context. + /// + /// This routine makes the declaration D visible to name lookup + /// within this context and, if this is a transparent context, + /// within its parent contexts up to the first enclosing + /// non-transparent context. Making a declaration visible within a + /// context does not transfer ownership of a declaration, and a + /// declaration can be visible in many contexts that aren't its + /// lexical context. + /// + /// If D is a redeclaration of an existing declaration that is + /// visible from this context, as determined by + /// NamedDecl::declarationReplaces, the previous declaration will be + /// replaced with D. + void makeDeclVisibleInContext(NamedDecl *D); + + /// all_lookups_iterator - An iterator that provides a view over the results + /// of looking up every possible name. + class all_lookups_iterator; + + all_lookups_iterator lookups_begin() const; + + all_lookups_iterator lookups_end() const; + + /// udir_iterator - Iterates through the using-directives stored + /// within this context. + typedef UsingDirectiveDecl * const * udir_iterator; + + typedef std::pair 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. + /// This may omit some names if we are lazily building the structure. + StoredDeclsMap *getLookupPtr() const { return LookupPtr.getPointer(); } + + /// \brief Ensure the lookup structure is fully-built and return it. + StoredDeclsMap *buildLookup(); + + /// \brief Whether this DeclContext has external storage containing + /// additional declarations that are lexically in this context. + bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; } + + /// \brief State whether this DeclContext has external storage for + /// declarations lexically in this context. + void setHasExternalLexicalStorage(bool ES = true) { + ExternalLexicalStorage = ES; + } + + /// \brief Whether this DeclContext has external storage containing + /// additional declarations that are visible in this context. + bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; } + + /// \brief State whether this DeclContext has external storage for + /// declarations visible in this context. + void setHasExternalVisibleStorage(bool ES = true) { + ExternalVisibleStorage = ES; + } + + /// \brief Determine whether the given declaration is stored in the list of + /// declarations lexically within this context. + bool isDeclInLexicalTraversal(const Decl *D) const { + return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl || + D == LastDecl); + } + + static bool classof(const Decl *D); + static bool classof(const DeclContext *D) { return true; } +#define DECL(NAME, BASE) +#define DECL_CONTEXT(NAME) \ + static bool classof(const NAME##Decl *D) { return true; } +#include "clang/AST/DeclNodes.inc" + + LLVM_ATTRIBUTE_USED void dumpDeclContext() const; + +private: + void LoadLexicalDeclsFromExternalStorage() const; + + /// @brief Makes a declaration visible within this context, but + /// suppresses searches for external declarations with the same + /// name. + /// + /// Analogous to makeDeclVisibleInContext, but for the exclusive + /// use of addDeclInternal(). + void makeDeclVisibleInContextInternal(NamedDecl *D); + + friend class DependentDiagnostic; + StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; + + void buildLookupImpl(DeclContext *DCtx); + void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, + bool Rediscoverable); + void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal); +}; + +inline bool Decl::isTemplateParameter() const { + return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm || + getKind() == TemplateTemplateParm; +} + +// Specialization selected when ToTy is not a known subclass of DeclContext. +template ::value> +struct cast_convert_decl_context { + static const ToTy *doit(const DeclContext *Val) { + return static_cast(Decl::castFromDeclContext(Val)); + } + + static ToTy *doit(DeclContext *Val) { + return static_cast(Decl::castFromDeclContext(Val)); + } +}; + +// Specialization selected when ToTy is a known subclass of DeclContext. +template +struct cast_convert_decl_context { + static const ToTy *doit(const DeclContext *Val) { + return static_cast(Val); + } + + static ToTy *doit(DeclContext *Val) { + return static_cast(Val); + } +}; + + +} // end clang. + +namespace llvm { + +/// isa(DeclContext*) +template +struct isa_impl { + static bool doit(const ::clang::DeclContext &Val) { + return To::classofKind(Val.getDeclKind()); + } +}; + +/// cast(DeclContext*) +template +struct cast_convert_val { + static const ToTy &doit(const ::clang::DeclContext &Val) { + return *::clang::cast_convert_decl_context::doit(&Val); + } +}; +template +struct cast_convert_val { + static ToTy &doit(::clang::DeclContext &Val) { + return *::clang::cast_convert_decl_context::doit(&Val); + } +}; +template +struct cast_convert_val { + static const ToTy *doit(const ::clang::DeclContext *Val) { + return ::clang::cast_convert_decl_context::doit(Val); + } +}; +template +struct cast_convert_val { + static ToTy *doit(::clang::DeclContext *Val) { + return ::clang::cast_convert_decl_context::doit(Val); + } +}; + +/// Implement cast_convert_val for Decl -> DeclContext conversions. +template +struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> { + static ::clang::DeclContext &doit(const FromTy &Val) { + return *FromTy::castToDeclContext(&Val); + } +}; + +template +struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> { + static ::clang::DeclContext *doit(const FromTy *Val) { + return FromTy::castToDeclContext(Val); + } +}; + +template +struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> { + static const ::clang::DeclContext &doit(const FromTy &Val) { + return *FromTy::castToDeclContext(&Val); + } +}; + +template +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/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h new file mode 100644 index 0000000..7f3ec4c --- /dev/null +++ b/clang/include/clang/AST/DeclCXX.h @@ -0,0 +1,2938 @@ +//===-- 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/ExprCXX.h" +#include "clang/AST/Decl.h" +#include "clang/AST/TypeLoc.h" +#include "clang/AST/UnresolvedSet.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/Compiler.h" + +namespace clang { + +class ClassTemplateDecl; +class ClassTemplateSpecializationDecl; +class CXXBasePath; +class CXXBasePaths; +class CXXConstructorDecl; +class CXXConversionDecl; +class CXXDestructorDecl; +class CXXMethodDecl; +class CXXRecordDecl; +class CXXMemberLookupCriteria; +class CXXFinalOverriderMap; +class CXXIndirectPrimaryBaseSet; +class FriendDecl; +class LambdaExpr; + +/// \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 { + typedef ::clang::NamedDecl* SimpleType; + static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) { + return Val; + } + }; + template<> struct simplify_type< ::clang::AnyFunctionDecl> + : public simplify_type {}; + + // 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 { + +/// AccessSpecDecl - An access specifier followed by colon ':'. +/// +/// An objects of this class represents sugar for the syntactic occurrence +/// of an access specifier followed by a colon in the list of member +/// specifiers of a C++ class definition. +/// +/// Note that they do not represent other uses of access specifiers, +/// such as those occurring in a list of base specifiers. +/// Also note that this class has nothing to do with so-called +/// "access declarations" (C++98 11.3 [class.access.dcl]). +class AccessSpecDecl : public Decl { + virtual void anchor(); + /// ColonLoc - The location of the ':'. + SourceLocation ColonLoc; + + AccessSpecDecl(AccessSpecifier AS, DeclContext *DC, + SourceLocation ASLoc, SourceLocation ColonLoc) + : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) { + setAccess(AS); + } + AccessSpecDecl(EmptyShell Empty) + : Decl(AccessSpec, Empty) { } +public: + /// getAccessSpecifierLoc - The location of the access specifier. + SourceLocation getAccessSpecifierLoc() const { return getLocation(); } + /// setAccessSpecifierLoc - Sets the location of the access specifier. + void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); } + + /// getColonLoc - The location of the colon following the access specifier. + SourceLocation getColonLoc() const { return ColonLoc; } + /// setColonLoc - Sets the location of the colon. + void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(getAccessSpecifierLoc(), getColonLoc()); + } + + static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS, + DeclContext *DC, SourceLocation ASLoc, + SourceLocation ColonLoc) { + return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); + } + static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const AccessSpecDecl *D) { return true; } + static bool classofKind(Kind K) { return K == AccessSpec; } +}; + + +/// 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). + SourceRange Range; + + /// \brief The source location of the ellipsis, if this is a pack + /// expansion. + SourceLocation EllipsisLoc; + + /// 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; + + /// InheritConstructors - Whether the class contains a using declaration + /// to inherit the named class's constructors. + bool InheritConstructors : 1; + + /// BaseTypeInfo - The type of the base class. This will be a class or struct + /// (or a typedef of such). The source code range does not include the + /// "virtual" or access specifier. + TypeSourceInfo *BaseTypeInfo; + +public: + CXXBaseSpecifier() { } + + CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, + TypeSourceInfo *TInfo, SourceLocation EllipsisLoc) + : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC), + Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { } + + /// getSourceRange - Retrieves the source range that contains the + /// entire base specifier. + SourceRange getSourceRange() const LLVM_READONLY { return Range; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } + + /// isVirtual - Determines whether the base class is a virtual base + /// class (or not). + bool isVirtual() const { return Virtual; } + + /// \brief Determine whether this base class is a base of a class declared + /// with the 'class' keyword (vs. one declared with the 'struct' keyword). + bool isBaseOfClass() const { return BaseOfClass; } + + /// \brief Determine whether this base specifier is a pack expansion. + bool isPackExpansion() const { return EllipsisLoc.isValid(); } + + /// \brief Determine whether this base class's constructors get inherited. + bool getInheritConstructors() const { return InheritConstructors; } + + /// \brief Set that this base class's constructors should be inherited. + void setInheritConstructors(bool Inherit = true) { + InheritConstructors = Inherit; + } + + /// \brief For a pack expansion, determine the location of the ellipsis. + SourceLocation getEllipsisLoc() const { + return EllipsisLoc; + } + + /// 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 BaseTypeInfo->getType(); } + + /// getTypeLoc - Retrieves the type and source location of the base class. + TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; } +}; + +/// 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; + + /// UserDeclareMoveConstructor - True when this class has a + /// user-declared move constructor. + bool UserDeclaredMoveConstructor : 1; + + /// UserDeclaredCopyAssignment - True when this class has a + /// user-declared copy assignment operator. + bool UserDeclaredCopyAssignment : 1; + + /// UserDeclareMoveAssignment - True when this class has a + /// user-declared move assignment. + bool UserDeclaredMoveAssignment : 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; + + /// IsStandardLayout - True when this class has standard layout. + /// + /// C++0x [class]p7. A standard-layout class is a class that: + /// * has no non-static data members of type non-standard-layout class (or + /// array of such types) or reference, + /// * has no virtual functions (10.3) and no virtual base classes (10.1), + /// * has the same access control (Clause 11) for all non-static data + /// members + /// * has no non-standard-layout base classes, + /// * either has no non-static data members in the most derived class and at + /// most one base class with non-static data members, or has no base + /// classes with non-static data members, and + /// * has no base classes of the same type as the first non-static data + /// member. + bool IsStandardLayout : 1; + + /// HasNoNonEmptyBases - True when there are no non-empty base classes. + /// + /// This is a helper bit of state used to implement IsStandardLayout more + /// efficiently. + bool HasNoNonEmptyBases : 1; + + /// HasPrivateFields - True when there are private non-static data members. + bool HasPrivateFields : 1; + + /// HasProtectedFields - True when there are protected non-static data + /// members. + bool HasProtectedFields : 1; + + /// HasPublicFields - True when there are private non-static data members. + bool HasPublicFields : 1; + + /// \brief True if this class (or any subobject) has mutable fields. + bool HasMutableFields : 1; + + /// \brief True if there no non-field members declared by the user. + bool HasOnlyCMembers : 1; + + /// HasTrivialDefaultConstructor - True when, if this class has a default + /// constructor, this default constructor is trivial. + /// + /// C++0x [class.ctor]p5 + /// A default constructor is trivial if it is not user-provided and if + /// -- its class has no virtual functions and no virtual base classes, + /// and + /// -- no non-static data member of its class has a + /// brace-or-equal-initializer, and + /// -- all the direct base classes of its class have trivial + /// default 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 + /// default constructor. + bool HasTrivialDefaultConstructor : 1; + + /// HasConstexprNonCopyMoveConstructor - True when this class has at least + /// one user-declared constexpr constructor which is neither the copy nor + /// move constructor. + bool HasConstexprNonCopyMoveConstructor : 1; + + /// DefaultedDefaultConstructorIsConstexpr - True if a defaulted default + /// constructor for this class would be constexpr. + bool DefaultedDefaultConstructorIsConstexpr : 1; + + /// DefaultedCopyConstructorIsConstexpr - True if a defaulted copy + /// constructor for this class would be constexpr. + bool DefaultedCopyConstructorIsConstexpr : 1; + + /// DefaultedMoveConstructorIsConstexpr - True if a defaulted move + /// constructor for this class would be constexpr. + bool DefaultedMoveConstructorIsConstexpr : 1; + + /// HasConstexprDefaultConstructor - True if this class has a constexpr + /// default constructor (either user-declared or implicitly declared). + bool HasConstexprDefaultConstructor : 1; + + /// HasConstexprCopyConstructor - True if this class has a constexpr copy + /// constructor (either user-declared or implicitly declared). + bool HasConstexprCopyConstructor : 1; + + /// HasConstexprMoveConstructor - True if this class has a constexpr move + /// constructor (either user-declared or implicitly declared). + bool HasConstexprMoveConstructor : 1; + + /// HasTrivialCopyConstructor - True when this class has a trivial copy + /// constructor. + /// + /// C++0x [class.copy]p13: + /// A copy/move constructor for class X is trivial if it is neither + /// user-provided and if + /// -- class X has no virtual functions and no virtual base classes, and + /// -- the constructor selected to copy/move each direct base class + /// subobject is trivial, and + /// -- for each non-static data member of X that is of class type (or an + /// array thereof), the constructor selected to copy/move that member + /// is trivial; + /// otherwise the copy/move constructor is non-trivial. + bool HasTrivialCopyConstructor : 1; + + /// HasTrivialMoveConstructor - True when this class has a trivial move + /// constructor. + /// + /// C++0x [class.copy]p13: + /// A copy/move constructor for class X is trivial if it is neither + /// user-provided and if + /// -- class X has no virtual functions and no virtual base classes, and + /// -- the constructor selected to copy/move each direct base class + /// subobject is trivial, and + /// -- for each non-static data member of X that is of class type (or an + /// array thereof), the constructor selected to copy/move that member + /// is trivial; + /// otherwise the copy/move constructor is non-trivial. + bool HasTrivialMoveConstructor : 1; + + /// HasTrivialCopyAssignment - True when this class has a trivial copy + /// assignment operator. + /// + /// C++0x [class.copy]p27: + /// A copy/move assignment operator for class X is trivial if it is + /// neither user-provided nor deleted and if + /// -- class X has no virtual functions and no virtual base classes, and + /// -- the assignment operator selected to copy/move each direct base + /// class subobject is trivial, and + /// -- for each non-static data member of X that is of class type (or an + /// array thereof), the assignment operator selected to copy/move + /// that member is trivial; + /// otherwise the copy/move assignment operator is non-trivial. + bool HasTrivialCopyAssignment : 1; + + /// HasTrivialMoveAssignment - True when this class has a trivial move + /// assignment operator. + /// + /// C++0x [class.copy]p27: + /// A copy/move assignment operator for class X is trivial if it is + /// neither user-provided nor deleted and if + /// -- class X has no virtual functions and no virtual base classes, and + /// -- the assignment operator selected to copy/move each direct base + /// class subobject is trivial, and + /// -- for each non-static data member of X that is of class type (or an + /// array thereof), the assignment operator selected to copy/move + /// that member is trivial; + /// otherwise the copy/move assignment operator is non-trivial. + bool HasTrivialMoveAssignment : 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; + + /// HasIrrelevantDestructor - True when this class has a destructor with no + /// semantic effect. + bool HasIrrelevantDestructor : 1; + + /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least + /// one non-static data member or base class of non-literal or volatile + /// type. + bool HasNonLiteralTypeFieldsOrBases : 1; + + /// ComputedVisibleConversions - True when visible conversion functions are + /// already computed and are available. + bool ComputedVisibleConversions : 1; + + /// \brief Whether we have a C++0x user-provided default constructor (not + /// explicitly deleted or defaulted). + bool UserProvidedDefaultConstructor : 1; + + /// \brief Whether we have already declared the default constructor. + bool DeclaredDefaultConstructor : 1; + + /// \brief Whether we have already declared the copy constructor. + bool DeclaredCopyConstructor : 1; + + /// \brief Whether we have already declared the move constructor. + bool DeclaredMoveConstructor : 1; + + /// \brief Whether we have already declared the copy-assignment operator. + bool DeclaredCopyAssignment : 1; + + /// \brief Whether we have already declared the move-assignment operator. + bool DeclaredMoveAssignment : 1; + + /// \brief Whether we have already declared a destructor within the class. + bool DeclaredDestructor : 1; + + /// \brief Whether an implicit move constructor was attempted to be declared + /// but would have been deleted. + bool FailedImplicitMoveConstructor : 1; + + /// \brief Whether an implicit move assignment operator was attempted to be + /// declared but would have been deleted. + bool FailedImplicitMoveAssignment : 1; + + /// \brief Whether this class describes a C++ lambda. + bool IsLambda : 1; + + /// NumBases - The number of base class specifiers in Bases. + unsigned NumBases; + + /// NumVBases - The number of virtual base class specifiers in VBases. + unsigned NumVBases; + + /// Bases - Base classes of this class. + /// FIXME: This is wasted space for a union. + LazyCXXBaseSpecifiersPtr Bases; + + /// VBases - direct and indirect virtual base classes of this class. + LazyCXXBaseSpecifiersPtr VBases; + + /// 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; + + /// \brief Retrieve the set of direct base classes. + CXXBaseSpecifier *getBases() const { + return Bases.get(Definition->getASTContext().getExternalSource()); + } + + /// \brief Retrieve the set of virtual base classes. + CXXBaseSpecifier *getVBases() const { + return VBases.get(Definition->getASTContext().getExternalSource()); + } + } *DefinitionData; + + /// \brief Describes a C++ closure type (generated by a lambda expression). + struct LambdaDefinitionData : public DefinitionData { + typedef LambdaExpr::Capture Capture; + + LambdaDefinitionData(CXXRecordDecl *D, bool Dependent) + : DefinitionData(D), Dependent(Dependent), NumCaptures(0), + NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0) + { + IsLambda = true; + } + + /// \brief Whether this lambda is known to be dependent, even if its + /// context isn't dependent. + /// + /// A lambda with a non-dependent context can be dependent if it occurs + /// within the default argument of a function template, because the + /// lambda will have been created with the enclosing context as its + /// declaration context, rather than function. This is an unfortunate + /// artifact of having to parse the default arguments before + unsigned Dependent : 1; + + /// \brief The number of captures in this lambda. + unsigned NumCaptures : 16; + + /// \brief The number of explicit captures in this lambda. + unsigned NumExplicitCaptures : 15; + + /// \brief The number used to indicate this lambda expression for name + /// mangling in the Itanium C++ ABI. + unsigned ManglingNumber; + + /// \brief The declaration that provides context for this lambda, if the + /// actual DeclContext does not suffice. This is used for lambdas that + /// occur within default arguments of function parameters within the class + /// or within a data member initializer. + Decl *ContextDecl; + + /// \brief The list of captures, both explicit and implicit, for this + /// lambda. + Capture *Captures; + }; + + struct DefinitionData &data() { + assert(DefinitionData && "queried property of class with no definition"); + return *DefinitionData; + } + + const struct DefinitionData &data() const { + assert(DefinitionData && "queried property of class with no definition"); + return *DefinitionData; + } + + struct LambdaDefinitionData &getLambdaData() const { + assert(DefinitionData && "queried property of lambda with no definition"); + assert(DefinitionData->IsLambda && + "queried lambda property of non-lambda class"); + return static_cast(*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 + TemplateOrInstantiation; + + friend class DeclContext; + friend class LambdaExpr; + + /// \brief Notify the class that member has been added. + /// + /// This routine helps maintain information about the class based on which + /// members have been added. It will be invoked by DeclContext::addDecl() + /// whenever a member is added to this record. + void addedMember(Decl *D); + + void markedVirtualFunctionPure(); + friend void FunctionDecl::setPure(bool); + + friend class ASTNodeImporter; + +protected: + CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, CXXRecordDecl *PrevDecl); + +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 + reverse_base_class_iterator; + + /// reverse_base_class_iterator = Iterator that traverses the base classes + /// of a class in reverse order. + typedef std::reverse_iterator + reverse_base_class_const_iterator; + + virtual CXXRecordDecl *getCanonicalDecl() { + return cast(RecordDecl::getCanonicalDecl()); + } + virtual const CXXRecordDecl *getCanonicalDecl() const { + return cast(RecordDecl::getCanonicalDecl()); + } + + const CXXRecordDecl *getPreviousDecl() const { + return cast_or_null(RecordDecl::getPreviousDecl()); + } + CXXRecordDecl *getPreviousDecl() { + return cast_or_null(RecordDecl::getPreviousDecl()); + } + + const CXXRecordDecl *getMostRecentDecl() const { + return cast_or_null(RecordDecl::getMostRecentDecl()); + } + CXXRecordDecl *getMostRecentDecl() { + return cast_or_null(RecordDecl::getMostRecentDecl()); + } + + CXXRecordDecl *getDefinition() const { + if (!DefinitionData) return 0; + return data().Definition; + } + + bool hasDefinition() const { return DefinitionData != 0; } + + static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0, + bool DelayTypeCreation = false); + static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC, + SourceLocation Loc, bool DependentLambda); + static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + + 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().getBases(); } + base_class_const_iterator bases_begin() const { return data().getBases(); } + base_class_iterator bases_end() { return bases_begin() + data().NumBases; } + base_class_const_iterator bases_end() const { + return bases_begin() + data().NumBases; + } + reverse_base_class_iterator bases_rbegin() { + return reverse_base_class_iterator(bases_end()); + } + reverse_base_class_const_iterator bases_rbegin() const { + return reverse_base_class_const_iterator(bases_end()); + } + reverse_base_class_iterator bases_rend() { + return reverse_base_class_iterator(bases_begin()); + } + reverse_base_class_const_iterator bases_rend() const { + return reverse_base_class_const_iterator(bases_begin()); + } + + /// getNumVBases - Retrieves the number of virtual base classes of this + /// class. + unsigned getNumVBases() const { return data().NumVBases; } + + base_class_iterator vbases_begin() { return data().getVBases(); } + base_class_const_iterator vbases_begin() const { return data().getVBases(); } + base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; } + base_class_const_iterator vbases_end() const { + return vbases_begin() + data().NumVBases; + } + reverse_base_class_iterator vbases_rbegin() { + return reverse_base_class_iterator(vbases_end()); + } + reverse_base_class_const_iterator vbases_rbegin() const { + return reverse_base_class_const_iterator(vbases_end()); + } + reverse_base_class_iterator vbases_rend() { + return reverse_base_class_iterator(vbases_begin()); + } + reverse_base_class_const_iterator vbases_rend() const { + return reverse_base_class_const_iterator(vbases_begin()); + } + + /// \brief Determine whether this class has any dependent base classes. + 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 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 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; + } + + /// \brief Determine if we need to declare a default constructor for + /// this class. + /// + /// This value is used for lazy creation of default constructors. + bool needsImplicitDefaultConstructor() const { + return !data().UserDeclaredConstructor && + !data().DeclaredDefaultConstructor; + } + + /// hasDeclaredDefaultConstructor - Whether this class's default constructor + /// has been declared (either explicitly or implicitly). + bool hasDeclaredDefaultConstructor() const { + return data().DeclaredDefaultConstructor; + } + + /// hasConstCopyConstructor - Determines whether this class has a + /// copy constructor that accepts a const-qualified argument. + bool hasConstCopyConstructor() const; + + /// getCopyConstructor - Returns the copy constructor for this class + CXXConstructorDecl *getCopyConstructor(unsigned TypeQuals) const; + + /// getMoveConstructor - Returns the move constructor for this class + CXXConstructorDecl *getMoveConstructor() const; + + /// \brief Retrieve the copy-assignment operator for this class, if available. + /// + /// This routine attempts to find the copy-assignment operator for this + /// class, using a simplistic form of overload resolution. + /// + /// \param ArgIsConst Whether the argument to the copy-assignment operator + /// is const-qualified. + /// + /// \returns The copy-assignment operator that can be invoked, or NULL if + /// a unique copy-assignment operator could not be found. + CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const; + + /// getMoveAssignmentOperator - Returns the move assignment operator for this + /// class + CXXMethodDecl *getMoveAssignmentOperator() const; + + /// 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; + } + + /// hasUserProvidedDefaultconstructor - Whether this class has a + /// user-provided default constructor per C++0x. + bool hasUserProvidedDefaultConstructor() const { + return data().UserProvidedDefaultConstructor; + } + + /// 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; + } + + /// \brief Determine whether this class has had its copy constructor + /// declared, either via the user or via an implicit declaration. + /// + /// This value is used for lazy creation of copy constructors. + bool hasDeclaredCopyConstructor() const { + return data().DeclaredCopyConstructor; + } + + /// hasUserDeclaredMoveOperation - Whether this class has a user- + /// declared move constructor or assignment operator. When false, a + /// move constructor and assignment operator may be implicitly declared. + bool hasUserDeclaredMoveOperation() const { + return data().UserDeclaredMoveConstructor || + data().UserDeclaredMoveAssignment; + } + + /// \brief Determine whether this class has had a move constructor + /// declared by the user. + bool hasUserDeclaredMoveConstructor() const { + return data().UserDeclaredMoveConstructor; + } + + /// \brief Determine whether this class has had a move constructor + /// declared. + bool hasDeclaredMoveConstructor() const { + return data().DeclaredMoveConstructor; + } + + /// \brief Determine whether implicit move constructor generation for this + /// class has failed before. + bool hasFailedImplicitMoveConstructor() const { + return data().FailedImplicitMoveConstructor; + } + + /// \brief Set whether implicit move constructor generation for this class + /// has failed before. + void setFailedImplicitMoveConstructor(bool Failed = true) { + data().FailedImplicitMoveConstructor = Failed; + } + + /// \brief Determine whether this class should get an implicit move + /// constructor or if any existing special member function inhibits this. + /// + /// Covers all bullets of C++0x [class.copy]p9 except the last, that the + /// constructor wouldn't be deleted, which is only looked up from a cached + /// result. + bool needsImplicitMoveConstructor() const { + return !hasFailedImplicitMoveConstructor() && + !hasDeclaredMoveConstructor() && + !hasUserDeclaredCopyConstructor() && + !hasUserDeclaredCopyAssignment() && + !hasUserDeclaredMoveAssignment() && + !hasUserDeclaredDestructor(); + } + + /// 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; + } + + /// \brief Determine whether this class has had its copy assignment operator + /// declared, either via the user or via an implicit declaration. + /// + /// This value is used for lazy creation of copy assignment operators. + bool hasDeclaredCopyAssignment() const { + return data().DeclaredCopyAssignment; + } + + /// \brief Determine whether this class has had a move assignment + /// declared by the user. + bool hasUserDeclaredMoveAssignment() const { + return data().UserDeclaredMoveAssignment; + } + + /// hasDeclaredMoveAssignment - Whether this class has a + /// declared move assignment operator. + bool hasDeclaredMoveAssignment() const { + return data().DeclaredMoveAssignment; + } + + /// \brief Determine whether implicit move assignment generation for this + /// class has failed before. + bool hasFailedImplicitMoveAssignment() const { + return data().FailedImplicitMoveAssignment; + } + + /// \brief Set whether implicit move assignment generation for this class + /// has failed before. + void setFailedImplicitMoveAssignment(bool Failed = true) { + data().FailedImplicitMoveAssignment = Failed; + } + + /// \brief Determine whether this class should get an implicit move + /// assignment operator or if any existing special member function inhibits + /// this. + /// + /// Covers all bullets of C++0x [class.copy]p20 except the last, that the + /// constructor wouldn't be deleted. + bool needsImplicitMoveAssignment() const { + return !hasFailedImplicitMoveAssignment() && + !hasDeclaredMoveAssignment() && + !hasUserDeclaredCopyConstructor() && + !hasUserDeclaredCopyAssignment() && + !hasUserDeclaredMoveConstructor() && + !hasUserDeclaredDestructor(); + } + + /// hasUserDeclaredDestructor - Whether this class has a + /// user-declared destructor. When false, a destructor will be + /// implicitly declared. + bool hasUserDeclaredDestructor() const { + return data().UserDeclaredDestructor; + } + + /// \brief Determine whether this class has had its destructor declared, + /// either via the user or via an implicit declaration. + /// + /// This value is used for lazy creation of destructors. + bool hasDeclaredDestructor() const { return data().DeclaredDestructor; } + + /// \brief Determine whether this class describes a lambda function object. + bool isLambda() const { return hasDefinition() && data().IsLambda; } + + /// \brief For a closure type, retrieve the mapping from captured + /// variables and this to the non-static data members that store the + /// values or references of the captures. + /// + /// \param Captures Will be populated with the mapping from captured + /// variables to the corresponding fields. + /// + /// \param ThisCapture Will be set to the field declaration for the + /// 'this' capture. + void getCaptureFields(llvm::DenseMap &Captures, + FieldDecl *&ThisCapture) const; + + typedef const LambdaExpr::Capture* capture_const_iterator; + capture_const_iterator captures_begin() const { + return isLambda() ? getLambdaData().Captures : NULL; + } + capture_const_iterator captures_end() const { + return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL; + } + + /// 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(); + } + + /// 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(); + + /// 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; } + + /// 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; } + + /// \brief True if this class is C-like, without C++-specific features, e.g. + /// it contains only public fields, no bases, tag kind is not 'class', etc. + bool isCLike() const; + + /// 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; } + + /// 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; } + + /// 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; } + + /// isStandardLayout - Whether this class has standard layout + /// (C++ [class]p7) + bool isStandardLayout() const { return data().IsStandardLayout; } + + /// \brief Whether this class, or any of its class subobjects, contains a + /// mutable field. + bool hasMutableFields() const { return data().HasMutableFields; } + + /// hasTrivialDefaultConstructor - Whether this class has a trivial default + /// constructor (C++11 [class.ctor]p5). + bool hasTrivialDefaultConstructor() const { + return data().HasTrivialDefaultConstructor && + (!data().UserDeclaredConstructor || + data().DeclaredDefaultConstructor); + } + + /// hasConstexprNonCopyMoveConstructor - Whether this class has at least one + /// constexpr constructor other than the copy or move constructors. + bool hasConstexprNonCopyMoveConstructor() const { + return data().HasConstexprNonCopyMoveConstructor || + (!hasUserDeclaredConstructor() && + defaultedDefaultConstructorIsConstexpr()); + } + + /// defaultedDefaultConstructorIsConstexpr - Whether a defaulted default + /// constructor for this class would be constexpr. + bool defaultedDefaultConstructorIsConstexpr() const { + return data().DefaultedDefaultConstructorIsConstexpr; + } + + /// defaultedCopyConstructorIsConstexpr - Whether a defaulted copy + /// constructor for this class would be constexpr. + bool defaultedCopyConstructorIsConstexpr() const { + return data().DefaultedCopyConstructorIsConstexpr; + } + + /// defaultedMoveConstructorIsConstexpr - Whether a defaulted move + /// constructor for this class would be constexpr. + bool defaultedMoveConstructorIsConstexpr() const { + return data().DefaultedMoveConstructorIsConstexpr; + } + + /// hasConstexprDefaultConstructor - Whether this class has a constexpr + /// default constructor. + bool hasConstexprDefaultConstructor() const { + return data().HasConstexprDefaultConstructor || + (!data().UserDeclaredConstructor && + data().DefaultedDefaultConstructorIsConstexpr && isLiteral()); + } + + /// hasConstexprCopyConstructor - Whether this class has a constexpr copy + /// constructor. + bool hasConstexprCopyConstructor() const { + return data().HasConstexprCopyConstructor || + (!data().DeclaredCopyConstructor && + data().DefaultedCopyConstructorIsConstexpr && isLiteral()); + } + + /// hasConstexprMoveConstructor - Whether this class has a constexpr move + /// constructor. + bool hasConstexprMoveConstructor() const { + return data().HasConstexprMoveConstructor || + (needsImplicitMoveConstructor() && + data().DefaultedMoveConstructorIsConstexpr && isLiteral()); + } + + // hasTrivialCopyConstructor - Whether this class has a trivial copy + // constructor (C++ [class.copy]p6, C++0x [class.copy]p13) + bool hasTrivialCopyConstructor() const { + return data().HasTrivialCopyConstructor; + } + + // hasTrivialMoveConstructor - Whether this class has a trivial move + // constructor (C++0x [class.copy]p13) + bool hasTrivialMoveConstructor() const { + return data().HasTrivialMoveConstructor; + } + + // hasTrivialCopyAssignment - Whether this class has a trivial copy + // assignment operator (C++ [class.copy]p11, C++0x [class.copy]p27) + bool hasTrivialCopyAssignment() const { + return data().HasTrivialCopyAssignment; + } + + // hasTrivialMoveAssignment - Whether this class has a trivial move + // assignment operator (C++0x [class.copy]p27) + bool hasTrivialMoveAssignment() const { + return data().HasTrivialMoveAssignment; + } + + // hasTrivialDestructor - Whether this class has a trivial destructor + // (C++ [class.dtor]p3) + bool hasTrivialDestructor() const { return data().HasTrivialDestructor; } + + // hasIrrelevantDestructor - Whether this class has a destructor which has no + // semantic effect. Any such destructor will be trivial, public, defaulted + // and not deleted, and will call only irrelevant destructors. + bool hasIrrelevantDestructor() const { + return data().HasIrrelevantDestructor; + } + + // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal or + // volatile type non-static data member or base class. + bool hasNonLiteralTypeFieldsOrBases() const { + return data().HasNonLiteralTypeFieldsOrBases; + } + + // isTriviallyCopyable - Whether this class is considered trivially copyable + // (C++0x [class]p6). + bool isTriviallyCopyable() const; + + // isTrivial - Whether this class is considered trivial + // + // C++0x [class]p6 + // A trivial class is a class that has a trivial default constructor and + // is trivially copiable. + bool isTrivial() const { + return isTriviallyCopyable() && hasTrivialDefaultConstructor(); + } + + // isLiteral - Whether this class is a literal type. + // + // C++11 [basic.types]p10 + // A class type that has all the following properties: + // -- it has a trivial destructor + // -- every constructor call and full-expression in the + // brace-or-equal-intializers for non-static data members (if any) is + // a constant expression. + // -- it is an aggregate type or has at least one constexpr constructor or + // constructor template that is not a copy or move constructor, and + // -- all of its non-static data members and base classes are of literal + // types + // + // We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by + // treating types with trivial default constructors as literal types. + bool isLiteral() const { + return hasTrivialDestructor() && + (isAggregate() || hasConstexprNonCopyMoveConstructor() || + hasTrivialDefaultConstructor()) && + !hasNonLiteralTypeFieldsOrBases(); + } + + /// \brief If this record is an instantiation of a member class, + /// retrieves the member class from which it was instantiated. + /// + /// This routine will return non-NULL for (non-templated) member + /// classes of class templates. For example, given: + /// + /// \code + /// template + /// struct X { + /// struct A { }; + /// }; + /// \endcode + /// + /// The declaration for X::A is a (non-templated) CXXRecordDecl + /// whose parent is the class template specialization X. For + /// this declaration, getInstantiatedFromMemberClass() will return + /// the CXXRecordDecl X::A. When a complete definition of + /// X::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(); + } + + 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); + + /// getDestructor - Returns the destructor decl for this class. + CXXDestructorDecl *getDestructor() 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(getDeclContext())) + return RD->isLocalClass(); + + return dyn_cast(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(const CXXRecordDecl *Base) const; + + /// \brief Determine whether this class is derived from the type \p Base. + /// + /// This routine only determines whether this class is derived from \p Base, + /// but does not account for factors that may make a Derived -> Base class + /// ill-formed, such as private/protected inheritance or multiple, ambiguous + /// base class subobjects. + /// + /// \param Base the base class we are searching for. + /// + /// \param Paths will contain the paths taken from the current class to the + /// given \p Base class. + /// + /// \returns true if this class is derived from Base, false otherwise. + /// + /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than + /// tangling input and output in \p Paths + bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const; + + /// \brief Determine whether this class is virtually derived from + /// the class \p Base. + /// + /// This routine only determines whether this class is virtually + /// derived from \p Base, but does not account for factors that may + /// make a Derived -> Base class ill-formed, such as + /// private/protected inheritance or multiple, ambiguous base class + /// subobjects. + /// + /// \param Base the base class we are searching for. + /// + /// \returns true if this class is virtually derived from Base, + /// false otherwise. + bool isVirtuallyDerivedFrom(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; + + /// \brief Get the indirect primary bases for this class. + void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) 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); + } + + /// \brief Indicates that the definition of this class is now complete. + virtual void completeDefinition(); + + /// \brief Indicates that the definition of this class is now complete, + /// and provides a final overrider map to help determine + /// + /// \param FinalOverriders The final overrider map for this class, which can + /// be provided as an optimization for abstract-class checking. If NULL, + /// final overriders will be computed if they are needed to complete the + /// definition. + void completeDefinition(CXXFinalOverriderMap *FinalOverriders); + + /// \brief Determine whether this class may end up being abstract, even though + /// it is not yet known to be abstract. + /// + /// \returns true if this class is not known to be abstract but has any + /// base classes that are abstract. In this case, \c completeDefinition() + /// will need to compute final overriders to determine whether the class is + /// actually abstract. + bool mayBeAbstract() const; + + /// \brief If this is the closure type of a lambda expression, retrieve the + /// number to be used for name mangling in the Itanium C++ ABI. + /// + /// Zero indicates that this closure type has internal linkage, so the + /// mangling number does not matter, while a non-zero value indicates which + /// lambda expression this is in this particular context. + unsigned getLambdaManglingNumber() const { + assert(isLambda() && "Not a lambda closure type!"); + return getLambdaData().ManglingNumber; + } + + /// \brief Retrieve the declaration that provides additional context for a + /// lambda, when the normal declaration context is not specific enough. + /// + /// Certain contexts (default arguments of in-class function parameters and + /// the initializers of data members) have separate name mangling rules for + /// lambdas within the Itanium C++ ABI. For these cases, this routine provides + /// the declaration in which the lambda occurs, e.g., the function parameter + /// or the non-static data member. Otherwise, it returns NULL to imply that + /// the declaration context suffices. + Decl *getLambdaContextDecl() const { + assert(isLambda() && "Not a lambda closure type!"); + return getLambdaData().ContextDecl; + } + + /// \brief Set the mangling number and context declaration for a lambda + /// class. + void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) { + getLambdaData().ManglingNumber = ManglingNumber; + getLambdaData().ContextDecl = ContextDecl; + } + + /// \brief Determine whether this lambda expression was known to be dependent + /// at the time it was created, even if its context does not appear to be + /// dependent. + /// + /// This flag is a workaround for an issue with parsing, where default + /// arguments are parsed before their enclosing function declarations have + /// been created. This means that any lambda expressions within those + /// default arguments will have as their DeclContext the context enclosing + /// the function declaration, which may be non-dependent even when the + /// function declaration itself is dependent. This flag indicates when we + /// know that the lambda is dependent despite that. + bool isDependentLambda() const { + return isLambda() && getLambdaData().Dependent; + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { + return K >= firstCXXRecord && K <= lastCXXRecord; + } + static bool classof(const CXXRecordDecl *D) { return true; } + static bool classof(const ClassTemplateSpecializationDecl *D) { + return true; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTReader; + friend class ASTWriter; +}; + +/// CXXMethodDecl - Represents a static or instance method of a +/// struct/union/class. +class CXXMethodDecl : public FunctionDecl { + virtual void anchor(); +protected: + CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + bool isStatic, StorageClass SCAsWritten, bool isInline, + bool isConstexpr, SourceLocation EndLocation) + : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo, + (isStatic ? SC_Static : SC_None), + SCAsWritten, isInline, isConstexpr) { + if (EndLocation.isValid()) + setRangeEnd(EndLocation); + } + +public: + static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + bool isStatic, + StorageClass SCAsWritten, + bool isInline, + bool isConstexpr, + SourceLocation EndLocation); + + static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + bool isStatic() const { return getStorageClass() == SC_Static; } + bool isInstance() const { return !isStatic(); } + + bool isVirtual() const { + CXXMethodDecl *CD = + cast(const_cast(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; + + /// \brief Determine whether this is a move assignment operator. + bool isMoveAssignmentOperator() const; + + const CXXMethodDecl *getCanonicalDecl() const { + return cast(FunctionDecl::getCanonicalDecl()); + } + CXXMethodDecl *getCanonicalDecl() { + return cast(FunctionDecl::getCanonicalDecl()); + } + + /// isUserProvided - True if it is either an implicit constructor or + /// if it was defaulted or deleted on first declaration. + bool isUserProvided() const { + return !(isDeleted() || getCanonicalDecl()->isDefaulted()); + } + + /// + void addOverriddenMethod(const CXXMethodDecl *MD); + + typedef const CXXMethodDecl *const* method_iterator; + + method_iterator begin_overridden_methods() const; + method_iterator end_overridden_methods() const; + unsigned size_overridden_methods() const; + + /// getParent - Returns the parent of this method declaration, which + /// is the class in which this method is defined. + const CXXRecordDecl *getParent() const { + return cast(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( + cast(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()->getTypeQuals(); + } + + /// \brief Retrieve the ref-qualifier associated with this method. + /// + /// In the following example, \c f() has an lvalue ref-qualifier, \c g() + /// has an rvalue ref-qualifier, and \c h() has no ref-qualifier. + /// \code + /// struct X { + /// void f() &; + /// void g() &&; + /// void h(); + /// }; + /// \endcode + RefQualifierKind getRefQualifier() const { + return getType()->getAs()->getRefQualifier(); + } + + bool hasInlineBody() const; + + /// \brief Determine whether this is a lambda closure type's static member + /// function that is used for the result of the lambda's conversion to + /// function pointer (for a lambda with no captures). + /// + /// The function itself, if used, will have a placeholder body that will be + /// supplied by IR generation to either forward to the function call operator + /// or clone the function call operator. + bool isLambdaStaticInvoker() const; + + // 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 >= firstCXXMethod && K <= lastCXXMethod; + } +}; + +/// CXXCtorInitializer - 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 CXXCtorInitializer { + /// \brief Either the base class name/delegating constructor type (stored as + /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field + /// (IndirectFieldDecl*) being initialized. + llvm::PointerUnion3 + Initializee; + + /// \brief The source location for the field name or, for a base initializer + /// pack expansion, the location of the ellipsis. In the case of a delegating + /// constructor, it will still include the type's source location as the + /// Initializee points to the CXXConstructorDecl (to allow loop detection). + SourceLocation MemberOrEllipsisLocation; + + /// \brief The argument used to initialize the base or member, which may + /// end up constructing an object (when multiple arguments are involved). + /// If 0, this is a field initializer, and the in-class member initializer + /// will be used. + Stmt *Init; + + /// LParenLoc - Location of the left paren of the ctor-initializer. + SourceLocation LParenLoc; + + /// RParenLoc - Location of the right paren of the ctor-initializer. + SourceLocation RParenLoc; + + /// \brief If the initializee is a type, whether that type makes this + /// a delegating initialization. + bool IsDelegating : 1; + + /// 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 : 13; + + CXXCtorInitializer(ASTContext &Context, FieldDecl *Member, + SourceLocation MemberLoc, SourceLocation L, Expr *Init, + SourceLocation R, VarDecl **Indices, unsigned NumIndices); + +public: + /// CXXCtorInitializer - Creates a new base-class initializer. + explicit + CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual, + SourceLocation L, Expr *Init, SourceLocation R, + SourceLocation EllipsisLoc); + + /// CXXCtorInitializer - Creates a new member initializer. + explicit + CXXCtorInitializer(ASTContext &Context, FieldDecl *Member, + SourceLocation MemberLoc, SourceLocation L, Expr *Init, + SourceLocation R); + + /// CXXCtorInitializer - Creates a new anonymous field initializer. + explicit + CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member, + SourceLocation MemberLoc, SourceLocation L, Expr *Init, + SourceLocation R); + + /// CXXCtorInitializer - Creates a new delegating Initializer. + explicit + CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, + SourceLocation L, Expr *Init, SourceLocation R); + + /// \brief Creates a new member initializer that optionally contains + /// array indices used to describe an elementwise initialization. + static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member, + SourceLocation MemberLoc, SourceLocation L, + Expr *Init, SourceLocation R, + VarDecl **Indices, unsigned NumIndices); + + /// isBaseInitializer - Returns true when this initializer is + /// initializing a base class. + bool isBaseInitializer() const { + return Initializee.is() && !IsDelegating; + } + + /// isMemberInitializer - Returns true when this initializer is + /// initializing a non-static data member. + bool isMemberInitializer() const { return Initializee.is(); } + + bool isAnyMemberInitializer() const { + return isMemberInitializer() || isIndirectMemberInitializer(); + } + + bool isIndirectMemberInitializer() const { + return Initializee.is(); + } + + /// isInClassMemberInitializer - Returns true when this initializer is an + /// implicit ctor initializer generated for a field with an initializer + /// defined on the member declaration. + bool isInClassMemberInitializer() const { + return !Init; + } + + /// isDelegatingInitializer - Returns true when this initializer is creating + /// a delegating constructor. + bool isDelegatingInitializer() const { + return Initializee.is() && IsDelegating; + } + + /// \brief Determine whether this initializer is a pack expansion. + bool isPackExpansion() const { + return isBaseInitializer() && MemberOrEllipsisLocation.isValid(); + } + + // \brief For a pack expansion, returns the location of the ellipsis. + SourceLocation getEllipsisLoc() const { + assert(isPackExpansion() && "Initializer is not a pack expansion"); + return MemberOrEllipsisLocation; + } + + /// If this is a base class initializer, returns the type of the + /// base class with location information. Otherwise, returns an NULL + /// type location. + TypeLoc getBaseClassLoc() const; + + /// If this is a base class initializer, returns the type of the base class. + /// Otherwise, returns NULL. + const Type *getBaseClass() const; + + /// Returns whether the base is virtual or not. + bool isBaseVirtual() const { + assert(isBaseInitializer() && "Must call this on base initializer!"); + + return IsVirtual; + } + + /// \brief Returns the declarator information for a base class or delegating + /// initializer. + TypeSourceInfo *getTypeSourceInfo() const { + return Initializee.dyn_cast(); + } + + /// getMember - If this is a member initializer, returns the + /// declaration of the non-static data member being + /// initialized. Otherwise, returns NULL. + FieldDecl *getMember() const { + if (isMemberInitializer()) + return Initializee.get(); + return 0; + } + FieldDecl *getAnyMember() const { + if (isMemberInitializer()) + return Initializee.get(); + if (isIndirectMemberInitializer()) + return Initializee.get()->getAnonField(); + return 0; + } + + IndirectFieldDecl *getIndirectMember() const { + if (isIndirectMemberInitializer()) + return Initializee.get(); + return 0; + } + + SourceLocation getMemberLocation() const { + return MemberOrEllipsisLocation; + } + + /// \brief Determine the source location of the initializer. + SourceLocation getSourceLocation() const; + + /// \brief Determine the source range covering the entire initializer. + SourceRange getSourceRange() const LLVM_READONLY; + + /// 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(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(pos); + } + + SourceLocation getLParenLoc() const { return LParenLoc; } + SourceLocation getRParenLoc() const { return RParenLoc; } + + /// \brief Determine the number of implicit array indices used while + /// described an array member initialization. + unsigned getNumArrayIndices() const { + return IsWritten ? 0 : SourceOrderOrNumArrayIndices; + } + + /// \brief Retrieve a particular array index variable used to + /// describe an array member initialization. + VarDecl *getArrayIndex(unsigned I) { + assert(I < getNumArrayIndices() && "Out of bounds member array index"); + return reinterpret_cast(this + 1)[I]; + } + const VarDecl *getArrayIndex(unsigned I) const { + assert(I < getNumArrayIndices() && "Out of bounds member array index"); + return reinterpret_cast(this + 1)[I]; + } + void setArrayIndex(unsigned I, VarDecl *Index) { + assert(I < getNumArrayIndices() && "Out of bounds member array index"); + reinterpret_cast(this + 1)[I] = Index; + } + ArrayRef getArrayIndexes() { + assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init"); + return ArrayRef(reinterpret_cast(this + 1), + getNumArrayIndices()); + } + + /// \brief Get the initializer. This is 0 if this is an in-class initializer + /// for a non-static data member which has not yet been parsed. + Expr *getInit() const { + if (!Init) + return getAnyMember()->getInClassInitializer(); + + return static_cast(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 { + virtual void anchor(); + /// 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. + /// CtorInitializers - The arguments used to initialize the base + /// or member. + CXXCtorInitializer **CtorInitializers; + unsigned NumCtorInitializers; + + CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + bool isExplicitSpecified, bool isInline, + bool isImplicitlyDeclared, bool isConstexpr) + : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false, + SC_None, isInline, isConstexpr, SourceLocation()), + IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false), + CtorInitializers(0), NumCtorInitializers(0) { + setImplicit(isImplicitlyDeclared); + } + +public: + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + bool isExplicit, + bool isInline, bool isImplicitlyDeclared, + bool isConstexpr); + + /// 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(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 CXXCtorInitializer **init_iterator; + + /// init_const_iterator - Iterates through the memberbase initializer list. + typedef CXXCtorInitializer * const * init_const_iterator; + + /// init_begin() - Retrieve an iterator to the first initializer. + init_iterator init_begin() { return CtorInitializers; } + /// begin() - Retrieve an iterator to the first initializer. + init_const_iterator init_begin() const { return CtorInitializers; } + + /// init_end() - Retrieve an iterator past the last initializer. + init_iterator init_end() { + return CtorInitializers + NumCtorInitializers; + } + /// end() - Retrieve an iterator past the last initializer. + init_const_iterator init_end() const { + return CtorInitializers + NumCtorInitializers; + } + + typedef std::reverse_iterator init_reverse_iterator; + typedef std::reverse_iterator + init_const_reverse_iterator; + + init_reverse_iterator init_rbegin() { + return init_reverse_iterator(init_end()); + } + init_const_reverse_iterator init_rbegin() const { + return init_const_reverse_iterator(init_end()); + } + + init_reverse_iterator init_rend() { + return init_reverse_iterator(init_begin()); + } + init_const_reverse_iterator init_rend() const { + return init_const_reverse_iterator(init_begin()); + } + + /// getNumArgs - Determine the number of arguments used to + /// initialize the member or base. + unsigned getNumCtorInitializers() const { + return NumCtorInitializers; + } + + void setNumCtorInitializers(unsigned numCtorInitializers) { + NumCtorInitializers = numCtorInitializers; + } + + void setCtorInitializers(CXXCtorInitializer ** initializers) { + CtorInitializers = initializers; + } + + /// isDelegatingConstructor - Whether this constructor is a + /// delegating constructor + bool isDelegatingConstructor() const { + return (getNumCtorInitializers() == 1) && + CtorInitializers[0]->isDelegatingInitializer(); + } + + /// getTargetConstructor - When this constructor delegates to + /// another, retrieve the target + CXXConstructorDecl *getTargetConstructor() const; + + /// 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); + } + + /// \brief Determine whether this constructor is a move constructor + /// (C++0x [class.copy]p3), which can be used to move values of the class. + /// + /// \param TypeQuals If this constructor is a move constructor, will be set + /// to the type qualifiers on the referent of the first parameter's type. + bool isMoveConstructor(unsigned &TypeQuals) const; + + /// \brief Determine whether this constructor is a move constructor + /// (C++0x [class.copy]p3), which can be used to move values of the class. + bool isMoveConstructor() const { + unsigned TypeQuals = 0; + return isMoveConstructor(TypeQuals); + } + + /// \brief Determine whether this is a copy or move constructor. + /// + /// \param TypeQuals Will be set to the type qualifiers on the reference + /// parameter, if in fact this is a copy or move constructor. + bool isCopyOrMoveConstructor(unsigned &TypeQuals) const; + + /// \brief Determine whether this a copy or move constructor. + bool isCopyOrMoveConstructor() const { + unsigned Quals; + return isCopyOrMoveConstructor(Quals); + } + + /// 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 + /// would copy the object to itself. Such constructors are never used to copy + /// an object. + bool isSpecializationCopyingObject() const; + + /// \brief Get the constructor that this inheriting constructor is based on. + const CXXConstructorDecl *getInheritedConstructor() const; + + /// \brief Set the constructor that this inheriting constructor is based on. + void setInheritedConstructor(const CXXConstructorDecl *BaseCtor); + + const CXXConstructorDecl *getCanonicalDecl() const { + return cast(FunctionDecl::getCanonicalDecl()); + } + CXXConstructorDecl *getCanonicalDecl() { + return cast(FunctionDecl::getCanonicalDecl()); + } + + // 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; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// CXXDestructorDecl - Represents a C++ destructor within a +/// class. For example: +/// +/// @code +/// class X { +/// public: +/// ~X(); // represented by a CXXDestructorDecl. +/// }; +/// @endcode +class CXXDestructorDecl : public CXXMethodDecl { + virtual void anchor(); + /// 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 StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + bool isInline, bool isImplicitlyDeclared) + : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false, + SC_None, isInline, /*isConstexpr=*/false, SourceLocation()), + ImplicitlyDefined(false), OperatorDelete(0) { + setImplicit(isImplicitlyDeclared); + } + +public: + static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo* TInfo, + bool isInline, + bool isImplicitlyDeclared); + static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); + + /// 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; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// CXXConversionDecl - Represents a C++ conversion function within a +/// class. For example: +/// +/// @code +/// class X { +/// public: +/// operator bool(); +/// }; +/// @endcode +class CXXConversionDecl : public CXXMethodDecl { + virtual void anchor(); + /// 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 StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + bool isInline, bool isExplicitSpecified, + bool isConstexpr, SourceLocation EndLocation) + : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false, + SC_None, isInline, isConstexpr, EndLocation), + IsExplicitSpecified(isExplicitSpecified) { } + +public: + static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, + QualType T, TypeSourceInfo *TInfo, + bool isInline, bool isExplicit, + bool isConstexpr, + SourceLocation EndLocation); + static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// 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(getFirstDeclaration()) + ->isExplicitSpecified(); + } + + /// getConversionType - Returns the type that this conversion + /// function is converting to. + QualType getConversionType() const { + return getType()->getAs()->getResultType(); + } + + /// \brief Determine whether this conversion function is a conversion from + /// a lambda closure type to a block pointer. + bool isLambdaToBlockPointerConversion() const; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const CXXConversionDecl *D) { return true; } + static bool classofKind(Kind K) { return K == CXXConversion; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// LinkageSpecDecl - This represents a linkage specification. For example: +/// extern "C" void foo(); +/// +class LinkageSpecDecl : public Decl, public DeclContext { + virtual void anchor(); +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; + /// ExternLoc - The source location for the extern keyword. + SourceLocation ExternLoc; + /// RBraceLoc - The source location for the right brace (if valid). + SourceLocation RBraceLoc; + + LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, + SourceLocation LangLoc, LanguageIDs lang, + SourceLocation RBLoc) + : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec), + Language(lang), ExternLoc(ExternLoc), RBraceLoc(RBLoc) { } + +public: + static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation ExternLoc, + SourceLocation LangLoc, LanguageIDs Lang, + SourceLocation RBraceLoc = SourceLocation()); + static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// \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 RBraceLoc.isValid(); } + + SourceLocation getExternLoc() const { return ExternLoc; } + SourceLocation getRBraceLoc() const { return RBraceLoc; } + void setExternLoc(SourceLocation L) { ExternLoc = L; } + void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + + SourceLocation getLocEnd() const LLVM_READONLY { + if (hasBraces()) + return getRBraceLoc(); + // No braces: get the end location of the (only) declaration in context + // (if present). + return decls_empty() ? getLocation() : decls_begin()->getLocEnd(); + } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(ExternLoc, getLocEnd()); + } + + 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(const_cast(D)); + } + static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } +}; + +/// UsingDirectiveDecl - Represents C++ using-directive. For example: +/// +/// using namespace std; +/// +// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide +// artificial names for all using-directives in order to store +// them in DeclContext effectively. +class UsingDirectiveDecl : public NamedDecl { + virtual void anchor(); + /// \brief The location of the "using" keyword. + SourceLocation UsingLoc; + + /// SourceLocation - Location of 'namespace' token. + SourceLocation NamespaceLoc; + + /// \brief The nested-name-specifier that precedes the namespace. + NestedNameSpecifierLoc QualifierLoc; + + /// 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 UsingLoc, + SourceLocation NamespcLoc, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation IdentLoc, + NamedDecl *Nominated, + DeclContext *CommonAncestor) + : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc), + NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc), + NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { } + +public: + /// \brief Retrieve the nested-name-specifier that qualifies the + /// name of the namespace, with source-location information. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + /// \brief Retrieve the nested-name-specifier that qualifies the + /// name of the namespace. + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } + + NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; } + const NamedDecl *getNominatedNamespaceAsWritten() const { + return NominatedNamespace; + } + + /// getNominatedNamespace - Returns namespace nominated by using-directive. + NamespaceDecl *getNominatedNamespace(); + + const NamespaceDecl *getNominatedNamespace() const { + return const_cast(this)->getNominatedNamespace(); + } + + /// \brief Returns the common ancestor context of this using-directive and + /// its nominated namespace. + DeclContext *getCommonAncestor() { return CommonAncestor; } + const DeclContext *getCommonAncestor() const { return CommonAncestor; } + + /// \brief Return the location of the "using" keyword. + SourceLocation getUsingLoc() const { return UsingLoc; } + + // FIXME: Could omit 'Key' in name. + /// getNamespaceKeyLocation - Returns location of namespace keyword. + SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; } + + /// getIdentLocation - Returns location of identifier. + SourceLocation getIdentLocation() const { return getLocation(); } + + static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation UsingLoc, + SourceLocation NamespaceLoc, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation IdentLoc, + NamedDecl *Nominated, + DeclContext *CommonAncestor); + static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(UsingLoc, getLocation()); + } + + 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 == UsingDirective; } + + // Friend for getUsingDirectiveName. + friend class DeclContext; + + friend class ASTDeclReader; +}; + +/// NamespaceAliasDecl - Represents a C++ namespace alias. For example: +/// +/// @code +/// namespace Foo = Bar; +/// @endcode +class NamespaceAliasDecl : public NamedDecl { + virtual void anchor(); + + /// \brief The location of the "namespace" keyword. + SourceLocation NamespaceLoc; + + /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc. + SourceLocation IdentLoc; + + /// \brief The nested-name-specifier that precedes the namespace. + NestedNameSpecifierLoc QualifierLoc; + + /// Namespace - The Decl that this alias points to. Can either be a + /// NamespaceDecl or a NamespaceAliasDecl. + NamedDecl *Namespace; + + NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc, + SourceLocation AliasLoc, IdentifierInfo *Alias, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation IdentLoc, NamedDecl *Namespace) + : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), + NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc), + QualifierLoc(QualifierLoc), Namespace(Namespace) { } + + friend class ASTDeclReader; + +public: + /// \brief Retrieve the nested-name-specifier that qualifies the + /// name of the namespace, with source-location information. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + /// \brief Retrieve the nested-name-specifier that qualifies the + /// name of the namespace. + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } + + /// \brief Retrieve the namespace declaration aliased by this directive. + NamespaceDecl *getNamespace() { + if (NamespaceAliasDecl *AD = dyn_cast(Namespace)) + return AD->getNamespace(); + + return cast(Namespace); + } + + const NamespaceDecl *getNamespace() const { + return const_cast(this)->getNamespace(); + } + + /// Returns the location of the alias name, i.e. 'foo' in + /// "namespace foo = ns::bar;". + SourceLocation getAliasLoc() const { return getLocation(); } + + /// Returns the location of the 'namespace' keyword. + SourceLocation getNamespaceLoc() const { return NamespaceLoc; } + + /// Returns the location of the identifier in the named namespace. + SourceLocation getTargetNameLoc() const { return IdentLoc; } + + /// \brief Retrieve the namespace that this alias refers to, which + /// may either be a NamespaceDecl or a NamespaceAliasDecl. + NamedDecl *getAliasedNamespace() const { return Namespace; } + + static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation NamespaceLoc, + SourceLocation AliasLoc, + IdentifierInfo *Alias, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation IdentLoc, + NamedDecl *Namespace); + + static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + virtual SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(NamespaceLoc, IdentLoc); + } + + 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 == 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 { + virtual void anchor(); + + /// The referenced declaration. + NamedDecl *Underlying; + + /// \brief The using declaration which introduced this decl or the next using + /// shadow declaration contained in the aforementioned using declaration. + NamedDecl *UsingOrNextShadow; + friend class UsingDecl; + + UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target) + : NamedDecl(UsingShadow, DC, Loc, DeclarationName()), + Underlying(Target), + UsingOrNextShadow(reinterpret_cast(Using)) { + if (Target) { + setDeclName(Target->getDeclName()); + 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); + } + + static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// \brief Gets the underlying declaration which has been brought into the + /// local scope. + NamedDecl *getTargetDecl() const { return Underlying; } + + /// \brief Sets the underlying declaration which has been brought into the + /// local scope. + void setTargetDecl(NamedDecl* ND) { + assert(ND && "Target decl is null!"); + Underlying = ND; + IdentifierNamespace = ND->getIdentifierNamespace(); + } + + /// \brief Gets the using declaration to which this declaration is tied. + UsingDecl *getUsingDecl() const; + + /// \brief The next using shadow declaration contained in the shadow decl + /// chain of the using declaration which introduced this decl. + UsingShadowDecl *getNextUsingShadowDecl() const { + return dyn_cast_or_null(UsingOrNextShadow); + } + + 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; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// UsingDecl - Represents a C++ using-declaration. For example: +/// using someNameSpace::someIdentifier; +class UsingDecl : public NamedDecl { + virtual void anchor(); + + /// \brief The source location of the "using" location itself. + SourceLocation UsingLocation; + + /// \brief The nested-name-specifier that precedes the name. + NestedNameSpecifierLoc QualifierLoc; + + /// DNLoc - Provides source/type location info for the + /// declaration name embedded in the ValueDecl base class. + DeclarationNameLoc DNLoc; + + /// \brief The first shadow declaration of the shadow decl chain associated + /// with this using declaration. The bool member of the pair store whether + /// this decl has the 'typename' keyword. + llvm::PointerIntPair FirstUsingShadow; + + UsingDecl(DeclContext *DC, SourceLocation UL, + NestedNameSpecifierLoc QualifierLoc, + const DeclarationNameInfo &NameInfo, bool IsTypeNameArg) + : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()), + UsingLocation(UL), QualifierLoc(QualifierLoc), + DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, IsTypeNameArg) { + } + +public: + /// \brief Returns the source location of the "using" keyword. + SourceLocation getUsingLocation() const { return UsingLocation; } + + /// \brief Set the source location of the 'using' keyword. + void setUsingLocation(SourceLocation L) { UsingLocation = L; } + + /// \brief Retrieve the nested-name-specifier that qualifies the name, + /// with source-location information. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + /// \brief Retrieve the nested-name-specifier that qualifies the name. + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } + + DeclarationNameInfo getNameInfo() const { + return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); + } + + /// \brief Return true if the using declaration has 'typename'. + bool isTypeName() const { return FirstUsingShadow.getInt(); } + + /// \brief Sets whether the using declaration has 'typename'. + void setTypeName(bool TN) { FirstUsingShadow.setInt(TN); } + + /// \brief Iterates through the using shadow declarations assosiated with + /// this using declaration. + class shadow_iterator { + /// \brief The current using shadow declaration. + UsingShadowDecl *Current; + + public: + typedef UsingShadowDecl* value_type; + typedef UsingShadowDecl* reference; + typedef UsingShadowDecl* pointer; + typedef std::forward_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + shadow_iterator() : Current(0) { } + explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { } + + reference operator*() const { return Current; } + pointer operator->() const { return Current; } + + shadow_iterator& operator++() { + Current = Current->getNextUsingShadowDecl(); + return *this; + } + + shadow_iterator operator++(int) { + shadow_iterator tmp(*this); + ++(*this); + return tmp; + } + + friend bool operator==(shadow_iterator x, shadow_iterator y) { + return x.Current == y.Current; + } + friend bool operator!=(shadow_iterator x, shadow_iterator y) { + return x.Current != y.Current; + } + }; + + shadow_iterator shadow_begin() const { + return shadow_iterator(FirstUsingShadow.getPointer()); + } + shadow_iterator shadow_end() const { return shadow_iterator(); } + + /// \brief Return the number of shadowed declarations associated with this + /// using declaration. + unsigned shadow_size() const { + return std::distance(shadow_begin(), shadow_end()); + } + + void addShadowDecl(UsingShadowDecl *S); + void removeShadowDecl(UsingShadowDecl *S); + + static UsingDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation UsingL, + NestedNameSpecifierLoc QualifierLoc, + const DeclarationNameInfo &NameInfo, + bool IsTypeNameArg); + + static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(UsingLocation, getNameInfo().getEndLoc()); + } + + 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 == Using; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// 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 A : public Base { +/// using Base::foo; +/// }; +class UnresolvedUsingValueDecl : public ValueDecl { + virtual void anchor(); + + /// \brief The source location of the 'using' keyword + SourceLocation UsingLocation; + + /// \brief The nested-name-specifier that precedes the name. + NestedNameSpecifierLoc QualifierLoc; + + /// DNLoc - Provides source/type location info for the + /// declaration name embedded in the ValueDecl base class. + DeclarationNameLoc DNLoc; + + UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty, + SourceLocation UsingLoc, + NestedNameSpecifierLoc QualifierLoc, + const DeclarationNameInfo &NameInfo) + : ValueDecl(UnresolvedUsingValue, DC, + NameInfo.getLoc(), NameInfo.getName(), Ty), + UsingLocation(UsingLoc), QualifierLoc(QualifierLoc), + DNLoc(NameInfo.getInfo()) + { } + +public: + /// \brief Returns the source location of the 'using' keyword. + SourceLocation getUsingLoc() const { return UsingLocation; } + + /// \brief Set the source location of the 'using' keyword. + void setUsingLoc(SourceLocation L) { UsingLocation = L; } + + /// \brief Retrieve the nested-name-specifier that qualifies the name, + /// with source-location information. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + /// \brief Retrieve the nested-name-specifier that qualifies the name. + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } + + DeclarationNameInfo getNameInfo() const { + return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); + } + + static UnresolvedUsingValueDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, + NestedNameSpecifierLoc QualifierLoc, + const DeclarationNameInfo &NameInfo); + + static UnresolvedUsingValueDecl * + CreateDeserialized(ASTContext &C, unsigned ID); + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(UsingLocation, getNameInfo().getEndLoc()); + } + + 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 == UnresolvedUsingValue; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// UnresolvedUsingTypenameDecl - Represents a dependent using +/// declaration which was marked with 'typename'. +/// +/// template class A : public Base { +/// using typename Base::foo; +/// }; +/// +/// The type associated with a unresolved using typename decl is +/// currently always a typename type. +class UnresolvedUsingTypenameDecl : public TypeDecl { + virtual void anchor(); + + /// \brief The source location of the 'using' keyword + SourceLocation UsingLocation; + + /// \brief The source location of the 'typename' keyword + SourceLocation TypenameLocation; + + /// \brief The nested-name-specifier that precedes the name. + NestedNameSpecifierLoc QualifierLoc; + + UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc, + SourceLocation TypenameLoc, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TargetNameLoc, + IdentifierInfo *TargetName) + : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName, + UsingLoc), + TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { } + + friend class ASTDeclReader; + +public: + /// \brief Returns the source location of the 'using' keyword. + SourceLocation getUsingLoc() const { return getLocStart(); } + + /// \brief Returns the source location of the 'typename' keyword. + SourceLocation getTypenameLoc() const { return TypenameLocation; } + + /// \brief Retrieve the nested-name-specifier that qualifies the name, + /// with source-location information. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + /// \brief Retrieve the nested-name-specifier that qualifies the name. + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } + + static UnresolvedUsingTypenameDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, + SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TargetNameLoc, DeclarationName TargetName); + + static UnresolvedUsingTypenameDecl * + CreateDeserialized(ASTContext &C, unsigned ID); + + 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 == UnresolvedUsingTypename; } +}; + +/// StaticAssertDecl - Represents a C++0x static_assert declaration. +class StaticAssertDecl : public Decl { + virtual void anchor(); + Expr *AssertExpr; + StringLiteral *Message; + SourceLocation RParenLoc; + + StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc, + Expr *assertexpr, StringLiteral *message, + SourceLocation RParenLoc) + : Decl(StaticAssert, DC, StaticAssertLoc), AssertExpr(assertexpr), + Message(message), RParenLoc(RParenLoc) { } + +public: + static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StaticAssertLoc, + Expr *AssertExpr, StringLiteral *Message, + SourceLocation RParenLoc); + static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + Expr *getAssertExpr() { return AssertExpr; } + const Expr *getAssertExpr() const { return AssertExpr; } + + StringLiteral *getMessage() { return Message; } + const StringLiteral *getMessage() const { return Message; } + + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(getLocation(), getRParenLoc()); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(StaticAssertDecl *D) { return true; } + static bool classofKind(Kind K) { return K == StaticAssert; } + + friend class ASTDeclReader; +}; + +/// Insertion operator for diagnostics. This allows sending AccessSpecifier's +/// into a diagnostic with <<. +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + AccessSpecifier AS); + +const PartialDiagnostic &operator<<(const PartialDiagnostic &DB, + AccessSpecifier AS); + +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h new file mode 100644 index 0000000..c5f2aa0 --- /dev/null +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -0,0 +1,223 @@ +//===-- 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 + +namespace clang { + +class DependentDiagnostic; + +/// StoredDeclsList - This is an array of decls optimized a common case of only +/// containing one entry. +struct StoredDeclsList { + + /// DeclsTy - When in vector form, this is what the Data pointer points to. + typedef SmallVector DeclsTy; + + /// \brief The stored data, which will be either a pointer to a NamedDecl, + /// or a pointer to a vector. + llvm::PointerUnion Data; + +public: + StoredDeclsList() {} + + StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { + if (DeclsTy *RHSVec = RHS.getAsVector()) + Data = new DeclsTy(*RHSVec); + } + + ~StoredDeclsList() { + // If this is a vector-form, free the vector. + if (DeclsTy *Vector = getAsVector()) + delete Vector; + } + + StoredDeclsList &operator=(const StoredDeclsList &RHS) { + if (DeclsTy *Vector = getAsVector()) + delete Vector; + Data = RHS.Data; + if (DeclsTy *RHSVec = RHS.getAsVector()) + Data = new DeclsTy(*RHSVec); + return *this; + } + + bool isNull() const { return Data.isNull(); } + + NamedDecl *getAsDecl() const { + return Data.dyn_cast(); + } + + DeclsTy *getAsVector() const { + return Data.dyn_cast(); + } + + void setOnlyValue(NamedDecl *ND) { + assert(!getAsVector() && "Not inline"); + Data = ND; + // Make sure that Data is a plain NamedDecl* so we can use its address + // at getLookupResult. + assert(*(NamedDecl **)&Data == ND && + "PointerUnion mangles the NamedDecl pointer!"); + } + + void remove(NamedDecl *D) { + assert(!isNull() && "removing from empty list"); + if (NamedDecl *Singleton = getAsDecl()) { + assert(Singleton == D && "list is different singleton"); + (void)Singleton; + Data = (NamedDecl *)0; + return; + } + + DeclsTy &Vec = *getAsVector(); + DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D); + assert(I != Vec.end() && "list does not contain decl"); + Vec.erase(I); + + assert(std::find(Vec.begin(), Vec.end(), D) + == Vec.end() && "list still contains decl"); + } + + /// getLookupResult - Return an array of all the decls that this list + /// represents. + DeclContext::lookup_result getLookupResult() { + if (isNull()) + return DeclContext::lookup_result(DeclContext::lookup_iterator(0), + DeclContext::lookup_iterator(0)); + + // 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"); + DeclsTy &Vector = *getAsVector(); + + // Otherwise, we have a range result. + return DeclContext::lookup_result(&Vector[0], &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(NamedDecl *D) { + // 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. + DeclsTy &Vec = *getAsVector(); + for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); + OD != ODEnd; ++OD) { + NamedDecl *OldD = *OD; + if (D->declarationReplaces(OldD)) { + *OD = D; + return true; + } + } + + return false; + } + + /// AddSubsequentDecl - This is called on the second and later decl when it is + /// not a redeclaration to merge it into the appropriate place in our list. + /// + void AddSubsequentDecl(NamedDecl *D) { + // If this is the second decl added to the list, convert this to vector + // form. + if (NamedDecl *OldD = getAsDecl()) { + DeclsTy *VT = new DeclsTy(); + VT->push_back(OldD); + Data = VT; + } + + DeclsTy &Vec = *getAsVector(); + + // Using directives end up in a special entry which contains only + // other using directives, so all this logic is wasted for them. + // But avoiding the logic wastes time in the far-more-common case + // that we're *not* adding a new using directive. + + // Tag declarations always go at the end of the list so that an + // iterator which points at the first tag will start a span of + // decls that only contains tags. + if (D->hasTagIdentifierNamespace()) + Vec.push_back(D); + + // Resolved using declarations go at the front of the list so that + // they won't show up in other lookup results. Unresolved using + // declarations (which are always in IDNS_Using | IDNS_Ordinary) + // follow that so that the using declarations will be contiguous. + else if (D->getIdentifierNamespace() & Decl::IDNS_Using) { + DeclsTy::iterator I = Vec.begin(); + if (D->getIdentifierNamespace() != Decl::IDNS_Using) { + while (I != Vec.end() && + (*I)->getIdentifierNamespace() == Decl::IDNS_Using) + ++I; + } + Vec.insert(I, D); + + // All other declarations go at the end of the list, but before any + // tag declarations. But we can be clever about tag declarations + // because there can only ever be one in a scope. + } else if (Vec.back()->hasTagIdentifierNamespace()) { + NamedDecl *TagD = Vec.back(); + Vec.back() = D; + Vec.push_back(TagD); + } else + Vec.push_back(D); + } +}; + +class StoredDeclsMap + : public llvm::DenseMap { + +public: + static void DestroyAll(StoredDeclsMap *Map, bool Dependent); + +private: + friend class ASTContext; // walks the chain deleting these + friend class DeclContext; + llvm::PointerIntPair 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/clang/include/clang/AST/DeclFriend.h b/clang/include/clang/AST/DeclFriend.h new file mode 100644 index 0000000..ba1eb8d --- /dev/null +++ b/clang/include/clang/AST/DeclFriend.h @@ -0,0 +1,198 @@ +//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the section of the AST representing C++ friend +// declarations. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLFRIEND_H +#define LLVM_CLANG_AST_DECLFRIEND_H + +#include "clang/AST/DeclCXX.h" +#include "llvm/Support/Compiler.h" + +namespace clang { + +/// FriendDecl - Represents the declaration of a friend entity, +/// which can be a function, a type, or a templated function or type. +// For example: +/// +/// @code +/// template class A { +/// friend int foo(T); +/// friend class B; +/// friend T; // only in C++0x +/// template friend class C; +/// template friend A& operator+=(A&, const U&) { ... } +/// }; +/// @endcode +/// +/// The semantic context of a friend decl is its declaring class. +class FriendDecl : public Decl { + virtual void anchor(); +public: + typedef llvm::PointerUnion FriendUnion; + +private: + // The declaration that's a friend of this class. + FriendUnion Friend; + + // A pointer to the next friend in the sequence. + LazyDeclPtr NextFriend; + + // Location of the 'friend' specifier. + SourceLocation FriendLoc; + + /// True if this 'friend' declaration is unsupported. Eventually we + /// will support every possible friend declaration, but for now we + /// silently ignore some and set this flag to authorize all access. + bool UnsupportedFriend; + + 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(), + FriendLoc(FriendL), + UnsupportedFriend(false) { + } + + explicit FriendDecl(EmptyShell Empty) + : Decl(Decl::Friend, Empty), NextFriend() { } + + FriendDecl *getNextFriend() { + return cast_or_null( + NextFriend.get(getASTContext().getExternalSource())); + } + +public: + static FriendDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, FriendUnion Friend_, + SourceLocation FriendL); + static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// If this friend declaration names an (untemplated but possibly + /// dependent) type, return the type; otherwise return null. This + /// is used for elaborated-type-specifiers and, in C++0x, for + /// arbitrary friend type declarations. + TypeSourceInfo *getFriendType() const { + return Friend.dyn_cast(); + } + + /// If this friend declaration doesn't name a type, return the inner + /// declaration. + NamedDecl *getFriendDecl() const { + return Friend.dyn_cast(); + } + + /// Retrieves the location of the 'friend' keyword. + SourceLocation getFriendLoc() const { + return FriendLoc; + } + + /// Retrieves the source range for the friend declaration. + SourceRange getSourceRange() const LLVM_READONLY { + /* FIXME: consider the case of templates wrt start of range. */ + if (NamedDecl *ND = getFriendDecl()) + return SourceRange(getFriendLoc(), ND->getLocEnd()); + else if (TypeSourceInfo *TInfo = getFriendType()) + return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc()); + else + return SourceRange(getFriendLoc(), getLocation()); + } + + /// Determines if this friend kind is unsupported. + bool isUnsupportedFriend() const { + return UnsupportedFriend; + } + void setUnsupportedFriend(bool Unsupported) { + UnsupportedFriend = Unsupported; + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const FriendDecl *D) { return true; } + static bool classofKind(Kind K) { return K == Decl::Friend; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// An iterator over the friend declarations of a class. +class CXXRecordDecl::friend_iterator { + FriendDecl *Ptr; + + friend class CXXRecordDecl; + explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {} +public: + friend_iterator() {} + + typedef FriendDecl *value_type; + typedef FriendDecl *reference; + typedef FriendDecl *pointer; + typedef int difference_type; + typedef std::forward_iterator_tag iterator_category; + + reference operator*() const { return Ptr; } + + friend_iterator &operator++() { + assert(Ptr && "attempt to increment past end of friend list"); + Ptr = Ptr->getNextFriend(); + return *this; + } + + friend_iterator operator++(int) { + friend_iterator tmp = *this; + ++*this; + return tmp; + } + + bool operator==(const friend_iterator &Other) const { + return Ptr == Other.Ptr; + } + + bool operator!=(const friend_iterator &Other) const { + return Ptr != Other.Ptr; + } + + friend_iterator &operator+=(difference_type N) { + assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator"); + while (N--) + ++*this; + return *this; + } + + friend_iterator operator+(difference_type N) const { + friend_iterator tmp = *this; + tmp += N; + return tmp; + } +}; + +inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const { + return friend_iterator(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/clang/include/clang/AST/DeclGroup.h b/clang/include/clang/AST/DeclGroup.h new file mode 100644 index 0000000..63cdac5 --- /dev/null +++ b/clang/include/clang/AST/DeclGroup.h @@ -0,0 +1,151 @@ +//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLGROUP_H +#define LLVM_CLANG_AST_DECLGROUP_H + +#include "llvm/Support/DataTypes.h" +#include + +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); + + unsigned size() const { return NumDecls; } + + Decl*& operator[](unsigned i) { + assert (i < NumDecls && "Out-of-bounds access."); + return ((Decl**) (this+1))[i]; + } + + Decl* const& operator[](unsigned i) const { + assert (i < NumDecls && "Out-of-bounds access."); + return ((Decl* const*) (this+1))[i]; + } +}; + +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(D) & Mask); + } + +public: + DeclGroupRef() : D(0) {} + + explicit DeclGroupRef(Decl* d) : D(d) {} + explicit DeclGroupRef(DeclGroup* dg) + : D((Decl*) (reinterpret_cast(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(this)->getSingleDecl(); + } + + DeclGroup &getDeclGroup() { + assert(isDeclGroup() && "Isn't a declgroup"); + return *((DeclGroup*)(reinterpret_cast(D) & ~Mask)); + } + const DeclGroup &getDeclGroup() const { + return const_cast(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(Ptr); + return X; + } +}; + +} // end clang namespace + +namespace llvm { + // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits. + template + class PointerLikeTypeTraits; + template <> + class PointerLikeTypeTraits { + 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/clang/include/clang/AST/DeclLookups.h b/clang/include/clang/AST/DeclLookups.h new file mode 100644 index 0000000..b8abe97 --- /dev/null +++ b/clang/include/clang/AST/DeclLookups.h @@ -0,0 +1,88 @@ +//===-- DeclLookups.h - Low-level interface to all names in a DC-*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines DeclContext::all_lookups_iterator. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H +#define LLVM_CLANG_AST_DECLLOOKUPS_H + +#include "clang/AST/DeclBase.h" +#include "clang/AST/DeclContextInternals.h" +#include "clang/AST/DeclarationName.h" + +namespace clang { + +/// all_lookups_iterator - An iterator that provides a view over the results +/// of looking up every possible name. +class DeclContext::all_lookups_iterator { + StoredDeclsMap::iterator It, End; +public: + typedef lookup_result value_type; + typedef lookup_result reference; + typedef lookup_result pointer; + typedef std::forward_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + all_lookups_iterator() {} + all_lookups_iterator(StoredDeclsMap::iterator It, + StoredDeclsMap::iterator End) + : It(It), End(End) {} + + reference operator*() const { return It->second.getLookupResult(); } + pointer operator->() const { return It->second.getLookupResult(); } + + all_lookups_iterator& operator++() { + // Filter out using directives. They don't belong as results from name + // lookup anyways, except as an implementation detail. Users of the API + // should not expect to get them (or worse, rely on it). + do { + ++It; + } while (It != End && + It->first == DeclarationName::getUsingDirectiveName()); + + return *this; + } + + all_lookups_iterator operator++(int) { + all_lookups_iterator tmp(*this); + ++(*this); + return tmp; + } + + friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) { + return x.It == y.It; + } + friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) { + return x.It != y.It; + } +}; + +DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { + DeclContext *Primary = const_cast(this)->getPrimaryContext(); + if (hasExternalVisibleStorage()) + getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary); + if (StoredDeclsMap *Map = Primary->buildLookup()) + return all_lookups_iterator(Map->begin(), Map->end()); + return all_lookups_iterator(); +} + +DeclContext::all_lookups_iterator DeclContext::lookups_end() const { + DeclContext *Primary = const_cast(this)->getPrimaryContext(); + if (hasExternalVisibleStorage()) + getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary); + if (StoredDeclsMap *Map = Primary->buildLookup()) + return all_lookups_iterator(Map->end(), Map->end()); + return all_lookups_iterator(); +} + +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h new file mode 100644 index 0000000..4ae073e --- /dev/null +++ b/clang/include/clang/AST/DeclObjC.h @@ -0,0 +1,1988 @@ +//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the DeclObjC interface and subclasses. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLOBJC_H +#define LLVM_CLANG_AST_DECLOBJC_H + +#include "clang/AST/Decl.h" +#include "clang/AST/SelectorLocationsKind.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Compiler.h" + +namespace clang { +class Expr; +class Stmt; +class FunctionDecl; +class RecordDecl; +class ObjCIvarDecl; +class ObjCMethodDecl; +class ObjCProtocolDecl; +class ObjCCategoryDecl; +class ObjCPropertyDecl; +class ObjCPropertyImplDecl; +class CXXCtorInitializer; + +class ObjCListBase { + 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) {} + 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 +class ObjCList : public ObjCListBase { +public: + void set(T* const* InList, unsigned Elts, ASTContext &Ctx) { + ObjCListBase::set(reinterpret_cast(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 { + SourceLocation *Locations; + + using ObjCList::set; + +public: + ObjCProtocolList() : ObjCList(), 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); +}; + + +/// ObjCMethodDecl - Represents an instance or class method declaration. +/// ObjC methods can be declared within 4 contexts: class interfaces, +/// categories, protocols, and class implementations. While C++ member +/// functions leverage C syntax, Objective-C method syntax is modeled after +/// Smalltalk (using colons to specify argument types/expressions). +/// Here are some brief examples: +/// +/// Setter/getter instance methods: +/// - (void)setMenu:(NSMenu *)menu; +/// - (NSMenu *)menu; +/// +/// Instance method that takes 2 NSView arguments: +/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView; +/// +/// Getter class method: +/// + (NSMenu *)defaultMenu; +/// +/// A selector represents a unique name for a method. The selector names for +/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. +/// +class ObjCMethodDecl : public NamedDecl, public DeclContext { +public: + enum ImplementationControl { None, Required, Optional }; +private: + // The conventional meaning of this method; an ObjCMethodFamily. + // This is not serialized; instead, it is computed on demand and + // cached. + mutable unsigned Family : ObjCMethodFamilyBitWidth; + + /// instance (true) or class (false) method. + unsigned IsInstance : 1; + unsigned IsVariadic : 1; + + // Synthesized declaration method for a property setter/getter + unsigned IsSynthesized : 1; + + // Method has a definition. + unsigned IsDefined : 1; + + /// \brief Method redeclaration in the same interface. + unsigned IsRedeclaration : 1; + + /// \brief Is redeclared in the same interface. + mutable unsigned HasRedeclaration : 1; + + // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum + /// @required/@optional + unsigned DeclImplementation : 2; + + // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum + /// in, inout, etc. + unsigned objcDeclQualifier : 6; + + /// \brief Indicates whether this method has a related result type. + unsigned RelatedResultType : 1; + + /// \brief Whether the locations of the selector identifiers are in a + /// "standard" position, a enum SelectorLocationsKind. + unsigned SelLocsKind : 2; + + // Result type of this method. + QualType MethodDeclType; + + // Type source information for the result type. + TypeSourceInfo *ResultTInfo; + + /// \brief Array of ParmVarDecls for the formal parameters of this method + /// and optionally followed by selector locations. + void *ParamsAndSelLocs; + unsigned NumParams; + + /// List of attributes for this method declaration. + SourceLocation 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; + + SelectorLocationsKind getSelLocsKind() const { + return (SelectorLocationsKind)SelLocsKind; + } + bool hasStandardSelLocs() const { + return getSelLocsKind() != SelLoc_NonStandard; + } + + /// \brief Get a pointer to the stored selector identifiers locations array. + /// No locations will be stored if HasStandardSelLocs is true. + SourceLocation *getStoredSelLocs() { + return reinterpret_cast(getParams() + NumParams); + } + const SourceLocation *getStoredSelLocs() const { + return reinterpret_cast(getParams() + NumParams); + } + + /// \brief Get a pointer to the stored selector identifiers locations array. + /// No locations will be stored if HasStandardSelLocs is true. + ParmVarDecl **getParams() { + return reinterpret_cast(ParamsAndSelLocs); + } + const ParmVarDecl *const *getParams() const { + return reinterpret_cast(ParamsAndSelLocs); + } + + /// \brief Get the number of stored selector identifiers locations. + /// No locations will be stored if HasStandardSelLocs is true. + unsigned getNumStoredSelLocs() const { + if (hasStandardSelLocs()) + return 0; + return getNumSelectorLocs(); + } + + void setParamsAndSelLocs(ASTContext &C, + ArrayRef Params, + ArrayRef SelLocs); + + ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, + Selector SelInfo, QualType T, + TypeSourceInfo *ResultTInfo, + DeclContext *contextDecl, + bool isInstance = true, + bool isVariadic = false, + bool isSynthesized = false, + bool isImplicitlyDeclared = false, + bool isDefined = false, + ImplementationControl impControl = None, + bool HasRelatedResultType = false) + : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), + DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), + IsInstance(isInstance), IsVariadic(isVariadic), + IsSynthesized(isSynthesized), + IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0), + DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), + RelatedResultType(HasRelatedResultType), + SelLocsKind(SelLoc_StandardNoSpace), + MethodDeclType(T), ResultTInfo(ResultTInfo), + ParamsAndSelLocs(0), NumParams(0), + EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) { + setImplicit(isImplicitlyDeclared); + } + + /// \brief A definition will return its interface declaration. + /// An interface declaration will return its definition. + /// Otherwise it will return itself. + virtual ObjCMethodDecl *getNextRedeclaration(); + +public: + static ObjCMethodDecl *Create(ASTContext &C, + SourceLocation beginLoc, + SourceLocation endLoc, + Selector SelInfo, + QualType T, + TypeSourceInfo *ResultTInfo, + DeclContext *contextDecl, + bool isInstance = true, + bool isVariadic = false, + bool isSynthesized = false, + bool isImplicitlyDeclared = false, + bool isDefined = false, + ImplementationControl impControl = None, + bool HasRelatedResultType = false); + + static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + virtual ObjCMethodDecl *getCanonicalDecl(); + const ObjCMethodDecl *getCanonicalDecl() const { + return const_cast(this)->getCanonicalDecl(); + } + + ObjCDeclQualifier getObjCDeclQualifier() const { + return ObjCDeclQualifier(objcDeclQualifier); + } + void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; } + + /// \brief Determine whether this method has a result type that is related + /// to the message receiver's type. + bool hasRelatedResultType() const { return RelatedResultType; } + + /// \brief Note whether this method has a related result type. + void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; } + + /// \brief True if this is a method redeclaration in the same interface. + bool isRedeclaration() const { return IsRedeclaration; } + void setAsRedeclaration(const ObjCMethodDecl *PrevMethod); + + // Location information, modeled after the Stmt API. + SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); } + SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; } + void setEndLoc(SourceLocation Loc) { EndLoc = Loc; } + virtual SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(getLocation(), EndLoc); + } + + SourceLocation getSelectorStartLoc() const { + if (isImplicit()) + return getLocStart(); + return getSelectorLoc(0); + } + SourceLocation getSelectorLoc(unsigned Index) const { + assert(Index < getNumSelectorLocs() && "Index out of range!"); + if (hasStandardSelLocs()) + return getStandardSelectorLoc(Index, getSelector(), + getSelLocsKind() == SelLoc_StandardWithSpace, + llvm::makeArrayRef(const_cast(getParams()), + NumParams), + EndLoc); + return getStoredSelLocs()[Index]; + } + + void getSelectorLocs(SmallVectorImpl &SelLocs) const; + + unsigned getNumSelectorLocs() const { + if (isImplicit()) + return 0; + Selector Sel = getSelector(); + if (Sel.isUnarySelector()) + return 1; + return Sel.getNumArgs(); + } + + ObjCInterfaceDecl *getClassInterface(); + const ObjCInterfaceDecl *getClassInterface() const { + return const_cast(this)->getClassInterface(); + } + + Selector getSelector() const { return getDeclName().getObjCSelector(); } + + QualType getResultType() const { return MethodDeclType; } + void setResultType(QualType T) { MethodDeclType = T; } + + /// \brief Determine the type of an expression that sends a message to this + /// function. + QualType getSendResultType() const { + return getResultType().getNonLValueExprType(getASTContext()); + } + + TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; } + void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; } + + // Iterator access to formal parameters. + unsigned param_size() const { return NumParams; } + typedef const ParmVarDecl *const *param_const_iterator; + typedef ParmVarDecl *const *param_iterator; + param_const_iterator param_begin() const { return getParams(); } + param_const_iterator param_end() const { return getParams() + NumParams; } + param_iterator param_begin() { return getParams(); } + param_iterator param_end() { return getParams() + NumParams; } + // This method returns and of the parameters which are part of the selector + // name mangling requirements. + param_const_iterator sel_param_end() const { + return param_begin() + getSelector().getNumArgs(); + } + + /// \brief Sets the method's parameters and selector source locations. + /// If the method is implicit (not coming from source) \arg SelLocs is + /// ignored. + void setMethodParams(ASTContext &C, + ArrayRef Params, + ArrayRef SelLocs = + ArrayRef()); + + // Iterator access to parameter types. + typedef std::const_mem_fun_t deref_fun; + typedef llvm::mapped_iterator + 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; } + + /// Determines the family of this method. + ObjCMethodFamily getMethodFamily() const; + + bool isInstanceMethod() const { return IsInstance; } + void setInstanceMethod(bool isInst) { IsInstance = isInst; } + bool isVariadic() const { return IsVariadic; } + void setVariadic(bool isVar) { IsVariadic = isVar; } + + bool isClassMethod() const { return !IsInstance; } + + bool isSynthesized() const { return IsSynthesized; } + void setSynthesized(bool isSynth) { IsSynthesized = isSynth; } + + bool isDefined() const { return IsDefined; } + void setDefined(bool isDefined) { IsDefined = isDefined; } + + // 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(const_cast(D)); + } + static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// ObjCContainerDecl - Represents a container for method declarations. +/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, +/// ObjCProtocolDecl, and ObjCImplDecl. +/// +class ObjCContainerDecl : public NamedDecl, public DeclContext { + virtual void anchor(); + + SourceLocation AtStart; + + // These two locations in the range mark the end of the method container. + // The first points to the '@' token, and the second to the 'end' token. + SourceRange AtEnd; +public: + + ObjCContainerDecl(Kind DK, DeclContext *DC, + IdentifierInfo *Id, SourceLocation nameLoc, + SourceLocation atStartLoc) + : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} + + // Iterator access to properties. + typedef specific_decl_iterator 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 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 + 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 + 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; + + SourceLocation getAtStartLoc() const { return AtStart; } + void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } + + // Marks the end of the container. + SourceRange getAtEndRange() const { + return AtEnd; + } + void setAtEndRange(SourceRange atEnd) { + AtEnd = atEnd; + } + + virtual SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(AtStart, 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 >= firstObjCContainer && + K <= lastObjCContainer; + } + + static DeclContext *castToDeclContext(const ObjCContainerDecl *D) { + return static_cast(const_cast(D)); + } + static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(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 +/// { // 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 + , public Redeclarable { + virtual void anchor(); + + /// TypeForDecl - This indicates the Type object that represents this + /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType + mutable const Type *TypeForDecl; + friend class ASTContext; + + struct DefinitionData { + /// \brief The definition of this class, for quick access from any + /// declaration. + ObjCInterfaceDecl *Definition; + + /// Class's super class. + ObjCInterfaceDecl *SuperClass; + + /// Protocols referenced in the @interface declaration + ObjCProtocolList ReferencedProtocols; + + /// Protocols reference in both the @interface and class extensions. + ObjCList AllReferencedProtocols; + + /// \brief List of categories and class extensions defined for this class. + /// + /// Categories are stored as a linked list in the AST, since the categories + /// and class extensions come long after the initial interface declaration, + /// and we avoid dynamically-resized arrays in the AST wherever possible. + ObjCCategoryDecl *CategoryList; + + /// IvarList - List of all ivars defined by this class; including class + /// extensions and implementation. This list is built lazily. + ObjCIvarDecl *IvarList; + + /// \brief Indicates that the contents of this Objective-C class will be + /// completed by the external AST source when required. + mutable bool ExternallyCompleted : 1; + + /// \brief The location of the superclass, if any. + SourceLocation SuperClassLoc; + + /// \brief The location of the last location in this declaration, before + /// the properties/methods. For example, this will be the '>', '}', or + /// identifier, + SourceLocation EndLoc; + + DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), + ExternallyCompleted() { } + }; + + ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, + SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, + bool isInternal); + + void LoadExternalDefinition() const; + + /// \brief Contains a pointer to the data associated with this class, + /// which will be NULL if this class has not yet been defined. + DefinitionData *Data; + + DefinitionData &data() const { + assert(Data != 0 && "Declaration has no definition!"); + return *Data; + } + + /// \brief Allocate the definition data for this class. + void allocateDefinitionData(); + + typedef Redeclarable redeclarable_base; + virtual ObjCInterfaceDecl *getNextRedeclaration() { + return RedeclLink.getNext(); + } + virtual ObjCInterfaceDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual ObjCInterfaceDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + +public: + static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC, + SourceLocation atLoc, + IdentifierInfo *Id, + ObjCInterfaceDecl *PrevDecl, + SourceLocation ClassLoc = SourceLocation(), + bool isInternal = false); + + static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + virtual SourceRange getSourceRange() const LLVM_READONLY { + if (isThisDeclarationADefinition()) + return ObjCContainerDecl::getSourceRange(); + + return SourceRange(getAtStartLoc(), getLocation()); + } + + /// \brief Indicate that this Objective-C class is complete, but that + /// the external AST source will be responsible for filling in its contents + /// when a complete class is required. + void setExternallyCompleted(); + + const ObjCProtocolList &getReferencedProtocols() const { + assert(hasDefinition() && "Caller did not check for forward reference!"); + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().ReferencedProtocols; + } + + ObjCImplementationDecl *getImplementation() const; + void setImplementation(ObjCImplementationDecl *ImplD); + + ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const; + + // Get the local instance/class method declared in a category. + ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const; + ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const; + ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const { + return isInstance ? getInstanceMethod(Sel) + : getClassMethod(Sel); + } + + typedef ObjCProtocolList::iterator protocol_iterator; + + protocol_iterator protocol_begin() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return protocol_iterator(); + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().ReferencedProtocols.begin(); + } + protocol_iterator protocol_end() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return protocol_iterator(); + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().ReferencedProtocols.end(); + } + + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + + protocol_loc_iterator protocol_loc_begin() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return protocol_loc_iterator(); + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().ReferencedProtocols.loc_begin(); + } + + protocol_loc_iterator protocol_loc_end() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return protocol_loc_iterator(); + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().ReferencedProtocols.loc_end(); + } + + typedef ObjCList::iterator all_protocol_iterator; + + all_protocol_iterator all_referenced_protocol_begin() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return all_protocol_iterator(); + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().AllReferencedProtocols.empty() + ? protocol_begin() + : data().AllReferencedProtocols.begin(); + } + all_protocol_iterator all_referenced_protocol_end() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return all_protocol_iterator(); + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().AllReferencedProtocols.empty() + ? protocol_end() + : data().AllReferencedProtocols.end(); + } + + typedef specific_decl_iterator ivar_iterator; + + ivar_iterator ivar_begin() const { + if (const ObjCInterfaceDecl *Def = getDefinition()) + return ivar_iterator(Def->decls_begin()); + + // FIXME: Should make sure no callers ever do this. + return ivar_iterator(); + } + ivar_iterator ivar_end() const { + if (const ObjCInterfaceDecl *Def = getDefinition()) + return ivar_iterator(Def->decls_end()); + + // FIXME: Should make sure no callers ever do this. + return ivar_iterator(); + } + + unsigned ivar_size() const { + return std::distance(ivar_begin(), ivar_end()); + } + + bool ivar_empty() const { return ivar_begin() == ivar_end(); } + + ObjCIvarDecl *all_declared_ivar_begin(); + const ObjCIvarDecl *all_declared_ivar_begin() const { + // Even though this modifies IvarList, it's conceptually const: + // the ivar chain is essentially a cached property of ObjCInterfaceDecl. + return const_cast(this)->all_declared_ivar_begin(); + } + void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; } + + /// setProtocolList - Set the list of protocols that this interface + /// implements. + void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num, + const SourceLocation *Locs, ASTContext &C) { + data().ReferencedProtocols.set(List, Num, Locs, C); + } + + /// mergeClassExtensionProtocolList - Merge class extension's protocol list + /// into the protocol list for this class. + void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, + unsigned Num, + ASTContext &C); + + /// \brief Determine whether this particular declaration of this class is + /// actually also a definition. + bool isThisDeclarationADefinition() const { + return Data && Data->Definition == this; + } + + /// \brief Determine whether this class has been defined. + bool hasDefinition() const { return Data; } + + /// \brief Retrieve the definition of this class, or NULL if this class + /// has been forward-declared (with @class) but not yet defined (with + /// @interface). + ObjCInterfaceDecl *getDefinition() { + return hasDefinition()? Data->Definition : 0; + } + + /// \brief Retrieve the definition of this class, or NULL if this class + /// has been forward-declared (with @class) but not yet defined (with + /// @interface). + const ObjCInterfaceDecl *getDefinition() const { + return hasDefinition()? Data->Definition : 0; + } + + /// \brief Starts the definition of this Objective-C class, taking it from + /// a forward declaration (@class) to a definition (@interface). + void startDefinition(); + + ObjCInterfaceDecl *getSuperClass() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().SuperClass; + } + + void setSuperClass(ObjCInterfaceDecl * superCls) { + data().SuperClass = + (superCls && superCls->hasDefinition()) ? superCls->getDefinition() + : superCls; + } + + ObjCCategoryDecl* getCategoryList() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + return data().CategoryList; + } + + void setCategoryList(ObjCCategoryDecl *category) { + data().CategoryList = category; + } + + ObjCCategoryDecl* getFirstClassExtension() 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 (declaresSameEntity(this, I)) + return true; + + I = I->getSuperClass(); + } + return false; + } + + /// isArcWeakrefUnavailable - Checks for a class or one of its super classes + /// to be incompatible with __weak references. Returns true if it is. + bool isArcWeakrefUnavailable() const { + const ObjCInterfaceDecl *Class = this; + while (Class) { + if (Class->hasAttr()) + return true; + Class = Class->getSuperClass(); + } + return false; + } + + /// isObjCRequiresPropertyDefs - Checks that a class or one of its super + /// classes must not be auto-synthesized. Returns class decl. if it must not be; + /// 0, otherwise. + const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const { + const ObjCInterfaceDecl *Class = this; + while (Class) { + if (Class->hasAttr()) + return Class; + Class = Class->getSuperClass(); + } + return 0; + } + + 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, + bool shallowCategoryLookup= false) const; + ObjCMethodDecl *lookupInstanceMethod(Selector Sel, + bool shallowCategoryLookup = false) const { + return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup); + } + ObjCMethodDecl *lookupClassMethod(Selector Sel, + bool shallowCategoryLookup = false) const { + return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup); + } + ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); + + // Lookup a method in the classes implementation hierarchy. + ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, bool Instance=true); + + SourceLocation getEndOfDefinitionLoc() const { + if (!hasDefinition()) + return getLocation(); + + return data().EndLoc; + } + + void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; } + + void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; } + SourceLocation getSuperClassLoc() const { return data().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 hasDefinition() ? Data->Definition->isImplicit() : isImplicit(); + } + + /// ClassImplementsProtocol - Checks that 'lProto' protocol + /// has been implemented in IDecl class, its super class or categories (if + /// lookupCategory is true). + bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, + bool lookupCategory, + bool RHSIsQualifiedID = false); + + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + /// Retrieves the canonical declaration of this Objective-C class. + ObjCInterfaceDecl *getCanonicalDecl() { + return getFirstDeclaration(); + } + const ObjCInterfaceDecl *getCanonicalDecl() const { + return getFirstDeclaration(); + } + + // Low-level accessor + const Type *getTypeForDecl() const { return TypeForDecl; } + void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const ObjCInterfaceDecl *D) { return true; } + static bool classofKind(Kind K) { return K == ObjCInterface; } + + friend class ASTReader; + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// 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 { + virtual void anchor(); + +public: + enum AccessControl { + None, Private, Protected, Public, Package + }; + +private: + ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, + bool synthesized) + : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, + /*Mutable=*/false, /*HasInit=*/false), + NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {} + +public: + static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, + AccessControl ac, Expr *BW = NULL, + bool synthesized=false); + + static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// \brief Return the class interface that this ivar is logically contained + /// in; this is either the interface where the ivar was declared, or the + /// interface the ivar is conceptually a part of in the case of synthesized + /// ivars. + const ObjCInterfaceDecl *getContainingInterface() const; + + ObjCIvarDecl *getNextIvar() { return NextIvar; } + const ObjCIvarDecl *getNextIvar() const { return NextIvar; } + void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; } + + void setAccessControl(AccessControl ac) { DeclAccess = ac; } + + AccessControl getAccessControl() const { return AccessControl(DeclAccess); } + + AccessControl getCanonicalAccessControl() const { + return DeclAccess == None ? Protected : AccessControl(DeclAccess); + } + + void setSynthesize(bool synth) { Synthesized = synth; } + bool getSynthesize() const { return Synthesized; } + + // 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: + /// NextIvar - Next Ivar in the list of ivars declared in class; class's + /// extensions and class's implementation + ObjCIvarDecl *NextIvar; + + // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum + unsigned DeclAccess : 3; + unsigned Synthesized : 1; +}; + + +/// ObjCAtDefsFieldDecl - Represents a field declaration created by an +/// @defs(...). +class ObjCAtDefsFieldDecl : public FieldDecl { + virtual void anchor(); + ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T, Expr *BW) + : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T, + /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ? + BW, /*Mutable=*/false, /*HasInit=*/false) {} + +public: + static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T, Expr *BW); + + static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool 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 originally drew inspiration from C++ pure virtual functions (a C++ +/// feature with nice semantics and lousy syntax:-). Here is an example: +/// +/// @protocol NSDraggingInfo +/// - (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 +/// @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 anyObjectThatImplementsNSDraggingInfo; +/// +class ObjCProtocolDecl : public ObjCContainerDecl, + public Redeclarable { + virtual void anchor(); + + struct DefinitionData { + // \brief The declaration that defines this protocol. + ObjCProtocolDecl *Definition; + + /// \brief Referenced protocols + ObjCProtocolList ReferencedProtocols; + }; + + DefinitionData *Data; + + DefinitionData &data() const { + assert(Data && "Objective-C protocol has no definition!"); + return *Data; + } + + ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, + SourceLocation nameLoc, SourceLocation atStartLoc, + ObjCProtocolDecl *PrevDecl); + + void allocateDefinitionData(); + + typedef Redeclarable redeclarable_base; + virtual ObjCProtocolDecl *getNextRedeclaration() { + return RedeclLink.getNext(); + } + virtual ObjCProtocolDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual ObjCProtocolDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + +public: + static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, + IdentifierInfo *Id, + SourceLocation nameLoc, + SourceLocation atStartLoc, + ObjCProtocolDecl *PrevDecl); + + static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + const ObjCProtocolList &getReferencedProtocols() const { + assert(hasDefinition() && "No definition available!"); + return data().ReferencedProtocols; + } + typedef ObjCProtocolList::iterator protocol_iterator; + protocol_iterator protocol_begin() const { + if (!hasDefinition()) + return protocol_iterator(); + + return data().ReferencedProtocols.begin(); + } + protocol_iterator protocol_end() const { + if (!hasDefinition()) + return protocol_iterator(); + + return data().ReferencedProtocols.end(); + } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + if (!hasDefinition()) + return protocol_loc_iterator(); + + return data().ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + if (!hasDefinition()) + return protocol_loc_iterator(); + + return data().ReferencedProtocols.loc_end(); + } + unsigned protocol_size() const { + if (!hasDefinition()) + return 0; + + return data().ReferencedProtocols.size(); + } + + /// setProtocolList - Set the list of protocols that this interface + /// implements. + void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, + const SourceLocation *Locs, ASTContext &C) { + assert(Data && "Protocol is not defined"); + data().ReferencedProtocols.set(List, Num, Locs, C); + } + + ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName); + + // Lookup a method. First, we search locally. If a method isn't + // found, we search referenced protocols and class categories. + ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const; + ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { + return lookupMethod(Sel, true/*isInstance*/); + } + ObjCMethodDecl *lookupClassMethod(Selector Sel) const { + return lookupMethod(Sel, false/*isInstance*/); + } + + /// \brief Determine whether this protocol has a definition. + bool hasDefinition() const { return Data != 0; } + + /// \brief Retrieve the definition of this protocol, if any. + ObjCProtocolDecl *getDefinition() { + return Data? Data->Definition : 0; + } + + /// \brief Retrieve the definition of this protocol, if any. + const ObjCProtocolDecl *getDefinition() const { + return Data? Data->Definition : 0; + } + + /// \brief Determine whether this particular declaration is also the + /// definition. + bool isThisDeclarationADefinition() const { + return getDefinition() == this; + } + + /// \brief Starts the definition of this Objective-C protocol. + void startDefinition(); + + virtual SourceRange getSourceRange() const LLVM_READONLY { + if (isThisDeclarationADefinition()) + return ObjCContainerDecl::getSourceRange(); + + return SourceRange(getAtStartLoc(), getLocation()); + } + + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + /// Retrieves the canonical declaration of this Objective-C protocol. + ObjCProtocolDecl *getCanonicalDecl() { + return getFirstDeclaration(); + } + const ObjCProtocolDecl *getCanonicalDecl() const { + return getFirstDeclaration(); + } + + 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; } + + friend class ASTReader; + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// ObjCCategoryDecl - Represents a category declaration. A category allows +/// you to add methods to an existing class (without subclassing or modifying +/// the original class interface or implementation:-). Categories don't allow +/// you to add instance data. The following example adds "myMethod" to all +/// NSView's within a process: +/// +/// @interface NSView (MyViewMethods) +/// - myMethod; +/// @end +/// +/// Categories also allow you to split the implementation of a class across +/// several files (a feature more naturally supported in C++). +/// +/// Categories were originally inspired by dynamic languages such as Common +/// Lisp and Smalltalk. More traditional class-based languages (C++, Java) +/// don't support this level of dynamism, which is both powerful and dangerous. +/// +class ObjCCategoryDecl : public ObjCContainerDecl { + virtual void anchor(); + + /// 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; + + /// true of class extension has at least one bitfield ivar. + bool HasSynthBitfield : 1; + + /// \brief The location of the category name in this declaration. + SourceLocation CategoryNameLoc; + + /// class extension may have private ivars. + SourceLocation IvarLBraceLoc; + SourceLocation IvarRBraceLoc; + + ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, + SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, + IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, + SourceLocation IvarLBraceLoc=SourceLocation(), + SourceLocation IvarRBraceLoc=SourceLocation()) + : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), + ClassInterface(IDecl), NextClassCategory(0), HasSynthBitfield(false), + CategoryNameLoc(CategoryNameLoc), + IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { + } +public: + + static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation AtLoc, + SourceLocation ClassNameLoc, + SourceLocation CategoryNameLoc, + IdentifierInfo *Id, + ObjCInterfaceDecl *IDecl, + SourceLocation IvarLBraceLoc=SourceLocation(), + SourceLocation IvarRBraceLoc=SourceLocation()); + static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } + const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } + + 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; } + + bool IsClassExtension() const { return getIdentifier() == 0; } + const ObjCCategoryDecl *getNextClassExtension() const; + + bool hasSynthBitfield() const { return HasSynthBitfield; } + void setHasSynthBitfield (bool val) { HasSynthBitfield = val; } + + typedef specific_decl_iterator 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 getCategoryNameLoc() const { return CategoryNameLoc; } + void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; } + + void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } + SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } + void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } + SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const ObjCCategoryDecl *D) { return true; } + static bool classofKind(Kind K) { return K == ObjCCategory; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +class ObjCImplDecl : public ObjCContainerDecl { + virtual void anchor(); + + /// Class interface for this class/category implementation + ObjCInterfaceDecl *ClassInterface; + +protected: + ObjCImplDecl(Kind DK, DeclContext *DC, + ObjCInterfaceDecl *classInterface, + SourceLocation nameLoc, SourceLocation atStartLoc) + : ObjCContainerDecl(DK, DC, + classInterface? classInterface->getIdentifier() : 0, + nameLoc, atStartLoc), + ClassInterface(classInterface) {} + +public: + const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } + ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } + void setClassInterface(ObjCInterfaceDecl *IFace); + + void addInstanceMethod(ObjCMethodDecl *method) { + // FIXME: Context should be set correctly before we get here. + method->setLexicalDeclContext(this); + addDecl(method); + } + void addClassMethod(ObjCMethodDecl *method) { + // FIXME: Context should be set correctly before we get here. + method->setLexicalDeclContext(this); + addDecl(method); + } + + void addPropertyImplementation(ObjCPropertyImplDecl *property); + + ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; + ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; + + // Iterator access to properties. + typedef specific_decl_iterator 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 >= firstObjCImpl && K <= lastObjCImpl; + } +}; + +/// ObjCCategoryImplDecl - An object of this class encapsulates a category +/// @implementation declaration. If a category class has declaration of a +/// property, its implementation must be specified in the category's +/// @implementation declaration. Example: +/// @interface I @end +/// @interface I(CATEGORY) +/// @property int p1, d1; +/// @end +/// @implementation I(CATEGORY) +/// @dynamic p1,d1; +/// @end +/// +/// ObjCCategoryImplDecl +class ObjCCategoryImplDecl : public ObjCImplDecl { + virtual void anchor(); + + // Category name + IdentifierInfo *Id; + + // Category name location + SourceLocation CategoryNameLoc; + + ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id, + ObjCInterfaceDecl *classInterface, + SourceLocation nameLoc, SourceLocation atStartLoc, + SourceLocation CategoryNameLoc) + : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc), + Id(Id), CategoryNameLoc(CategoryNameLoc) {} +public: + static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, + IdentifierInfo *Id, + ObjCInterfaceDecl *classInterface, + SourceLocation nameLoc, + SourceLocation atStartLoc, + SourceLocation CategoryNameLoc); + static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// getIdentifier - Get the identifier that names the category + /// interface associated with this implementation. + /// FIXME: This is a bad API, we are 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; + + SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } + + /// getName - Get the name of identifier for the class interface associated + /// with this implementation as a StringRef. + // + // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean + // something different. + 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;} + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID); + +/// ObjCImplementationDecl - Represents a class definition - this is where +/// method definitions are specified. For example: +/// +/// @code +/// @implementation MyClass +/// - (void)myMethod { /* do something */ } +/// @end +/// @endcode +/// +/// 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 { + virtual void anchor(); + /// Implementation Class's super class. + ObjCInterfaceDecl *SuperClass; + /// @implementation may have private ivars. + SourceLocation IvarLBraceLoc; + SourceLocation IvarRBraceLoc; + + /// Support for ivar initialization. + /// IvarInitializers - The arguments used to initialize the ivars + CXXCtorInitializer **IvarInitializers; + unsigned NumIvarInitializers; + + /// true if class has a .cxx_[construct,destruct] method. + bool HasCXXStructors : 1; + + /// true of class extension has at least one bitfield ivar. + bool HasSynthBitfield : 1; + + ObjCImplementationDecl(DeclContext *DC, + ObjCInterfaceDecl *classInterface, + ObjCInterfaceDecl *superDecl, + SourceLocation nameLoc, SourceLocation atStartLoc, + SourceLocation IvarLBraceLoc=SourceLocation(), + SourceLocation IvarRBraceLoc=SourceLocation()) + : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), + SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc), + IvarRBraceLoc(IvarRBraceLoc), + IvarInitializers(0), NumIvarInitializers(0), + HasCXXStructors(false), HasSynthBitfield(false){} +public: + static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, + ObjCInterfaceDecl *classInterface, + ObjCInterfaceDecl *superDecl, + SourceLocation nameLoc, + SourceLocation atStartLoc, + SourceLocation IvarLBraceLoc=SourceLocation(), + SourceLocation IvarRBraceLoc=SourceLocation()); + + static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// init_iterator - Iterates through the ivar initializer list. + typedef CXXCtorInitializer **init_iterator; + + /// init_const_iterator - Iterates through the ivar initializer list. + typedef CXXCtorInitializer * const * init_const_iterator; + + /// 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, + CXXCtorInitializer ** initializers, + unsigned numInitializers); + + bool hasCXXStructors() const { return HasCXXStructors; } + void setHasCXXStructors(bool val) { HasCXXStructors = val; } + + bool hasSynthBitfield() const { return HasSynthBitfield; } + void setHasSynthBitfield (bool val) { HasSynthBitfield = val; } + + /// getIdentifier - Get the identifier that names the class + /// interface associated with this implementation. + IdentifierInfo *getIdentifier() const { + return getClassInterface()->getIdentifier(); + } + + /// getName - Get the name of identifier for the class interface associated + /// with this implementation as a StringRef. + // + // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean + // something different. + 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; } + + void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } + SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } + void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } + SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } + + typedef specific_decl_iterator 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; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID); + +/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is +/// declared as @compatibility_alias alias class. +class ObjCCompatibleAliasDecl : public NamedDecl { + virtual void anchor(); + /// Class that this is an alias of. + ObjCInterfaceDecl *AliasedClass; + + ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, + ObjCInterfaceDecl* aliasedClass) + : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {} +public: + static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, + ObjCInterfaceDecl* aliasedClass); + + static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } + ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } + void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool 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 { + virtual void anchor(); +public: + enum PropertyAttributeKind { + OBJC_PR_noattr = 0x00, + OBJC_PR_readonly = 0x01, + OBJC_PR_getter = 0x02, + OBJC_PR_assign = 0x04, + OBJC_PR_readwrite = 0x08, + OBJC_PR_retain = 0x10, + OBJC_PR_copy = 0x20, + OBJC_PR_nonatomic = 0x40, + OBJC_PR_setter = 0x80, + OBJC_PR_atomic = 0x100, + OBJC_PR_weak = 0x200, + OBJC_PR_strong = 0x400, + OBJC_PR_unsafe_unretained = 0x800 + // Adding a property should change NumPropertyAttrsBits + }; + + enum { + /// \brief Number of bits fitting all the property attributes. + NumPropertyAttrsBits = 12 + }; + + enum SetterKind { Assign, Retain, Copy, Weak }; + enum PropertyControl { None, Required, Optional }; +private: + SourceLocation AtLoc; // location of @property + SourceLocation LParenLoc; // location of '(' starting attribute list or null. + TypeSourceInfo *DeclType; + unsigned PropertyAttributes : NumPropertyAttrsBits; + unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; + // @required/@optional + unsigned PropertyImplementation : 2; + + Selector GetterName; // getter name of NULL if no getter + Selector SetterName; // setter name of NULL if no setter + + ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method + ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method + ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property + + ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, + SourceLocation AtLocation, SourceLocation LParenLocation, + TypeSourceInfo *T) + : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), + LParenLoc(LParenLocation), DeclType(T), + PropertyAttributes(OBJC_PR_noattr), + PropertyAttributesAsWritten(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, + SourceLocation LParenLocation, + TypeSourceInfo *T, + PropertyControl propControl = None); + + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } + + SourceLocation getLParenLoc() const { return LParenLoc; } + void setLParenLoc(SourceLocation L) { LParenLoc = L; } + + TypeSourceInfo *getTypeSourceInfo() const { return DeclType; } + QualType getType() const { return DeclType->getType(); } + void setType(TypeSourceInfo *T) { DeclType = T; } + + PropertyAttributeKind getPropertyAttributes() const { + return PropertyAttributeKind(PropertyAttributes); + } + void setPropertyAttributes(PropertyAttributeKind PRVal) { + PropertyAttributes |= PRVal; + } + + PropertyAttributeKind getPropertyAttributesAsWritten() const { + return PropertyAttributeKind(PropertyAttributesAsWritten); + } + + bool hasWrittenStorageAttribute() const { + return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy | + OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong | + OBJC_PR_weak); + } + + void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { + PropertyAttributesAsWritten = 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); + } + + /// isAtomic - Return true if the property is atomic. + bool isAtomic() const { + return (PropertyAttributes & OBJC_PR_atomic); + } + + /// isRetaining - Return true if the property retains its value. + bool isRetaining() const { + return (PropertyAttributes & + (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); + } + + /// getSetterKind - Return the method used for doing assignment in + /// the property setter. This is only valid if the property has been + /// defined to have a setter. + SetterKind getSetterKind() const { + if (PropertyAttributes & OBJC_PR_strong) + return getType()->isBlockPointerType() ? Copy : Retain; + if (PropertyAttributes & OBJC_PR_retain) + return Retain; + if (PropertyAttributes & OBJC_PR_copy) + return Copy; + if (PropertyAttributes & OBJC_PR_weak) + return Weak; + return Assign; + } + + Selector getGetterName() const { return GetterName; } + void setGetterName(Selector Sel) { GetterName = Sel; } + + Selector getSetterName() const { return SetterName; } + void setSetterName(Selector Sel) { SetterName = Sel; } + + ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } + void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } + + ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } + void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } + + // Related to @optional/@required declared in @protocol + void setPropertyImplementation(PropertyControl pc) { + PropertyImplementation = pc; + } + PropertyControl getPropertyImplementation() const { + return PropertyControl(PropertyImplementation); + } + + void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { + PropertyIvarDecl = Ivar; + } + ObjCIvarDecl *getPropertyIvarDecl() const { + return PropertyIvarDecl; + } + + virtual SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(AtLoc, getLocation()); + } + + /// 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 + + /// \brief For @synthesize, the location of the ivar, if it was written in + /// the source code. + /// + /// \code + /// @synthesize int a = b + /// \endcode + SourceLocation IvarLoc; + + /// Property declaration being implemented + ObjCPropertyDecl *PropertyDecl; + + /// Null for @dynamic. Required for @synthesize. + ObjCIvarDecl *PropertyIvarDecl; + + /// Null for @dynamic. Non-null if property must be copy-constructed in getter + Expr *GetterCXXConstructor; + + /// Null for @dynamic. Non-null if property has assignment operator to call + /// in Setter synthesis. + Expr *SetterCXXAssignment; + + ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L, + ObjCPropertyDecl *property, + Kind PK, + ObjCIvarDecl *ivarDecl, + SourceLocation ivarLoc) + : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), + IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl), + GetterCXXConstructor(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, + SourceLocation ivarLoc); + + static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + virtual SourceRange getSourceRange() const LLVM_READONLY; + + SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } + void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } + + ObjCPropertyDecl *getPropertyDecl() const { + return PropertyDecl; + } + void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; } + + Kind getPropertyImplementation() const { + return PropertyIvarDecl ? Synthesize : Dynamic; + } + + ObjCIvarDecl *getPropertyIvarDecl() const { + return PropertyIvarDecl; + } + SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; } + + void setPropertyIvarDecl(ObjCIvarDecl *Ivar, + SourceLocation IvarLoc) { + PropertyIvarDecl = Ivar; + this->IvarLoc = IvarLoc; + } + + 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; } + + friend class ASTDeclReader; +}; + +} // end namespace clang +#endif diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h new file mode 100644 index 0000000..36549ea --- /dev/null +++ b/clang/include/clang/AST/DeclTemplate.h @@ -0,0 +1,2106 @@ +//===-- 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/Redeclarable.h" +#include "clang/AST/TemplateBase.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/Support/Compiler.h" +#include + +namespace clang { + +class TemplateParameterList; +class TemplateDecl; +class RedeclarableTemplateDecl; +class FunctionTemplateDecl; +class ClassTemplateDecl; +class ClassTemplatePartialSpecializationDecl; +class TemplateTypeParmDecl; +class NonTypeTemplateParmDecl; +class TemplateTemplateParmDecl; +class TypeAliasTemplateDecl; + +/// \brief Stores a template parameter of any kind. +typedef llvm::PointerUnion3 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; + +protected: + TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, + NamedDecl **Params, unsigned NumParams, + SourceLocation RAngleLoc); + +public: + static TemplateParameterList *Create(const 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(this + 1); } + const_iterator begin() const { + return reinterpret_cast(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]; + } + + /// \brief Returns the minimum number of arguments needed to form a + /// template specialization. This may be fewer than the number of + /// template parameters, if some of the parameters have default + /// arguments or if there is a parameter pack. + unsigned getMinRequiredArguments() const; + + /// \brief Get the depth of this template parameter list in the set of + /// template parameter lists. + /// + /// The first template parameter list in a declaration will have depth 0, + /// the second template parameter list will have depth 1, etc. + unsigned getDepth() const; + + SourceLocation getTemplateLoc() const { return TemplateLoc; } + SourceLocation getLAngleLoc() const { return LAngleLoc; } + SourceLocation getRAngleLoc() const { return RAngleLoc; } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(TemplateLoc, RAngleLoc); + } +}; + +/// FixedSizeTemplateParameterList - Stores a list of template parameters for a +/// TemplateDecl and its derived classes. Suitable for creating on the stack. +template +class FixedSizeTemplateParameterList : public TemplateParameterList { + NamedDecl *Params[N]; + +public: + FixedSizeTemplateParameterList(SourceLocation TemplateLoc, + SourceLocation LAngleLoc, + NamedDecl **Params, SourceLocation RAngleLoc) : + TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) { + } +}; + +/// \brief A template argument list. +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 Arguments; + + /// \brief The number of template arguments in this template + /// argument list. + unsigned NumArguments; + + TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL + void operator=(const TemplateArgumentList &Other); // DO NOT IMPL + + TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, + bool Owned) + : Arguments(Args, Owned), NumArguments(NumArgs) { } + +public: + /// \brief Type used to indicate that the template argument list itself is a + /// stack object. It does not own its template arguments. + enum OnStackType { OnStack }; + + /// \brief Create a new template argument list that copies the given set of + /// template arguments. + static TemplateArgumentList *CreateCopy(ASTContext &Context, + const TemplateArgument *Args, + unsigned NumArgs); + + /// \brief Construct a new, temporary template argument list on the stack. + /// + /// The template argument list does not own the template arguments + /// provided. + explicit TemplateArgumentList(OnStackType, + const TemplateArgument *Args, unsigned NumArgs) + : Arguments(Args, false), NumArguments(NumArgs) { } + + /// \brief Produces a shallow copy of the given template argument list. + /// + /// This operation assumes that the input argument list outlives it. + /// This takes the list as a pointer to avoid looking like a copy + /// constructor, since this really really isn't safe to use that + /// way. + explicit TemplateArgumentList(const TemplateArgumentList *Other) + : Arguments(Other->data(), false), NumArguments(Other->size()) { } + + /// \brief Retrieve the template argument at a given index. + const TemplateArgument &get(unsigned Idx) const { + assert(Idx < NumArguments && "Invalid template argument index"); + return data()[Idx]; + } + + /// \brief Retrieve the template argument at a given index. + const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); } + + /// \brief Retrieve the number of template arguments in this + /// template argument list. + unsigned size() const { return NumArguments; } + + /// \brief Retrieve a pointer to the template argument list. + const TemplateArgument *data() const { + return Arguments.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 { + virtual void anchor(); +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: + /// 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 RedeclarableTemplateDecl *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 classof(const TypeAliasTemplateDecl *D) { return true; } + static bool classofKind(Kind K) { + return K >= firstTemplate && K <= lastTemplate; + } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(TemplateParams->getTemplateLoc(), + TemplatedDecl->getSourceRange().getEnd()); + } + +protected: + NamedDecl *TemplatedDecl; + TemplateParameterList* TemplateParams; + +public: + /// \brief Initialize the underlying templated declaration and + /// template parameters. + void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) { + assert(TemplatedDecl == 0 && "TemplatedDecl already set!"); + assert(TemplateParams == 0 && "TemplateParams already set!"); + TemplatedDecl = templatedDecl; + TemplateParams = templateParams; + } +}; + +/// \brief Provides information about a function template specialization, +/// which is a FunctionDecl that has been explicitly specialization or +/// instantiated from a function template. +class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode { + FunctionTemplateSpecializationInfo(FunctionDecl *FD, + FunctionTemplateDecl *Template, + TemplateSpecializationKind TSK, + const TemplateArgumentList *TemplateArgs, + const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation POI) + : Function(FD), + Template(Template, TSK - 1), + TemplateArguments(TemplateArgs), + TemplateArgumentsAsWritten(TemplateArgsAsWritten), + PointOfInstantiation(POI) { } + +public: + static FunctionTemplateSpecializationInfo * + Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, + TemplateSpecializationKind TSK, + const TemplateArgumentList *TemplateArgs, + const TemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation POI); + + /// \brief The function template specialization that this structure + /// describes. + FunctionDecl *Function; + + /// \brief The function template from which this function template + /// specialization was generated. + /// + /// The two bits are contain the top 4 values of TemplateSpecializationKind. + llvm::PointerIntPair Template; + + /// \brief The template arguments used to produce the function template + /// specialization from the function template. + const TemplateArgumentList *TemplateArguments; + + /// \brief The template arguments as written in the sources, if provided. + const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten; + + /// \brief The point at which this function template specialization was + /// first instantiated. + SourceLocation PointOfInstantiation; + + /// \brief Retrieve the template from which this function was specialized. + FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); } + + /// \brief Determine what kind of template specialization this is. + TemplateSpecializationKind getTemplateSpecializationKind() const { + return (TemplateSpecializationKind)(Template.getInt() + 1); + } + + bool isExplicitSpecialization() const { + return getTemplateSpecializationKind() == TSK_ExplicitSpecialization; + } + + /// \brief 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->data(), + TemplateArguments->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, +/// member class or member enumeration. +class MemberSpecializationInfo { + // The member declaration from which this member was instantiated, and the + // manner in which the instantiation occurred (in the lower two bits). + llvm::PointerIntPair MemberAndTSK; + + // The point at which this member was first instantiated. + SourceLocation PointOfInstantiation; + +public: + explicit + MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, + SourceLocation POI = SourceLocation()) + : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) { + assert(TSK != TSK_Undeclared && + "Cannot encode undeclared template specializations for members"); + } + + /// \brief Retrieve the member declaration from which this member was + /// instantiated. + NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); } + + /// \brief Determine what kind of template specialization this is. + TemplateSpecializationKind getTemplateSpecializationKind() const { + return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1); + } + + /// \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 void foo(T); +/// template 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(this+1); + } + +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 explicit template arguments that were given. + const TemplateArgumentLoc *getTemplateArgs() const { + return reinterpret_cast( + &getTemplates()[getNumTemplates()]); + } + + /// \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 redeclarable template. +class RedeclarableTemplateDecl : public TemplateDecl, + public Redeclarable +{ + typedef Redeclarable redeclarable_base; + virtual RedeclarableTemplateDecl *getNextRedeclaration() { + return RedeclLink.getNext(); + } + virtual RedeclarableTemplateDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + +protected: + template struct SpecEntryTraits { + typedef EntryType DeclType; + + static DeclType *getMostRecentDecl(EntryType *D) { + return D->getMostRecentDecl(); + } + }; + + template , + typename _DeclType = typename _SETraits::DeclType> + class SpecIterator : public std::iterator { + typedef _SETraits SETraits; + typedef _DeclType DeclType; + + typedef typename llvm::FoldingSet::iterator SetIteratorType; + + SetIteratorType SetIter; + + public: + SpecIterator() : SetIter() {} + SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {} + + DeclType *operator*() const { + return SETraits::getMostRecentDecl(&*SetIter); + } + DeclType *operator->() const { return **this; } + + SpecIterator &operator++() { ++SetIter; return *this; } + SpecIterator operator++(int) { + SpecIterator tmp(*this); + ++(*this); + return tmp; + } + + bool operator==(SpecIterator Other) const { + return SetIter == Other.SetIter; + } + bool operator!=(SpecIterator Other) const { + return SetIter != Other.SetIter; + } + }; + + template + SpecIterator makeSpecIterator(llvm::FoldingSet &Specs, + bool isEnd) { + return SpecIterator(isEnd ? Specs.end() : Specs.begin()); + } + + template typename SpecEntryTraits::DeclType* + findSpecializationImpl(llvm::FoldingSet &Specs, + const TemplateArgument *Args, unsigned NumArgs, + void *&InsertPos); + + struct CommonBase { + CommonBase() : InstantiatedFromMember(0, false) { } + + /// \brief The template from which this was most + /// directly instantiated (or null). + /// + /// The boolean value indicates whether this template + /// was explicitly specialized. + llvm::PointerIntPair + InstantiatedFromMember; + }; + + /// \brief Pointer to the common data shared by all declarations of this + /// template. + CommonBase *Common; + + /// \brief Retrieves the "common" pointer shared by all (re-)declarations of + /// the same template. Calling this routine may implicitly allocate memory + /// for the common pointer. + CommonBase *getCommonPtr(); + + virtual CommonBase *newCommon(ASTContext &C) = 0; + + // Construct a template decl with name, parameters, and templated element. + RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName Name, TemplateParameterList *Params, + NamedDecl *Decl) + : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { } + +public: + template friend class RedeclarableTemplate; + + /// Retrieves the canonical declaration of this template. + RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDeclaration(); } + const RedeclarableTemplateDecl *getCanonicalDecl() const { + return getFirstDeclaration(); + } + + /// \brief Determines whether this template was a specialization of a + /// member template. + /// + /// In the following example, the function template \c X::f and the + /// member template \c X::Inner are member specializations. + /// + /// \code + /// template + /// struct X { + /// template void f(T, U); + /// template struct Inner; + /// }; + /// + /// template<> template + /// void X::f(int, T); + /// template<> template + /// struct X::Inner { /* ... */ }; + /// \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); + } + + /// \brief Retrieve the member template from which this template was + /// instantiated, or NULL if this template was not instantiated from a + /// member template. + /// + /// A template is instantiated from a member template when the member + /// template itself is part of a class template (or member thereof). For + /// example, given + /// + /// \code + /// template + /// struct X { + /// template void f(T, U); + /// }; + /// + /// void test(X x) { + /// x.f(1, 'a'); + /// }; + /// \endcode + /// + /// \c X::f is a FunctionTemplateDecl that describes the function + /// template + /// + /// \code + /// template void X::f(int, U); + /// \endcode + /// + /// which was itself created during the instantiation of \c X. Calling + /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will + /// retrieve the FunctionTemplateDecl for the original template "f" within + /// the class template \c X, i.e., + /// + /// \code + /// template + /// template + /// void X::f(T, U); + /// \endcode + RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() { + return getCommonPtr()->InstantiatedFromMember.getPointer(); + } + + void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) { + assert(!getCommonPtr()->InstantiatedFromMember.getPointer()); + getCommonPtr()->InstantiatedFromMember.setPointer(TD); + } + + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const RedeclarableTemplateDecl *D) { return true; } + static bool classof(const FunctionTemplateDecl *D) { return true; } + static bool classof(const ClassTemplateDecl *D) { return true; } + static bool classof(const TypeAliasTemplateDecl *D) { return true; } + static bool classofKind(Kind K) { + return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate; + } + + friend class ASTReader; + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +template <> struct RedeclarableTemplateDecl:: +SpecEntryTraits { + typedef FunctionDecl DeclType; + + static DeclType * + getMostRecentDecl(FunctionTemplateSpecializationInfo *I) { + return I->Function->getMostRecentDecl(); + } +}; + +/// Declaration of a template function. +class FunctionTemplateDecl : public RedeclarableTemplateDecl { + static void DeallocateCommon(void *Ptr); + +protected: + /// \brief Data that is common to all of the declarations of a given + /// function template. + struct Common : CommonBase { + Common() : InjectedArgs(0) { } + + /// \brief The function template specializations for this function + /// template, including explicit specializations and instantiations. + llvm::FoldingSet Specializations; + + /// \brief The set of "injected" template arguments used within this + /// function template. + /// + /// This pointer refers to the template arguments (there are as + /// many template arguments as template parameaters) for the function + /// template, and is allocated lazily, since most function templates do not + /// require the use of this information. + TemplateArgument *InjectedArgs; + }; + + FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { } + + CommonBase *newCommon(ASTContext &C); + + Common *getCommonPtr() { + return static_cast(RedeclarableTemplateDecl::getCommonPtr()); + } + + friend class FunctionDecl; + + /// \brief Retrieve the set of function template specializations of this + /// function template. + llvm::FoldingSet &getSpecializations() { + return getCommonPtr()->Specializations; + } + + /// \brief Add a specialization of this function template. + /// + /// \param InsertPos Insert position in the FoldingSet, must have been + /// retrieved by an earlier call to findSpecialization(). + void addSpecialization(FunctionTemplateSpecializationInfo* Info, + void *InsertPos); + +public: + /// Get the underlying function declaration of the template. + FunctionDecl *getTemplatedDecl() const { + return static_cast(TemplatedDecl); + } + + /// Returns whether this template declaration defines the primary + /// pattern. + bool isThisDeclarationADefinition() const { + return getTemplatedDecl()->isThisDeclarationADefinition(); + } + + /// \brief Return the specialization with the provided arguments if it exists, + /// otherwise return the insertion point. + FunctionDecl *findSpecialization(const TemplateArgument *Args, + unsigned NumArgs, void *&InsertPos); + + FunctionTemplateDecl *getCanonicalDecl() { + return cast( + RedeclarableTemplateDecl::getCanonicalDecl()); + } + const FunctionTemplateDecl *getCanonicalDecl() const { + return cast( + RedeclarableTemplateDecl::getCanonicalDecl()); + } + + /// \brief Retrieve the previous declaration of this function template, or + /// NULL if no such declaration exists. + FunctionTemplateDecl *getPreviousDecl() { + return cast_or_null( + RedeclarableTemplateDecl::getPreviousDecl()); + } + + /// \brief Retrieve the previous declaration of this function template, or + /// NULL if no such declaration exists. + const FunctionTemplateDecl *getPreviousDecl() const { + return cast_or_null( + RedeclarableTemplateDecl::getPreviousDecl()); + } + + FunctionTemplateDecl *getInstantiatedFromMemberTemplate() { + return cast_or_null( + RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); + } + + typedef SpecIterator spec_iterator; + + spec_iterator spec_begin() { + return makeSpecIterator(getSpecializations(), false); + } + + spec_iterator spec_end() { + return makeSpecIterator(getSpecializations(), true); + } + + /// \brief Retrieve the "injected" template arguments that correspond to the + /// template parameters of this function template. + /// + /// Although the C++ standard has no notion of the "injected" template + /// arguments for a function template, the notion is convenient when + /// we need to perform substitutions inside the definition of a function + /// template. + std::pair getInjectedTemplateArgs(); + + /// \brief Create a function template node. + static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + DeclarationName Name, + TemplateParameterList *Params, + NamedDecl *Decl); + + /// \brief Create an empty function template node. + static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + // Implement isa/cast/dyncast support + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const FunctionTemplateDecl *D) { return true; } + static bool classofKind(Kind K) { return K == FunctionTemplate; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +//===----------------------------------------------------------------------===// +// 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) + { /* llvm_unreachable("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; } + void setDepth(unsigned D) { Depth = D; } + + /// Get the position of the template parameter within its parameter list. + unsigned getPosition() const { return Position; } + void setPosition(unsigned P) { Position = P; } + + /// Get the index of the template parameter within its parameter list. + unsigned getIndex() const { return Position; } +}; + +/// TemplateTypeParmDecl - Declaration of a template type parameter, +/// e.g., "T" in +/// @code +/// template 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 The default template argument, if any. + TypeSourceInfo *DefaultArgument; + + TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + bool Typename) + : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename), + InheritedDefault(false), DefaultArgument() { } + + /// Sema creates these on the stack during auto type deduction. + friend class Sema; + +public: + static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC, + SourceLocation KeyLoc, + SourceLocation NameLoc, + unsigned D, unsigned P, + IdentifierInfo *Id, bool Typename, + bool ParameterPack); + static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, + unsigned ID); + + /// \brief Whether this template type parameter was declared with + /// the 'typename' keyword. If not, it was declared with the 'class' + /// keyword. + bool wasDeclaredWithTypename() const { return Typename; } + + /// \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 Set whether this template type parameter was declared with + /// the 'typename' or 'class' keyword. + void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; } + + /// \brief Retrieve the depth of the template parameter. + unsigned getDepth() const; + + /// \brief Retrieve the index of the template parameter. + unsigned getIndex() const; + + /// \brief Returns whether this is a parameter pack. + bool isParameterPack() const; + + SourceRange getSourceRange() const LLVM_READONLY; + + // 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 class array { }; +/// @endcode +class NonTypeTemplateParmDecl + : public DeclaratorDecl, protected TemplateParmPosition { + /// \brief The default template argument, if any, and whether or not + /// it was inherited. + llvm::PointerIntPair DefaultArgumentAndInherited; + + // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index + // down here to save memory. + + /// \brief Whether this non-type template parameter is a parameter pack. + bool ParameterPack; + + /// \brief Whether this non-type template parameter is an "expanded" + /// parameter pack, meaning that its type is a pack expansion and we + /// already know the set of types that expansion expands to. + bool ExpandedParameterPack; + + /// \brief The number of types in an expanded parameter pack. + unsigned NumExpandedTypes; + + NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, unsigned D, unsigned P, + IdentifierInfo *Id, QualType T, + bool ParameterPack, TypeSourceInfo *TInfo) + : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), + TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false), + ParameterPack(ParameterPack), ExpandedParameterPack(false), + NumExpandedTypes(0) + { } + + NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, unsigned D, unsigned P, + IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, + const QualType *ExpandedTypes, + unsigned NumExpandedTypes, + TypeSourceInfo **ExpandedTInfos); + + friend class ASTDeclReader; + +public: + static NonTypeTemplateParmDecl * + Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, + QualType T, bool ParameterPack, TypeSourceInfo *TInfo); + + static NonTypeTemplateParmDecl * + Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, + QualType T, TypeSourceInfo *TInfo, + const QualType *ExpandedTypes, unsigned NumExpandedTypes, + TypeSourceInfo **ExpandedTInfos); + + static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, + unsigned ID, + unsigned NumExpandedTypes); + + using TemplateParmPosition::getDepth; + using TemplateParmPosition::setDepth; + using TemplateParmPosition::getPosition; + using TemplateParmPosition::setPosition; + using TemplateParmPosition::getIndex; + + SourceRange getSourceRange() const LLVM_READONLY; + + /// \brief Determine whether this template parameter has a default + /// argument. + bool hasDefaultArgument() const { + return DefaultArgumentAndInherited.getPointer() != 0; + } + + /// \brief Retrieve the default argument, if any. + Expr *getDefaultArgument() const { + return DefaultArgumentAndInherited.getPointer(); + } + + /// \brief Retrieve the location of the default argument, if any. + SourceLocation getDefaultArgumentLoc() const; + + /// \brief Determines whether the default argument was inherited + /// from a previous declaration of this template. + bool defaultArgumentWasInherited() const { + return DefaultArgumentAndInherited.getInt(); + } + + /// \brief Set the default argument for this template parameter, and + /// whether that default argument was inherited from another + /// declaration. + void setDefaultArgument(Expr *DefArg, bool Inherited) { + DefaultArgumentAndInherited.setPointer(DefArg); + DefaultArgumentAndInherited.setInt(Inherited); + } + + /// \brief Removes the default argument of this template parameter. + void removeDefaultArgument() { + DefaultArgumentAndInherited.setPointer(0); + DefaultArgumentAndInherited.setInt(false); + } + + /// \brief Whether this parameter is a non-type template parameter pack. + /// + /// If the parameter is a parameter pack, the type may be a + /// \c PackExpansionType. In the following example, the \c Dims parameter + /// is a parameter pack (whose type is 'unsigned'). + /// + /// \code + /// template struct multi_array; + /// \endcode + bool isParameterPack() const { return ParameterPack; } + + /// \brief Whether this parameter is a non-type template parameter pack + /// that has different types at different positions. + /// + /// A parameter pack is an expanded parameter pack when the original + /// parameter pack's type was itself a pack expansion, and that expansion + /// has already been expanded. For example, given: + /// + /// \code + /// template + /// struct X { + /// template + /// struct Y { /* ... */ }; + /// }; + /// \endcode + /// + /// The parameter pack \c Values has a \c PackExpansionType as its type, + /// which expands \c Types. When \c Types is supplied with template arguments + /// by instantiating \c X, the instantiation of \c Values becomes an + /// expanded parameter pack. For example, instantiating + /// \c X results in \c Values being an expanded parameter + /// pack with expansion types \c int and \c unsigned int. + /// + /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions + /// return the expansion types. + bool isExpandedParameterPack() const { return ExpandedParameterPack; } + + /// \brief Retrieves the number of expansion types in an expanded parameter + /// pack. + unsigned getNumExpansionTypes() const { + assert(ExpandedParameterPack && "Not an expansion parameter pack"); + return NumExpandedTypes; + } + + /// \brief Retrieve a particular expansion type within an expanded parameter + /// pack. + QualType getExpansionType(unsigned I) const { + assert(I < NumExpandedTypes && "Out-of-range expansion type index"); + void * const *TypesAndInfos = reinterpret_cast(this + 1); + return QualType::getFromOpaquePtr(TypesAndInfos[2*I]); + } + + /// \brief Retrieve a particular expansion type source info within an + /// expanded parameter pack. + TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const { + assert(I < NumExpandedTypes && "Out-of-range expansion type index"); + void * const *TypesAndInfos = reinterpret_cast(this + 1); + return static_cast(TypesAndInfos[2*I+1]); + } + + // 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